首页 > 解决方案 > Linq 或 EF - 使用过滤属性多次加入非匿名对象

问题描述

我正在使用 EF,不幸的是 includefiltered 不是选项。所以我必须以某种方式重写我的代码并从中创建非匿名对象。我决定重写它加入,但它可以是任何工作。

我有实体,简化版 Car.Tires.Manufacturers。汽车可以有零到多个轮胎,轮胎可以有零到多个制造商

我想获得具有特定 ID 的汽车,并且只有特定制造商的轮胎。问题是我的结果汽车的轮胎总是有零制造商。

我当前的代码是:

 var car1 = (from c in this.dbContext.Cars
                            .Include(cr => cr.Tires)
                            .ThenInclude(crt => crt.Manufacturers)

            join t in this.dbContext.Tires
                            .Include(ct => ct.Manufacturers)
                      on c.ID equals t.CarID into carTires

       from t in carTires.DefaultIfEmpty()
       join m in this.dbContext.Manufacturers on t.ManufacturerID equals m.ID into completeSet

       from cs in completeSet.DefaultIfEmpty()
       where (c.ID == someCarID ) // and later I will add filter for tire's manufacturer


       select new Car
       {
          ID = c.ID,
          Tires = c.Tires
       }

如果我使用代码

       var car2 = this.dbContext.Cars
                .Include(c => c.Tires)
                    .ThenInclude(t => t.Manufacturers)
                Where(c => c.ID == someCarID)

在 Car2 中有一些制造商。

为什么car1轮胎的制造商为空,如何解决?

注意:这是中间目标。我的最终目标是只为选定的制造商购买带轮胎的汽车。

标签: c#entity-frameworklinq

解决方案


尝试:

var manufacturerTires = dbContext.Tires.Where(t => t.ManufacturerID == someManufacturerID);

var carTires = dbContext.Cars.
        Where(car => car.ID == someCarID)
        .Join(manufacturerTires,
              car => car.ID,
              tire => tire.CarID,
              (car, tire) => new { car, tire })
        .ToList();

这应该返回一个匿名对象new { Car, Tire }

如果我们需要获取 Car 和 Car.Tires 的现有结构,我们可以在上述查询的末尾添加一个 GroupBy,例如:

.GroupBy(c => c.car, c => c.tire, (car, tires) => new Car{ ID = car.ID, Tires = tires}); 
//this could be an expensive query as the GroupBy is on all the columns in Car table

推荐阅读