繁体   English   中英

多对多关系-实体框架正在创建新对象

[英]Many to Many Relationship - Entity Framework is creating new objects

我使用代码优先方法使用Entity Framework(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”之后,数据库中有两个新标签。

实体框架为什么要在数据库中插入现有标签? 我该如何更改,仅插入丢失的标签?

编辑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 ICollection虚拟化,以便代理可以覆盖它。 那也可能是难以发现的错误来源。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM