bottleneck using entity framework inheritance

你。 提交于 2019-12-17 16:49:22

问题


so first my entities

the problem i want to have a page with all the story titles and their types

there are three stories LongStory , CoOpStory, GenericStory

the generic story is associated with StoryType for the type of the generic story

i have two problems

first when i want to check if the story is LongStory or CoOpStory i have to get all the entity and check the entity type if it is LongStory then do something , i don't know how to retrieve some data [only the title] and check the type

my second problem like i said i want to have a page with all the story titles and their types i don't know how to do that without making a lot of queries , i can't make a join to the StoryType table because it must be GenericStory to be associated with that , so what i do first get all the stories then do an extra query for every GenericStory to get the type


回答1:


You are looking of OfType and Concat extension methods.

To get only LongStory instances you just need to call:

var longStories = context.Stories.OfType<LongStory>().ToList();

To get your bigger query it is little bit more complex. You can either try:

var allStories = context.Stories
                        .OfType<GenericStory>()
                        .Include("StoryType") // I'm not sure how this works with concat
                        .Concat(
                             context.Stories.OfType<LongStory>.Concat(         
                                  context.Stories.OfType<CoOpStory>()));

Or you can do a projection:

var allStories = context.Stories
                        .OfType<GenericStory>()
                        .Select(s => new { s.Title, s.StoryType.Name })
                        .Concat(
                             context.Stories
                                    .OfType<LongStory>
                                    .Select(s => new { s.Title, "LongStory" })
                                    .Concat(         
                                        context.Stories
                                               .OfType<CoOpStory>()
                                               .Select(s => new { s.Title, Type })));



回答2:


Ladislav's answer is for your second question. Here is a possible solution to your first question.

As far as I can see you cannot query directly the type in an projection (using GetType() for instance won't work in LINQ to Entities). But the following will work if you want for instance only query the title and the type of a story:

var stories = context.Stories
    .Select(s => new
    {
        Title = s.Title,
        Type = (s is LongStory) ? "LongStory" :
               (s is CoOpStory) ? "CoOpStory" :
               (s is GenericStory) ? "GenericStory" :
               (s is Story) ? "Story" : // forget this if Story is abstract
               "Unknown"
    }).ToList();

You would get a list of anonymous objects where the Type property represents the type as your custom string in this query.

Not very nice because you had to change this query every time you add a new class to the hierarchy. Also the order matters (most derived classes must be first in the expression for the Type property). But I don't know another way.




回答3:


Have you tried something like this?

context.Stories.OfType<LongStory>.Where(...).Cast<Story>()
 .Union(context.Stories.OfType<GenericStory>.‌​Where(...).Include(s => s.StoryType).Cast<Story>())
 .Union(context.Stories.OfType<CoOpStory>.Where(...).Cast<Story>());


来源:https://stackoverflow.com/questions/6586574/bottleneck-using-entity-framework-inheritance

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!