使用 Linq Zip 函数合并 Silverlight 中视图的集合

发布于 2024-12-06 09:47:59 字数 754 浏览 0 评论 0原文

根据之前的问题,我这里。我想将两个集合连接在一起,以便合并后的数据可以显示在 Silverlight UI 的 DataGrid 中。

使用 Linq Zip 函数,我能够合并我的两个集合,如下所示,

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

这似乎正是我想要的。但是输出是匿名类型。如何将组合All 类型转换为集合(List、ObservableColl.IENum),然后将其传递到 UI 中的视图(绑定到数据网格)。然后,输出应在网格中显示每个项目的列和值(如上面列出的七列)。

提前致谢

-干杯

Based upon a prior question I had Here. I wanted to join two collections together so that the merged data could be then displayed within a DataGrid of a Silverlight UI.

Using the Linq Zip function I was able to merge my two collections as follows

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

This seems to do just what I wanted. However the output is an Anonymous Type. How can I cast the combinedAll type to a collection (List, ObservableColl. IENum) that I can then pass to a view in my UI ( Bind to a datagrid) . The output should then display within the grid a column and value for each item ( as listed above seven columns).

Thanks in advance

-Cheers

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(1

妥活 2024-12-13 09:47:59

您可以使用在匿名类型上指定的所有属性专门为合并结果创建一个具体类型,而不是创建匿名类型。

例如:

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,或者您可以将其保留为 IEnumerable 的形式

编辑

鉴于您提供的信息,这似乎是存储如此多值的唯一有效方法,同时保持使用 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 个属性。在这种情况下,自动属性和优秀的文本编辑器是您最好的朋友。

您还可以将 C# 4 中的新动态类型与 .NET 4.0 框架结合使用,如下例所示:

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

不过,这会将动态引入您的代码中。它可能没有您想要的性能指标,并且如果您不留意自己正在做的事情,可能会导致很多运行时错误。这是因为您在创建或访问属性时可能会拼写错误(这也是字典设置的问题),这将在您尝试访问它时导致运行时异常。同样,可能最好只使用最后键入的具体名称。

Instead of making an anonymous type, you could create a concrete type specifically for the merged results with all of the properties you specified on the anonymous type.

For example:

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

Where PersonWithPhoneNumber is the type with all of the specified properties.

Then you can call ToList() on the result to convert it to an IList<PersonWithPhoneNumber> or you can leave it in the form it is in as an IEnumerable<PersonWithPhoneNumber>

EDIT

Given the information that you provided, it would appear about the only effective way to store so many values while maintaining the ability to use LINQ and not have to define a separate type would be to create a dictionary for each item in the zipped collection, for example:

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

This way, you can have as many Key/Value pairs in the dictionary for each item as you would like. However, you essentially lose any type safety using this method and will end up boxing all value types for each property. This means you will have to know the type to cast back to. I would honestly not recommend doing this. I would simply just make a type, even if that type needs 100 properties. In this scenario auto-properties and a good text editor are your best friend.

You could also us the new dynamic type in C# 4 with the .NET 4.0 framework as in the following example:

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

This will introduce dynamic into your code, though. Which may not have the performance metrics you desire and can lead to a lot of run-time errors if you don't keep an eye out on what you're doing. This is because you could misspell a property while creating or accessing it (this is also an issue with the dictionary setup) which will lead to a run-time exception when you attempt to access it. Again, probably best to just use a concrete, named typed in the end.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文