实体框架和多对多映射:更新问题

本文关键字:更新 新问题 映射 框架 实体 | 更新日期: 2023-09-27 18:09:51

我在模型中映射了一个多对多关系。Material实体与许多Color实体相关,反之亦然。我使用中间表(MaterialColor),它只有两个id列引用每个表的每个id。

这是如何配置它在我的DbContext实现:

       modelBuilder.Entity<Material>().HasMany<Color>(p => p.Colors).WithMany()
           .Map(m =>
           {
               m.ToTable("MaterialColor");
               m.MapLeftKey("MaterialId");
               m.MapRightKey("ColorId");
           });

到目前为止,它还没有一个问题:除了现在我有另一个多对多关系映射到材质与实体打印机:映射是完全相同的方式配置:

        modelBuilder.Entity<Printer>().HasMany<Material>(p => p.Materials).WithMany()
           .Map(m =>
           {
               m.ToTable("PrinterMaterial");
               m.MapLeftKey("PrinterId");
               m.MapRightKey("MaterialId");
           });

真正的问题发生在我尝试创建Printer实体及其与中的Material的关系时,但是我不想插入新的Materials或新的Colors,当然, MaterialColor都没有记录

我一直在一点一点地修复这个问题,并设法跳过它插入到我不想插入的表:

        _dbContext.Printers.Add(printer);
        foreach (var material in printer.Materials)
        {
            foreach (var color in material.Colors)
            {
                _dbContext.Entry(color).State = EntityState.Unchanged;
            }
            _dbContext.Entry(material).State = EntityState.Unchanged;
        }
        _dbContext.SaveChanges();

问题没有完全解决,因为它仍然试图插入在MaterialColor。我不知道如何告诉EF也跳过这种关系。

我试过了:

        _dbContext.Entry(material).Property(m => m.Colors).IsModified = false;

但是我得到这个错误:

附加信息:类型"Material"上的属性"Colors"为不是原始的或复杂的属性。Property方法只能是用于原始的或复杂的属性使用参考资料或收集方法。

这是有意义的,因为"Colors"是一个集合。

我如何告诉EF忽略这个关系?

(注:

:加载没有颜色的材料不是一个选项)

EDIT:添加打印机和打印机。材料初始化:

        var printer = new Printer();
        printer.Materials = new List<Material>();
        printer.Materials.Add(_materialService.GetMaterialById(materialId)); // this gives the material with many properties populated, like Colors.

实体框架和多对多映射:更新问题

由于我找不到解决这个问题的方法,我不得不删除这个映射:

       modelBuilder.Entity<Material>().HasMany<Color>(p => p.Colors).WithMany()
       .Map(m =>
       {
           m.ToTable("MaterialColor");
           m.MapLeftKey("MaterialId");
           m.MapRightKey("ColorId");
       });

并创建具有两个字段的实体:

public class MaterialColor : ICacheableEntity
{
    public virtual Material Material { get; set; }
    public virtual Color Color { get; set; }
    public int ColorId { get; set; }
    public int MaterialId { get; set; }
}

这样我就可以在需要的时候将Material实体的MaterialColor集合元素设置为Unchanged