В связанных объектах нетерпеливой загрузки EF легко.
Но я испытываю затруднения включая наследованные объекты при загрузке данных с помощью модели таблицы на тип.
Это - моя модель:
Объекты:
ArticleBase
(основывайте объект статьи), ArticleSpecial
(наследованный от ArticleBase
)UserBase
(основывайте пользовательский объект), UserSpecial
(наследованный от UserBase
)Image
Отношения находятся как показано на изображении (опускающий много столбцов):
В действительности мои пользователи всегда имеют тип 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
не работать.
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, но они не загружают объекты в контекст (я предполагаю).
Это кажется ограничением в текущей версии 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 загружать связанные объекты.