Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

LINQ Error with GroupBy

Tags:

c#

linq

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].[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);

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?

like image 883
Sunit Avatar asked Oct 14 '22 23:10

Sunit


1 Answers

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;
like image 194
digEmAll Avatar answered Nov 02 '22 09:11

digEmAll