2014-12-03 10 views
6

Mam formularz z wieloma kryteriami wyszukiwania, których może użyć użytkownik do wyszukania danych pracownika, np. FirstName, LastName, HireDate, Department, itp.Nieporęczna instrukcja LINQ z wieloma kryteriami wyszukiwania

Używam LINQ i zastanawiam się, jaką metodę mogę użyć do wysłania zapytania do zbioru Employesów z jednym z kryteriów wyszukiwania, tzn. Użytkownik nie musi wprowadzać wszystkich, ale muszą wprowadzić co najmniej jeden z parametrów wyszukiwania.

Do tej pory, podczas testowania mojej instrukcji LINQ z dwoma parametrami wyszukiwania, wydaje się, że muszę sprawdzić, czy parametr wyszukiwania jest wprowadzony czy nie. W takim przypadku może to być dość nieporęczne w przypadku wielu parametrów wyszukiwania.

// only FirstName is entered 
if (!string.IsNullOrEmpty(FirstName) && string.IsNullOrEmpty(LastName)) 
{ 
    var employees = DB.Employees 
     .Where(emp => emp.FirstName.Contains(fName)); 
} 
// only LastName is entered 
else if (string.IsNullOrEmpty(FirstName) && !string.IsNullOrEmpty(LastName)) 
{ 
    var employees = DB.Employees 
     .Where(emp => emp.LastName.Contains(lName)); 
} 
// both parameters are entered 
else if (!string.IsNullOrEmpty(FirstName) && !string.IsNullOrEmpty(LastName)) 
{ 
    var employees = DB.Employees 
     .Where(emp => emp.FirstName.Contains(fName)) 
     .Where(emp => emp.LastName.Contains(lName)); 
} 

FYI, początkowo myślałem, że może po prostu dołączyć Gdzie() sprawozdanie do mojego oświadczenia LINQ z istotnych parametrów wyszukiwania, ale zauważyłem, że nie były zwrócone wszystkie rekordy, które powinny, a więc powyżej logika IF- następnie wyciągi.

+0

Możesz dodać wiele instrukcji LINQ, jeśli pracujesz z IQueryable. Czy to LINQ to Objects, czy używasz ORM do wysyłania zapytań do bazy danych? – cost

+0

@cost - Na początku nie zrozumiałem Twojej sugestii, ale po zobaczeniu dostarczonych odpowiedzi, wierzę, że masz rację. Dzięki! –

Odpowiedz

6

Co o coś takiego:

IQueryable<Employee> employees = DB.Employees; 

if (!string.IsNullOrEmpty(FirstName)) 
{ 
    employees = employees 
     .Where(emp => emp.FirstName.Contains(fName)); 
} 
if (!string.IsNullOrEmpty(LastName)) 
{ 
    employees = employees 
     .Where(emp => emp.Last.Contains(lName)); 
} 
+0

Ahh! Jeśli rozumiem Twoją logikę, za każdym razem, gdy przejdzie ona przez instrukcję "if", oryginalny produkt IQueryable, pracownicy, będzie dalej dołączany z większą liczbą instrukcji .Where(), poprawne? –

+0

@frenu 'IQueryable' jest jak nieoceniona instrukcja LINQ. Dopóki nie wykonasz iteracji względem zapytania (jak w przypadku '.ToList()'), samo zapytanie nie zostanie wykonane.Więc kontynuuj budowanie swoich klauzul Where, a następnie zostaną one ocenione i wykonane, gdy w końcu spróbujesz pobrać dane. – cost

+0

@cost: Dzięki za wyjaśnienie! –

4

można napisać tak:

var employees = DB.Employees.AsQueryable(); 
if (!string.IsNullOrEmpty(fName) 
    employees = employees.Where(emp => emp.FirstName.Contains(fName)); 

if (!string.IsNullOrEmpty(lName) 
    employees = employees.Where(emp => emp.LastName.Contains(lName)); 
+0

Czy nie musisz jawnie deklarować 'pracowników' jako' IQueryable'? – cost

+0

@cost, tak, całkiem dobrze, dzięki. – Magnus

1

natknąłem się na podobne wyzwanie, w którym użytkownik może wybrać 0, 1 lub wiele wartości do około 10 wyszukiwane pola i potrzebne do skonstruowania tego zapytania w środowisku wykonawczym.

skończyło się używając LINQKit: http://www.albahari.com/nutshell/linqkit.aspx

W szczególności Kiedyś to orzeczenie budowniczy, który jest opisany tutaj: http://www.albahari.com/nutshell/predicatebuilder.aspx

W przykładzie powyżej, masz obejmował wielokrotne zapytania wewnątrz if . Alternatywą jest budowanie zapytania w trakcie podróży.

Jeśli miałbyś zadeklarować pracowników var = DB. Pracownicy spoza tych instrukcji if (Zakładając, że jest to zawsze istotne), możesz po prostu zastosować instrukcje dotyczące miejsc w instrukcjach if, jeśli są one odpowiednie.

LINQ daje odroczoną egzekucję, więc nie trzeba mieć całego wyrażenia w jednym bloku (Nawet jeśli wydaje się to najbardziej naturalne, aby to zrobić, aw wielu przypadkach będzie).

Sprawy się nieco bardziej skomplikowana, jeśli chcesz mieszać w OR jest z AND, ale to gdzie orzecznik wcześniej wspomniano budowniczy przychodzi.

Niestety nie mam żadnych przykładów akcji, ale te linki powinny dobry start.

+0

Rzeczywiście mam książkę 5.0 Albahari i jestem klientem LINQPad. Nie myślałem nawet o LINQKit, ale na coś, na co w tej chwili się nie patrzę. Dzięki! –

0
var resultData = (from data in db.Abc 
        where !string.IsNullOrEmpty(firstName) ? data.FirstName == firstName : true 
&& data.UserType == userTypeValue 
&& !string.IsNullOrEmpty(lastName) ? data.LastName == lastName : true 
&& !string.IsNullOrEmpty(gender) ? data.Gender == gender : true 
&& !string.IsNullOrEmpty(phone) ? data.CellPhone == phone : true 
&& !string.IsNullOrEmpty(fax) ? data.Fax == fax : true 
&& !string.IsNullOrEmpty(emailAddress) ? data.Email == emailAddress : true 
&& !string.IsNullOrEmpty(address1) ? data.Address == address1 : true 
           select new 
           { 
            UserName = data.UserName, 
            FirstName = data.FirstName, 
            Address = data.Address, 
            CellPhone = data.CellPhone, 
            Fax = data.Fax, 
            Email = data.Email 
           }).ToList(); 
+0

Możesz użyć tego kodu, Jeśli chcesz szukać Przedmioty oparte na wielu warunkach wyszukiwania –

+0

Cześć Ramu, dziękuję za Twój wkład. będzie lepiej, jeśli dodasz wskaźniki i komentarze, aby wyjaśnić, dlaczego ten kod będzie działał, aby rozwiązać ten problem. – NSNoob

Powiązane problemy