2013-08-27 11 views
5

Mam następujący kodPojedyncza lub domyślna lub gdy stan z klauzulą ​​

return 
    this.Storage.Customer.OfType<Preferred>() 
    .Include(b => b.Order) 
    .Where(cust => cust.Id == customerId && cust.CustomerType== (int)cusType) 
    .SingleOrDefault(); 

może być przepisana następująco eliminując gdzie.

return 
    this.Storage.Customer.OfType<Preferred>() 
    .Include(b => b.Order) 
    .SingleOrDefault(cust => cust.Id == customerId && cust.CustomerType == (int)cusType); 

Która z nich jest lepszą praktyką i dlaczego?

+7

Wygenerowane zapytanie "SQL" będzie takie samo, więc powiedziałbym, że to tylko Twoja opinia, która jest lepsza. – MarcinJuraszek

+1

Drugi jest krótszy i nadal łatwy do odczytania. –

+3

Myślę, że pierwszy postępuje zgodnie z kodem krok po kroku i jest łatwiejsze do rozwinięcia/debugowania. –

Odpowiedz

1

Przede wszystkim trzeba zrozumieć różnicę

this.Storage.Customer.OfType<Preferred>() 
.Include(b => b.Order) 
.Where(cust => cust.Id == customerId && cust.CustomerType== (int)cusType) 

spowoduje to utworzenie zapytania, ale nie zostanie wykonane, dopóki nie zostanie wywołana metoda ToList.

Metoda SingleOrDefault faktycznie wykona zapytanie. Więc jeśli chcesz sprawdzić lub zrobić coś z zapytaniem przed jego wykonaniem, powinieneś użyć gdzie, a następnie wywołać SingleOrDefault.

tak ogólnie, używając gdzie jest dobra praktyka, jak na moim osobistym zdaniem

2

Dzięki złożoności debugowania zwracanej wartości funkcji i niemożności używania wyrażeń lambda w debugger, jest to najlepszy sposób:

var temp = this.Storage.Customer.OfType<Preferred>() 
    .Include(b => b.Order) 
    .Where(cust => cust.Id == customerId && cust.CustomerType == (int)cusType); 

return temp.SingleOrDefault(); 

W ten sposób, jeśli istnieje wyjątek na SingleOrDefault() (coś dość powszechne, jeśli robi złożonych wyrażeń), które można umieścić punkt przerwania na return i zrobić w panelu watch: temp.ToList();

+3

Z całym szacunkiem, to jest opinia. – Maarten

+1

@Maarten Nazwiemy to doświadczeniem z pierwszej ręki :-) Mój kod jest lepszy niż dwie wersje sugerowane przez OP, ponieważ moje ma możliwą do sprawdzenia przewagę. Wynikowy kod jest równoważny/prawie równoważny z OP (na poziomie IL), jest równie czytelny i łatwiejszy do debugowania. – xanatos

0

Stary post i to w dużej mierze na podstawie opinii, ale tu jest inny uwagę nie wymienione powyżej:

SingleOrDefault klauzula nie może być a następnie inne warunki, takie jak Select, ponieważ, jak zauważa Patel powyżej, faktycznie wykonuje zapytanie. Na przykład powiedzieć w dół drogi chcesz zmodyfikować kwerendę, aby powrócić tylko nazwisko klienta:

this.Storage.Customer.OfType<Preferred>() 
.Include(b => b.Order) 
.SingleOrDefault(cust => cust.Id == customerId && cust.CustomerType == (int)cusType) 
.Select(cust=>cust.Name); //compile error 

nie będzie działać, a nie można przenieść do klauzuli Select przed SingleOrDefault bo wtedy Id i CustomerType pola nie będą widoczne dla wyrażenia lambda w SingleOrDefault. Zamiast tego trzeba by włożyć z powrotem klauzuli Where pierwszy:

this.Storage.Customer.OfType<Preferred>() 
.Include(b => b.Order) 
.Where(cust => cust.Id == customerId && cust.CustomerType == (int)cusType) 
.Select(cust=>cust.Name) 
.SingleOrDefault(); 

Zatem ponieważ klauzula Where często jest konieczne i zawsze co najmniej tak dobre wyniki, to prawdopodobnie dobra praktyka, aby zawsze używać go do konsystencji, czytelność, i łatwość konserwacji.

Powiązane problemy