Запрос 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, но пока я не нашел решения.


person pat    schedule 27.12.2016    source источник
comment
Можете ли вы сказать нам, что случилось? Чего вы ожидаете и что получаете?   -  person Sefe    schedule 27.12.2016


Ответы (2)


Это лучше сделать с помощью 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; }
    }
}
person jdweng    schedule 27.12.2016

Желаемый результат отсутствует, но я могу сказать вам, что то, что вы делаете прямо сейчас, не принесет много пользы.

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

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

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

person Chrotenise    schedule 27.12.2016