多对多关系-实体框架正在创建新对象
本文关键字:新对象 对象 创建 关系 实体 框架 | 更新日期: 2023-09-27 18:01:08
我使用的是代码优先的实体框架(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"插入到对象的Collection中。在我将这部电影添加到DbContext并调用方法"SaveChanges"之后,我的数据库中有两个新标签。
为什么实体框架在我的数据库中插入现有标记?如果只插入缺少的Tag,我需要做些什么?
第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();
}
第2版:我发现了问题!这是我如何设置项目的问题。我将Ninject用于DI,并且没有将DbContext绑定到请求(InRequestScope(。所以每次调用我的一个服务时,它都使用不同的DbContext,因此它不知道已经加载的标签。
您能提供添加Tag的代码吗?
与此同时,我认为它有点像
Movie.Tags.Add(new Tag { Name = "foo" });
你可能想添加一个现有的标签如下:
Movie.Tags.Add(ctx.Tags.First(T => T.Name == "foo"));
或者从上下文中获取Tag的等效代码。
此外,你可能想让Tags ICollection成为虚拟的,这样代理就可以覆盖它。这也可能是一个很难找到的错误来源。