Как получить строку продукта из каждого порядка списка дочерних таблиц с помощью Entity Framework Core? - PullRequest
0 голосов
/ 07 мая 2020

У меня есть два объекта модели:

public class Order
{
        [Key]
        [DatabaseGenerated(DatabaseGeneratedOption.Identity)]
        public int OrderId { get; set; }
        public Guid OrderGuid { get; set; }
        public string CustomOrderNumber { get; set; }
        public int StoreId { get; set; }
        public int UserId { get; set; }
        public virtual IList<OrderItem> OrderItems { get; set; }
}

public class OrderItem
{
        [Key]
        [DatabaseGenerated(DatabaseGeneratedOption.Identity)]
        public int OrderItemId { get; set; }
        public Guid OrderItemGuid { get; set; }
        public int OrderId { get; set; }
        public int Sno { get; set; }
        public int ProductId { get; set; }
        public string ProductName { get; set; }
        public int SKUId { get; set; }
        public string SKU { get; set; }
        public int Quantity { get; set; }
        public virtual Order Order { get; set; }
        public virtual ProductSKU ProductSKU { get; set; }
}

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

Например, предположим, что данные в заказе, orderitms имеет 5 записей о продукте.

и предположим, что в названии продукта указано ab c с 2 записями.

Для 2-го заказа позиции заказа имеют 3 записи, одна из которых - abc Название продукта.

Я хочу получить список заказов только с элементами заказа abc ... ниже я пробовал путь туда. в этом я получаю общее количество заказов

Пожалуйста, помогите мне?

Я пробовал вот так:

List<Contracts.Entities.Order> orders = DbSet.Include(t => t.OrderItems).ToList();

if (!string.IsNullOrEmpty(request.ProductName))
{
    List<OrderItem> orderItems = orders.SelectMany(t => t.OrderItems).Where(t => t.ProductName == request.ProductName).ToList();
    orders = orderItems.Select(t => t.Order).ToList();
}

Ответы [ 2 ]

0 голосов
/ 08 мая 2020

Можно написать так:

List<Contracts.Entities.Order> orders = DbSet.Order.Include(t => t.OrderItems).ToList();

        if (!string.IsNullOrEmpty(request.ProductName))
        {
            orders = orders.Where(r => r.OrderItems.Any(rc => rc.ProductName == request.ProductName)).ToList();
        }
0 голосов
/ 07 мая 2020

Итак, у каждого OrderItem есть ProductName, и вы хотите (несколько свойств) всех заказов, которые имеют хотя бы один OrderItem с этим ProductName.

string productName = ...
var ordersWithProductName = dbContext.Orders.GroupJoin  
    dbContext.OrderItems,             // GroupJoin Orders with OrderItems
    order => order.OrderId            // from every Order take the primary key
    orderItem => orderItem.OrderId,   // from every OrderItem take the foreign key

    // parameter ResultSelector: 
    // take each Order with all its zero or more OrderItems to make one new object
    (order, orderItemsOfThisOrder) => new
    {
        // Select only the Order properties that you plan to use:
        Id = order.OrderId,
        UserId = order.UserId,
        ...

        Items = orderItemsOfThisOrder.Select(orderItem => new
        {
            Id = orderItem.OrderItemId,
            ProductName = orderItem.ProductName,
            ...

            // not needed, you know the value:
            // OrderId = orderItem.OrderId
        })
        .ToList(),
    })

    // keep only those Orders that have at least on OrderItem with productName
    .Where(order => order.Items
                         .Where(orderItem => orderItem.ProductName == productName)
                         .Any());

Таким образом, вы получите все заказы, каждый со всеми его OrderItems, у которых есть хотя бы один OrderItem с ProductName, равным productName.

В структуре сущностей вам не нужно самостоятельно использовать GroupJoin, вместо этого вы можете использовать виртуальную коллекцию ICollection. Я не уверен, поддерживает ли ef-core это:

    var ordersWithProductName = dbContext.Orders.Select(order => new
    {
        // Select only the Order properties that you plan to use:
        Id = order.OrderId,
        UserId = order.UserId,
        ...

        Items = order.OrderItems.Select(orderItem => new
        {
            Id = orderItem.OrderItemId,
            ProductName = orderItem.ProductName,
            ...

            // not needed, you know the value:
            // OrderId = orderItem.OrderId
        })
        .ToList(),
    })

    // keep only those Orders that have at least on OrderItem with productName
    .Where(order => order.Items
                         .Where(orderItem => orderItem.ProductName == productName)
                         .Any());

Последнее замечание: вы уверены, что свойство Order.OrderItems является списком? Имеет ли Order.OrderItems [4] определенное значение? Разве это не должно быть ICollection<OrderItem>?

...