Select() 中的条件 Select()

Conditional Select() in Select()

我有一个简单的 table 'Cars':

IdCar      |   Name     |     Id_Base
 1             Toyota          null
 2             Honda           5
 3             Ford            4
 4             Buick           null 
 5             Volvo           1

Id_Base 是对此 table CarsIdCar 字段的引用。所以这就像一个循环引用。我知道这很奇怪,但我无能为力。

我有一个 CarDTO:

public class CarDTO
{       
    public int IdCar { get; set; }
    public int? Id_Base { get; set; }
    public string Name { get; set; }
    public CarDto InnerCar {get; set; }
}       

如果 Id_BaseNOT NULL,我的目标是将 table Cars 的每个元素投影到 CarDTO。那就是我通过它的 IdCar 得到一个 Car 并填充 InnerCar 属性 of CarDTO.

所以如意的结果应该是这样的:

new Car(){ IdCar = 1, Name = "Toyota", Id_Base = null},

new Car(){ IdCar = 2, Name = "Honda", Id_Base = 5, 
    InnerCar = new Car(){ IdCar = 5, Name="Volvo" }},

new Car(){ IdCar = 3, Name = "Ford", Id_Base = 4, 
    InnerCar = new Car(){ IdCar = 4, Name="Buick" }},

new Car(){ IdCar = 4, Name = "Buick", Id_Base = null },

new Car(){ IdCar = 5, Name = "Volvo", Id_Base = 1, 
    InnerCar = new Car(){ IdCar = 5, Name="Toyota" }}

我尝试过的:

var cars = from car in db.Cars
     let innerCar =
         (from inCar in db.Cars
          where inCar.id_Base != null && inCar.IdCar == car.IdCar
          select new CarDTO
          {                                       
               Name = inCar.Name,
               IdCar = inCar.IdCar,                                       
               IdBase = inCar.id_Base,
               InnerCar = null
           }
           ).FirstOrDefault(x => x.IdBase == car.id_Base)
       select new CarDTO
           {                                  
               Name = car.Name,
               IdCar = car.IdCar,                                  
               IdBase = car.id_Base,
               InnerCar = innerCar
           };

InnerCar 始终为空。我不明白我做错了什么。有人知道如何投影每个元素并创建 InnerCar 吗?

那行 inCar.IdCar == car.IdCar 似乎是错误的。

应该是inCar.IdBase == car.IdCar.

您的线路只会收到具有相同 IdCar 的线路。

或者您想写:

inCar.IdCar != car.IdCar - 不等于而不是等于

我个人认为这更容易阅读:

var cars = (from car in db.Cars
          select new CarDTO
          {                                       
               Name = car.Name,
               IdCar = car.IdCar,                                       
               IdBase = car.id_Base,
           }).ToList(); //call .ToList() to fix possible EF errors by materializing all objects

cars.ForEach(x => x.InnerCar = cars.FirstOrDefault(y => y.IdCar == x.IdBase));

Does anybody know how to project each element and create InnerCar?

我不知道。但我还是觉得我可以帮到你。

首先,如果您不知道什么是映射器库,请检查一下它是什么。 'Automapper' 例如。它可以极大地简化你的生活。 如果你不想使用它,你可以通过简单地使用字典来设置内部汽车。它会花费你 O(n) 并且它是一个简单的代码,这是一个加号

      class Program
      {
        static void Main(string[] args)
        {
          var allCars = GetAllCars();
          var allCarsDtoDict = allCars.Select(a =>
          new CarDTO() { Id_Base = a.Id_Base, IdCar = a.IdCar, Name = a.Name }).ToDictionary(a => a.IdCar, a => a);
          foreach (var car in allCarsDtoDict.Values)
          {
            if (car.Id_Base.HasValue)
              car.InnerCar = allCarsDtoDict[car.Id_Base.Value];
          }

          var allCardWithSetInnerCard = allCarsDtoDict.Values;
        }

        private static IEnumerable<CarDO> GetAllCars()
        {
          return new List<CarDO>()
          {
            new CarDO(){ IdCar = 1, Name = "Toyota", Id_Base = null},
            new CarDO(){ IdCar = 2,Name = "Honda",Id_Base = 5,},
            new CarDO(){ IdCar = 3,Name = "Ford",Id_Base = 4},
            new CarDO(){ IdCar = 4, Name = "Buick", Id_Base = null },
            new CarDO(){IdCar = 5,Name = "Volvo",Id_Base = 1,}
          };
        }
      }