2010-10-04 3 views
5

J'essaye de faire fonctionner ce LINQ mais échoue avec l'erreur.Erreur LINQ avec GroupBy

Impossible de convertir l'expression lambda de type « System.Collections.Generic.IEqualityComparer » parce qu'il est pas un type de délégué

Fondamentalement, j'ai IEnumerable<DataRow> et je suis en train de regrouper les données, comme dans :

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

Des pensées?

suggestion de DigEmAll aidé (merci) et je devais faire:

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

Et puis changer le LINQ à cette GroupBy clé:

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

Ne pas comme créer un type concret pour la clé ... de toute façon autour de cela?

+0

On dirait que LINQ est à la recherche de la 2ème surcharge qui exige un IEnumerable public static IEqualityComparer > GroupBy ( cette IEnumerable source de , Func comparateur keySelector, IEqualityComparer ); – Sunit

Répondre

3

Je pense que votre problème est dans le Field<T> dans votre définition de type anonyme.

Vous devez spécifier le type T (ne peut être déduit de l'utilisation), le compilateur reconnaît la surcharge GroupBy correcte.


EDIT en fonction des changements OP:

Vous n'avez pas besoin de créer un type concret, simplement spécifier explicitement le T droit dans Field<T>(...), donc dans votre code:

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

EDIT 2:

OK, j'ai édité votre question car en réalité vos <...> étaient cachés (n'utilisez pas <code><pre> manuellement, cliquez simplement sur le bouton approprié ;-)).

Quoi qu'il en soit, votre dernier code a une erreur dans la spécification GroupBy types:

n'est pas <DataRow, GroupKey, IEnumerable<Customer>>,

mais <DataRow, GroupKey, Customer>

car il vous suffit de préciser le type interne du retour IEnumerable.

Puis, je l'ai essayé votre dernier code, et le retrait également le type de béton GroupKey (et la suppression de toute évidence la spécification des types GroupBy) il est parfaitement valable:

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

Bon point, j'ai raté ça. .. Mais dans ce cas, le compilateur ne montre pas la cause réelle de l'erreur –

+0

Ou peut-être l'OP ne l'a pas remarqué? Je ne sais pas je devine ... – digEmAll

+0

@Sunit: vérifier ma modification;) – digEmAll

1

Vous avez mélangé votre GroupBy et Select. Essayez ce qui suit comme un travail autour (en regardant la surcharge que vous utilisez):

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

Votre solution devrait retourner le résultat attendu, mais en fait je pense que l'OP essaie d'utiliser [cette surcharge GroupBy] (http://msdn.microsoft.com/en-us/library/bb549393.aspx), donc il n'est pas vraiment "mélange" quoi que ce soit ... Je ne vois pas pourquoi le code d'origine ne compile pas –

+0

J'utilise la surcharge pour IEnumerable de public static GroupBy > GroupBy ( cette source IEnumerable, Func keySelector, Func elementSelector); – Sunit

+0

Thomas m'a battu à l'explication (: – Sunit