How to use product entity if child view exists

-1

ASP.NET 5 MVC Shopping cart application uses EF Core with Npgsql data provider. Database contains products table

create table Product (
  Product char(20) primary key;
  Description char(50);
  )

It is mapped to Product entity by EF Core Scaffold

public class Product {
  public string Product1 { get; set; }
  public string Description { get; set; }
  }

Read-only product view entity has special shadow properties which do not exist in database and in Product class:

public class ShopToode: Product {
  public decimal CartPrice { get; set; }
  }

public DbSet<ShopToode> ShopToodes { get; set; }
public DbSet<Product> Products { get; set; }

ShopToode is used only to view data using FromSqlRaw:

var tooteinfo = await ctx.ShopToodes.FromSqlRaw(@"select *, 
  1.2 as CartPrice 
  from Product").AsNoTracking().ToListAsync();

Trying to get product like

 var t = ctx.Products.First();

throws error

Npgsql.PostgresException (0x80004005): 42703: column t.Discriminator does not exist

How to use Product entity if view also exists ?

entity-framework
asp.net-core
entity-framework-core
asp.net-core-mvc
npgsql
asked on Stack Overflow Mar 23, 2021 by Andrus

1 Answer

0

Not sure what a ShopToode is, but it sounds like a Shop Cart Item. Unless a ShopToode needs to be actually saved to the database, I wouldn't have it declared like an entity, and definitely would not inherit from Product. You can declare a view model or DTO that you intend to serialize or chuck in a session variable and project details from a product to it:

var tooteinfo = await ctx.Products
    .Select(x => new TooteInfo
    {
       ProductId = x.ProductId,
       // ...
       CartPrice = 1.2
    }).ToListAsync(); 

For a structure that is persisted to data where I had a Cart (for a User), with CartProduct linking a product to a cart, and a Product, this is more a case for a many-to-many relationship:

public class Cart
{
    [Key]
    public int CartId { get; set; } 
    public int UserId {get; set; }
    // ...

    public virtual ICollection<CartProduct> CartProducts { get; set; } = new List<CartProduct>();
}

public class CartProduct
{
    [Key, Column(Order=0), ForeignKey("Cart")]
    public int CartId { get; set; }
    [Key, Column(Order=1), ForeignKey("Product")]
    public int ProductId { get; set; }

    public int Quantity { get; set; }
    public decimal UnitPrice { get; set; }
    
    [NotMapped]
    public decimal CartPrice
    {
        get { return UnitPrice * Quantity; }
    }

    public virtual Cart Cart { get; set; }
    public virtual Product Product { get; set; }
}

public class Product
{
    [Key]
    public int ProductId { get; set; }
    // ...
}

From there you can query a Cart and select details from CartProducts and through that to Product to build a view model.

answered on Stack Overflow Mar 24, 2021 by Steve Py

User contributions licensed under CC BY-SA 3.0