GroupBy не работает правильно на IQueryable - PullRequest
0 голосов
/ 04 января 2019

У меня есть класс:

class Entity
{
    public string Name { get; set; }
    public bool IsMain { get; set; }
}

Я получаю данные из БД, используя GroupBy:

var grouppedEntitiesByName = context.GetEntities<Entity>().GroupBy(en => en.Name);

У меня есть некоторые данные в БД:

IsMain = true, Name = "entity"  
IsMain = false, Name = "entity"
IsMain = true, Name = "Entity"

Я использую сгруппированные объекты, как это:

 foreach (var entity in grouppedEntitiesByName)
    {
        var mainEntity = entity.Single(a => a.IsMain);
    }

Здесь я получаю Sequence contains more than one matching element исключение.Сгруппированные сущности имеют один ключ entity и три элемента:

  IsMain = true, Name = "entity"  
    IsMain = false, Name = "entity"
    IsMain = true, Name = "Entity"

Тогда я попробовал это:

var grouppedEntitiesByName = context.GetEntities<Entity>().ToList().GroupBy(en => en.Name);

Здесь сгруппированные сущности имеют два ключа: entity и Entity Почемунекорректно работает group by в IQueryable и как это исправить?(Я использую EF)

Ответы [ 2 ]

0 голосов
/ 04 января 2019

Это потому, что IEnumerable GroupBy запрашивает данные из коллекции в памяти, а IQueryable GroupBy запрашивает из коллекции вне памяти. (источник: https://www.c -sharpcorner.com / UploadFile / a20beb / ienumerable-vs-iqueryable-in-linq / )

В вашем примере

IQueryable:

var grouppedEntitiesByName = context.GetEntities<Entity>().GroupBy(en => en.Name);

оператор переводится в SQL-запрос - select whatever from Entity group by Name, который является нечувствительной к регистру группой.

IEunumerable:

var grouppedEntitiesByName = context.GetEntities<Entity>().ToList().GroupBy(en => en.Name);

Часть ToList() загружает данные в память, и ваш GroupBy теперь IEnumerable.GroupBy, который чувствителен к регистру.

0 голосов
/ 04 января 2019

По умолчанию SQL Server имеет сортировку без учета регистра.EF выдаст оператор SQL, поэтому на результаты группировки будут влиять настройки вашей базы данных.

Если вам нужно сгруппировать с учетом регистра, вам нужно сделать это вручную, например, добавив новый столбец с регистромнечувствительный ключ, таким образом, вы все еще используете базу данных.Другой вариант, который будет частично выполняться в памяти, - использовать LINQ для группирования с помощью специального сортировщика.

...