2017-11-27 28 views
0

が、私は単純なテーブルを持っている '車':選択中の条件を選択し()()

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ある場合CarDTOにテーブルCarsの各要素を投影することです。つまり、私はをIdCarとし、InnerCarのプロパティを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は常にnullです。私は何が間違っているのか理解できません。誰も各要素を投影してInnerCarを作成する方法を知っていますか?

+0

プラスである単純なコードであり、これまでにnullではない 'innerCar'(小文字の 'L')ですか? '.FirstOrDefault(x => x.IdBase == car.id_Base)'はこれまでにnull以外を返しますか?サブクエリが常にnullを返す場合は、その理由を把握します。 –

+0

どのエンティティフレームワークのバージョンを使用していますか? – jag

+4

ホンダはボルボのブランドですか? –

答えて

2

誰もがそれぞれの要素を投影する方法を知っていますがInnerCarを作成しますか?

私はしません。しかし、私はまだあなたを助けることができると思います。

まず、マッパーライブラリが何であるかわからない場合は、まずそれを確認してください。例えば ​​'Automapper'。それはあなたの人生を大きく単純化することができます。 あなたがそれを使用しないことを望むなら、単に辞書を使って内側の車を設定することができます。これは、(n)は、あなたのOを要するだろうし、それが

 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,} 
      }; 
     } 
     } 
0

その行inCar.IdCar == car.IdCarが間違っているようです。

おそらくinCar.IdBase == car.IdCarである必要があります。

あなたのラインは同じものを持つものだけを得るでしょうIdCar

またはあなたが書きたい:

inCar.IdCar != car.IdCar - unequalsの代わりに、私はこれが読みやすいと考えてい

個人的に等しい:

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