2017-08-02 5 views
1

私は3つのクラスUser、Orderを持っています&単一のテーブルに格納されているプロジェクト。注文とプロジェクトはどちらもユーザーとn: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} 
    ... 
} 

はのorderID/PROJECTID関連のすべてのリストが含まれています。

これでDapperを使用してクエリを実行します。私はのリストでかなりうまく動作するこの解決策を得ました。しかし、2番目のリストの完全なユーザーオブジェクトを照会しようとすると、すべての結果に最初のリストの結果の数が乗算されます。 ユーザーが3桁と2つのプロジェクトを得たのであればオーダーリストは、罰金になりますとprojectlistは、両方のプロジェクトの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(); 

この問題はoccuresなぜ私は(2内部結合)を理解するが、私はしませんが本当にそれを解決する方法を得る。

答えて

1

Dapperがこれを自動的に実行しないという事実を把握するのにも苦労しました。

まず、「splitOn」のコンマ区切り値についてはわかりません。私はあなたがそこで一つの価値しか持てないと思った。ですから、結果セットには複数の列があり、たとえば "ID"という名前が付けられています。

第2に、適切な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; 
    } 
} 

+0

実際に私は同じような解決策を得て、私は1対Nの関係を照会し、foreach – emuuu

関連する問題