2011-09-24 81 views
0

根据之前的问题,我有Here。我想将两个集合连接在一起,以便合并的数据可以显示在Silverlight UI的DataGrid中。使用Linq Zip函数合并Silverlight中视图的集合

使用LINQ的压缩功能我能合并我的两个集合如下

public void CombineAllCollections() 
    { 
     var combineAll = Persons.Zip(PhoneNumbers, (x, y) => new 
     { 
      FirstName = x.FirstName, 
      LastName = x.LastName, 
      Address = x.Address, 
      State = x.State, 
      Zip = x.Zip, 
      AreaCode = y.AreaCode, 
      PhoneNumber = y.Number 
     }); 
     } 

这似乎做正是我想要的。但是,输出是匿名类型。我怎样才能将combinedAll类型转换为一个集合(List,ObservableColl.IENum),然后我可以将它传递给我的UI中的视图(绑定到数据网格)。然后,输出应该在网格中显示每个项目的列和值(如上面列出的七列)。

在此先感谢

-Cheers

回答

4

,而不是使匿名类型,你可以创建一个特定的具体类型与所有你的匿名类型指定的属性的合并结果。

例如:

public void CombineAllCollections() 
{ 
    var combineAll = Persons.Zip(PhoneNumbers, (x, y) => new PersonWithPhoneNumber 
    { 
     FirstName = x.FirstName, 
     LastName = x.LastName, 
     Address = x.Address, 
     State = x.State, 
     Zip = x.Zip, 
     AreaCode = y.AreaCode, 
     PhoneNumber = y.Number 
    }); 
} 

PersonWithPhoneNumber是与所有的指定属性的类型。

然后你可以在结果上调用ToList()把它转换为IList<PersonWithPhoneNumber>或者你可以把它留在它是作为一个IEnumerable<PersonWithPhoneNumber>

编辑

鉴于信息的形式,你只要保留使用LINQ的能力并且不必定义单独类型的唯一有效方法就是为压缩集合中的每个项目创建字典,例如:

using System; 
using System.Collections.Generic; 
using System.Linq; 

namespace Test 
{ 
    class Program 
    { 
     static void Main(string[] args) 
     { 
      var xs = new[] {1, 2, 3, 4, 5, 6}; 
      var ys = new[] {7, 8, 9, 10, 11, 12}; 

      var zipped = xs.Zip(ys, (x, y) => 
            new Dictionary<string, object> 
             { 
              { "X", x}, 
              { "Y", y} 
             }); 

      foreach (var pair in zipped.SelectMany(tuple => tuple)) 
      { 
       Console.WriteLine("{0} = {1}", pair.Key, pair.Value); 
      } 
     } 
    } 
} 

这样,您可以在字典中为每个项目设置尽可能多的键/值对,只要您愿意。但是,使用此方法实质上会失去任何类型的安全性,并且会最终为每个属性装箱所有值类型。这意味着你必须知道要返回的类型。我诚实地不建议这样做。我只是简单地创建一个类型,即使该类型需要100个属性。在这种情况下,自动属性和一个好的文本编辑器是你最好的朋友。

你也可以与我们的.NET 4.0框架,如下面的例子中,新的动态类型在C#4:

using System; 
using System.Dynamic; 
using System.Linq; 

namespace Test 
{ 
    class Program 
    { 
     static void Main(string[] args) 
     { 
      var xs = new[] {1, 2, 3, 4, 5, 6}; 
      var ys = new[] {7, 8, 9, 10, 11, 12}; 

      var zipped = xs.Zip(ys, (x, y) => 
             { 
              dynamic value = new ExpandoObject(); 

              value.X = x; 
              value.Y = y; 

              return value; 
             }); 

      foreach (var pair in zipped) 
      { 
       Console.WriteLine("X = {0}, Y = {1}", pair.X, pair.Y); 
      } 
     } 
    } 
} 

这将引入动态到你的代码,虽然。如果你不注意你正在做的事情,这可能没有你想要的性能指标,并可能导致大量运行时错误。这是因为在创建或访问属性时可能会拼错一个属性(这也是字典设置的问题),当您尝试访问它时会导致运行时异常。同样,最好使用最后输入的具体名称。

+0

谢谢约书亚有没有办法做到这一点,我不必定义类型?我正在考虑两种类型都由服务或某个外部POCO定义的情况,每种类型都包含100个属性。如果可能的话,我想消除手动重新生成所有这些特性的需要。这是一个很好的解决方案,可以满足我需要的功能,我只是在考虑其他的实现。感谢adivce! – rlcrews

+0

@randyc:100属性!?哇!你可能没有显示那么多列的网格,那么是否有一些动态构建要显示的属性列表的方法?这可能需要一个完全不同的方法,而不是制作专门的类或视图模型。 –

+0

您可以随时使用字典或带动态的ExpandoObject。 –