1
下面的方法将一些分离的节点作为输入参数。目标是从数据库加载任何现有的别名,将缺失的节点插入数据库,并且如果分离的节点的别名实体已经在数据库中,只需将其设置为数据库中的一个。实体框架6 - 分离的实体防止保存重复的导航属性
但是,在SaveChanges()上,数据库中已经存在的别名似乎又被插入了。我如何解决这个问题?
internal async Task InsertMissingNodesToDb(INWatchNode[] nodes)
{
if (nodes.Any(x => x == null)) {
Trace.TraceError("Some null element in nodes array in InsertMissingNodesToDb().");
nodes = nodes.Where(x => x != null).ToArray();
}
// De-dup nodes based on ID
nodes = nodes.GroupBy(x => x.Id).Select(y => y.FirstOrDefault()).ToArray();
List<string> aliasNames = new List<string>();
foreach (var node in nodes) {
foreach (var alias in node.Aliases) {
if (!aliasNames.Contains(alias)) {
aliasNames.Add(alias);
}
}
}
using (var dbContext = Application.GetDbContext()) {
dbContext.Aliases.Where(x => aliasNames.Contains(x.Alias)).Load();
foreach (var node in nodes) {
var entityNode = await dbContext.Nodes.FindAsync(node.Id);
if (entityNode == null) {
entityNode = node is NWatchNode ? (NWatchNode)node : new NWatchNode(node);
for (int i = 0; i < entityNode.AliasEntities.Count; i++) {
var currentElement = entityNode.AliasEntities.ElementAt(i);
var loadedAlias = dbContext.Aliases.Local.
FirstOrDefault(x => x.Alias == currentElement.Alias);
if (loadedAlias != null) {
currentElement.Id = loadedAlias.Id;
currentElement = loadedAlias;
dbContext.Entry(loadedAlias).State = EntityState.Unchanged;
}
}
dbContext.Nodes.Add(entityNode);
}
}
await dbContext.SaveChangesAsync();
}
}
'entityNode.AliasEntities.ElementAt(ⅰ)= loadedAlias;'不编译:( AliasEntites是ICollection的,所以我得到的信息,即左手必须是一个属性或索引 – blgrnboy
我或许你需要删除'currentElement',然后添加'loadedAlias'而不是? –
你说得对,我必须做一个'entityNode.AliasEntities.Remove(currentElement);'insetad,然后'entityNode.AliasEntities。添加(loadedAlias);' 偶然的,你知道如果Remove()去掉哈希以找到一个要移除的元素,或者它会使用Id吗? – blgrnboy