EF4 - Linq - Query.Any() 异常

发布于 2024-11-04 02:51:28 字数 1439 浏览 1 评论 0原文

我使用 EF 一段时间了,但从未遇到过这个问题。基本上我们有一个为 Web 前端提供数据的 WCF 服务。在该服务中,我们使用 EF 4 作为数据实现。绕过所有存储库和单例,一个简单的 Get 函数如下:

using (OurEntities DataContext = new OurEntities())
{
    DataContext.Order.MergeOption = System.Data.Objects.MergeOption.NoTracking;
    List<Order> orders = new List<Order>();
    var query = from p in DataContext.Order.Include("OrderDetail")
                where (p.OrderID == orderId || orderId == 0)
                   && (p.OrderStatus == orderStatus || orderStatus == 0)
                   && (p.OrderType == orderType || orderType == 0)
                   && (p.OrderFlag == null || p.OrderFlag == false)
                select p;

    if (query.Any())
    {
        foreach (Order order in query)
        {
            orders.Add(order);
        }
    }
    return orders;
}

orderId, orderStatus & orderType 在参数中传递。
正如预期的那样,代码工作没有任何问题......直到我们运行一些压力测试,从不同的客户端同时调用服务(即 GET 函数)。几分钟后,我们收到一堆InvalidOperationException:从物化“System.Int32”类型到“System.Boolean”类型的指定转换无效。在我们的 SQL 2008 数据库中,OrderID 是 int (identity, auto-gen),OrderFlag 是唯一数据类型 = bit 的字段(由 EF 转换为布尔值)。
在调试过程中,我发现当查询中的单个项目转换为 Order 时,异常是由 query.Any() 或 foreach 子句引发的。但是,如果我以任何方式接触事务(在 SSMS 上运行相同的查询或在“监视”窗口中执行 query.Any()),查询就会使用正确的数据进行更新,并且它会正常工作......
我们的环境:VS 2010、.Net Framework 4、EF 4、SQL Server 2008 Express + Standard(我都尝试过)
任何评论或任何帮助将不胜感激...
埃里克

I've using EF for a while but I've never had this problem. Basically we have a WCF services that provide data for web front end. In that service, we use EF 4 as data implementation. Bypass all the repository and singleton, a simple Get function would be as below:

using (OurEntities DataContext = new OurEntities())
{
    DataContext.Order.MergeOption = System.Data.Objects.MergeOption.NoTracking;
    List<Order> orders = new List<Order>();
    var query = from p in DataContext.Order.Include("OrderDetail")
                where (p.OrderID == orderId || orderId == 0)
                   && (p.OrderStatus == orderStatus || orderStatus == 0)
                   && (p.OrderType == orderType || orderType == 0)
                   && (p.OrderFlag == null || p.OrderFlag == false)
                select p;

    if (query.Any())
    {
        foreach (Order order in query)
        {
            orders.Add(order);
        }
    }
    return orders;
}

orderId, orderStatus & orderType are passed in parameters.
The code works without any problems, as expected... until we run a few stress tests where we call the services (i.e. the GET functions) simultaneously from different clients. After a few minutes, we get a bunch of InvalidOperationException: The specified cast from a materialized 'System.Int32' type to the 'System.Boolean' type is not valid. In our SQL 2008 database, OrderID is int (identity, auto-gen) and OrderFlag is the only field with data type = bit (translated to boolean by EF).
During debug, I found out that the exception was either thrown by query.Any() or by the foreach clause, when a single item in query is casted to Order. But if I touch the transaction by any mean (either run the same query on SSMS or execute query.Any() in the Watch window), query get updated with proper data and it just works....
Our evironment: VS 2010, .Net framework 4, EF 4, SQL Server 2008 express + standard (I've tried on both)
Any comments or any help would be greatly appreciated...
Eric

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

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

发布评论

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

评论(1

安穩 2024-11-11 02:51:28

您应该首先将代码修改为:

using (OurEntities DataContext = new OurEntities())
{
    DataContext.Order.MergeOption = System.Data.Objects.MergeOption.NoTracking;
    var query = from p in DataContext.Order.Include("OrderDetail")
                where (p.OrderID == orderId || orderId == 0)
                   && (p.OrderStatus == orderStatus || orderStatus == 0)
                   && (p.OrderType == orderType || orderType == 0)
                   && (p.OrderFlag == null || p.OrderFlag == false)
                select p;

    return query.ToList();
}

并再次运行测试。我不认为这会解决您的问题,但您当前的代码不应该通过代码审查。

You should start with modifying your code to:

using (OurEntities DataContext = new OurEntities())
{
    DataContext.Order.MergeOption = System.Data.Objects.MergeOption.NoTracking;
    var query = from p in DataContext.Order.Include("OrderDetail")
                where (p.OrderID == orderId || orderId == 0)
                   && (p.OrderStatus == orderStatus || orderStatus == 0)
                   && (p.OrderType == orderType || orderType == 0)
                   && (p.OrderFlag == null || p.OrderFlag == false)
                select p;

    return query.ToList();
}

And run your tests again. I don't except that this will solve your problem but your current code is something that should not pass code review.

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