Используя Включают () с наследованными объектами

В связанных объектах нетерпеливой загрузки EF легко.

Но я испытываю затруднения включая наследованные объекты при загрузке данных с помощью модели таблицы на тип.

Это - моя модель:

Объекты:

  • ArticleBase (основывайте объект статьи),
    • ArticleSpecial (наследованный от ArticleBase)
  • UserBase (основывайте пользовательский объект),
    • UserSpecial (наследованный от UserBase)
  • Image

Отношения находятся как показано на изображении (опускающий много столбцов): alt text

В действительности мои пользователи всегда имеют тип UserSpecial, с тех пор UserBase используется в другом приложении, таким образом мы можем совместно использовать учетные данные. Это - единственная причина, у меня есть две отдельных таблицы. UserBase таблица не может быть изменена всегда форма или форма, потому что другое приложение повредилось бы.

Вопрос

Как я, предполагают для загрузки ArticleSpecial с обоими CreatedBy и EditedBy набор, так, чтобы оба имели тип UserSpecial (который определяет Image отношение)?


Я попробовал (неудачно хотя) эти опции:

1. Используя лямбда-выражения:

context.ArticleBases
    .OfType()
    .Include("UserCreated.Image")
    .Include("UserEdited.Image");

В этом случае проблема - это оба CreatedBy и EditedBy связаны с UserBase, это не определяет Image навигация. Таким образом, я должен так или иначе бросить эти два к UserSpecial введите как:

context.ArticleBases
    .OfType()
    .Include("UserCreated.Image")
    .Include("UserEdited.Image");

Но конечно использование дженериков в Include("UserCreated.Image") не работать.

2. Я попытался использовать запрос LINQ

var results = from articleSpecial in ctx.ArticleBase.OfType()
                  join created in ctx.UserBase.OfType().Include("Image")
                  on articleSpecial.UserCreated.Id equals created.Id
                  join edited in ctx.UserBase.OfType().Include("Image")
                  on articleSpecial.UserEdited.Id equals edited.Id   
              select articleSpecial;

В этом случае я только добираюсь ArticleSpecial экземпляры объектов без связанных устанавливаемых свойств. Я знаю, что должен выбрать их так или иначе, но я не знаю как?

Избранная часть в моем LINQ могла быть изменена на что-то как

select new { articleSpecial, articleSpecial.UserCreated, articleSpecial.UserEdited };

но изображения все еще не загружаются в мой контекст. Мои соединения в этом случае едва используются для отфильтровывания результатов articleSpecial, но они не загружают объекты в контекст (я предполагаю).

12
задан Glorfindel 20 June 2019 в 16:04
поделиться

1 ответ

Это кажется ограничением в текущей версии Entity Framework (1.0) Взгляните на этот связанный вопрос SO .

В вашем случае правильным решением будет включение связанных свойств UserCreated и UserEdited в проекцию. Однако, если вы также хотите заполнить свойство Image в объекте UserSpecial , вы должны обязательно включить его:

var results = from articleSpecial in ctx.ArticleBase.OfType<ArticleSpecial>()
              select new
              {
                  articleSpecial,
                  articleSpecial.UserCreated,
                  ((UserSpecial)articleSpecial.UserCreated).Image,
                  articleSpecial.UserEdited,
                  ((UserSpecial)articleSpecial.UserEdited).Image
              };

Конечно, этот запрос основан на предположении, что все объекты ArticleSpecial всегда ссылаются на объект UserSpecial , в противном случае преобразование не будет выполнено.
Если это предположение не всегда верно, вы можете выразить тот же запрос, используя методы расширения LINQ и многострочную лямбда-функцию, чтобы выполнить безопасное преобразование:

var results = ctx.ArticleBase
                 .OfType<ArticleSpecial>()
                 .AsEnumerable()
                 .Select(a =>
                  {
                      var userCreated = a.UserCreated as UserSpecial;

                      if (userCreated != null)
                      {
                          var image = userCreated.Image;
                      }

                      var userEdited = a.UserEdited as UserSpecial;

                      if (userEdited != null)
                      {
                          var image = userEdited.Image;
                      }

                      return a;
                  });

В последнем примере вы также не нужно включать объекты UserSpecial и Image в результаты. Вместо этого вам просто нужно получить доступ к свойствам навигации на объектах ArticleSpecial на этапе проектирования, чтобы заставить Entity Framework загружать связанные объекты.

3
ответ дан 2 December 2019 в 23:51
поделиться
Другие вопросы по тегам:

Похожие вопросы: