Существует тип сущности, называемый продуктом, который создается структурой сущности. Я написал этот запрос
public IQueryable<Product> GetProducts(int categoryID)
{
return from p in db.Products
where p.CategoryID== categoryID
select new Product { Name = p.Name};
}
Код ниже выдает следующую ошибку:
«Объект или комплексный тип Shop.Product не могут быть созданы в запросе LINQ to Entities»
var products = productRepository.GetProducts(1).Tolist();
Но когда я использую select p
вместо select new Product { Name = p.Name};
этого работает правильно.
Как я могу предварительно создать пользовательский раздел выбора?
c#
entity-framework
Гути Фаранджи
источник
источник
Ответы:
Вы не можете (и не должны иметь возможность) проецировать на сопоставленную сущность. Однако вы можете проецировать на анонимный тип или DTO :
И ваш метод вернет список DTO.
источник
Вы можете проецировать в анонимный тип, а затем из него в тип модели
Изменить : я собираюсь быть более конкретным, так как этот вопрос привлек много внимания.
Вы не можете напрямую проецировать в тип модели (ограничение EF), поэтому нет никакого способа обойти это. Единственный способ - проецировать на анонимный тип (1-я итерация), а затем моделировать тип (2-я итерация).
Также имейте в виду, что когда вы частично загружаете объекты таким образом, они не могут быть обновлены, поэтому они должны оставаться отсоединенными, как они есть.
Я никогда полностью не понимал, почему это невозможно, и ответы в этой теме не дают веских оснований для этого (в основном речь идет о частично загруженных данных). Это верно, что в частично загруженном состоянии объект не может быть обновлен, но тогда этот объект будет отсоединен, поэтому случайные попытки сохранить их будут невозможны.
Рассмотрим метод, который я использовал выше: в результате у нас все еще есть частично загруженный объект модели. Эта сущность отделена.
Рассмотрим этот (существующий) возможный код:
Это также может привести к списку отдельных объектов, поэтому нам не нужно делать две итерации. Компилятор был бы разумным, чтобы видеть, что AsNoTracking () был использован, что приведет к отдельным объектам, поэтому он может позволить нам сделать это. Однако, если AsNoTracking () был опущен, он может выдать то же исключение, что и сейчас, чтобы предупредить нас о том, что нам нужно быть достаточно конкретными относительно результата, который мы хотим.
источник
Есть еще один способ, которым я нашел работы: вы должны создать класс, производный от вашего класса Product, и использовать его. Например:
Не уверен, что это «разрешено», но это работает.
источник
Вот один из способов сделать это без объявления дополнительного класса:
Однако это следует использовать только в том случае, если вы хотите объединить несколько объектов в один объект. Вышеуказанная функциональность (простое сопоставление продуктов) выполняется следующим образом:
источник
Еще один простой способ :)
источник
.ToList
запрос, он выполняется и получает данные с сервера, тогда какой смысл делать это сноваAsQueryable
?Вы можете использовать это, и оно должно работать -> Вы должны использовать,
toList
прежде чем создавать новый список, используя select:источник
В ответ на другой вопрос, который был отмечен как дубликат ( см. Здесь ), я нашел быстрое и простое решение, основанное на ответе Сорена:
Примечание. Это решение работает, только если у вас есть свойство навигации (внешний ключ) в классе Task (здесь оно называется «Инцидент»). Если у вас его нет, вы можете просто использовать одно из других опубликованных решений с «AsQueryable ()».
источник
Вы можете решить эту проблему с помощью объектов передачи данных (DTO).
Это немного похоже на модели представления, где вы вводите нужные вам свойства, и вы можете отобразить их вручную в вашем контроллере или с помощью сторонних решений, таких как AutoMapper.
С DTO вы можете:
Я изучал это в школе в этом году, и это очень полезный инструмент.
источник
Если вы используете Entity Framework, попробуйте удалить свойство из DbContext, которое использует вашу сложную модель как Entity. У меня возникла та же проблема при отображении нескольких моделей в модель представления с именем Entity.
Удаление записи из DbContext исправило мою ошибку.
источник
если вы выполняете,
Linq to Entity
вы не можете использоватьClassType
сnew
вselect
закрытии запросаonly anonymous types are allowed (new without type)
взгляните на этот фрагмент моего проекта
вы добавили
new keyword
закрытие в Select даже наcomplex properties
эту ошибкупотому что он будет преобразован в оператор SQL и выполняется на SqlServer
так когда я могу использовать
new with types
наselect
закрытие?Вы можете использовать его, если вы имеете дело с
LINQ to Object (in memory collection)
после того, как я выполнил
ToList
запрос, сталоin memory collection
так, что мы можем использоватьnew ClassTypes
в selectисточник
Во многих случаях преобразование не требуется. Подумайте, по какой причине вам нужен тип List, и оцените, хотите ли вы просто получить данные, например, в веб-сервисе или для их отображения. Неважно, тип. Вам просто нужно знать, как его прочитать и убедиться, что он идентичен свойствам, определенным в анонимном типе, который вы определили. Это оптимальный сценарий, потому что вам не нужны все поля сущности, и именно поэтому существует анонимный тип.
Простой способ сделать это:
источник
Это не позволит вам перейти обратно на Product, так как это ваш стол, который вы запрашиваете. Вам нужна анонимная функция, затем вы можете добавить ее в ViewModel и добавить каждую ViewModel в
List<MyViewModel>
и вернуть их. Это небольшое отступление, но я включаю предостережения по поводу обработки необнуляемых дат, потому что с ними трудно справиться, на всякий случай. Вот как я справился с этим.Надеюсь, у вас есть
ProductViewModel
:У меня есть структура внедрения / репозитория зависимостей, где я вызываю функцию для получения моих данных. Используя ваш пост в качестве примера, при вызове функции Controller это будет выглядеть так:
В классе репозитория:
Вернувшись в контроллер, вы делаете:
источник
только добавить AsEnumerable ():
источник
Вы можете добавить AsEnumerable в свою коллекцию следующим образом:
источник