Запрос LINQ Базы Данных Northwind

Я новичок в Linq, и я пытаюсь написать запрос, используя базу данных northwind, которая должна возвращать всех поставщиков, у которых есть два или более продуктов в той же категории.

var test1 =
(from p in Products
join pi in Products on p.CategoryID equals pi.CategoryID
join pf in Products on p.SupplierID equals pf.SupplierID
where p.ProductID != pi.ProductID
select new 
{p.ProductName, p.CategoryID, p.SupplierID}).ToList().Distinct();


test1.Dump();

Это была моя последняя попытка, которая не сработала. Я немного смирился, потому что я пытался понять это в течение нескольких часов, и он по-прежнему не будет делать то, что он должен. Может, я просто все неправильно понял?

Мой подход состоял в том, что должно быть два или более списков с одним и тем же SupplierID и CategoryID, но разным ProductID, но все же я не нашел решения.

2 ответа

  1. Это лучше сделать с помощью GroupBy() :

    using System;
    using System.Collections.Generic;
    using System.Linq;
    using System.Text;
    using System.Data;
    using System.Data.SqlClient;
    
    
    namespace ConsoleApplication1
    {
        class Program
        {
            static void Main(string[] args)
            {
                List<Product> Products = new List<Product>() {
                    new Product() { ProductName = "ABC", CategoryID = 1, SupplierID = 1},
                    new Product() { ProductName = "DEF", CategoryID = 1, SupplierID = 1},
                    new Product() { ProductName = "GHI", CategoryID = 1, SupplierID = 3},
                    new Product() { ProductName = "JKL", CategoryID = 1, SupplierID = 3},
                    new Product() { ProductName = "MNO", CategoryID = 2, SupplierID = 1},
                    new Product() { ProductName = "PQR", CategoryID = 3, SupplierID = 1},
                    new Product() { ProductName = "STU", CategoryID = 4, SupplierID = 1},
                    new Product() { ProductName = "VWX", CategoryID = 4, SupplierID = 1},
                    new Product() { ProductName = "YZ1", CategoryID = 4, SupplierID = 1},
                    new Product() { ProductName = "234", CategoryID = 5, SupplierID = 1}
                };
    
    
    
                var test1 = Products.GroupBy(x => new { supplier = x.SupplierID, category = x.CategoryID })
                    .Where(x => x.Count() >= 2).Select(y => y.Select(z => new { name = z.ProductName, supplier = y.Key.supplier, category = y.Key.category })).SelectMany(x => x).ToList();
    
                foreach (var item in test1)
                {
                    Console.WriteLine("Name = '{0}', Supplier = '{1}', Category = '{2}'", item.name, item.supplier, item.category);
                }
                Console.ReadLine();
            }
    
        }
        public class Product
        {
            public string ProductName { get; set; }
            public int CategoryID { get; set; }
            public int SupplierID { get; set; }
        }
    }
    
  2. Ваш желаемый результат отсутствует, но я могу сказать вам, что то, что вы делаете прямо сейчас, не принесет большой пользы.

    Проще говоря, в настоящее время вы просите базу данных вернуть все продукты, которые соответствуют всем продуктам, которые соответствуют всем продуктам, что в основном приводит к тому, что вы получаете все продукты, если база данных не истекает. Таким образом, мы можем упростить ваш запрос к этому:

    var test1 =
    (from p in Products
    select new 
    {p.ProductName, p.CategoryID, p.SupplierID}).ToList().Distinct();
    

    После этого необходимо выбрать уникальные списки наименований продуктов, категорий и поставщиков. Главный вопрос здесь: вы хотите уникальный список комбинаций, или одно из трех свойств должно быть уникальным? Предполагая, что первый, самый простой способ получить результат-это как таковой:

    public class ProductResult  : IEquatable<ProductResult> // we have to tell C# compiler how to check if the objects are different from one another
    {
       public string Name { get; set; }
       public string Category { get; set; }
       public string Supplier { get; set; }
    
       public bool Equals(ProductResultother)
                {
                    if (other == null)
                        return false;
    
                    return (Category == other.Category) 
                           && Supplier  == other.Supplier)
                           && Name  == other.Name ); // optionally do an .Equals() to make this case-insensitive (check for nulls first if you do this!)
                }
    }
    

    Тогда вы можете сделать это:

    var test1 = (from p in Products
    select new ProductResult()
    {
       Name = p.ProductName,
       Category = p.CategoryId,
       Supplier = p.SupplierID,
    }).Distinct();
    

    Теперь у вас есть список всех уникальных комбинаций название продукта / категория / поставщик.