繁体   English   中英

实体框架避免多对多关系中的重复

[英]Entity Framework avoid duplications in many to many relations

我对 EF 6 数据库优先的方法有些困惑。

我在 SQL 服务器中有 3 个表:

  • 成员
  • 团队
  • JT_Teams_Members(联结表)

我想将数据插入到这种关系中。

从代码中,我得到了我迭代的团队列表

插入:

foreach (var team in teams.Teams)
{
    var teamEntity = new Contexts.Team
            {
                TeamName = team.Name,
                ....
            };

    foreach (var member in team.Members)
    {
        teamEntity.Members.Add(
                new Contexts.Member()
                {
                    MemberName = member.Name,
                    EmailAddress = member.Email,  
                ...
                });
    }

    DbUtility.Context.Teams.Add(teamEntity);
}

我的问题是我在 members 表中发现了很多重复,这不太好。

如何管理插入以避免重复并将 ID 重定向到正确的位置?

在处理关联时,您将希望对相关实体使用相同的引用,而不是为每个相关实体新建一个引用。

如果我要插入多个包含成员的团队,其中一些成员可能是新成员并在团队之间共享,而其他成员可能是数据库中已有的成员:

  1. 对于所有关联实体,始终在您的视图模型中传递 PK。 对于会员,如果您可以从现有会员中获取 select,即使您只显示姓名和电子邮件地址,也请在您的视图 model 中传递会员 ID 以供以后查找。

从那里我们可以开始看下面的东西:

var memberIds = teams.Teams
    .SelectMany(t => t.Members)
    .Select(m => m.MemberId)
    .Where(m => m.MemberId != 0)
    .ToList();

var existingMembers = Context.Members
    .Where(m => memberIds.Contains(m.MemberId))
    .ToList();


foreach (var team in teams.Teams)
{
    var teamEntity = new Contexts.Team
    {
        TeamName = team.Name,
        ....
    };

    foreach (var member in team.Members)
    {   //We assume that all e-mail addresses are unique.
        var existingMember = existingMembers.SingleOrDefault(m => m.Email == member.Email);
        if (existingMember == null)
        {
            existingMember = new Member()
            {
                MemberName = member.Name,
                EmailAddress = member.Email,  
            ...
            });
            existingMembers.Add(existingMember); // For future reference.
        }
        teamEntity.Members.Add(existingMember);
    }

    DbUtility.Context.Teams.Add(teamEntity);
}

第一步是为团队寻找任何现有成员。 如果您知道将存在现有成员,那么您可以跳过该加载,而只需使用最初为空的集合。 当我们通过我们的团队 go 时,我们首先检查现有集合中是否有与电子邮件地址匹配的成员。 如果我们找到一个,我们使用它,否则我们创建一个新成员并将其添加到集合中。 这样,当添加具有相同成员的另一个团队时,它会在集合中找到并且将使用相同的引用。

当 EF 插入数据时,它尊重引用,不一定是 ID/约束将实体关联到相同的引用,而不是创建重复项。 如果您有 2 个实体引用同一个成员 (joe.smith@gmail.com),那么您要确保两个实体引用 joe.smith 的同一个成员实体,而不是 2 个具有相同电子邮件地址的不同实体。 在处理批量操作(插入许多团队)时,您将希望保留本地缓存或从 DbContext 读取以利用其缓存。 对于单个操作,您应该始终 go 到 DbContext 以在尝试创建新引用之前检索现有实体(如果可用)。 (避免重复数据或违反约束/重复键异常。)

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM