Stas Iliukovich
Stas Iliukovich

Reputation: 69

Cannot implicitly convert type List<<anonymous type: ..>> to IEnumerable<Product>

I am trying the execute linq query Join but an Exception has popped up.

This my method:

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;
}

This my model:

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; }

}

This is the error I have encountered:

Error CS0266 Cannot implicitly convert type 'System.Collections.Generic.List<>' to 'System.Collections.Generic.IEnumerable<.Models.Product>'.

Upvotes: 3

Views: 751

Answers (2)

TanvirArjel
TanvirArjel

Reputation: 32119

Its seems that your expected return output is combination of both Product and ProductType model class. So make a DTO (Data Transfer Object) class as follows which will contain all the fields of your output query.

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; }
}

Now write your controller method as follows where return type of the method is 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;
}

Moreover you don't need explicit LINQ join as you did, you can achieve the same thing using EF projection as I have done with more simplicity.

Upvotes: 2

Ashkan Mobayen Khiabani
Ashkan Mobayen Khiabani

Reputation: 34180

Change this:

 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();

to this:

 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();

Upvotes: 0

Related Questions