2015-07-14 6 views
5

Przyjrzałem się innym pytaniom na ten temat i po prostu nie mogę się dowiedzieć, jak zastosować odpowiedzi do mojej konkretnej sytuacji. Załóżmy, że masz kilka modeli, które wyglądać tak:Używając logiki z jednej lambdy w ciągu drugiej lambda

public class Person 
{ 
    public int PersonId { get; set; } 
} 

public class Business 
{ 
    public int BusinessId { get; set; } 
} 

Chcę być w stanie napisać kilka różnych metod generycznych: jeden, który dostaje modele za pomocą dostarczonego Lambda, że ​​może wyglądać tak:

GetWhere(p => p.PersonId == 1) 

I jedno, aby uzyskać modele za pomocą unikatowego klucza - aby ten elastyczny, chciałbym być w stanie określić unikalny klucz przy użyciu lambda:

GetByUniqueKey(p => p.PersonId, 1) 

Albo

GetByUniqueKey(b => b.BusinessId, 1) 

Idealnie GetByUniqueKey będzie tylko skrótowym sposób zbudować wyrażenie, aby wysłać do GetWhere, a następnie powrócić FirstOrDefault() wynik. Ale logika, aby to zrobić, całkowicie mi ucieka. Co chcę zrobić:

public IEnumerable<TModel> GetWhere(Expression<Func<TModel, bool>> whereExpression) 
{ 
    // Get from DB using expression provided 
} 

public TModel GetByUniqueKey<TUniqueKey>(
     Expression<Func<TModel, TUniqueKey>> uniqueKeyProperty, 
     TUniqueKey value) 
{ 
    return GetWhere(m => uniqueKeyProperty(m) == value).FirstOrDefault(); 
} 

Więc chcę wziąć ekspresję uniqueKeyProperty, powołać go na parametr dostarczanego jakoś dostać nieruchomość, a następnie użycie że własność w wyrażeniu whereExpression.

Uwaga na zduplikowanych pytania: Wiem, że to wygląda duplikatu innych podobnych pytań, ale proszę pamiętać Znam tych i po prostu nie może dowiedzieć się, jak zastosować te odpowiedzi do mojego konkretnego zastosowania walizka.

pewne wyjaśnienia w odpowiedzi na komentarze:

Mówiąc prościej, chcę wykonać następujące czynności:

Chcę podjąć Expression p => p.PersonId i wartość 1, a generują whereExpression który wygląda jak to p => p.PersonId == 1. (Dzięki @Rob)

+0

Nie możesz po prostu zrobić 'context.Set () .FirstOrDefault (whereExpression)'? – Rob

+0

W twoim przykładzie potrzebuję "whereExpression", aby zawrzeć wynik drugiej lambda. Myślę też, że używasz EF, którego nie jestem. –

+0

Jeśli pytasz bazę danych, 'whereExpression' nie może mieć wyniku - będzie to nadal wyrażenie, ponieważ porównujemy wartości w wierszu do czegoś (i nie załadowaliśmy wierszy). Czy możesz dołączyć kod, w jaki sposób ręcznie ładowałeś dane z bazy danych? – Rob

Odpowiedz

1

Można zbudować nowy wyraz z przycisku wyboru i wartości dostarczonych tak:

public TModel GetByUniqueKey<TUniqueKey>(
    Expression<Func<TModel, TUniqueKey>> uniqueKeySelector, 
    TUniqueKey value) 
{ 
    return GetWhere(Expression.Lambda<Func<TModel,bool>>(
     Expression.MakeBinary(
      ExpressionType.Equal, 
      uniqueKeySelector.Body, 
      Expression.Constant(value, typeof(TUniqueKey))), 
     uniqueKeySelector.Parameters)); 
} 

Dla zapytań przez ID I nie przejmuj się tym podejściem.Sprawdź inne statyczne metody na Expression class.

+0

Dzięki @pmccloghrylaing, zastosowałem to podejście, dzięki czemu mogę mieć przyjemną metodę skrótu do pobierania pojedynczego elementu za pomocą dowolnego unikalnego identyfikatora, bez konieczności stosowania FirstOrDefault za każdym razem. W mojej rzeczywistej implementacji mam również pewne kontrole, aby zagwarantować, że znaleziono tylko jeden wynik. Jeszcze raz dziękuję, twoje rozwiązanie jest doskonałe. –

0

Jak najwyraźniej chcesz realizować jakąś polimorfizmu, jedną z możliwości byłoby mieć Person i Business dziedziczą z tej samej klasy bazowej lub dziedziczyć z tego samego interfejsu i podzielić nieruchomość Id. Można zdefiniować

public class Identifiable 
{ 
    public int Id { get; set; } 
} 

i uczynić Person i Business Dziedzicz w. Wtedy zwrotna

Func<Identifiable,bool> = iIdentifiable => iIdentifiable.Id == 1 

można nazwać dla obiektów obu klas. Jednak oryginalne klasy musiałyby zostać zmienione, aby takie podejście działało.

+0

Dzięki, to zdecydowanie opłacalne podejście, ale kod, który dostarczyłem, był tylko jednym z przykładów, istnieją inne sposoby wykorzystania tego rodzaju elastyczności, więc nadal chciałbym móc łączyć te lambdy, jeśli to w ogóle możliwe. –

Powiązane problemy