Проблема создания пустого объекта IQueryable <T> - PullRequest
6 голосов
/ 17 августа 2010

В основном я хочу объединить два Iqueryable в один Iqueryable и затем вернуть полный набор записей после завершения цикла. Он работает отлично, но в конце концов у моего объекта нет ничего, кроме как при отладке цикла. У объекта есть несколько записей. что я делаю не так

IQueryable<MediaType> objret = Enumerable.Empty<MediaType>().AsQueryable();
var typ = _db.MediaTypes.Where(e => e.int_MediaTypeId != 1 && e.int_MediaTypeId_FK == null).ToList();
for (int i = 0; i < typ.Count; i++)
{ 
    IQueryable<MediaType> obj = _db.MediaTypes.Where(e => e.bit_IsActive == true && e.int_MediaTypeId_FK == typ[i].int_MediaTypeId);
    IQueryable<MediaType> obj1 = _db.MediaTypes.Where(e => e.int_OrganizationId == Authorization.OrganizationID && e.bit_IsActive == true && e.int_MediaTypeId_FK == typ[i].int_MediaTypeId);

    if (obj1.Count() > 0)
        obj.Concat(obj1);
    if(obj.Count() > 0)
        objret.Concat(obj);
}
return objret;

Ответы [ 2 ]

4 голосов
/ 17 августа 2010

Как и другие операторы запросов, Concat не меняет существующую последовательность - она ​​возвращает новую последовательность.

Итак, эти строки:

if (obj1.Count() > 0)
    obj.Concat(obj1);
if(obj.Count() > 0)
    objret.Concat(obj);

должно быть

if (obj1.Count() > 0)
    objret = objret.Concat(obj1);
if(obj.Count() > 0)
    objret = objret.Concat(obj);

Я не уверен, насколько хорошо IQueryable справится с этим, учитывая, что вы смешиваете LINQ to SQL (? Возможно, Entities) с Enumerable.AsQueryable, заметьте,,Учитывая, что вы уже выполняете запросы в некоторой степени из-за вызовов Count(), рассматривали ли вы вместо этого создание List<T>?

(Вам не нужно выполнять Count() ввсе - просто позвоните List<T>.AddRange(obj1) и то же самое для obj.)

Как упоминал jeroenh, в идеале было бы неплохо использовать решение, которое могло бы сделать все это, что база данных вообще не зацикливается в вашем коде C #.

0 голосов
/ 17 августа 2010

Я думаю, вы не должны делать это с циклом for.Размещенный вами код будет идти в базу данных для каждого отдельного активного медиатипа дважды, чтобы получить Count (), и дополнительно, дважды, чтобы получить фактические результаты.

Проверка свойства Count () не требуется: объединение пустых наборов результатовбез дополнительного эффекта.

Более того, я думаю, что вы пытаетесь достичь, можно сделать с помощью одного запроса, что-то вроде (не проверено):

        // build up the query

        var rootTypes = _db.MediaTypes.Where(e => e.int_MediaTypeId != 1 && e.int_MediaTypeId_FK == null);
        var activeChildren = _db.MediaTypes
                                .Where(e => e.bit_IsActive);
        var activeChildrenForOrganization = _db.MediaTypes
                                .Where(e => e.int_OrganizationId == Authorization.OrganizationID && e.bit_IsActive);

        var q = from types in rootTypes
                join e in activeChildren 
                on types.int_MediaTypeId equals e.int_MediaTypeId_FK into joined1
                join e in activeChildrenForOrganization 
                on types.int_MediaTypeId equals e.int_MediaTypeId_FK into joined2
                select new {types, joined1, joined2};


        // evaluate the query and concatenate the results. 
        // This will only go to the db once
        return q.ToList().SelectMany(x => x.joined1.Concat(x.joined2));
...