实体框架在种子数据库上插入重复项 [英] Entity Framework inserting duplicates on Seeding database

查看:120
本文介绍了实体框架在种子数据库上插入重复项的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

编辑----

此处,我尝试在播种方法中分配ID,这是确定语言,但是当我向客户添加地址并为这些地址分配ID时,却没有,而是再次创建了重复对象...

两个地址和语言在我的上下文中被声明为DbSet< ...>

我尝试过的事情:

  • 添加1个地址(带有ID)-将其添加到1个客户=> 创建一个 欺骗
  • 添加1种语言& 1个地址(带ID)-将两者都添加到1个客户中 => 创建骗子
  • 添加1个客户,但只保留其名称=> 不创建 欺骗
  • 添加1种语言(带ID)-将其添加到1个客户=> 不 创建一个骗子

我在Customer上有一个Override ToString()方法,该方法返回其名称,我可以观察到,当在调试1时使用该名称查看重复项时,另一个是Customer类所在的命名空间,似乎loguc是因为在Dupes情况下Name为NULL,但无论如何我还是想提一下它.

----编辑

我正在使用一些元数据为数据库播种,并且我发现它具有从未见过的非常奇怪的行为.我要插入一个实体"Customer",它将这个实体插入2次,第一次插入是正确的并且具有它应有的所有内容,另一个具有NULL属性(字符串值),但是有些(例如日期时间)具有值.

我完全不知道为什么发生这种情况,这是在我调用base.Seed(ctx);时发生的.方法,我确定是因为我在此之后停止了Webapp,然后才将其停止.

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

我有另一个帖子打开了(没有的建议)在发生相同问题且突然发生的情况下,我自己并未对模型或播种方法进行任何更改...

基本实体:

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);

OnModelCreating:

     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);                      
    }

任何人都可以在这方面为我提供帮助,在此先感谢您的任何反馈. 我尝试使用AddOrUpdate()时没有运气.

解决方案

因此将实体客户 Address 类中的关系更改为ICollection,而不是1 Single客户不会创建重复对象(并且还会创建我实际想要的CustomerAddress表).

从数据库日志(log4net)看来,由于关系EF首先要为客户的地址引用插入客户(NULL),然后插入带有其引用的客户(NOT NULL)...当我比较时地址和语言我看到语言也有一个客户集合"(地址"没有),这解释了地址"为什么要创建重复的客户条目. (如果有人需要任何澄清,让我知道我会尽力而为)

此帖子已移至此处

我要感谢所有以任何方式做出贡献的人!

EDIT----

From here i tried assigning Id's in the seeding method and this was OK for Languages but not when i added Address to the customer and assign Id's as well to these addresses, than it created the dupes again...

Both Address & Language are declared as DbSet<...> in my Context

What i tried:

  • Adding 1 Address (with Id) - add this to 1 customer => Creates a dupe
  • Adding 1 language & 1 Address (with Id's) - add both to 1 customer => Creates a dupe
  • Adding 1 Customer with nothing buts its name => Doesn't create a dupe
  • Adding 1 language (with Id) - add this to 1 customer => Doesn't create a dupe

I have a Override ToString() method on my Customer which return its name, I can observe that when i look at the duplicate while debugging 1 is with the name, the other is the Namespace where the Customer class resides in, which seems loguc since the Name is NULL in the Dupes case but i figured to mention it anyway ...

----EDIT

I am seeding my database with some metadata and i see that it has a very strange behavior i never saw before. I am inserting a Entity "Customer" and it inserts this entity 2 times, first insert is correct and has everything it should have, the other one has NULL properties (string values) but some (like datetimes) have values.

I have totally no clue why this is happening, it is occurring when i call the base.Seed(ctx); method, that i am sure since i stopped the Webapp after this before it reached anything else.

This entity Customer has a related Entity Language as well as a Collection of Addresses.

I have another post open (no suggestions yet) where the same issue occurs and this happened suddenly, i did not make any changes myself to my model or seeding methods ...

Base Entity:

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

Customer:

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

Language:

public class Language : BaseEntity

{
    public string Name { get; set; }
    public string LanguageCode { get; set; }

    [Required]
    public ICollection<Customer> Customers { get; set; }
}

Address:

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

Seeding method:

  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);

OnModelCreating:

     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);                      
    }

Can anyone help me on this one please, thank you in advance for any feedback. I have tried using AddOrUpdate() with no luck.

解决方案

So changing the relation in the Address Class of the Entity Customer to a ICollection instead of 1 Single Customer doesn't create a dupe (and creates a CustomerAddress table which i actually want as well).

Seems from the database logs (log4net) that due to the relation EF is first inserting a Customer (NULL) for the Address Reference of the customer, AND inserts the Customer (NOT NULL) with its references ... When i compare Address & Language I see that Language has a Collection of Customers as well (which Address didn't), this explains why Address was creating the duplicate customer entry. (If anyone needs any clarification on this let me know ill do my best)

This post HAS MOVED TO HERE

I want to thank everyone that has contributed in any way!

这篇关于实体框架在种子数据库上插入重复项的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆