【问题标题】:Entity Framework database mapping relationships (Duplicate creation using Seed() method)实体框架数据库映射关系(使用 Seed() 方法重复创建)
【发布时间】:2018-12-11 09:58:23
【问题描述】:

我用an issueanother issue 创建了一个帖子。 这些可以作为参考,但我认为它们已处理。

我对这些问题提出的问题以及我(需要或不需要)应用的操作困扰着我,因为我不太了解 EF 的行为和期望。

我有一个 Product、PurchasePrice 和 SalesPrice 实体,我最初的想法是 1 个 Product 可以有多个 PurchasePrice,但 1 个 PurchasePrice 只能存在于 1 个 Product 中(SalesPrice 也是如此)。

因此这些关系:

// NOTE that BaseEntity just has a "int ID" prop and datetimes/stamps
public class Product : BaseEntity
{
   public  ICollection<PurchasePrice> PurchasePrices { get; set; }
   public  ICollection<PurchasePrice> SalesPrices { get; set; }
}

public  class PurchasePrice:BaseEntity
{      
   public Product Product { get; set; }
}

public  class SalesPrice:BaseEntity
{      
   public Product Product { get; set; }
}

现在,让我们向它添加一个供应商实体,因为这就是我将销售和采购分开并且不从中创建枚举的原因,因为 1 个产品(在数据库中)可以有多个供应商,每个供应商都有自己的销售/购买价格另一个 Productnumber 值。

所以上面变成了:

public class Product : BaseEntity
{
   public  ICollection<PurchasePrice> PurchasePrices { get; set; }
   public  ICollection<PurchasePrice> SalesPrices { get; set; }
   // added
   public  ICollection<Supplier> Suppliers { get; set; }
}

public  class PurchasePrice:BaseEntity
{      
   public Product Product { get; set; }
   // added
   public Supplier Supplier { get; set; }
}

public  class SalesPrice:BaseEntity
{      
   public Product Product { get; set; }
   // added
   public Supplier Supplier { get; set; }
}

// added Entity Supplier into the party
public class Supplier : BaseEntity
{
    public ICollection<Product> Products { get; set; }
    public ICollection<PurchasePrice> PurchasePrices { get; set; }
    public ICollection<SalesPrice> SalesPrices { get; set; }
}

让我们继续说下去,因为它并不止于此,我想跟踪这些产品-供应商-价格关系,所以我创建了一个名为“ProductSupplierForContract”的实体,它具有以下内容结构:

public class ProductSupplierForContract:BaseEntity
{
    public string ProductnumberValue { get; set; }

    public int Product_Id { get; set; }
    public int Supplier_Id { get; set; }
    public int? Contract_Id { get; set; }

    public virtual Product Product { get; set; }
    public virtual Supplier Supplier { get; set; }
    public virtual Contract Contract { get; set; }
}

最后我有一个 Contract 实体,它具有以下结构:

public class Contract:BaseEntity
{
  [Required]
  public ICollection<Product> Products { get; set; }
  public ICollection<ProductSupplierForContract> ProductSupplierForContracts { get; set; }
}

所以产品变成:

public class Product : BaseEntity
{
   public  ICollection<PurchasePrice> PurchasePrices { get; set; }
   public  ICollection<PurchasePrice> SalesPrices { get; set; }    
   public  ICollection<Supplier> Suppliers { get; set; }
   // added
   public  ICollection<Contract> Contracts { get; set; }
}   

自定义播种(从 DropCreateDatabaseAlways 继承):

protected override void Seed(ApplicationDbContext context)
{
   PurchasePrice purchaseprice = new PurchasePrice((decimal)17.70);
   ctx.PurchasePrices.Add(purchaseprice);

   Product product1 = new Product("test product 1",purchaseprice);
   ctx.Products.Add(product1);

   base.Seed(ctx);
}

我还在 Fluent API 中定义了映射:

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

    }

现在,最初我没有任何问题,我真的不明白是什么导致了这种突然的变化,我现在在为我的数据库播种时得到了重复的产品。我可以将其简化为仅添加一个带有值的简单 PurchasePrice 和一个具有此 PurchasePrice 引用的 Product ,这是我的副本。

将实体产品的 PurchasePrice 类中的关系更改为 ICollection 不会创建重复但我不想要这个集合,因为它不是多对多关系...

我已经尝试了很多东西,但没有什么可以“解决”这个问题(如果这是一个开始的问题,对我来说是的,但可能不是 EF),比如删除继承 BaseEntity、更改映射(流利和注释)、更改我播种和初始化一切的方式,我自己定义 ID,你命名它......

请注意,其目的不是优化我的播种方式,而是拥有一个体面的工作模型,并了解 EF 做什么以及它想要什么。

我的问题:

  • 为什么会出现/出现这种重复?
  • 如果我希望能够有 1 个实例持有关系 价格-供应商-产品-合同,我该怎么做? Answer is here

【问题讨论】:

  • 在列表中添加了 1 个问题,这是我正在尝试做的事情的核心,但我认为我没有正确地解决这个问题。

标签: asp.net-mvc orm entity-framework-6 relational-database code-first


【解决方案1】:

我通过重新设计模型解决了我的问题。我添加了一个额外的实体 ProductForSupplier ,它包含一个产品和供应商以及一个产品编号的关系。

public class ProductForSupplier:BaseEntity
{
    public string ProductnumberValue { get; set; }

    [Required]
    public Product Product { get; set; }

    [Required]
    public Supplier Supplier { get; set; }
}

添加了一个实体ProductsForContract,它将持有一份合同的产品-供应商关系的金额:

public class ProductsForContract
{
    public int ProductsForContractId { get; set; }        
    public int Amount { get; set; }
    public ProductForSupplier ProductForSupplier { get; set; }
    public Contract Contract { get; set; }
}

现有实体 ProductSupplierForContract 变为:

public class ProductSupplierForContract:BaseEntity
{
    public ICollection<ProductsForContract> ProductsForContract { get; set; }

    [Required]
    public Contract Contract { get; set; }
}

这使我可以灵活地保持实体之间的任何类型的关系,并且还处理了重复项(我仍然不知道其原因)。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2019-03-27
    • 1970-01-01
    • 2010-10-14
    • 2013-01-17
    • 1970-01-01
    • 1970-01-01
    • 2014-09-30
    相关资源
    最近更新 更多