【问题标题】:Why EF inserted duplicates in the table?为什么 EF 在表中插入重复项?
【发布时间】:2017-01-20 23:02:25
【问题描述】:

我的模型类如下所示:

 public class Car {
        public int Id { get; set; }
        public string Make { get; set; }
        public string Model { get; set; }
    }

ApplicationDbContext 类:

public class ApplicationDbContext : DbContext {
    public DbSet<Car> Cars { get; set; }

    public ApplicationDbContext()
        : base("Rental") {
        Configuration.LazyLoadingEnabled = true;
    }
}

和种子方法:

 protected override void Seed(ApplicationDbContext context) {

        context.Cars.AddOrUpdate(c => c.Id,
            new Car { Id = 1, Make = "BMW", Model = "750i" },
            new Car { Id = 2, Make = "Audi", Model = "A6" },
            new Car { Id = 3, Make = "Honda", Model = "Civic" }
            );
 }

在我在包管理器控制台中执行(任意多次)update-database 之后,这些对象一旦添加到数据库中。

但是在我添加了 Car 类的子类之后:

public class Car {
    public int Id { get; set; }
    public string Make { get; set; }
    public string Model { get; set; }
    public virtual ICollection<Rental> Rentals { get; set; }
}

public class JetCar : Car {
    public int Thrust { get; set; }//kN
}

public class Dragster : Car {
    public double Acceleration { get; set; }
}

然后修改ApplicationDbContext:

 public class ApplicationDbContext : DbContext {
        public DbSet<Car> Cars { get; set; }
        public DbSet<JetCar> JetCars { get; set; }
        public DbSet<Dragster> Dragsters { get; set; }
        public ApplicationDbContext()
            : base("Rental") {
            Configuration.LazyLoadingEnabled = true;
        }
    }

然后是种子方法

    protected override void Seed(ApplicationDbContext context) {

         context.Cars.AddOrUpdate(c => c.Id,
            new Car { Id = 1, Make = "BMW", Model = "750i" },
            new Car { Id = 2, Make = "Audi", Model = "A6" },
            new Car { Id = 3, Make = "Honda", Model = "Civic" }
            );

        context.Dragsters.AddOrUpdate(d => d.Id,
            new Dragster { Id = 4, Make = "Chevy", Acceleration = 3.23, }
            );

        context.JetCars.AddOrUpdate(d => d.Id,
           new JetCar { Id = 4, Make = "Jetty", Thrust = 89 }
           );

       }

然后在我执行update-database 之后,我最终得到了原始本田、宝马和奥迪汽车的副本,但鉴别器设置为Car。为什么会这样?如何预防?

【问题讨论】:

    标签: c# entity-framework


    【解决方案1】:

    您必须对所有种子对象进行如下测试。

    var car1 = context.Cars.FirstOrDefault(c => c.Make == " BMW ");
    
    if(car1 == null)
    {
        context.Cars.Add(new Car { Id = 1, Make = "BMW", Model = "750i" });
    }
    

    【讨论】:

      【解决方案2】:

      您有重复项,因为对于 Entity FrameWork,它们是不同的。 使用继承时,EF 保留同一张表,但带有鉴别器。请注意,如果没有继承,则没有鉴别器(不需要它)。

      您首先添加的 Cars 是真正的 Car 类型,但由于不存在继承(目前),EF 不会添加鉴别器。 添加DragsterJetCar 后,EF 现在需要 Discriminator。

      由于您第一次添加的汽车没有识别器,因此 EF 无法识别它们。现在,EF 在查询 Car 类型时正在寻找 Discriminator = 'Car'。

      您可以更改种子脚本并手动调整一些数据(您可以在添加 DragsterJetCar 的迁移中添加手动查询) 或者您应该将继承交换为 2 个表之间的链接。

      【讨论】:

      • 谢谢,但是为什么EF没有在update-database命令上为已经存在的记录设置鉴别器呢?是有原因还是他们忘记实现此功能?
      • 因为 EF 在更新数据库之前不知道它是什么。你的工作就是定义什么 Discriminator 应该是“旧”汽车。也许它们都是一种类型,也许它们都是另一种类型,也许两者都有……
      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2016-10-16
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多