LINQ как мне указать выбор определенных столбцов в объединениях «один ко многим»

#c# #linq #join #select #multiple-columns

#c# #linq #Присоединиться #выберите #несколько столбцов

Вопрос:

У меня ситуация, когда у меня есть запрос LINQ. Он имеет два объединения (один ко многим), но возвращает все столбцы в объединенных таблицах. Я не уверен, как создать запрос LINQ, чтобы возвращать только несколько полей из объединенных таблиц.

 var data = from mc in ctx.MembershipChapters
           where mc.PartitionKey == controllerStateManager.PartitionKey amp;amp; mc.MembershipId == membershipId
           join prd in ctx.Products on mc.ProductId 
           equals prd.Id into prods
           from prd in prods.DefaultIfEmpty()

           join oli in ctx.OrderLineItems on mc.OrderLineItemId equals oli.OrderLineItemId into olis
           from oli in olis.DefaultIfEmpty()
           select new
           {
             MembershipName = mc.Membership.Name,
             Products = prods.Select(p => new { 
ProductName = p.Name, ProductId = p.Id }),

OrderLineItems = olis.Select(o => new { OrderLineItemName = o.Description, OrderLineItemId = o.OrderLineItemId })
};
controllerStateManager.Data = data.ToList();
 

Это не работает…Я получаю сообщение об ошибке: «o» не входит в область видимости.

В основном вывод должен следовать этому:

MembershipChapter —> OrderLineItems ———-> Продукты

Я новичок в LINQ, и я слишком долго боролся с этим.

Комментарии:

1. Здравствуйте, ваш псевдоним повторяется oli / prd, а также порядок соединений мне не подходит, я напишу это так: из mc в ctx.MembershipChapters, где mc.PartitionKey == controllerStateManager. Ключ раздела amp;amp; mc.MembershipId == membershipId присоединяется к prd в ctx. Продукты в mc.ProductID равны prd. Идентификатор в prods присоединяется к oli в ctx. OrderLineItems в mc.OrderLineItemId равен oli. OrderLineItemId в olis из prd2 в prods. DefaultIfEmpty() из oli2 в olis. DefaultIfEmpty()

Ответ №1:

Если у вас есть отношение «один ко многим», и вам нужны элементы «один», каждый из которых имеет ноль или более подпунктов, например, школы с их нулевыми или более учениками; Клиенты с их нулевыми или более заказами или, как в вашем случае: MembershipChapters с их OrderLineItems, рассмотрите возможностьиспользуйте одну из перегрузок запроса.Групповое соединение.

Если вы начинаете со стороны «много», и вам нужен каждый элемент с одним родительским элементом, поэтому вы хотите, чтобы учащийся был в школе, которую он посещает, или Заказ с одним и единственным клиентом, который разместил заказ, используйте одну из перегрузок Queryable.Join .

Я почти всегда использую перегрузку с параметром resultSelector , чтобы вы могли точно определить, что должно быть в результате.

Требование: для заданных таблиц MembershipChapters, OrderLineItems и Products. Между MembershipChapters и OrderLineItems существует отношение «один ко многим». Каждый элемент MembershipChapter имеет ноль или более элементов OrderLineItem, каждый элемент OrderLineItem принадлежит ровно одному элементу MembershipChapter, а именно элементу MembershipChapter, на который ссылается внешний ключ. Между элементами OrderLineItems и продуктами существует аналогичное отношение «один ко многим». Дайте мне все (или некоторые) MembershipChapters, каждый MembershipChapter с его нулевыми или более элементами OrderLineItem и каждый элемент OrderLineItem с его нулевыми или более продуктами.

 var result = dbContext.MemberShipChapters
    .Where(membershipChapter => ...)       // only if you don't want all MembershipChapters
    .GroupJoin(dbContext.OrderLineItems,

    membershipChapter => membershipChapter.Id, // from every membershipChapter get the primary key
    orderlineItem => orderLineItem.MembershipChapterId, // from every OrderlineItem get the foreign key

    // parameter resultSelector: from every MembershipChapter with its zero or more
    // OrderLineItems, make one new:
    (membershipChapter, orderLineItemsOfThisMembershipChapter) => new
    {
        // Select only the membershipChapter properties that you plan to use
        Id = membershipChapter.Id,
        Name = membershipChapter.Name,
        ...

        // The zero or more OrderLineItems of this membershipChapter
        OrderLineItems = orderLineItemsOfThisMembershipChapter
            .Select(orderLineItem => new
            {
                // Select only the OrderLineItems that you plan to use:
                Id = orderLineItem.Id,
                ...

                // not needed, you already know the value
                // MembershipChapterId = orderLineItem.MembershipChapterId,
            })
            .ToList(),
    });
 

Это довольно просто. Однако, если вы хотите объединить в группу три таблицы, это выглядит ужасно, хотя и выполнимо.

Другой метод, который выглядит проще:

     var result = dbContext.MemberShipChapters
    .Where(membershipChapter => ...)
    .Select((membershipChapter => new
    {
        Id = membershipChapter.Id,
        Name = membershipChapter.Name,
        ...

        OrderLineItems = dbContext.OrderLineItems

            // keep only the OrderLineItems with a foreign key referring to this MembershipChapter
            .Where(orderLineItem => orderLineItem.MemberShipChapterId == membershipChapter.Id)
            .Select(orderLineItem => new
            {
                Id = orderLineItem.Id,
                ...


                // do the same with the third table
                Products = dbContext.Products
                .Where(product => product.OrderLineItemId == orderLineItem.Id)
                .Select(product => new
                {
                     Id = product.Id,
                     Price = product.Price,
                     ...
                })
                .ToList(),
            })
            .ToList(),
        });
 

Ответ №2:

Это немного сложно читать, но если домен связан правильно, я думаю, вы просто хотите получить такой запрос:

 from ol in ctx.OrderLines where
    ol.MembershipChapter.PartitionKey == controllerStateManager.PartitionKey
    select new {ol.Whatever, ol.Product.Whatever};
 

Комментарии:

1. Я ценю предложения… но мой настоящий вопрос заключается в том, что у меня есть одна запись MembershipChapter и два списка данных. Мне нужно знать, как выбрать 3 свойства из каждого элемента в каждом списке:

2. выберите создать { Имя_участника = mc.Membership.Name , Продукты = продукты. Выберите(p => создать { ProductName = p.Name , ProductID = p.Id }), OrderLineItems = olis. Выберите(o => создать { OrderLineItemName = o.Описание, OrderLineItemId = o.OrderLineItemId }) };