GroupBy的LINQ错误

时间:2010-10-04 18:46:21

标签: c# linq

我正在尝试让这个LINQ工作,但失败并出现错误。

  

无法将lambda表达式转换为类型'System.Collections.Generic.IEqualityComparer',因为它不是委托类型

基本上我有IEnumerable<DataRow>而我正在尝试对数据进行分组,如:

string sql = @"SELECT [t0].[Contact_Account] AS [Contact], [t0].[Work_Phone] AS [WorkPhone], [t0].[SR_NUM] AS [SRNum] ";
sql += "FROM [Base_SR] AS [t0] ";
sql += "WHERE ([t0].[Country] = 'USA') AND (NOT ([t0].[Work_Phone] LIKE '+%')) ";
sql += "AND ([t0].[Product] = 'SP3D') AND (DATEPART(Year, [t0].[DateOpened]) = {0})";

sql = String.Format(sql, curYear);

var sqlCmd  = new SqlCommand(sql, new SqlConnection(connectionString));
var adapter = new SqlDataAdapter(sqlCmd);
var dataSet = new DataSet();
adapter.Fill(dataSet);
var siebelRows = dataSet.Tables[0].AsEnumerable();

return siebelRows.GroupBy(sr => new { AreaCode = sr.Field<string>("WorkPhone").Substring(0, 3), 
          Contact = sr.Field<string>("Contact") },
     (key, lst) => new Customer 
     {
                        Id = Guid.NewGuid(),
      AreaCode = key.AreaCode,
      CustAccount = key.Contact,
      FirstPhoneNo = lst.First().Field<string>("WorkPhone").Substring(0, 10),
      FirstSRNum= lst.First().Field<string>("SRNum"),
      SRCount = lst.Count()
     })
     .Take(5);

有什么想法吗?

DigEmAll的建议有所帮助(谢谢),我不得不这样做:

public class GroupKey
{
    public string AreaCode { get; set; }
    public string Contact { get; set; }
}

然后将LINQ更改为此GroupBy键:

GroupBy<DataRow, GroupKey, IEnumerable<Customer>>

return siebelRows.GroupBy<DataRow, GroupKey, IEnumerable<Customer>>(sr => new GroupKey
{
    Contact = sr.Field<string>("Contact"),
    AreaCode = sr.Field<string>("WorkPhone").Substring(0, 3)
},
    (key, lst) => new Customer
        {
            Id = Guid.NewGuid(),
            AreaCode = key.AreaCode,
            CustAccount = key.Contact,
            FirstPhoneNo = lst.First().Field<string>("WorkPhone").Substring(0, 10),
            FirstSRNum = lst.First().Field<string>("SRNum"),
            SRCount = lst.Count()
        }).OrderByDescending(c => c.SRCount)
        .Take(5);

不喜欢为密钥创建一个具体的类型......围绕这个方法吗?

2 个答案:

答案 0 :(得分:3)

我认为您的问题出在匿名类型定义的Field<T>中。

您应该指定类型T(不能从用法中推断出来),然后编译器将识别正确的GroupBy重载。


根据OP改变编辑:

您不需要创建具体类型,只需在T中明确指定右Field<T>(...),所以在您的代码中:

sr => new { AreaCode = sr.Field<string>("WorkPhone").Substring(0, 3), 
            Contact = sr.Field<string>("Contact") }

编辑2:

好的,我已经编辑了你的问题,因为实际上你的<...>被隐藏了(不要手动使用<code><pre>,只需点击相应的按钮;-))。

无论如何,您的上一个代码在GroupBy类型规范中有错误:

不是<DataRow, GroupKey, IEnumerable<Customer>>

但是<DataRow, GroupKey, Customer>

因为您只需要指定返回的IEnumerable的内部类型。

然后,我尝试了你的最后一个代码,并删除了具体类型GroupKey(显然删除了GroupBy类型规范),这是完全有效的:

var customers = siebelRows.GroupBy( 
    sr => new 
    {
        Contact = sr.Field<string>("Contact"),
        AreaCode = sr.Field<string>("WorkPhone").Substring(0, 3)
    },
    (key, lst) => new Customer
    {
        Id = Guid.NewGuid(),
        AreaCode = key.AreaCode,
        CustAccount = key.Contact,
        FirstPhoneNo = lst.First().Field<string>("WorkPhone").Substring(0, 10),
        FirstSRNum = lst.First().Field<string>("SRNum"),
        SRCount = lst.Count()
    })
    .OrderByDescending(c => c.SRCount)
    .Take(5);
return customers;

答案 1 :(得分:1)

您混合了GroupBy和Select。尝试以下方法(查看您正在使用的重载):

return siebelRows.GroupBy(sr => new
                          { 
                              AreaCode = sr.Field("AreaCode")
                                           .Substring(0, 3),
                              Contact = sr.Field("Contact")
                          })
                 .Select(kvp => new Customer
                                {
                                    Id = Guid.NewGuid(),
                                    AreaCode = kvp.Key.AreaCode,
                                    CustAccount = kvp.Key.Contact,
                                    // rest of the assignment
                                }
                 .Take(5);