locked
Using EF Core entity if child view also exists throws error RRS feed

  • Question

  • User-1262787652 posted
    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 ?

    Tuesday, March 23, 2021 6:24 PM

All replies

  • User475983607 posted

    The raw SQL has an extra field that does not exist in models.  A discriminator column indicates inheritance.  It seems you are trying to manually generate a derived type without telling EF???

    Tuesday, March 23, 2021 6:39 PM
  • User-1262787652 posted

    Yes.  How to suppress exception about Disciminator column ?

    In this case discriminator is not required. Inherited class is used only to get view with additional properties. 

    How to create fake discriminator column or property if this suppresses the exception?

    Tuesday, March 23, 2021 6:52 PM
  • User475983607 posted

    It seems you want to hack EF Core tools.  I'm not sure if what you want to do is even possible.  

    Anyway, the official documentation covers Entity Inheritance.  You might find what you're looking for in the reference docs.

    https://docs.microsoft.com/en-us/ef/core/modeling/inheritance

    Tuesday, March 23, 2021 7:19 PM
  • User-1262787652 posted

    Hi!

    I want to use product view and product entities. This common requirement, not hack.

    I added column Grupp to database and Product class and tried according to doc

            protected override void OnModelCreating(ModelBuilder modelBuilder)
            {
    base.OnModelCreating(modelBuilder);
    modelBuilder.Entity<ShopToode>()
    .HasBaseType((Type)null)
    .HasNoKey();
    
    modelBuilder.Entity<Product>()
    .HasDiscriminator(b => b.Grupp)
    .HasValue<Product>('L')
     .IsComplete(false)
    .HasValue<ShopToode>('L');
            }
    

    but EF Core then produdes exception about duplicate discriminator values. In may case both entities have same record which has same value.

    How to force EF Core to allow to use Product type ?  Using ShopToode works OK. Only trying to access Product object causes exception.

    Tuesday, March 23, 2021 7:36 PM
  • User475983607 posted

    I want to use product view and product entities. This common requirement, not hack.

    I don't understand the design approach when you could simply use EF features as openly documented. 

    Try including only the properties that make up a ShopToodes type in the hard coded SELECT. 

    Tuesday, March 23, 2021 9:10 PM
  • User-1262787652 posted

    Try including only the properties that make up a ShopToodes type in the hard coded SELECT. 

    In shopping cart Product has about 200 properties and properties are different in different shops.

    Every shop has different Product table and class scaffolded at installation.

    Datacontext is in separarate assembly different in different shops.

    I asked for code which do not require manually hard-coding Product properties when ShopToode DTO is used.

    How to create code which does not require hard -coded properties like 

    SELECT *, 1.2 AS CartPrice 
    FROM Product 

    in question. 

    Based on you answer it looks like inheritance cannot used since EF Core blocks it.

    Should ShopToode DTO created as separate entity and should it contain only reference (product id) to product entity, removing inheritance?

    Wednesday, March 24, 2021 7:20 AM
  • User475983607 posted

    I asked for code which do not require manually hard-coding Product properties when ShopToode DTO is used.

    How to create code which does not require hard -coded properties like 

    SELECT *, 1.2 AS CartPrice 
    FROM Product 

    I recommend reading the openly published documentation linked in my second post.  Then craft a project query to populate the DTO.  https://docs.microsoft.com/en-us/dotnet/csharp/programming-guide/concepts/linq/projection-operations

    Based on you answer it looks like inheritance cannot used since EF Core blocks it.

    I'm confused. The hard code SQL was your intended design.

    Should ShopToode DTO created as separate entity and should it contain only reference (product id) to product entity, removing inheritance?

    ShopToode is an entity in your design.  It inherits from Product.  

    Wednesday, March 24, 2021 10:52 AM