3 Stimmen

Hängende Linq-Abfrage mit Guid.Empty im where-Ausdruck

Ich habe ein Problem mit dem folgenden 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;
        }
    }

Wenn meine Webanwendung diese Methode aufruft, bleibt sie immer hängen, wenn ich die folgende Zeile nicht auskommentiere:

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

Haben Sie eine Idee, warum dies der Fall sein könnte?

3voto

mattruma Punkte 16315

Der folgende Code funktioniert ... interessanterweise ... irgendeine Idee, warum?

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

0voto

BFree Punkte 100035

Versuchen Sie, den Code zu ändern:

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

Melden Sie sich, wenn das geholfen hat...

0voto

mattruma Punkte 16315

@BFree ... Versucht, was Sie vorgeschlagen ... und immer noch das Gleiche tun. Es ist seltsam, ich kann den folgenden Code in LinqPad ohne Probleme ausführen:

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

Auch die folgende Codezeile kann ich ohne Probleme verwenden:

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

Es ist nur, wenn ich Guid.Empty verwende. Einfach nur merkwürdig.

0voto

Marc Gravell Punkte 970173

Es könnte daran liegen, wie das Lambda interpretiert wird; bei "Guid.Empty" ist das "Guid.Empty" Teil des endgültigen Lambdas. Ich frage mich, ob der LINQ-Provider dies irgendwie als Sonderfall behandelt?

Sie könnten es versuchen:

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

Aber eigentlich, abgesehen von Guid gegenüber einer vom Compiler erzeugten Capture-Klasse ist der Ausdrucksbaum hierfür derselbe (beide beinhalten Lambda=>BinaryExpression=>MemberExpression).

Wenn die oben genannten auch beschwert, dann versuchen Sie einen TSQL-Trace auf, oder aktivieren Sie Ihre LINQ-Provider-Protokollierung - für LINQ-to-SQL, etwas wie unten funktioniert (zitieren Sie mich nicht!):

ctx.Log = Console.Out;

CodeJaeger.com

CodeJaeger ist eine Gemeinschaft für Programmierer, die täglich Hilfe erhalten..
Wir haben viele Inhalte, und Sie können auch Ihre eigenen Fragen stellen oder die Fragen anderer Leute lösen.

Powered by:

X