在实体框架中包含一个实体的多个表
本文关键字:实体 包含一 框架 | 更新日期: 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上创建一个自我引用,然后为"交易产品"指向"实际产品"。
我能想到的另一种方法是存储产品历史而不是创建产品的副本,即在产品更改而不是在交易创建时创建产品副本。这样,当创建一个交易时,您总是链接到您的产品的当前版本。