LINQ różnica przy wyciąganiu danych

1

[OT]nie mam pojęcia jaki tytuł sensowny nadać[/OT]

mam jakiś obiekt IQueryable i chcę wyszukać obiektu po właściwości, która jest unikalna (chociaż to chyba nie ma znaczenia). Czy jest jakaś różnica między

x.Where(y => y.UniqueField == "cos").SingleOrDefault();

a

x.SingleOrDefault(y => y.UniqueField == "cos")

Generalnie czy jeśli potrzebuję jeden element (może być jedyny albo pierwszy) to pominięcie Where i przeniesienie warunku do SingleOrDefault lub FirstOrDefault może nieść ze sobą jakieś konsekwencje? Działają obie wersje ale czy aby na pewno :)

3

Implementacja SingleOrDefault z wyjasnieniem (jaka optymalizacja jest zaimplementowana i dlaczego)
https://stackoverflow.com/questions/915357/how-does-linq-implement-the-singleordefault-method

Tutaj moge minac sie z prawda, bo nie moge znalezc implementacji z predykatem (czyli to co robisz)
Gdy jest wywolywant predykat to wtedy jest wywolywany .Where na ten predykat. Where zwraca kolekcje na ktorej SingleOrDefault ma pracowac (czyli to wczesniej z linka)

Odpowiadajac na Twoje pytanie
Nie ma roznicy

Jeszcze mozna sprawdzic w .NET Core jak oni zaimplemntowali SingleOrDefault z predykatem i na podstawie tego odrzucic lub zatwierdzic teze ;)

1

Where jest opóźnione a SingleOrDefault nie jest :)

1

@abrakadaber: jest roznica

public static TSource Single<TSource>(this IEnumerable<TSource> source, Func<TSource, bool> predicate)
        {
            if (source == null)
            {
                throw Error.ArgumentNull(nameof(source));
            }

            if (predicate == null)
            {
                throw Error.ArgumentNull(nameof(predicate));
            }

            using (IEnumerator<TSource> e = source.GetEnumerator())
            {
                while (e.MoveNext())
                {
                    TSource result = e.Current;
                    if (predicate(result))
                    {
                        while (e.MoveNext())
                        {
                            if (predicate(e.Current))
                            {
                                throw Error.MoreThanOneMatch();
                            }
                        }

                        return result;
                    }
                }
            }

            throw Error.NoMatch();
        }

https://github.com/dotnet/corefx/blob/f17f1e847aeab830de77f8a46656339d7b0f1b43/src/System.Linq/src/System/Linq/Where.cs

Ale skoro i tak uzywasz SingleOrDefault (i chcesz tylko jeden obiekt) to SingleOrDefault powinien wystarczyc w zupelnosci.

1 użytkowników online, w tym zalogowanych: 0, gości: 1