我使用实体框架(6.1.3)和代码第一种方法。我有一个模型类电影和一个模型类标签,如下所示:
public class Movie
{
public int Id { get; set; }
public string Name { get; set; }
public ICollection<Tag> Tags { get; set; }
}
public class Tag
{
public int Id { get; set; }
public string Name { get; set; }
}
在DbContext中,我覆盖了OnModelCreating方法来设置这样的一对多关系:
protected override void OnModelCreating(DbModelBuilder modelBuilder)
{
modelBuilder.Entity<Movie>()
.HasMany(a => a.Tags)
.WithMany()
.Map(x =>
{
x.MapLeftKey("Movie_Id");
x.MapRightKey("Tag_Id");
x.ToTable("MovieTags");
});
base.OnModelCreating(modelBuilder);
}
如果我尝试使用某些标签将电影插入数据库,我就会遇到创建不需要的标签的问题。
例如我已经有两个标签&#34; Foo&#34; (Id:1)和&#34; Bar&#34; (Id:2)在数据库中。现在我创建一个新的Movie对象并插入现有的Tag&#34; Foo&#34; (从数据库加载)和新标签&#34; Foobar&#34;到对象的集合。将此影片添加到DbContext并调用Method&#34; SaveChanges&#34;我的数据库中有两个新标签。
为什么实体框架会在我的数据库中插入现有标签?我需要更改只插入缺少的标签吗?
修改-1: 这是Controller代码,我在其中添加标签并保存
List<Tag> tagList = new List<Tag>();
// ViewModel.Tags either contains the Tag-Id or the Tag-Name (if it is new)
foreach (string tag in viewModel.Tags)
{
if (IsDigitsOnly(tag))
{
// Load the existing Tag from the DbContext and add to List
tagList.Add(TagService.Get(int.Parse(tag)));
}
else
{
// Create new Tag
tagList.Add(new Tag() { Name = tag });
}
}
Movie movie = new Movie();
movie.Name = viewModel.Name;
movie.Tags = tagList;
MovieService.Insert(movie);
以下是带有插入
的MovieService代码public void Insert(Movie movie)
{
Context.Movie.Add(movie);
Context.SaveChanges();
}
修改-2: 我发现了问题!这是我设置项目的一个问题。我使用Ninject进行DI,我没有将DbContext绑定到请求(InRequestScope)。因此,每次调用我的一个服务时,它都使用不同的DbContext,因此它不知道已加载的标签。
答案 0 :(得分:0)
您可以提供添加标签的代码吗?
与此同时,我认为它类似于
Movie.Tags.Add(new Tag { Name = "foo" });
您可能希望添加现有标记,如下所示:
Movie.Tags.Add(ctx.Tags.First(T => T.Name == "foo"));
...或从您的上下文中获取Tag的等效代码。
此外,您可能希望将标签ICollection设为虚拟,以便代理可以覆盖它。这也可能是一个难以找到的错误来源。