EF:在多对多关系

时间:2018-06-11 08:07:41

标签: sql sql-server entity-framework linq

对于我搜索的内容,有两种方法可以将已存在的记录插入ICollection列表中:

  1. group.Users.Add(db.Users.FirstOrDefault(x=> x.Id = 1));
  2. var to_add = new User{Id: 1}; db.Users.Attach(to_add); group.Users.Add(to_add);
  3. 上述方法的问题是每次我们想要添加记录时都会进行db调用。虽然我们已经知道用户的ID和群组的ID以及创建关系所需的全部内容。

    想象一下要添加的长列表,上述两种方法都会对db进行多次调用。

1 个答案:

答案 0 :(得分:0)

所以你有GroupsUsers。每个Group都有零个或多个Users;每个User都有零个或多个Groups。传统的多对多关系。

通常会向User添加Group,或向Group添加User。但是,如果您没有Group,也没有User,那么您只有GroupIdUserId。并且由于大量插入,您不想获取要创建关系的UsersGroups

问题是,如果您可以将GroupId-UserId组合直接添加到联结表中,您怎么知道您不会添加已存在的组 - 用户关系?如果你不在乎,你最终会得到两倍的关系。这会导致问题:如果您要问Users的{​​{1}},是否希望它们显示两次?如果关系结束,应该删除哪一个,还是应该删除它们?

如果你真的想实现双重关系的可能性,那么你需要Implement a a Custom Junction Table as described here额外的字段将是关系的数量。

这对您的大批量没有帮助,因为您仍然需要从自定义联结表中获取字段以增加Group值。

另一方面,如果您不想要双重关系,则必须检查该值是否已存在,并且您在插入之前并不想获取数据。

通常,数据库的添加次数远远少于查询次数。如果要插入大批数据,则通常仅在数据库的初始化阶段进行。我不会太过优化初始化。

考虑记住字典中已经获取的组和用户,防止它们被提取两次。但是,如果您的列表非常庞大,那么这不是一个实用的解决方案。

如果您确实需要长时间使用此功能,请考虑创建一个存储过程来检查联结表中是否已存在GroupId / UserId,如果不存在,请添加它。