创建空 IQueryable时出现问题目的

发布于 2024-09-14 15:17:41 字数 873 浏览 0 评论 0原文

基本上我想将两个 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;

Basically i want to merge two Iqueryable to one Iqueryable and then return the complete record set after my loop ends. It runs perfectly but in the end my objret have nothing but when i debug the loop obj have some records. wht im doing wrong

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;

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(2

逐鹿 2024-09-21 15:17:41

就像其他查询运算符一样,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(?也许是实体)与 Enumerable.AsQueryable 混合在一起代码>,请注意。鉴于由于 Count() 调用,您已经在某种程度上执行查询,您是否考虑过构建一个 List

(您根本不需要执行 Count() - 只需调用 List.AddRange(obj1) 即可,对于 obj 也是如此>.)

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

Just like the other query operators, Concat doesn't change the existing sequence - it returns a new sequence.

So these lines:

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

should be

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

I'm not sure how well IQueryable is going to handle this, given that you're mixing LINQ to SQL (? maybe Entities) with Enumerable.AsQueryable, mind you. Given that you're already executing the queries to some extent due to the Count() calls, have you considered building up a List<T> instead?

(You don't need to execute the Count() at all - just call List<T>.AddRange(obj1) and ditto for obj.)

As jeroenh mentioned, ideally it would be nice to use a solution which could do it all that the database without looping at all in your C# code.

不离久伴 2024-09-21 15:17:41

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

I think you should not do this with a for loop. The code you posted will go to the db for every single active mediatype twice to get Count() and additionally, twice to get actual results.

Checking the Count() property is not necessary: concatenating empty result sets has no additional effect.

Furthermore, I think what you're trying to achieve can be done with a single query, something along the lines of (not tested):

        // 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));
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文