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

实体框架在种子数据库上插入重复项[重复]

  •  0
  • Dimitri  · 技术社区  · 7 年前

    here 我尝试在种子设定方法中分配Id,结果失败 好的,语言 但当我向客户添加地址并将Id分配给这些地址时,它不会再次创建副本。。。

    我尝试的是:

    • 创建一个 欺骗
    • 增加1种语文及;1个地址(带Id)-将这两个地址添加到1个客户 => 制造一个复制品
    • 不会产生一个
    • 不 制作一个复制品

    ----编辑

    我完全不知道为什么会发生这种情况,它是在我调用base.Seed(ctx)时发生的;方法,我确信,因为在此之后,我在Web应用到达任何其他位置之前停止了它。

    此实体客户具有相关的实体语言以及地址集合。

    我有 another post open (还没有建议)当同样的问题突然发生时,我自己没有对我的模型或播种方法做任何更改。。。

    基本实体:

    public class BaseEntity
    {
        public int ID { get; set; }
    }
    

    客户:

    public class Customer:BaseEntity
    {
        public string Name { get; set; }
        public Language Language { get; set; }
        public ICollection<Address> Addresses { get; set; }
    }
    

    语言:

    public class Language : BaseEntity
    
    {
        public string Name { get; set; }
        public string LanguageCode { get; set; }
    
        [Required]
        public ICollection<Customer> Customers { get; set; }
    }
    

    public class Address : BaseEntity
    {
        public Customer Customer { get; set; }
    }
    

      Language newLanguageNL = new Language("Dutch");
      newLanguageNL.ID = 1;
    
      Language newLanguageFR = new Language("French");
      newLanguageFR.ID = 2;
    
      Language newLanguageEN = new Language("English");
      newLanguageEN.ID = 3;
    
      ctx.Languages.Add(newLanguageNL); 
      ctx.Languages.Add(newLanguageEN); 
      ctx.Languages.Add(newLanguageFR);
    
      Address addressBE = new Address("informatica laan", "10", "bus nr 1", "8900", "België");
      addressBE.ID = 1;
    
      Address addressBE2 = new Address("rue de l'informatique", "20", "boite nr 2", "7780", "Belgique");
      addressBE2.ID = 2;
    
      Address addressEN = new Address("techstreet", "30", "box nr 1", "4000", "Bulgaria");
      addressEN.ID = 3;
    
      ctx.Addresses.Add(addressEN);
      ctx.Addresses.Add(addressBE);
      ctx.Addresses.Add(addressBE2);
    
      Customer newCustomer = new Customer("Customer name", newLanguageNL, addressBE);
      // ctx.Customers.AddOrUpdate(c => c.Name, newCustomer);
      ctx.Customers.Add(newCustomer);
    
      base.Seed(ctx);
    

         protected override void OnModelCreating(DbModelBuilder modelBuilder)
        {
            base.OnModelCreating(modelBuilder);      
    
            // setting the Product FK relation required + related entity
            modelBuilder.Entity<Entity.ProductSupplierForContract>().HasRequired(psfc => psfc.Product)
                                                                .WithMany(p => p.ProductSupplierForContracts)
                                                                .HasForeignKey(psfc => psfc.Product_Id);
    
            // setting the Supplier FK relation required + related entity
            modelBuilder.Entity<Entity.ProductSupplierForContract>().HasRequired(psfc => psfc.Supplier)
                                                               .WithMany(s => s.ProductSupplierForContracts)
                                                               .HasForeignKey(psfc => psfc.Supplier_Id);
    
            // setting the Contract FK relation required + related entity
            modelBuilder.Entity<Entity.ProductSupplierForContract>().HasOptional(psfc => psfc.Contract)
                                                              .WithMany(c => c.ProductSupplierForContracts)
                                                              .HasForeignKey(psfc => psfc.Contract_Id);
    
    
            modelBuilder.Entity<Entity.PurchasePrice>()
         .ToTable("PurchasePrices");
    
            modelBuilder.Entity<Entity.SalesPrice>()
        .ToTable("SalesPrices");
    
            // Bundle in Bundle
            modelBuilder.Entity<Entity.Bundle>().HasMany(b => b.ChildBundles);                      
        }
    

    谁能在这一点上帮助我,请提前感谢您的任何反馈。

    3 回复  |  直到 7 年前
        1
  •  1
  •   Kostarsus    7 年前

    您的地址和语言将保留在您向客户提供建议的位置。我想在你们的建筑商里,你们是向顾客推荐这些收藏品的,是吗? 这不是必要的。您可以在没有明确的集合建议的情况下持续向客户提供服务。EF将自己映射集合。

        2
  •  1
  •   Steve Greene    7 年前

    int 名为ID的列将是一个标识列,因此如果不发出 SET IDENTITY_INSERT Language ON

    AddOrUpdate 适用于这些情况。您尚未显示该代码。另一种方式如下所示:

    ...
    if (!ctx.Languages.Any(l => l.ID == 1))  // Check if already on file
    {
        ctx.Database.ExecuteSqlCommand("SET IDENTITY_INSERT Language ON");  // Omit if not identity column
        var dutch = new Language {
            ID = 1,
            Name = "Dutch",
            Code = "NL"
        };
        ctx.Languages.Add(dutch);
        ctx.SaveChanges();
        ctx.Database.ExecuteSqlCommand("SET IDENTITY_INSERT Language OFF"); // Omit if not identity column
    }
    ... repeat for other languages
    ... similar code for other seeded tables
    
        3
  •  0
  •   Dimitri    7 年前

    因此,改变了 实体的类别 顾客 对于一个ICollection而不是一个Customer,不会创建一个dupe(并且会创建一个CustomerAddress表,这也是我实际上想要的)。

    从数据库日志(log4net)中可以看出,由于关系EF首先为客户的地址引用插入客户(NULL),然后插入客户(非NULL)及其引用。。。当我比较地址和;语言我看到该语言也有一个客户集合(哪个地址没有),这解释了为什么Address创建了重复的客户条目(如果有人需要对此进行任何澄清,请告诉我(我将尽我最大的努力)

    本帖 HAS MOVED TO HERE