почему не работает метод OrderBy в ядре EF? - PullRequest
0 голосов
/ 11 апреля 2019

Я хочу получить отсортированные продукты (табличные продукты) по «значению» (таблица Product Parameters) в соответствии с «ParamertomId» (табличные параметры) из моей модели. Как правильно отсортировать связанные данные?

Это мои модельные классы:

public class Product 
{
    public int Id { get; set; }

    public string Name { get; set; }
    public string Number { get; set; }
    public double Amount { get; set; }
    public double PrimeCostEUR { get; set; }

    [ForeignKey("ProductTypeId")]
    public int  ProductTypeId {  get; set; }
    public virtual ProductType ProductType { get; set; }

    public ICollection<ProductParameter> ProductParameters { get; set; } = new List<ProductParameter>();
}
public class ProductType //: BaseObject
{   
    public int Id { get; set; }

    public string NameType { get; set; }

    public ICollection<Parameter> Parameters { get; set; } = new List<Parameter>();
    public ICollection<Product> Products { get; set; } = new List<Product>();
}
public class Parameter 
{
    public int Id { get; set; }
    public string Name { get; set; }

    [ForeignKey("ProductType")]
    public int ProductTypeId { get; set; }
    public  virtual ProductType ProductType { get; set; }

    public ICollection<ProductParameter> ProductParameters { get; set; } = new List<ProductParameter>();
}
 public class ProductParameter 
{
    public int Id { get; set; }

    public int ProductId { get; set; }
    public virtual Product Product { get; set; }

    public int ParameterId { get; set; }
    public virtual Parameter Parameter { get; set; }

    public string Value { get; set; }

}

Это мои классы DTO, необходимые для отображения нужных мне данных.

public class ProductDTO{   
   public int ProductId { get; set; }
   public string Number { get; set; }
   public double Amount { get; set; }
   public double PrimeCostEUR { get; set; }

   public int ProductTypeId { get; set; }
   public string NameType { get; set; }

   public ICollection<ParameterDTO> Parameters { get; set; } = new 
   List<ParameterDTO>();}

public class ParameterDTO {
   public int Id { get; set; }
   public string Name { get; set; }
   public string Value { get; set; }
}

Я получаю связанные данные из трех таблиц. Это мой метод GetSortedProducts:

public async Task<IEnumerable<ProductDTO>> GetProducts(int id)
{
    var typeParams = _context.Parameters
        .Where(t => t.ProductTypeId == id)
        .ToList();

    var products =  _context.Products
        .Include(t => t.ProductParameters)
        .Where(t => t.ProductTypeId == id)
        .ToList();

    var items = new List<ProductDTO>();

    foreach (var product in products)
    {
        var productDTO = new ProductDTO()
        {
            ProductId = product.Id,
            Number = product.Number,
            Amount = product.Amount,
            PrimeCostEUR = product.PrimeCostEUR,
            ProductTypeId = product.ProductTypeId
        };

        foreach (var typeParam in typeParams)
        {
            var paramDTO = new ParameterDTO();                        
            var value = product.ProductParameters.FirstOrDefault(t => t.ParameterId == typeParam.Id);
            if (value != null)
            {
                paramDTO.Id = value.Id;
                paramDTO.Value = value.Value;
            }
            paramDTO.ParameterId = typeParam.Id;
            paramDTO.Name = typeParam.Name;

            productDTO.Parameters.Add(paramDTO);
        }
          // sort products by value
         productDTO.Parameters.Where(y => y.ParameterId == 4)
         .OrderBy(t => t.Value).ToList();

         items.Add(productDTO);
    }        

    return items;           
}

1 Ответ

1 голос
/ 11 апреля 2019

Это не работает, потому что LINQ никогда не влияет на исходную коллекцию, так что это вообще ничего не делает:

productDTO.Parameters
    .Where(y => y.ParameterId == 4)
    .OrderBy(t => t.Value)
    .ToList();

В общем, в любом случае, этот код даже близко не подходит к хорошему коду. Не создавайте Product (и другие) объекты только для того, чтобы преобразовать их в версию DTO. Правильно используйте Entity Framework:

var products = await _context.Products
    .Where(prod => prod.ProductTypeId == id)
    .Select(prod => new ProductDTO
    {
        ProductId = prod.ProductId,
        // rest of properties...

        // now get the parameters
        Parameters = prod.Parameters
            // assuming you want to order by value, the question isn't very clear
            .OrderBy(par => par.Value)
            .Select(par => new ParameterDTO
            {
                Id = par.Id,
                // etc
            })
            .ToList()
    })
    .ToListAsync();

Сравните этот отдельный запрос к базе данных с несколькими вызовами, которые выполняет код вопроса , когда данные уже находятся в памяти .

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...