我正在尝试使用Entity Framework 5进行具有多对多关系的简单插入 .
我有两个POCO课程如下 .
public class Category
{
public virtual string Title { get; set; }
public virtual DateTime EntryDate { get; set; }
public virtual DateTime LastUpdated { get; set; }
public virtual ICollection<Article> Articles { get; set; }
}
public class Article
{
public virtual string Title { get; set; }
public virtual string Content { get; set; }
public virtual DateTime EntryDate { get; set; }
public virtual DateTime LastUpdated { get; set; }
public virtual ICollection<Category> Categories { get; set; }
}
以下流畅的api映射代码......
public class CategoryMap : EntityTypeConfiguration<Category>
{
public CategoryMap()
{
this.ToTable("Categories");
this.HasKey(x => x.ID);
this.Property(x => x.Title).IsRequired().HasMaxLength(255);
}
}
public class ArticleMap : EntityTypeConfiguration<Article>
{
public ArticleMap()
{
this.ToTable("Articles");
this.HasKey(x => x.ID);
this.HasMany(x => x.Categories)
.WithMany(x => x.Articles)
.Map(x =>
{
x.ToTable("MapArticleCats");
x.MapLeftKey("CategoryID");
x.MapRightKey("ArticleID");
});
this.Property(x => x.Title).IsRequired().HasMaxLength(255);
this.Property(x => x.Content).IsRequired().HasMaxLength(4000);
}
}
然后,实体框架将生成Category和Article表以及第三个映射表,其中详细信息在ArticleMap代码(MapArticleCats)中指定,在SQL Server中如下所示 .
ArticleID - int
CategoryID -int
以下代码(给出或采取几行)将类别添加到我的控制器中的文章 .
IEnumerable<Category> GetCats = CategoryRepository.GetAll();
//DO SOME CODE TO FIGURE WHICH CATEGORIES I NEED.
IEnumerable<Category> Categories = InferCategoriesFromPostedData(Model.Categories, GetCats);
foreach (Category c in Categories)
{
Article.Categories.Add(c);
}
这似乎在插入时产生了一些奇怪的行为 . 它会在类别表(DUPLICATE)中插入一个新类别,并将新创建的CategoryID(而不是原始ID)和正确的ArticleID插入MapArticleCats表 .
谁能看到我出错的地方?
3 回答
好吧,在提交这篇文章之前我应该做的事情(以及之前的那些...大规模有罪)是搜索StackOverflow并且更加彻底 .
我找到了问题的答案here
发生的事情完全与上面的代码无关 . 这是因为我基本上将两个数据上下文注入我的控制器(一个在文章存储库中,另一个在类别存储库中),因此创建了重复的记录 .
==================================================================================
IMPORTANT EDIT
==================================================================================
只是详细说明我的答案......
即使在完成上述修复之后,这仍然无法解决我无法更新导航属性(类别)的原始问题 . 对此的修复程序如下所示......
我是使用AsNoTracking()绑定实体(文章)的模型,如果你只想更新主实体本身但你不能对导航属性做任何事情,这是可以的 . 例如在我的案例中添加/删除文章中的类别 .
这让我有点蠢蠢,因为我通过将实体与上下文分离来尝试类似的方法,但这两种方式最终给我带来了无法操纵导航属性的相同问题 .
解决这个问题的方法只是简单地模拟绑定/选择实体 . 没有AsNoTracking(),没有分离 . 当将实体附加回上下文时,使用以下代码...
这样你可以选择它而不用任何AsNoTracking / Detaching垃圾,它会更新得很好 . 这对我来说没问题,有些人可能会发现额外的数据库攻击有点令人反感,但为了所有那些适合我的悲伤就好了 .
对我来说问题是我试图将新实例设置为导航属性 .
我在做:
相反,你应该坚持现有的ICollection实例,如下所示:
重复的PRIMARY KEY错误消失了 .
在dbcontext CaveChanges调用中:
这对我有用 .