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);
精彩评论