【问题标题】:Flatten LINQ collection object with nested object collections使用嵌套对象集合展平 LINQ 集合对象
【发布时间】:2011-11-23 01:03:12
【问题描述】:

这是一个棘手的问题。我试图展平 LINQ 对象集合。集合中的每个项目都有可能拥有两个其他对象的集合。请参阅下面的示例。

public class DemoClass
{
    public string Name {get; set;}
    public string Address {get; set;}
    public List<Foo> Foos = new List<Foo>();
    public List<Bar> Bars = new List<Bars>();
}

我一直在做的是使用这个代码块来展平这个对象

var output = from d in DemoClassCollection
    from f in d.Foos
    from b in d.Bars
    select new {
        d.Name, 
        d.Address,
        f.FooField1, 
        f.FooField2, 
        b.BarField1,
        b.BarField2
    };

但我遇到的问题是我得到的结果是只有那些在 Foos 和 Bars 集合中有对象的 DemoClass 对象。无论 Foos 和 Bars 集合中是否有对象,我都需要获取 DemoClass 中的所有对象。

任何帮助将不胜感激。

谢谢!

【问题讨论】:

  • “扁平化”是什么意思?这并不是说这就像一棵树,而您想要获得一个序列。您能否提供一些输入值和预期结果的示例?

标签: linq c#-4.0


【解决方案1】:

听起来你可能想使用DefaultIfEmpty

var output = from d in DemoClassCollection
    from f in d.Foos.DefaultIfEmpty()
    from b in d.Bars.DefaultIfEmpty()
    select new {
        d.Name, 
        d.Address,
        FooField1 = f == null ? null : f.FooField1, 
        FooField2 = f == null ? null : f.FooField2, 
        BarField1 = b == null ? null : b.BarField1, 
        BarField2 = b == null ? null : b.BarField2
    };

【讨论】:

    【解决方案2】:

    看起来 Linq 中的左外连接可以工作 (http://msdn.microsoft.com/en-us/library/bb397895.aspx

    var output = from d in DemoClassCollection
        from f in d.Foos.DefaultIfEmpty()
        from b in d.Bars.DefaultIfEmpty()
        select new {
            d.Name, 
            d.Address,
            f.FooField1, 
            f.FooField2, 
            b.BarField1,
            b.BarField2
        };
    

    【讨论】:

      【解决方案3】:

      我相信您可以根据您实现 CompareTo() 方法的方式实现 IComparer 以在 linq 中执行自定义 JOINS 或 UNIONS

      来自 MSDN:http://msdn.microsoft.com/en-us/library/system.icomparable.aspx

      using System;
      using System.Collections;
      
        public class Temperature : IComparable 
        {
        // The temperature value
        protected double temperatureF;
      
          public int CompareTo(object obj) {
          if (obj == null) return 1;
      
          Temperature otherTemperature = obj as Temperature;
          if (otherTemperature != null) 
              return this.temperatureF.CompareTo(otherTemperature.temperatureF);
          else
             throw new ArgumentException("Object is not a Temperature");
      }
      
      public double Fahrenheit 
      {
          get 
          {
              return this.temperatureF;
          }
          set {
              this.temperatureF = value;
          }
      }
      
      public double Celsius 
      {
          get 
          {
              return (this.temperatureF - 32) * (5.0/9);
          }
          set 
          {
              this.temperatureF = (value * 9.0/5) + 32;
          }
        }
       }
      
       public class CompareTemperatures
      {
       public static void Main()
       {
        ArrayList temperatures = new ArrayList();
        // Initialize random number generator.
        Random rnd = new Random();
      
        // Generate 10 temperatures between 0 and 100 randomly.
        for (int ctr = 1; ctr <= 10; ctr++)
        {
           int degrees = rnd.Next(0, 100);
           Temperature temp = new Temperature();
           temp.Fahrenheit = degrees;
           temperatures.Add(temp);   
        }
      
        // Sort ArrayList.
        temperatures.Sort();
      
        foreach (Temperature temp in temperatures)
           Console.WriteLine(temp.Fahrenheit);
      

      } }

      // The example displays the following output to the console (individual
      // values may vary because they are randomly generated):
      

      // 2 // 7 // 16 // 17 // 31 // 37 // 58 // 66 // 72 // 95

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 2011-07-23
        • 2017-01-21
        • 2020-04-15
        • 1970-01-01
        • 1970-01-01
        • 2013-03-26
        • 2020-06-15
        相关资源
        最近更新 更多