Я пытаюсь выполнить запрос linq Join
но возникла исключительная ситуация.
Это мой метод:
public async Task<IEnumerable<Product>> TestProducts()
{
var items = await _context.Products.Join(_context.ProductTypes,
p => p.ProductId,
c => c.ProductTypeId,
(p, c) => new
{
productId = p.ProductId,
number = p.Number,
amount = p.Amount,
primeCostEUR = p.PrimeCostEUR,
nameType = c.NameType
}).ToListAsync();
return items;
}
Это моя модель:
public class Product //: BaseObject
{
public long ProductId { get; set; }
public string Number { get; set; }
public double Amount { get; set; }
public double PrimeCostEUR { get; set; }
public long ProductTypeId { get; set; }
public ProductType ProductType { get; set; }
public long ProductParameterId { get; set; }
public ICollection<ProductParameter> ProductParameters { get; set; } =
new List<ProductParameter>();
}
public class ProductType //: BaseObject
{
public long ProductTypeId { get; set; }
public string NameType { get; set; }
public ICollection<Product> Products { get; set; }
public ICollection<Parameter> Parameters { get; set; }
}
Это ошибка, с которой я столкнулся:
Ошибка CS0266 Невозможно неявно преобразовать тип 'System.Collections.Generic.List<>' в 'System.Collections.Generic.IEnumerable <.Models.Product>'.
Кажется, что вы ожидаете, что результат будет комбинацией класса модели Product
и ProductType
. Поэтому создайте класс DTO (Data Transfer Object) следующим образом, который будет содержать все поля вашего выходного запроса.
public class ProductDto
{
public long ProductId { get; set; }
public string Number { get; set; }
public double Amount { get; set; }
public double PrimeCostEUR { get; set; }
public string ProductTypeName { get; set; }
}
Теперь напишите ваш метод контроллера следующим образом, где возвращаемый тип метода IEnumerable<ProductDto>
:
public async Task<IEnumerable<ProductDto>> TestProducts()
{
var items = await _context.Products.Select(p => new ProductDto
{
ProductId= p.ProductId,
Number= p.Number,
Amount= p.Amount,
PrimeCostEUR= p.PrimeCostEUR,
ProductTypeName = p.ProductType.NameType
}).ToListAsync();
return items;
}
Более того, вам не нужно явное LINQ-соединение, как вы это сделали, вы можете достичь того же, используя проекцию EF, как я сделал с большей простотой.
Изменить это:
var items = await _context.Products.Join(_context.ProductTypes,
p => p.ProductId,
c => c.ProductTypeId,
(p, c) => new
{
productId = p.ProductId,
number = p.Number,
amount = p.Amount,
primeCostEUR = p.PrimeCostEUR,
nameType = c.NameType
}).ToListAsync();
к этому:
var items = await _context.Products.Join(_context.ProductTypes,
p => p.ProductId,
c => c.ProductTypeId,
(p, c) => new Product //as Product not anonymous
{
productId = p.ProductId,
number = p.Number,
amount = p.Amount,
primeCostEUR = p.PrimeCostEUR,
nameType = c.NameType
}).ToListAsync();
Product
не имеет NameType
...
new Product { }
вместо анонимного типаnew { }
? Ой, подождите, вы включаетеNameType
, который не является собственностьюProduct
. По сути, поскольку вы определили метод как возвращающийIEnumerable<Product>
, то это то, что вы должны вернуть. Так что либо измените тип возврата, либо измените то, что вы возвращаете.