Мне нравится делать проекцию из моделей объектов в модели с использованием методов расширения. Это означает, что я не переустанавливаю/не подбираю для своих моделей, и это делает код приятным и читаемым. Имеет смысл, что иногда прогнозы могут включать вложенные модели, и я хочу получить повторное использование этих подпроекций.Проекция одиночных объектов в EF с методами расширения
Я хочу быть в состоянии сделать что-то вроде следующего:
ctx.People.FiltersAndThings().ToViewModels();//the project my DB Models into view models
методы расширения для реальной проекции
public static IQueryable<PersonModel> ToViewModels(this IQueryable<Person> entities)
{
return entities.Select(x => new PersonModel {
Me = x.Me.ToViewModel(), //this method cannot be translated into a store expression
Friends = x.Friends.AsQueryable().ToViewModels() //works fine with some magic (tm)
});
}
public static IQueryable<ProfileModel> ToViewModels(this IQueryable<Profile> entities)
{
return entities.Select(x => new ProfileModel { Name = x.Name });
}
public static ProfileModel ToViewModel(this Profile entity)
{
return new ProfileModel { Name = entity.Name };
}
При использовании запрашиваемых (например Friends = x.Friends.AsQueryable().ToViewModels()
) мы можем использовать некоторую магию, чтобы расплющить это выражение (см. https://stackoverflow.com/a/10726256/1070291, ответ by @LordTerabyte). Но когда мы выполняем назначение с новым предложением (например, Me = new ProfileModel { Name = x.Me.Name }
), это не выражение, поэтому, если мы свяжем это под методом расширения (например, Me = x.Me.ToViewModel()
), мы не можем сгладить это выражение.
Как присвоение нового объекта работает под сценами в EF?
Есть ли способ сделать переход на новый объект с помощью метода расширения?
Полный демо-код здесь: https://github.com/lukemcgregor/ExtensionMethodProjection
Edit:
теперь у меня есть сообщение в блоге (Composable Repositories - Nesting Extensions) и nuget package, чтобы помочь с гнездовыми методами расширения в LINQ
Работает ли он с вашим текущим кодом? –
'Me = x.Me.ToViewModel()' не работает, если вы хотите, чтобы демонстрационное приложение остального работало, я могу отправить сообщение в GH –
Фактически это поможет увидеть вашу модель «Person» и «PersonModel», а не полный код, но соответствующие части. –