Динамическое условие где в LINQ - PullRequest
11 голосов
/ 15 апреля 2011

У меня есть сценарий, в котором я должен использовать динамическое условие where в LINQ.

Я хочу что-то вроде этого:

public void test(bool flag)
{
   from e in employee
   where e.Field<string>("EmployeeName") == "Jhom"
   If (flag == true)
   {
       e.Field<string>("EmployeeDepartment") == "IT"
   }
   select e.Field<string>("EmployeeID")
}

Я знаю, что мы не можем использовать 'If' в середине запроса Linq, но каково решение для этого?

Пожалуйста, помогите ...

Ответы [ 5 ]

11 голосов
/ 15 апреля 2011

Пожалуйста, ознакомьтесь с полным сообщением в блоге: Динамический запрос с Linq

Существует два варианта, которые вы можете использовать:

Динамическая библиотека LINQ

string condition = string.Empty;
if (!string.IsNullOrEmpty(txtName.Text))
    condition = string.Format("Name.StartsWith(\"{0}\")", txtName.Text);

EmployeeDataContext edb = new EmployeeDataContext();
if(condition != string.empty)
{
  var emp = edb.Employees.Where(condition);
 ///do the task you wnat
}
else
{
 //do the task you want 
}

Конструктор предикатов

Конструктор предикатов работает аналогично библиотеке Dynamic LINQ, ноэто безопасный тип:

var predicate = PredicateBuilder.True<Employee>();

if(!string.IsNullOrEmpty(txtAddress.Text))
    predicate = predicate.And(e1 => e1.Address.Contains(txtAddress.Text));

EmployeeDataContext edb= new EmployeeDataContext();
var emp = edb.Employees.Where(predicate);

разница между вышеупомянутой библиотекой:

  • PredicateBuilder позволяет создавать безопасных динамических запросов .
  • Динамическая библиотека LINQ позволяет создавать запросы с динамическими предложениями Where и OrderBy, указанными с использованием строк .
9 голосов
/ 15 апреля 2011

Итак, если flag равно false, вам нужны все Jhoms, а если flag верно, вам нужны только Jhoms в ИТ-отделе

Это состояние

!flag || (e.Field<string>("EmployeeDepartment") == "IT"

удовлетворяет этому критерию (это всегда верно, если флаг равен false и т. Д.), Поэтому запрос станет:

from e in employee    
where e.Field<string>("EmployeeName") == "Jhom"
  && (!flag || (e.Field<string>("EmployeeDepartment") == "IT")
select e.Field<string>("EmployeeID") 

также, этот e.Field<string>("EmployeeID") бизнес, пахнущий программным кодированием , может взглянуть на это. Я думаю

from e in employee    
where e.EmployeeName == "Jhom"
  && (!flag || (e.EmployeeDepartment == "IT")
select e.EmployeeID

будет более компактным и менее подверженным ошибкам при печати. ​​


РЕДАКТИРОВАТЬ: Этот ответ работает для этого конкретного сценария. Если у вас много запросов такого рода, во что бы то ни стало вкладывайте средства, предложенные в других ответах.

2 голосов
/ 15 апреля 2011

Вы можете связать методы:

public void test(bool flag)
{
   var res = employee.Where( x => x.EmployeeName = "Jhom" );

   if (flag)
   {
       res = res.Where( x => x.EmployeeDepartment == "IT")
   }

   var id = res.Select(x => x.EmployeeID );
}
0 голосов
/ 15 апреля 2011

Вы можете явно вызывать методы LINQ и условно их связывать.

public IEnumerable<string> FilterEmployees (IEnumerable<Employee> source, bool restrictDepartment)
{
    var query = source.Where (e => e.Field<string>("EmployeeName") == "Jhom");

    if (restrictDepartment) // btw, there's no need for "== true"
        query = query.Where (e => e.Field<string>("EmployeeDepartment") == "IT");

    return query.Select (e => e.Field<string>("EmployeeID"));
}
0 голосов
/ 15 апреля 2011
from e in employee    
where e.Field<string>("EmployeeName") == "Jhom" &&
(!flag || e.Field<string>("EmployeeDepartment") == "IT")
select e.Field<string>("EmployeeID") 
...