如何迭代 Linq 组结果集?

发布于 2024-11-19 05:49:19 字数 817 浏览 3 评论 0 原文

我从数据库中获取一些数据,并使用 linq 计算总和和计数并对数据进行分组。 这就是我所拥有的:

        var si = _repository.GetAllByDate(date);

        var cs = from s in si
        group s by s.Name into g
        select new { Comm = g.Key, SIList = g.ToList(), Count = g.Count() };

我现在需要将 cs 传递给另一个类中的方法,以便我可以为组中的每个项目提取 Comm、SIList 和 Count,我应该将其传递为什么类型? IEnumerable 不起作用。实际的 linq 组结果类型似乎是:

{System.Linq.Enumerable.WhereSelectEnumerableIteratorf__AnonymousTyped,int>>}

有什么想法吗?我实际上想将 cs 作为变量传递并在那里迭代它。

I'm getting some data from my database and using linq to calculate sums and counts and group the data.
This is what I have:

        var si = _repository.GetAllByDate(date);

        var cs = from s in si
        group s by s.Name into g
        select new { Comm = g.Key, SIList = g.ToList(), Count = g.Count() };

i now need to pass cs to a method in another class so that I can extract Comm, SIList and Count for each item in the group, what type do I pass it as? IEnumerable doesn't work. The actual linq group result type seems to be:

{System.Linq.Enumerable.WhereSelectEnumerableIterator<System.Linq.IGrouping<Model.Domain.MasterData
.MyItem,Model.Domain.SI<>f__AnonymousTyped<Model.Domain.MasterData.MyItem,System.Collections.Generic.List<Model.Domain.SI>,int>>}

Any ideas? I effectively want to pass cs as a variable and iterate through it there.

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

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

发布评论

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

评论(5

泪意 2024-11-26 05:49:19

如果要在不同的范围中使用,您需要创建一个与匿名类型的定义相匹配的类型。

public class SomeClass {
    public Comm Comm { get; set; }
    public IList<String> SIList { get; set; }
    public Int32 Count { get; set; }
}

var si = _repository.GetAllByDate(date);

var cs = from s in si
         group s by s.Name into g
         select new SomeClass { Comm = g.Key, SIList = g.ToList(), Count = g.Count() };

编辑:我想我们可以假设该列表将是String,所以我正在对此进行编辑。如果这是错误的类型,您需要相应地更改 IList 定义。

You'll need to create a type that matches the definition of your anonymous type, if it's going to be used in different scopes.

public class SomeClass {
    public Comm Comm { get; set; }
    public IList<String> SIList { get; set; }
    public Int32 Count { get; set; }
}

var si = _repository.GetAllByDate(date);

var cs = from s in si
         group s by s.Name into g
         select new SomeClass { Comm = g.Key, SIList = g.ToList(), Count = g.Count() };

EDIT: I supposed we can assume that the list will be of String so I'm editing for that. If that's the wrong type you'll need to change the IList<T> definition accordingly.

白首有我共你 2024-11-26 05:49:19

得到如此复杂的类型的原因是因为查询使用延迟执行。您正在查看返回结果的表达式的类型,而不是结果的类型。

结果的类型为 IEnumerable<_hidden_​​internal_class_name_>,即当您在查询中创建匿名对象时,结果是编译器内部创建的类的对象流。

将该结果传递给另一个方法是毫无用处的,因为它需要使用反射来读取对象中的属性。您应该为结果中的对象创建一个命名类,以便可以轻松访问其属性。

The reason that you get such a complicated type is because the query uses lazy execution. You are looking at the type of the expression that returns the result, not the type of the result.

The type of the result is IEnumerable<_hidden_internal_class_name_>, i.e. as you are creating anonymous objects in the query, the result is a stream of objects of a class that the compiler creates internally.

It's pretty useless to pass on that result to another method, as it would need to use reflection to read the properties in the objects. You should create a named class for the objects in the result, so that it's easy to access its properties.

箜明 2024-11-26 05:49:19
      class Pet
        {
            public string Name { get; set; }
            public int Age { get; set; }
        }

        // Uses method-based query syntax.
        public static void GroupByEx1()
        {
            // Create a list of pets.
            List<Pet> pets =
                new List<Pet>{ new Pet { Name="Barley", Age=8 },
                               new Pet { Name="Boots", Age=4 },
                               new Pet { Name="Whiskers", Age=1 },
                               new Pet { Name="Daisy", Age=4 } };

            // Group the pets using Age as the key value 
            // and selecting only the pet's Name for each value.
            IEnumerable<IGrouping<int, string>> query =
                pets.GroupBy(pet => pet.Age, pet => pet.Name);

            // Iterate over each IGrouping in the collection.
            foreach (IGrouping<int, string> petGroup in query)
            {
                // Print the key value of the IGrouping.
                Console.WriteLine(petGroup.Key);
                // Iterate over each value in the 
                // IGrouping and print the value.
                foreach (string name in petGroup)
                    Console.WriteLine("  {0}", name);
            }
        }

        /*
         This code produces the following output:

         8
           Barley
         4
           Boots
           Daisy
         1
           Whiskers
        */
      class Pet
        {
            public string Name { get; set; }
            public int Age { get; set; }
        }

        // Uses method-based query syntax.
        public static void GroupByEx1()
        {
            // Create a list of pets.
            List<Pet> pets =
                new List<Pet>{ new Pet { Name="Barley", Age=8 },
                               new Pet { Name="Boots", Age=4 },
                               new Pet { Name="Whiskers", Age=1 },
                               new Pet { Name="Daisy", Age=4 } };

            // Group the pets using Age as the key value 
            // and selecting only the pet's Name for each value.
            IEnumerable<IGrouping<int, string>> query =
                pets.GroupBy(pet => pet.Age, pet => pet.Name);

            // Iterate over each IGrouping in the collection.
            foreach (IGrouping<int, string> petGroup in query)
            {
                // Print the key value of the IGrouping.
                Console.WriteLine(petGroup.Key);
                // Iterate over each value in the 
                // IGrouping and print the value.
                foreach (string name in petGroup)
                    Console.WriteLine("  {0}", name);
            }
        }

        /*
         This code produces the following output:

         8
           Barley
         4
           Boots
           Daisy
         1
           Whiskers
        */
鲜肉鲜肉永远不皱 2024-11-26 05:49:19

创建类型是一个很好的主意,但是当返回 Tuple< 时为什么要这样做/a> 可以在不创建新类或结构的情况下完成吗?如果需要是本地和/或内部的并且该类不会被重用,请尝试使用元组。

Select new Tuple<Comm, IEnumerable<string>, Int32>( new Comm(), myStringList.AsEnumerable(), myCount )

Creating a type is an excellent idea, but why do that when a returned Tuple can be done without creating a new class or struct? If the need is local and or internal and the class won't be reused, try using a Tuple instead.

Select new Tuple<Comm, IEnumerable<string>, Int32>( new Comm(), myStringList.AsEnumerable(), myCount )
夜光 2024-11-26 05:49:19

将其作为 object 传递,并在 foreach 循环中使用 var 作为迭代器。

Pass it as object and in your foreach loop, use var as the iterator.

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