在 where 表达式中使用 Guid.Empty 悬挂 Linq 查询

发布于 2024-07-10 16:54:24 字数 1394 浏览 10 评论 0原文

我在使用以下代码时遇到问题:

    private void DataPortal_Fetch(TaskCriteria criteria)
    {
        using (var ctx = ContextManager<Gimli.Data.GimliDataContext>
                    .GetManager(Database.ApplicationConnection, false))
        {
            this.RaiseListChangedEvents = false;
            this.IsReadOnly = false;

            IQueryable<Data.Task> query = ctx.DataContext.Tasks;

            if (criteria.ReadyForPricing)
            {
                query = query.Where(row => row.IsPriced != true);
                query = query.Where(row => row.Status == (int)TaskStatus.Closed);
                query = query.Where(row => row.InvoiceId == Guid.Empty);
            }

            if (criteria.ReadyForInvoicing)
            {
                query = query.Where(row => row.IsPriced == true);
                query = query.Where(row => row.Status == (int)TaskStatus.Closed);
                query = query.Where(row => row.InvoiceId == Guid.Empty);
            }

            var data = query.Select(row => TaskInfo.FetchTaskInfo(row));

            this.AddRange(data);

            this.IsReadOnly = true;
            this.RaiseListChangedEvents = true;
        }
    }

当我的 Web 应用程序调用此方法时,如果我不注释掉以下行,它总是挂起:

query = query.Where(row => row.InvoiceId == Guid.Empty)

知道为什么会发生这种情况吗?

I'm having an issue with the following code:

    private void DataPortal_Fetch(TaskCriteria criteria)
    {
        using (var ctx = ContextManager<Gimli.Data.GimliDataContext>
                    .GetManager(Database.ApplicationConnection, false))
        {
            this.RaiseListChangedEvents = false;
            this.IsReadOnly = false;

            IQueryable<Data.Task> query = ctx.DataContext.Tasks;

            if (criteria.ReadyForPricing)
            {
                query = query.Where(row => row.IsPriced != true);
                query = query.Where(row => row.Status == (int)TaskStatus.Closed);
                query = query.Where(row => row.InvoiceId == Guid.Empty);
            }

            if (criteria.ReadyForInvoicing)
            {
                query = query.Where(row => row.IsPriced == true);
                query = query.Where(row => row.Status == (int)TaskStatus.Closed);
                query = query.Where(row => row.InvoiceId == Guid.Empty);
            }

            var data = query.Select(row => TaskInfo.FetchTaskInfo(row));

            this.AddRange(data);

            this.IsReadOnly = true;
            this.RaiseListChangedEvents = true;
        }
    }

My web application, when it calls this method, always hangs if I don't comment out the following line:

query = query.Where(row => row.InvoiceId == Guid.Empty)

Any idea why this would be happening?

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

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

发布评论

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

评论(4

归途 2024-07-17 16:54:24

下面的代码有效......有趣的是......知道为什么吗?

query = query.Where(row => row.InvoiceId == new Guid("00000000-0000-0000-0000-000000000000"));

The following code works ... interestingly enough ... any idea of why?

query = query.Where(row => row.InvoiceId == new Guid("00000000-0000-0000-0000-000000000000"));
烙印 2024-07-17 16:54:24

尝试将代码更改为:

query.Where(row => object.Equals(row.InvoiceId, Guid.Empty))

如果有帮助,请回发...

Try changing the code to:

query.Where(row => object.Equals(row.InvoiceId, Guid.Empty))

Post back if that helped...

空城之時有危險 2024-07-17 16:54:24

@BFree ...尝试了你的建议...并且仍然做同样的事情。 奇怪的是,我可以在 LinqPad 中毫无问题地运行以下代码:

from t in Tasks
where  t.IsPriced == false
&& t.IsNotInvoiceable == false
&& t.Status == 5
&& t.InvoiceId == Guid.Empty
select t

我也可以毫无问题地使用以下代码行:

if (criteria.ProjectId != Guid.Empty)
     query = query.Where(row => row.ProjectId == criteria.ProjectId);

就在我使用 Guid.Empty 时。 简直太奇怪了。

@BFree ... Tried what you suggested ... and still do the same thing. It's odd, I can run the following code in LinqPad with no problem:

from t in Tasks
where  t.IsPriced == false
&& t.IsNotInvoiceable == false
&& t.Status == 5
&& t.InvoiceId == Guid.Empty
select t

As well as I can use the following line of code with not problems either:

if (criteria.ProjectId != Guid.Empty)
     query = query.Where(row => row.ProjectId == criteria.ProjectId);

It's just when I use Guid.Empty. Just plain odd.

橘寄 2024-07-17 16:54:24

这可能是因为 lambda 的解释方式; 对于“Guid.Empty”,“Guid.Empty”是最终 lambda 的一部分。 我想知道 LINQ 提供者是否以某种方式将此视为特殊情况?

您可以尝试:

Guid empty = Guid.Empty;
query = query.Where(row => row.InvoiceId == empty);

但实际上,除了 Guid 与某些编译器生成的捕获类之外,其表达式树是相同的(它们都涉及 lambda=>BinaryExpression=>MemberExpression)。

如果上述出现问题,那么请尝试打开 TSQL 跟踪,或启用 LINQ 提供程序日志记录 - 对于 LINQ-to-SQL,类似下面的内容有效(不要引用我!):

ctx.Log = Console.Out;

It could be because of how the lambda is interpreted; with "Guid.Empty", the "Guid.Empty" is part of the final lambda. I wonder whether the LINQ-provider is treating this as a special case somehow?

You could try:

Guid empty = Guid.Empty;
query = query.Where(row => row.InvoiceId == empty);

But actually, other than Guid vs some compiler-generated capture class, the expression tree for this is the same (they both involve lambda=>BinaryExpression=>MemberExpression).

If the above also complains, then try putting a TSQL trace on, or enabling your LINQ-providers logging - for LINQ-to-SQL, something like below works (don't quote me!):

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