EF4 - Linq - Исключение для Query.Any () - PullRequest
0 голосов
/ 30 апреля 2011

Я некоторое время пользуюсь EF, но у меня никогда не было этой проблемы. По сути, у нас есть службы 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).
Во время отладки я обнаружил, что исключение было либо сгенерировано query.Any (), либо предложением foreach, когда отдельный элемент в запросе приводится к Order. Но если я касаюсь транзакции любым способом (либо запускаю тот же запрос в SSMS, либо выполняю query.Any () в окне Watch), запрос обновляется с правильными данными, и он просто работает ....
Наша среда: VS 2010, .Net Framework 4, EF 4, SQL Server 2008 Express + Standard (я пробовал на обоих)
Любые комментарии или любая помощь будет принята с благодарностью ...
Eric

1 Ответ

3 голосов
/ 30 апреля 2011

Вам следует начать с изменения кода:

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();
}

и снова запустить тесты.Я не исключаю, что это решит вашу проблему, но ваш текущий код не должен проходить проверку кода.

...