2017-08-02 49 views
1

我有三个类User,Order &项目存储在单个表中。订单和项目都与用户有n:n的关系。 为了实现我有两个映射这些关系的交叉表(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} 
    ... 
} 

正如你可以看到用户对象包含与单编号/专案编号的每一个列表。

现在我想用Dapper来查询它。我有这个解决方案,它与一个列表很好地工作。但是,如果我尝试查询第二个列表的完整用户对象,我会将每个结果乘以第一个列表中的结果数量。 因此,如果用户有3个单和2个项目orderlist将被罚款和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”的结果集中有多个列。

其次,要获得正确的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