2013-02-28 2 views
0

Я столкнулся с этой проблемой, когда делал группу с помощью сущности.Проблема EF с группировкой на сервере

.Net: 4,5, EF: 5,0, базы данных: Oracle

Моя проблема была, когда я группируя на сервере и получать обратно данные, сгруппированные данные (список лиц) возвращается первая запись через и более для всех сгруппированных данных, но группа KEY была правильной.

Если я не делаю группу по записям, как ожидалось, но у меня есть некоторые требования к группировке, и мое обходное решение ... да, не заставляя меня чувствовать, что хорошо, и код должен работать ... но он делает не.

x.D = остаток строки является целым числом/комбинацией строк.

Вот код, который не работает:

db.ENTITY_NAME 
.Where(x => 
     wantedGs.Contains(x.G) && 
     wantedAs.Contains(x.A) 
    ) 
.GroupBy(x => x.D) 
.ToList() 
.Select(x => x.FirstOrDefault()) 
.Select(x => new MyEntity 
    { 
     A = x.A, 
     B = x.B, 
     C = x.C, 
     E = x.E, 
     D = x.D, 
     F = x.F, 
     G = x.G 
    }) 
.ToList(); 

Вот обходной путь мне удалось сделать то, что я хочу:

db.ENTITY_NAME 
.Where(x => 
     wantedGs.Contains(x.G) && 
     wantedAs.Contains(x.A) 
    ) 
.Select(x => new 
{ 
    x.A, 
    x.B, 
    x.C, 
    x.D, 
    x.E, 
    x.F, 
    x.G 
}) 
.ToList() 
.GroupBy(x => x.D) 
.Select(x => x.FirstOrDefault()) 
.Select(x => new MyEntity 
    { 
     A = x.A, 
     B = x.B, 
     C = x.C, 
     E = x.E, 
     D = x.D, 
     F = x.F, 
     G = x.G 
    }) 
.ToList(); 
+0

Каков результат, если вы только выполняете 'GroupBy (x => x.D)' первого запроса? –

ответ

0

Если это не работает, пожалуйста, напишите некоторый образец данные, которые отображают проблему

db.ENTITY_NAME 
.Where(x => 
     wantedGs.Contains(x.G) && 
     wantedAs.Contains(x.A) 
    ) 
.GroupBy(x => x.D) 
.Select(x => x.FirstOrDefault()) 
.AsEnumerable() 
.Select(x => new MyEntity 
    { 
     A = x.A, 
     B = x.B, 
     C = x.C, 
     E = x.E, 
     D = x.D, 
     F = x.F, 
     G = x.G 
    }) 
.ToList(); 
0

Я нахожу LINQPad полезным при диагностике такого рода проблем. Запрос на таблицу Oracle и переключение с Результаты вкладка на вкладку SQL . Обратите внимание, как первый пример приводит к одному начальному SQL select, за которым следуют несколько последующих операторов select, которые не будут полезны при достижении правильной группировки обязательный. Похож на меня.

Эта проблема представляется специфичной для Oracle (возможно, конкретной версией клиента). Аналогичный GroupBy в базе данных Microsoft SQL Express дал правильные результаты, хотя было также несколько SQL select.

Кажется, мы должны быть осторожны при использовании GroupBy на соединениях с базой данных; он может быть как быстрее, так и точнее оценивать ранние (например, преобразование в список), так что мы используем LINQ для данных с этой точки.

Обновление с REPRO случае:

Сначала Oracle (9i) создания таблицы и строки вставки:

create table payees (
    name varchar2(10), 
    amount number(5)); 
insert into payees values ('JACK', 150); 
insert into payees values ('BARRY', 100); 
insert into payees values ('EMMA', 20); 
insert into payees values ('FLAVIA', 15); 
insert into payees values ('SYLVIA', 300); 
commit; 

Хорошие и плохие заявления LINQ (с использованием Oracle 9i клиента):

var good = Payees.ToList().GroupBy(p => p.Amount/100); 
var bad = Payees.GroupBy(p => p.Amount/100); 

Пример запроса, который я ожидал от интеллектуального драйвера LINQ to Oracle:

select trunc(amount/100) pay_category, name, amount 
from payees 
order by pay_category; 

PAY_CATEGORY NAME   AMOUNT 
------------ ---------- ---------- 
      0 EMMA    20 
      0 FLAVIA    15 
      1 JACK    150 
      1 BARRY    100 
      3 SYLVIA   300 

Фактические странные отчеты запросы LINQPad на вкладке SQL, в результате никакой полезной группировки на всех:

SELECT t0.AMOUNT 
FROM GENSYS.PAYEES t0 
GROUP BY t0.AMOUNT 

SELECT t0.AMOUNT, t0.NAME 
FROM GENSYS.PAYEES t0 
WHERE ((t0.AMOUNT IS NULL AND :n0 IS NULL) OR (t0.AMOUNT = :n0)) 
-- n0 = [15] 

SELECT t0.AMOUNT, t0.NAME 
FROM GENSYS.PAYEES t0 
WHERE ((t0.AMOUNT IS NULL AND :n0 IS NULL) OR (t0.AMOUNT = :n0)) 
-- n0 = [20] 

SELECT t0.AMOUNT, t0.NAME 
FROM GENSYS.PAYEES t0 
WHERE ((t0.AMOUNT IS NULL AND :n0 IS NULL) OR (t0.AMOUNT = :n0)) 
-- n0 = [100] 

SELECT t0.AMOUNT, t0.NAME 
FROM GENSYS.PAYEES t0 
WHERE ((t0.AMOUNT IS NULL AND :n0 IS NULL) OR (t0.AMOUNT = :n0)) 
-- n0 = [150] 

SELECT t0.AMOUNT, t0.NAME 
FROM GENSYS.PAYEES t0 
WHERE ((t0.AMOUNT IS NULL AND :n0 IS NULL) OR (t0.AMOUNT = :n0)) 
-- n0 = [300] 

я могу ожидать слишком много LINQ к SQL, хотя. (Мой LINQPad сообщает, что драйвер LINQPad - IQ V2.0.7.0, если это помогает).

Смежные вопросы