2010-10-04 2 views
5

Я пытаюсь заставить этот LINQ работать, но не с ошибкой.Ошибка LINQ с GroupBy

Невозможно преобразовать лямбда-выражения к типу «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); 

Не нравится создавая конкретный тип для ключа ... каким-то образом вокруг этого?

+0

Похоже, LINQ ищу 2-ой перегрузки что требует публичного статического IEqualityComparer IEnumerable > GroupBy ( это IEnumerable источник, Func keySelector, IEqualityComparer Comparer); – Sunit

ответ

3

Я думаю, ваша проблема заключается в Field<T> в вашем определении типа Anonymous.

Вы должны указать тип T (не может быть выведен из использования), тогда компилятор распознает правильную перегрузку GroupBy.


EDIT в соответствии с изменениями OP:

Вам не нужно, чтобы создать конкретный тип, только явно указать правильный T в Field<T>(...), так что в вашем коде:

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

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

Хорошо, я пропустил это. .. Но в этом случае компилятор не показывает фактическую причину ошибки –

+0

Или, возможно, ОП не заметил этого? Я не знаю, что я угадываю ... – digEmAll

+0

@Sunit: проверить мои изменения;) – digEmAll

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

Ваше решение должно вернуть ожидаемый результат, но на самом деле я думаю, что OP пытается использовать [эту перегрузку GroupBy] (http://msdn.microsoft.com/en-us/library/bb549393.aspx), поэтому он на самом деле не «смешивание» ничего ... Я не могу понять, почему исходный код не компилируется –

+0

я использую перегрузку для GroupBy общественности статической IEnumerable > GroupBy ( это IEnumerable источника, Func keySelector, Func elementSelector); – Sunit

+0

Томас избил меня до объяснения (: – Sunit