【问题标题】:Declaring list with anonymous type使用匿名类型声明列表
【发布时间】:2018-10-16 18:26:31
【问题描述】:

我正在尝试声明其中包含匿名类型的列表。我试图将列表值分配给 null 并尝试将列表分配给新实体列表,但它显示错误。有什么指点吗?

var finalEntries = new List<MyDbTableEntity>();

var groupedItemList = _context.MyDbTableEntity
                      .Select(k => new { name = k.name.ToString(), data = k.info.ToString() })
                      .GroupBy(k => k.name)
                      .ToList();

finalEntries.AddRange(groupedItemList);

错误

cannot convert from 
'System.Collections.Generic.List<System.Linq.IGrouping<string, <anonymous type: string name, string data>>>' 
to 
'System.Collections.Generic.IEnumerable<MyDbTableEntity>'

【问题讨论】:

  • 抱歉,请问您收到的错误不是很明显吗?它准确地告诉您 IEnumerable&lt;MyDbTableEntity&gt; 不等于 List&lt;IGrouping&lt;string, &lt;anonymous type&gt;&gt;&gt; 出了什么问题?因此,您唯一的选择是使它们相等,或者如果您没有比object 更通用的基类,则至少是一些通用基类,因为一切都是object
  • 我试过了,不知道如何传递匿名参数。

标签: c# .net list entity-framework linq


【解决方案1】:

它不起作用,因为您有一个MyDbTableEntity 的键入列表。您不能在此类型列表中添加其他类型。尝试定义正确的类型?

var finalEntries = new List<MyDbTableEntity>();

var groupedItemList = _context.MyDbTableEntity
                      .Select(k => new MyDbTableEntity { Name = k.name.ToString(), Data = k.info.ToString() })
                      .GroupBy(k => k.Name)
                      .ToList();

finalEntries.AddRange(groupedItemList);

或它或将其更改为object 的列表。

var finalEntries = new List<object>();

// not sure about your type
var groupedItemList = _context.MyDbTableEntity
                      .Select(k => new { name = k.name.ToString(), data = k.info.ToString() })
                      .GroupBy(k => k.name)
                      .ToList();

finalEntries.AddRange(groupedItemList);

重要提示:问题是当你失去这个范围时,你将不会得到一个类型化的匿名类型,我的意思是,你需要使用一些工件来读取属性,例如:使用reflection 将类型转换为dictionary

【讨论】:

    【解决方案2】:

    在此示例中,Select().GroupBy().ToList() 实质上返回一个列表列表。顶级列表包含由 GroupBy() 创建的所有组,而第二级 lists 包含从 Select() 方法返回的每个组的行。这些是与 MyDbTableEntity 完全不同的匿名类型对象

    组列表和匿名类型对象都不能转换为您的 MyDbTableEntity 类型。为了说明我的意思,如果您删除了 Select() 语句(以及匿名类型),您可以将最后一行更改为以下内容,它会起作用:

    foreach(var items in groupedItemList) finalEntries.AddRange(items);
    

    当然,这首先违背了分组的目的,但它确实说明了原始代码为何不起作用的一个方面。第二个方面是通过删除 Select() 语句来证明的

    这是我的意思的一个例子:

        class Person {
            public string FirstName;
            public string LastName;
            public Person(string firstName, string lastName) {
                FirstName = firstName;
                LastName = lastName;
            }
        }
    
        Person[] people = {
            new Person("Fred", "Bloggs"),
            new Person("Linda", "Bloggs"),
            new Person("Joe", "Bloe"),
            new Person("Jane", "Bloe"),
            new Person("Fred", "Flinstone")};
    
        public void Test() {
            List<Person> list = new List<Person>();     
    
            // This works   
            var peopleGroupedByLastName = people.GroupBy(k => k.LastName).ToList();
            foreach(var grp in peopleGroupedByLastName) {
                // The grp var holds a list of Person objects, each with the same last name
                list.AddRange(grp); // Pointless, but works
            }
    
            // The following will not even compile because the anonymous typed objects are
            // not compatible with Person objects, despite having exactly the same fields
            var peopleGroupedByLastName2 = people
                .Select(k => new { FirstName = k.FirstName, LastName = k.LastName })
                .GroupBy(k => k.LastName)
                .ToList();
            foreach(var grp in peopleGroupedByLastName2)
                list.AddRange(grp); // Not "Person" objects
        }
    

    【讨论】:

      【解决方案3】:
      var finalEntries = Enumerable.Empty<MyDbTableEntity>()
                            .Select(k => new MyDbTableEntity { Name = k.name.ToString(), Data = k.info.ToString() })
                            .GroupBy(k => k.Name)
                            .ToList();
      
      var groupedItemList = _context.MyDbTableEntity
                            .Select(k => new MyDbTableEntity { Name = k.name.ToString(), Data = k.info.ToString() })
                            .GroupBy(k => k.Name)
                            .ToList();
      
      finalEntries.AddRange(groupedItemList);
      

      http://rextester.com/KNLMR37736

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2015-03-15
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多