#c# #sql-server #entity-framework #linq #automapper
#c# #sql-server #entity-framework #linq #automapper
Вопрос:
Я пытаюсь извлечь данные из SQL Server 2014, используя лямбда-выражение LINQ, которое является требованием моего проекта. Но поскольку я новичок в LINQ, мне кажется, я делаю что-то не так с приведенным здесь кодом, и я получаю сообщение об ошибке.
Я могу извлечь только одну строку без какой-либо ошибки, но если я поставлю условие для извлечения нескольких строк, то получу ошибку.
Вот мой код — это класс репозитория:
public DettagliModel GetByIdDoc(int id)
{
using (var dbCtx = new USDevEntities())
{
var dettagli = dbCtx.Dettaglis.Where(x => x.IDDoc == id);
if (dettagli != null)
{
return ConvertTo(dettagli); // Getting error here
}
else
{
return null;
}
}
}
public DettagliModel ConvertTo(Dettagli entity)
{
var model = Mapper.Map<DettagliModel>(entity);
return model;
}
Я получаю эту ошибку:
Аргумент 1: не удается выполнить преобразование из ‘System.Linq.IQueryable’ to ‘DAL.Service.Сущность.Dettagli’ Core.Service
Эта ошибка возникает при написании кода, но если я помещу после
.Where(x => x.IDDoc == id).FirstOrDefault();
затем ошибка исчезает.
Пожалуйста, подскажите мне, что я могу сделать, чтобы решить эту проблему, поскольку мне нужно получить несколько строк, поэтому я не могу использовать FirstOrDefault()
метод. Спасибо.
Комментарии:
1. Используете ли вы automapper?
2. да, я использую его.
3. Я включил этот тег в ваш вопрос, потому что это актуально
4. Спасибо @octavioccl
Ответ №1:
Where
метод расширения возвращает IQueryable<T>
, что означает, что это более одного элемента. Если вы хотите сопоставить множественные объекты с другой моделью с помощью Automapper, то я предлагаю вам использовать ProjectTo<T>
метод расширения:
public IEnumerable<DettagliModel> ConvertTo(IQueryable<Dettagli> entities)
{
return entities.ProjectTo<DettagliModel>().ToList();
}
public IEnumerable<DettagliModel> GetByIdDocs(int id)
{
using (var dbCtx = new USDevEntities())
{
return ConvertTo(dbCtx.Dettaglis.Where(x => x.IDDoc == id));
}
}
Комментарии:
1. Спасибо за ответ. Я пробовал ваш код, но строка ProjectTo<DettagliModel>() выдает ошибку, которая «Не содержит определения ProjectTo». Не могли бы вы, пожалуйста, рассказать мне, как это реализовать?
2. вам нужно добавить пространство имен. Я не помню названия. Подождите секунду
3.
using AutoMapper.QueryableExtensions;
Ответ №2:
Во-первых, это никогда не будет равно null:
var dettagli = dbCtx.Dettaglis.Where(x => x.IDDoc == id);
Кроме того, не возвращайте, null
когда что-то есть IEnumerable<T>
, используйте Enumerable.Empty<T>()
.
Теперь ваш метод стремится вернуть одну, DettagliModel
которая ConvertTo
создается из одной Dettagli
.
Возможно, вам потребуется изменить возвращаемый тип на IEnumerable<DettagliModel>
Теперь вы можете просто использовать .Select
для проецирования объектов базы данных в свои собственные типы:
return
dettagli.Select(d => ConvertTo(d));
//or just dettagli.Select(ConvertTo); if you like.
Это будет отложенная коллекция, поэтому я бы, вероятно, преобразовал ее в не отложенную, используя .ToList()
в конце (а затем .AsReadOnly()
или используя .ToArray()
YMMV).
Ответ №3:
.Where(x => x.IDDoc == id).ToList();
ВОЗВРАТ List<dbCtx.Dettaglis>