EF6 DbContext - 避免重新插入root的子记录

时间:2016-04-28 16:24:37

标签: c# entity-framework entity-framework-6 dbcontext

有一个Node实体。节点可以有许多别名(具有ID和别名(字符串)属性)。别名基于其别名(字符串)属性应该是唯一的。

我正在尝试实现一个将任何缺少的节点插入数据库的方法。传递的节点将包括可能已经或可能不在数据库中的别名集合。由于将节点(根)添加到DbContext也将所有别名标记为EntityState.Added,我最终将一些相同的别名重新插入到数据库中。实际上,如果数据库中存在别名,则应该将节点的引用更新为该别名。

我开始尝试解决这个问题,但是因为我不知道确保DbContext.Aliases.Local中没有重复别名的最佳方法,同时还将EntityState设置为EntityState.Unchaged为那些数据库中已存在的别名。

using (var dbContext = Application.GetDbContext()) {
    foreach (var node in nodes) {
        if (node != null) {
            var entityNode = await dbContext.Nodes.FindAsync(node.Id);

            if (entityNode == null) {
                entityNode = node is Node ? (Node)node : new Node(node);

                // Add root node.  Any navigation properties, such as 
                // aliases will be marked as EntityState.Added by default.
                dbContext.Nodes.Add(entityNode);

                for (int i = 0; i < entityNode.AliasEntities.Count; i++) {
                    var currentElement = entityNode.AliasEntities.ElementAt(i);

                    // Check cache, if null, check database for the Alias
                    var dbAliasEntity = dbContext.Aliases.FirstOrDefaultCache(x => x.Alias == currentElement.Alias);

                    // If Alias already exists in the database, mark it as Unchanged.
                    if (dbAliasEntity != null) {
                        currentElement = dbAliasEntity;
                        dbContext.Entry(currentElement).State = EntityState.Unchanged;
                    }
                }
            }
        }
    }

    await dbContext.SaveChangesAsync();
}

上面的代码目前抛出以下异常:

  

保存或接受更改失败,因为多个实体   类型'NWatch.Entities.NWatchAlias'具有相同的主键值。   确保显式设置的主键值是唯一的。确保这件事   数据库生成的主键在中正确配置   数据库和实体框架模型。使用实体设计器   用于Database First / Model First配置。使用   'HasDatabaseGeneratedOption'流畅的API或   用于Code First配置的'DatabaseGeneratedAttribute'。什么   我需要进行修改才能确保只有别名   插入的数据库中是否已插入?

0 个答案:

没有答案