在实体框架中包含一个实体的多个表

本文关键字:实体 包含一 框架 | 更新日期: 2023-09-27 18:14:38

我正在开发一个销售产品的系统。这个系统有产品,每个产品类型都有子类。

public abstract class Product 
{
    public int ProductId { get; set; }
    public string naam { get; set; }
    public string barcode { get; set; }
}
public class Card :Product
{
    [Display(Name = "Cardnumber")]
    public int nummer { get; set; }
    public Kaliber kaliber { get; set; }
}

此外,我想保留我销售的所有产品的历史记录,其中包含当时所有正确的数据。

 public class Transaction
{
    public int transactionId { get; set; }
    public Member member { get; set; }
    public virtual ICollection<Product> producten { get; set; }
    public double totaalprijs { get; set; }
    public DateTime tijdstip { get; set; }
    public string kantoorMedewerker { get; set; }
}

问题是,该实体现在在Product to Transaction中生成一个FK。那不是我想要的。我想给他们每人一个单独的桌子;一个Products表和一个SoldProducts表。我已经在我的productContext:

中尝试过了
public DbSet<Product> producten { get; set; }
public DbSet<Product> uitgifte_producten { get; set; }

这是不可能的,因为EF不允许每个类型有多个对象集。这事看似微不足道,但我还是搞不懂。创建两个类,一个是Product,一个是Soldproduct,它们都有产品类型的子类,看起来相当难看。我试过了,但是VS2012抱怨它不能将Product转换为SoldProduct。

在c#, .net 4.0和EF中这样做似乎是一个好主意?

在实体框架中包含一个实体的多个表

为什么不直接使用基本的多对多关系链接到事务类中的产品呢?

使用EF Fluent API,您可以添加如下配置类:

public class TransactionConfig : EntityTypeConfiguration<Transaction>
{
    public TransactionConfig ()
    {
        this.HasMany(t => t.Products)
            .WithMany()
            .Map(x =>
            {
                x.MapLeftKey("TransactionId");
                x.MapRightKey("ProductId");
                x.ToTable("TransactionProducts");
            });
    }
}

然后,用:

覆盖DbContext的OnModelCreating函数:
protected override void OnModelCreating(DbModelBuilder modelBuilder)
{
    modelBuilder.Configurations.Add(new TransactionConfig());
}

我假设你正在使用EF Code First。当您的Transactions表中有一个产品集合时,EF会将其视为典型的一对多关系。

我将添加一个TransactionDetail表,我将从Product中复制所有我需要的详细信息:

 public class TransactionDetail{
     public int TransactionId { get; set; }
     public int ProductId { get; set; }
     public string naam { get; set; }
     public string barcode { get; set; }
}

回复评论的更新:

仍然假设您使用代码优先。在您的场景中,您可以使用上面的TransactionDetail类作为基类,然后根据产品类型拥有更多的派生类。您将能够捕获每个产品所需的所有详细信息,并且在数据库中只需要多一个表。

我不知道有什么方法可以在EF中做这样的事情。

如果您真的想保留每个事务的所有产品数据,我建议为每个事务创建产品副本,然后将它们存储在DB中,并从事务中引用它们。您还可以考虑在product上创建一个自我引用,然后为"交易产品"指向"实际产品"。

我能想到的另一种方法是存储产品历史而不是创建产品的副本,即在产品更改而不是在交易创建时创建产品副本。这样,当创建一个交易时,您总是链接到您的产品的当前版本。