最新消息:雨落星辰是一个专注网站SEO优化、网站SEO诊断、搜索引擎研究、网络营销推广、网站策划运营及站长类的自媒体原创博客

EF Core view derived from table unexpected results - Stack Overflow

programmeradmin1浏览0评论

I have a database view, based on a table with an additional column.

My classes first looked like this:

public class Person
{
    public int Id { get; set; }
    public string Name { get; set; }
}

public class PersonView
{
    public int Id { get; set; }
    public string Name { get; set; }
    
    public string Additional { get; set; }
}

In my context, I've added them like this:

modelBuilder.Entity<Person>().ToTable("Person", "dbo");
modelBuilder.Entity<PersonView>().ToView("PersonView", "dbo");

This all worked like expected, I can query the Person table or the ViewPerson view like

ctx.Set<Person>().Where ....
ctx.Set<PersonView>().Where ....

Now I tried to derive the class for the view from the table, only extending it with the additional properties. Now my classes look like this:

public class Person
{
    public int Id { get; set; }
    public string Name { get; set; }
}

public class PersonView : Person
{
    public string Additional { get; set; }
}

From here, I am struggling around, cause leaving the context as is, the query to ctx.Set<Person>().Where(..) suddenly returns a mix of Person and ViewPerson types.

So I dove into EF Core and handling hierarchy, reading about TPH, TPT and TPC and learned that TPH is the default used by EF Core.

I think, that is not what I want it to be, so I changed the strategy in my context like this:

modelBuilder.Entity<Person>().UseTpcMappingStrategy().ToTable("Person", "dbo");
modelBuilder.Entity<PersonView>().ToView("PersonView", "dbo");

This indeed makes my query returning only objects of type Person if I query the table, but unfortunately the records are now doubled up.

Can anyone bring some light into this hierarchy for me? The database already exists and all I want is to query the table OR the view, and don't want any interaction between them but using the same base class for the table and the view.

Is this not possible with a derived class, and I have the classes for the table and the view to define separately as I had it at the beginning (and this was working).

Thanks for any hints or links to tips!


As Gert Arnold noted I tried the following:

public class PersonBase
{
    public int Id { get; set; }
    public string Name { get; set; }
}

public class Person : PersonBase {}

public class PersonView : PersonBase
{
    public string Additional { get; set; }
}

I'm leaving my context untouched:

modelBuilder.Entity<Person>().ToTable("Person", "dbo");
modelBuilder.Entity<PersonView>().ToView("PersonView", "dbo");

Seems to work, I wonder why and how? :-)

I have a database view, based on a table with an additional column.

My classes first looked like this:

public class Person
{
    public int Id { get; set; }
    public string Name { get; set; }
}

public class PersonView
{
    public int Id { get; set; }
    public string Name { get; set; }
    
    public string Additional { get; set; }
}

In my context, I've added them like this:

modelBuilder.Entity<Person>().ToTable("Person", "dbo");
modelBuilder.Entity<PersonView>().ToView("PersonView", "dbo");

This all worked like expected, I can query the Person table or the ViewPerson view like

ctx.Set<Person>().Where ....
ctx.Set<PersonView>().Where ....

Now I tried to derive the class for the view from the table, only extending it with the additional properties. Now my classes look like this:

public class Person
{
    public int Id { get; set; }
    public string Name { get; set; }
}

public class PersonView : Person
{
    public string Additional { get; set; }
}

From here, I am struggling around, cause leaving the context as is, the query to ctx.Set<Person>().Where(..) suddenly returns a mix of Person and ViewPerson types.

So I dove into EF Core and handling hierarchy, reading about TPH, TPT and TPC and learned that TPH is the default used by EF Core.

I think, that is not what I want it to be, so I changed the strategy in my context like this:

modelBuilder.Entity<Person>().UseTpcMappingStrategy().ToTable("Person", "dbo");
modelBuilder.Entity<PersonView>().ToView("PersonView", "dbo");

This indeed makes my query returning only objects of type Person if I query the table, but unfortunately the records are now doubled up.

Can anyone bring some light into this hierarchy for me? The database already exists and all I want is to query the table OR the view, and don't want any interaction between them but using the same base class for the table and the view.

Is this not possible with a derived class, and I have the classes for the table and the view to define separately as I had it at the beginning (and this was working).

Thanks for any hints or links to tips!


As Gert Arnold noted I tried the following:

public class PersonBase
{
    public int Id { get; set; }
    public string Name { get; set; }
}

public class Person : PersonBase {}

public class PersonView : PersonBase
{
    public string Additional { get; set; }
}

I'm leaving my context untouched:

modelBuilder.Entity<Person>().ToTable("Person", "dbo");
modelBuilder.Entity<PersonView>().ToView("PersonView", "dbo");

Seems to work, I wonder why and how? :-)

Share Improve this question edited Mar 13 at 9:39 marc_s 756k184 gold badges1.4k silver badges1.5k bronze badges asked Mar 13 at 7:39 HelmutHelmut 5023 silver badges18 bronze badges 2
  • 2 If possible, make a PersonBase class that both classes inherit and make sure EF doesn't know the base class. – Gert Arnold Commented Mar 13 at 8:09
发布评论

评论列表(0)

  1. 暂无评论