开发者

LINQ Error with GroupBy

I'm trying to get this LINQ to work but fails with the error.

Cannot convert lambda expression to type 'System.Collections.Generic.IEqualityComparer' because it is not a delegate type

Basically I have IEnumerable<DataRow> and I'm trying to group the data, as in:

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].[Produ开发者_高级运维ct] = '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);

Any thoughts ?

DigEmAll's suggestion helped (thanks) and I had to do this:

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

And then change the LINQ to this GroupBy key:

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

Don't like creating a concrete type for the key...any way around this?


I think your problem is in the Field<T> in your Anonymous type definition.

You should specify the type T (cannot be inferred from the usage), then compiler will recognize the correct GroupBy overload.


EDIT according to OP changes:

You don't need to create a concrete type, just specify explicitly the right T in Field<T>(...), so in your code:

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

EDIT 2:

OK, I've edited your question because actually your <...> were hidden (don't use <code><pre> manually, just click on the appropriate button ;-) ).

Anyway, your last code has an error in the GroupBy types specification:

is not <DataRow, GroupKey, IEnumerable<Customer>>,

but <DataRow, GroupKey, Customer>

because you just have to specify the inner Type of the returned IEnumerable.

Then, I've tried your last code, and also removing the concrete type GroupKey (and obviously removing the GroupBy types specification) it is perfectly valid:

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;


You mixed your GroupBy and Select. Try the following as a work-around (looking into the overload you're using):

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

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜