代码之家  ›  专栏  ›  技术社区  ›  Sami

为什么Entity framework会添加相关记录,即使它已经存在于数据库中?

  •  0
  • Sami  · 技术社区  · 4 年前

    为什么Entity Framework会添加相关记录,即使它已经存在于数据库中?在这种情况下,它应该只更新连接表)?

    我与Entity Framework 6合作,我与 Directors Movies .我想用Dto发布一部新电影,名为 MovieUpdateDto . Movie 类具有类型为的属性 ICollection<Directors> Directors .

    代表Dto的json如下所示:

    {
        "Name": "new movie",
        "Description": "new movie Description",
        "Price": 1000.0,
        "Directors": [{"Id": 11, "Name": "Coco"}, {"Id": "12", "Name": "Jambo"}]
    }
    

    这篇文章的问题在于,当插入一部有一个或多个现有导演(已经添加到db中)的电影时,它不能像预期的那样工作。在这种情况下,这些董事将被告知争议裁决委员会。

    作为补充说明,当我添加带有导演信息的电影dto时,EF隐式地将导演添加为导演表中的新记录,并且隐式地处理连接表 MoviesDirectors .

    以下是我的第一次尝试:

    // POST: api/movies
    public void Post([FromBody] MovieUpdateDto movie) 
    {
        var bookToInsert = Mapper.Map<Movie>(movie);
    
        foreach (var director in movieToInsert.Directors)
        {
            var existingDirector = _unitOfWork.Directors.Find(d => d.Id == director.Id);
            if (existingDirector.Any())
            {
                // don't add director again to the database, but do add (directorId, bookId) in the MoviesDirectors junction table. 
                // How do I reference the junction table though? Should this work somehow without referencing the juntion table? 
            }
        }
        _unitOfWork.Movies.Add(movieToInsert);
        _unitOfWork.Complete();
    }    
    

    附言:

    交接台叫 电影导演 在设置正确的配置时由EF自动生成。更准确地说,在 MovieConfiguration 同学们,我有:

    HasMany(c => c.Directors)
        .WithMany(t => t.Movies)
        .Map(m =>
        {
            m.ToTable("MoviesDirectors"); // a way to overwrite the name that EF gives this table
            m.MapLeftKey("MovieId");
            m.MapRightKey("DirectorId");
        });
        
    

    自动创建 电影导演 .

    0 回复  |  直到 4 年前
        1
  •  0
  •   Guru Stron    4 年前

    对于你的第二次尝试,你可以 foreach (var director in movieToInsert.Directors.ToList()) ,但我建议您检查一下 director.Id 不是默认值( 0 Guid.Empty )如果不是,使用 Attach :

    foreach (var director in movieToInsert.Directors)
    {
        if (director.Id > 0)
        {
           _unitOfWork.Directors.Attach(director);
        }
    }