简体   繁体   中英

Multiple tables containing one entity in Entity Framework

I am working on a system that sells products. This system has products, with subclasses for every producttype.

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

Furthermore, i want to keep a history of all the products i sold with all the data that was correct at that moment.

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

The problem is, that entity now makes a FK in Product to Transaction. That's not what i want. I want a seperate table for each of them; a Products table and a SoldProducts table. I already tried this in my productContext:

public DbSet<Product> producten { get; set; }
public DbSet<Product> uitgifte_producten { get; set; }

That's not possible, because EF doesn't allow multiple object sets per type . This seems like something trivial, but i can't figure it out. Making two classes, one Product and one Soldproduct, with both of having subclasses of the producttypes, seems rather ugly. I tried it, but VS2012 complains that it can't converty Product to SoldProduct.

What seems to be a good idea to do this in C#, .net 4.0 and EF?

I assume you are using EF Code First. When you have a collection of products in your Transactions table, EF will take this to be a typical one to many relationship.

I would add a TransactionDetail table to which I would copy all the details I need from Product:

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

Update in response to comment:

Still assuming you are using code-first. In your scenario, you could use the TransactionDetail class above as a base class then have more derived classes in respect to the types of products. You will be able to capture all the required details per product and you will only have one more extra table in your db.

Why not just link to products from your transaction class using a basic many-to-many relationship?

Using EF Fluent API, you can add a config class with the following:

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

Then, override the OnModelCreating function of you DbContext with:

protected override void OnModelCreating(DbModelBuilder modelBuilder)
{

    modelBuilder.Configurations.Add(new TransactionConfig());

}

I don't know of any way to do something like this in EF.

If you really want to keep all the product data for each transaction, I'd suggest creating product copies for every transaction and then storing them in the DB and referencing them from the transaction. You might also think about creating a self-reference on product, which could then point to the "actual product" for "transaction products".

Another approach I can think of is storing the product history instead of creating a copy of the product, ie creating product copies on product change instead of on transaction creation. This way, when creating a transaction you always link to the current version of your product.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM