【问题标题】:LINQ query on entities with join returning items by category对实体的 LINQ 查询,按类别返回项目
【发布时间】:2020-05-08 17:52:19
【问题描述】:

我正在使用实体框架核心。我有以下实体:

public class Category {
    public long Id { get; set; }
    public string Name { get; set; }
}

public class Product {
    public long Id { get; set; }
    public long CategoryId { get; set; }
    public string Name { get; set; }
}

我想要一个分组,其中我的键是我的类别,并且我有一个产品列表。我想对数据库运行单个查询来执行此操作。

var data = context.Categories
            .Join(
                Products,
                c => c.Id,
                p => p.CategoryId,
                (c, p) => new {
                   Category = c,
                   Product = p
               }
            )
            .ToList();

这会运行我想要的查询,并且似乎会生成一个带有匿名对象的列表,该对象具有类别和产品。如果我然后执行以下操作,它会做我想要的:

var grouped = data.GroupBy(x => new { x.Category });

键很好,但值列表似乎重复了类别。有没有办法做到这一点,所以我有一个类别的键,然后值是产品对象的列表?更喜欢方法语法,但在这一点上,如果有人能得到我,我希望能弄清楚查询语法。

【问题讨论】:

  • 我猜,你应该为 Category 类覆盖 EqualsGetHashCode 以使其正确地与分组一起工作
  • 从:x.Category 到:x.Category.Id
  • 添加导航属性,您将免费获得。

标签: c# .net linq


【解决方案1】:

尝试以下:

   class Program
    {
        static void Main(string[] args)
        {
            Context context = new Context();

            var results = (from c in context.Categories
                           join p in context.Products on c.Id equals p.CategoryId
                           select new { category = c, product = p })
                          .GroupBy(x => x.category.Id)
                          .ToList();
        }
    }
    public class Context
    {
        public List<Category> Categories { get; set; }
        public List<Product> Products { get; set; }
    }
    public class Category
    {
        public long Id { get; set; }
        public string Name { get; set; }
    }

    public class Product
    {
        public long Id { get; set; }
        public long CategoryId { get; set; }
        public string Name { get; set; }
    }

【讨论】:

    【解决方案2】:

    这将是一个按类别分组的产品列表

    public class Category {
        public long Id { get; set; }
        public string Name { get; set; }
    }
    
    public class Product {
        public long Id { get; set; }
        public long CategoryId { get; set; }
        public string Name { get; set; }
    }
    
    class Program
    {
        static void Main(string[] args)
        {
            ICollection<Category> categories = new Collection<Category>(new List<Category>());
            ICollection<Product> products = new Collection<Product>(new List<Product>());
    
            var data = categories
            .Join(
                products,
                c => c.Id,
                p => p.CategoryId,
                (c, p) => new {
                   Category = c,
                   Product = p
               }
            )
            .ToList();
    
            var grouped = data.GroupBy(o => o.Category, o => o.Product);
        }
    }
    

    【讨论】:

      【解决方案3】:

      正确的解决方案是这样的:

      var result = (from p in context.Products
                    join c in context.Categories
                        on p.CategoryId equals c.Id
                    select new
                    {
                        Product = p,
                        Category = c
                    })
                    .ToList() // because still grouping object is not supported in EF Core we have to materialize first and then do our grouping
                    .GroupBy(g => g.Category, g => g.Product)
                    .ToDictionary(p => p.Key, p => p.ToList());
      

      【讨论】:

        【解决方案4】:

        这就是我最终解决它的方式:

        var grouped = data
            .GroupBy(x => new { x.Category })
            .Select(x => new {
                Category = x.Key.Category,
                Products = x.ToList().Select(x => x.Product).ToList()
            });;
        

        【讨论】:

          猜你喜欢
          • 1970-01-01
          • 1970-01-01
          • 2013-11-05
          • 1970-01-01
          • 2021-04-23
          • 2011-03-06
          • 2023-03-11
          • 1970-01-01
          • 1970-01-01
          相关资源
          最近更新 更多