动态 LINQ 语句
Dynamic LINQ statement
我正在尝试使用 EF 和 LINQ 查询数据库。我有多个查询来根据应用程序中的用户权限过滤数据。
from p in db.EmployeeDetails
join i in db.EmployeeDept on p.DeptId equals i.DeptId into inst
from i in inst.DefaultIfEmpty()
join s in db.Employee on p.EmpId equals s.EmpId into manager
from s in manager.DefaultIfEmpty()
join e in db.EmpStatus on p.EnrollmentStatusID equals e.StatusID into estatus
from e in estatus.DefaultIfEmpty()
where p.SomeId== id && (p.IsActive == true || p.SomeStatus == null)
select new EmployeeBase
{
//select list common to all queries.
};
这是基本查询的示例。为此,如果用户属于特定角色,我需要再添加一个 where 子句,如果用户属于其他角色,我需要添加一个新的 table。我能够通过 if...else 条件检查的五个不同查询来做到这一点。但是新的需求带来了更多的条件和更多的 tables 以及更多的 where 子句,这使得代码如此重复以至于成为维护的噩梦。
我尝试了 PredicateBuilder,但我不确定如何将 PredicateBuilder 应用于多个实体和外连接。
我从 ScottGu 的区块中找到了动态 LINQ 库,但我不确定它是否有 .Net 4.5 版本并且在这种情况下是否有用。
有没有一种方法可以动态构建查询,这样我就不需要在需求发生微小变化时更改每个查询。
public IQueryable<EmployeeBase> Employees() {
return (
from p in db.EmployeeDetails
join i in db.EmployeeDept on p.DeptId equals i.DeptId into inst
from i in inst.DefaultIfEmpty()
join s in db.Employee on p.EmpId equals s.EmpId into manager
from s in manager.DefaultIfEmpty()
join e in db.EmpStatus on p.EnrollmentStatusID equals e.StatusID into estatus
from e in estatus.DefaultIfEmpty()
where p.SomeId== id && (p.IsActive == true || p.SomeStatus == null)
select new EmployeeBase
{
//select list common to all queries.
});
}
...
var awesomeEmployee=Employees().Single(x=>x.name=="Me");
var listToFire=Employees().OrderByDescending(x=>x.Salary).Take(3);
var listToPromote=Employees().OrderByDescending(x=>x.Performance).Take(1);
不过,我建议重新使用 EF 对象,并确保您正确设置了导航属性。从您的代码来看,您似乎根本没有使用它们——这会导致您陷入混乱。你真的应该有像这些扩展方法这样的东西:
public static IQueryable<EmployeeDetails> IsActive(this IQueryable<EmployeeDetails> eb) {
return eb.Where(p=>p.IsActive == true || p.SomeStatus == null);
}
然后您可以像这样访问您的数据:
var employee=db.EmployeeDetails
.IsActive()
.Include(x=>x.Manager);
foreach(var e in employee) {
Console.Writeline("{0}'s manager is {1}",
e.name,
e.Manager.name);
}
我正在尝试使用 EF 和 LINQ 查询数据库。我有多个查询来根据应用程序中的用户权限过滤数据。
from p in db.EmployeeDetails
join i in db.EmployeeDept on p.DeptId equals i.DeptId into inst
from i in inst.DefaultIfEmpty()
join s in db.Employee on p.EmpId equals s.EmpId into manager
from s in manager.DefaultIfEmpty()
join e in db.EmpStatus on p.EnrollmentStatusID equals e.StatusID into estatus
from e in estatus.DefaultIfEmpty()
where p.SomeId== id && (p.IsActive == true || p.SomeStatus == null)
select new EmployeeBase
{
//select list common to all queries.
};
这是基本查询的示例。为此,如果用户属于特定角色,我需要再添加一个 where 子句,如果用户属于其他角色,我需要添加一个新的 table。我能够通过 if...else 条件检查的五个不同查询来做到这一点。但是新的需求带来了更多的条件和更多的 tables 以及更多的 where 子句,这使得代码如此重复以至于成为维护的噩梦。
我尝试了 PredicateBuilder,但我不确定如何将 PredicateBuilder 应用于多个实体和外连接。
我从 ScottGu 的区块中找到了动态 LINQ 库,但我不确定它是否有 .Net 4.5 版本并且在这种情况下是否有用。
有没有一种方法可以动态构建查询,这样我就不需要在需求发生微小变化时更改每个查询。
public IQueryable<EmployeeBase> Employees() {
return (
from p in db.EmployeeDetails
join i in db.EmployeeDept on p.DeptId equals i.DeptId into inst
from i in inst.DefaultIfEmpty()
join s in db.Employee on p.EmpId equals s.EmpId into manager
from s in manager.DefaultIfEmpty()
join e in db.EmpStatus on p.EnrollmentStatusID equals e.StatusID into estatus
from e in estatus.DefaultIfEmpty()
where p.SomeId== id && (p.IsActive == true || p.SomeStatus == null)
select new EmployeeBase
{
//select list common to all queries.
});
}
...
var awesomeEmployee=Employees().Single(x=>x.name=="Me");
var listToFire=Employees().OrderByDescending(x=>x.Salary).Take(3);
var listToPromote=Employees().OrderByDescending(x=>x.Performance).Take(1);
不过,我建议重新使用 EF 对象,并确保您正确设置了导航属性。从您的代码来看,您似乎根本没有使用它们——这会导致您陷入混乱。你真的应该有像这些扩展方法这样的东西:
public static IQueryable<EmployeeDetails> IsActive(this IQueryable<EmployeeDetails> eb) {
return eb.Where(p=>p.IsActive == true || p.SomeStatus == null);
}
然后您可以像这样访问您的数据:
var employee=db.EmployeeDetails
.IsActive()
.Include(x=>x.Manager);
foreach(var e in employee) {
Console.Writeline("{0}'s manager is {1}",
e.name,
e.Manager.name);
}