[英]Entity Framework: Avoiding Inserting Duplicates
說,我有以下概念模型,有些標簽有多個標簽(多個,所以它是多對多的關系),加上每個標簽都屬於一個特定的類別。
我的數據來自外部源,在插入之前我想確保沒有添加重復的標簽。
更新的代碼段:
static void Main(string[] args)
{
Story story1 = new Story();
story1.Title = "Introducing the Entity Framework";
story1.Tags.Add(new Tag { Name = ".net", });
story1.Tags.Add(new Tag { Name = "database" });
Story story2 = new Story();
story2.Title = "Working with Managed DirectX";
story2.Tags.Add(new Tag { Name = ".net" });
story2.Tags.Add(new Tag { Name = "graphics" });
List<Story> stories = new List<Story>();
stories.Add(story1);
stories.Add(story2);
EfQuestionEntities db = new EfQuestionEntities();
Category category = (from c in db.Categories
where c.Name == "Programming"
select c).First();
foreach (Story story in stories)
{
foreach (Tag tag in story.Tags)
{
Tag currentTag = tag;
currentTag = GetTag(tag.Name, category, db);
}
db.Stories.AddObject(story);
}
db.SaveChanges();
}
public static Tag GetTag(string name, Category category, EfQuestionEntities db)
{
var dbTag = from t in db.Tags.Include("Category")
where t.Name == name
select t;
if (dbTag.Count() > 0)
{
return dbTag.First();
}
var cachedTag = db.ObjectStateManager.GetObjectStateEntries(EntityState.Added).
Where(ose => ose.EntitySet == db.Tags.EntitySet).
Select(ose => ose.Entity).
Cast<Tag>().Where(x => x.Name == name);
if (cachedTag.Count() != 0)
{
return cachedTag.First();
}
Tag tag = new Tag();
tag.Name = name;
tag.Category = category;
db.Tags.AddObject(tag);
return tag;
}
但是,我得到一個異常,該對象具有與ObjectContext中已存在的相同的EntityKey。
此外,如果我刪除else語句,我將獲得有關違反FK約束的異常,因此它的Category屬性似乎設置為null。
我和EF有同樣的問題。 這是我最終做的事情:
story1.Tags.Add(new Tag { Name = ".net", })
,通過這樣的幫助方法路由所有Tag
創建: story1.Tags.Add(GetTag(".net"))
。 GetTag
方法檢查上下文中的標記,以查看它是否應該返回現有實體,就像您一樣。 如果是,則返回該值。 ObjectStateManager
以查看是否有Tag
實體添加到上下文但尚未寫入db。 如果找到匹配的Tag
,則返回該Tag
。 Tag
,它會創建一個新Tag
,將其添加到上下文中,然后返回它。 實質上,這將確保在整個程序中將使用任何Tag
的任何實例(無論是已存在還是剛創建)。
一些示例代碼從我的項目中解除(使用InventoryItem
而不是Tag
,但是你明白了)。
步驟3中的檢查是這樣完成的:
// Second choice: maybe it's not in the database yet, but it's awaiting insertion?
inventoryItem = context.ObjectStateManager.GetObjectStateEntries(EntityState.Added)
.Where(ose => ose.EntitySet == context.InventoryItems.EntitySet)
.Select(ose => ose.Entity)
.Cast<InventoryItem>()
.Where(equalityPredicate.Compile())
.SingleOrDefault();
if (inventoryItem != null) {
return inventoryItem;
}
如果在步驟3中找不到Tag
,則這是步驟4的代碼:
inventoryItem = new InventoryItem();
context.InventoryItems.AddObject(inventoryItem);
return inventoryItem;
更新:
它應該像這樣使用:
Story story1 = new Story();
story1.Title = "Introducing the Entity Framework";
story1.Tags.Add(GetTag(".net", category, db));
story1.Tags.Add(GetTag("database", category, db));
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.