узкое место с использованием наследования структуры объекта - PullRequest
4 голосов
/ 05 июля 2011

так что сначала мои сущности

Entities

проблема, я хочу иметь страницу со всеми заголовками историй и их типами

есть три истории LongStory, CoOpStory, GenericStory

общая история связана с StoryType для типа общей истории

У меня две проблемы

сначала, когда я хочу проверить, является ли история LongStory или CoOpStory, я должен получить всю сущность и проверить тип сущности, если это LongStory, затем сделать что-то, я не знаю, как извлечь некоторые данные [только название] и проверьте тип

моя вторая проблема, как я сказал, я хочу иметь страницу со всеми заголовками и типами историй, я не знаю, как это сделать, не делая много запросов, я не могу присоединиться к StoryType таблица, потому что это должно быть GenericStory, чтобы быть связанным с этим, так что сначала я получаю все истории, затем делаю дополнительный запрос для каждого GenericStory, чтобы получить тип

Ответы [ 3 ]

4 голосов
/ 06 июля 2011

Вы ищете OfType и Concat методы расширения.

Чтобы получить только экземпляры LongStory, вам просто нужно позвонить:

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

Чтобы получить более крупный запрос, этонемного сложнее.Вы можете попробовать:

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>()));

Или вы можете сделать прогноз:

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 })));
3 голосов
/ 06 июля 2011

Ладислав отвечает на ваш второй вопрос.Вот возможное решение вашего первого вопроса.

Насколько я вижу, вы не можете напрямую запрашивать тип в проекции (например, использование GetType() не будет работать в LINQ to Entities).Но следующее будет работать, если вы хотите, например, только запросить заголовок и тип истории:

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();

Вы получите список анонимных объектов, где свойство Type представляет тип как ваш пользовательскийСтрока в этом запросе.

Не очень хорошо, потому что вам приходилось менять этот запрос каждый раз, когда вы добавляете новый класс в иерархию.Также имеет значение порядок (большинство производных классов должно быть первым в выражении для свойства Type).Но я не знаю другого пути.

0 голосов
/ 26 августа 2011

Вы пробовали что-то подобное?

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>());
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...