创建空IQueryable <t>对象</t>时出现问题

时间:2010-08-17 06:45:17

标签: c# collections iqueryable

基本上我想将两个Iqueryable合并为一个Iqueryable,然后在循环结束后返回完整的记录集。它运行完美,但最后我的objret什么都没有,但当我调试循环obj有一些记录。我做错了

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 个答案:

答案 0 :(得分:4)

与其他查询运算符一样,Concat不会更改现有序列 - 它会返回 new 序列。

所以这些行:

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(?可能实体)与Enumerable.AsQueryable混合在一起,请注意。鉴于由于Count()来电,您已经在某种程度上执行了查询,您是否考虑过构建List<T>

(您根本不需要执行Count() - 只需致电List<T>.AddRange(obj1),然后同意obj。)

正如jeroenh所提到的,理想情况下使用一个解决方案可以很好地完成数据库而不需要在C#代码中循环。

答案 1 :(得分:0)

我认为你不应该用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));