Зависание запроса Linq с Guid.Empty в выражении where

У меня проблема со следующим кодом:

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

Мое веб-приложение, когда оно вызывает этот метод, всегда зависает, если я не закомментирую следующую строку:

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

Есть идеи, почему это происходит?

11.12.2008 03:13:56
4 ОТВЕТА

Попробуйте изменить код на:

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

Отпишитесь, если это помогло ...

0
11.12.2008 03:18:26
Все еще висит ... действительно странно. Я могу выполнить тот же запрос в LinqPad, и он работает просто отлично.
mattruma 11.12.2008 03:29:51
Хм, подумал, что это стоило того. Я больше ничего не получил .. извините!
BFree 11.12.2008 03:37:22
Спасибо, я ценю это! Получил следующее для работы нового Guid ("00000000-0000-0000-0000-000000000000") ... вместо Guid.Empty.
mattruma 11.12.2008 03:38:12

@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. Просто странно.

0
11.12.2008 03:29:07
РЕШЕНИЕ

Следующий код работает ... достаточно интересно ... есть идеи почему?

query = query.Where(row => row.InvoiceId == new Guid("00000000-0000-0000-0000-000000000000"));
3
11.12.2008 03:37:29
Что происходит, когда вы запускаете трассировку SQL Server Profiler? Различаются ли два запроса на стороне сервера SQL?
Dave Markle 11.12.2008 03:41:36
Хороший вопрос ... Я собираюсь проверить это.
mattruma 11.12.2008 03:43:28

Это может быть из-за того, как интерпретируется лямбда; с "Guid.Empty", "Guid.Empty" является частью окончательной лямбды. Интересно, рассматривает ли 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;
0
11.12.2008 05:14:15