【发布时间】:2015-03-22 00:38:15
【问题描述】:
对象
public class Noun
{
public int Id { get; set; }
[MaxLength(128)]
public string Name { get; set; }
public bool Active { get; set; }
public virtual Category Category { get; set; }
public int CategoryId { get; set; }
}
public class Category
{
public int Id { get; set; }
[MaxLength(128)]
public string Name { get; set; }
}
存储库
public Noun CreateNoun(string name, string categoryName)
{
using (MyContext context = new MyContext())
{
Noun noun;
Category category;
lock (NounLock)
{
// don't create it if it already exists
noun = context.Nouns
.Include(t => t.Category)
.FirstOrDefault(t => t.Name == name && t.Category.Name == categoryName);
if (noun == null)
{
// make the category if it doesn't already exist
lock (CategoryLock)
{
category = context.Categories.FirstOrDefault(c => c.Name == categoryName);
if (category == null)
{
category = new Category() { Name = categoryName };
context.Categories.Add(category);
context.SaveChanges();
}
}
noun = new Noun()
{
Name = name,
Category = category,
CategoryId = category.Id
};
context.Nouns.Add(noun);
}
else
{
category = noun.Category;
}
// make sure the noun is set as active
noun.Active = true;
context.Entry(category).State = EntityState.Unchanged;
context.SaveChanges();
return noun;
}
}
}
上下文
internal class MyContext : DbContext
{
public DbSet<Category> Categories { get; set; }
public DbSet<Noun> Nouns { get; set; }
public MyContext()
: base("DefaultConnection")
{
}
protected override void OnModelCreating(DbModelBuilder modelBuilder)
{
// Nouns
modelBuilder.Entity<Noun>()
.HasRequired(t => t.Category);
}
}
问题
当调用 CreateNoun() 时,当该类别的名词已经存在时,它应该(基于我认为我正在做的事情),只需从数据库中加载现有名词并将其标记为活动。但相反,它插入了一个新名词和一个新类别。我究竟做错了什么?我知道这可能是一件小事。
PS:锁是静态的并且就位,因为这可能被多线程租户使用
示例
Noun newNoun = repo.CreateNoun("name", "cat");
// should load existing noun from db, and set it as active, but instead duplicates it
Noun oldNoun = repo.CreateNoun("name", "cat");
【问题讨论】:
-
检查以确保您的重复检查实际上得到了重复。
-
尝试删除 context.Entry(category).State = EntityState.Unchanged 看看是否有影响。
-
我发现了问题,完全是在另一个线程中被 Noun 欺骗了 :( 多线程很棒。感谢所有 cmets/回复,为大家点赞!
标签: c# entity-framework ef-code-first entity-framework-6 duplication