【问题标题】:Conditional Select() in Select()Select() 中的条件 Select()
【发布时间】:2017-11-27 15:53:09
【问题描述】:

我有一个简单的表格“汽车”:

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

Id_Base 是对该表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,我的目标是将表Cars 的每个元素投影到CarDTO。那就是我通过它的IdCar 得到一个Car 并填充CarDTOInnerCar 属性。

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

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

【问题讨论】:

  • innerCar(小写的l)永远不为空吗? .FirstOrDefault(x => x.IdBase == car.id_Base) 是否返回非空值?如果子查询总是返回 null,请找出原因。
  • 本田是沃尔沃的品牌吗?
  • 我建议提取所有数据,然后使用递归算法在内存中创建关系,因为您真正拥有的是表中的树结构。
  • 我已经撤回了我的回答,因为您现在已经使用正确的标签编辑了问题。我仍然认为您应该使用Join,但我没有时间设置环境来演示如何。 EF 连接的文档应该足够好,以便您了解如何使其适应您的情况。

标签: c# entity-framework linq linq-to-entities


【解决方案1】:

有人知道如何投影每个元素并创建 InnerCar 吗?

我没有。但我仍然认为我可以帮助你。

如果您不知道映射器库是什么,首先请查看它是什么。例如“自动映射器”。它可以极大地简化您的生活。 如果您不想使用它,您可以通过简单地使用字典来设置内部汽车。这将花费你 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,}
          };
        }
      }

【讨论】:

    【解决方案2】:

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

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2018-11-29
      • 2018-03-17
      • 2019-03-09
      • 1970-01-01
      • 2013-11-12
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多