以下のメソッドは、いくつかの独立したノードを入力パラメータとして受け取ります。目的は、データベースから既存のエイリアスをロードし、欠落したノードをデータベースに挿入し、デタッチされたノードのエイリアスエンティティがすでにデータベースに存在する場合は、データベースのエイリアスエンティティに設定するだけです。Entity Framework 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(I)= loadedAlias;'コンパイルされない:( AliasEntitesこといるICollectionであるので、私は左手がプロパティまたはインデクサーでなければならないというメッセージを取得 – blgrnboy
Iでした'currentElement'を削除してから' loadedAlias'を追加する必要がありますか? –
あなたは正しく、entityNode.AliasEntities.Remove(currentElement); 'insetad'、' entityNode.AliasEntities'を実行しなければなりませんでした。追加(loadedAlias); ' Remove()が削除する要素を見つけるためにハッシュを解除するか、それともIdを使用するのかを知っていますか? – blgrnboy