User、Order、Projectの3つのクラスがあり、これらは1つのテーブルに格納されています。注文とプロジェクトはどちらもユーザーと:nの関係があります。これを実装するために、これらの関係をマップする2つのクロステーブル(UserOrders、UserProjects)があります。
public class User
{
public string UserID {get;set;}
public List<string> Orders{get;set;}
public List<string> Projects {get;set;}
}
public class Order
{
public string OrderID {get;set}
...
}
public class Project
{
public string ProjectID {get;set}
...
}
ご覧のとおり、Userオブジェクトには、関連するすべてのorderID / projectIDのリストが含まれています。
今、私はこれをDapperで照会したいと思います。私は1つのリストでかなりうまく機能するこのソリューションを持っています。しかし、2番目のリストの完全なユーザーオブジェクトをクエリしようとすると、すべての結果に最初のリストの結果の数が乗算されます。したがって、ユーザーが3つの注文と2つのプロジェクトを受け取った場合、注文リストは問題なく、プロジェクトリストには両方のプロジェクトが3回含まれます。
var lookup = new Dictionary<string, User>();
var multi = dbDapperFM.Query<User, string, string, User>("SELECT u.*, uo.OrderID, up.ProjectID "+
"FROM User u INNER JOIN UserOrders uo ON u.UserID=uo.UserID "+
"INNER JOIN UserProjects up ON u.UserID=up.UserID", (u, uo, up) =>
{
User user;
if (!lookup.TryGetValue(m.UserID, out user))
lookup.Add(u.UserID, user= u);
if (user.Orders == null)
user.Orders = new List<string>();
user.Orders.Add(uo);
if (user.Projects == null)
user.Projects = new List<string>();
user.Projects.Add(up);
return user;
}, splitOn: "UserID , OrderID, ProjectID ").AsQueryable();
この問題が発生する理由(2つの内部結合)は理解していますが、実際には解決方法がわかりません。
また、Dapperがこれを自動的に行わないという事実を理解するのに苦労しました。
まず、「splitOn」のカンマ区切りの値についてはよくわかりません。そこには1つの価値しかないと思いました。たとえば、結果セットには「ID」という名前の複数の列があります。
次に、適切な1:N関係を取得するには、追加の手動手順を実行する必要があります。たとえば、参加者とその電話番号を2テーブルで結合しました。それから私はこれをしなければなりませんでした:
private List<Participant> CollapseResultSet(List<Participant> rawdataset)
{
List<Participant> ret = new List<Participant>();
if (!rawdataset.Any())
{
return ret;
}
else
{
List<string> partIds = rawdataset.Select(p => p.ID).Distinct().ToList();
foreach (string pId in partIds)
{
Participant tmp = rawdataset.Where(p => p.ID == pId).FirstOrDefault();
tmp.PhoneNumbers = rawdataset.Where(p => p.ID == pId).Select(n => n.PhoneNumbers[0]).ToList();
ret.Add(tmp);
}
return ret;
}
}
それがお役に立てば幸いです。
この記事はインターネットから収集されたものであり、転載の際にはソースを示してください。
侵害の場合は、連絡してください[email protected]
コメントを追加