【发布时间】:2016-08-07 12:07:06
【问题描述】:
我正在使用实体框架 (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);
}
如果我尝试将带有一些标签的电影插入数据库,我会遇到创建不需要的标签的问题。
例如,我已经在数据库中有两个标签“Foo”(Id:1)和“Bar”(Id:2)。现在我创建一个新的 Movie 对象并将现有的标签“Foo”(从数据库加载)和新的标签“Foobar”插入到对象的集合中。在我将此电影添加到 DbContext 并调用方法“SaveChanges”后,我的数据库中有两个新标签。
为什么实体框架将现有标签插入我的数据库?只插入缺少的标签,我需要更改什么?
Edit-1: 这是我添加标签并保存的控制器代码
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();
}
Edit-2: 我发现了问题!这是我如何设置项目的问题。我将 Ninject 用于 DI,并且没有将 DbContext 绑定到请求(InRequestScope)。因此,每次调用我的一项服务时,它都会使用不同的 DbContext,因此它不知道已加载的标签。
【问题讨论】:
-
能否请您更正帖子标题 - 您在讨论的是多对多关系。
-
是的,我改了。我不知道我为什么写“一对多”。我知道这是多对多...
标签: c# entity-framework