C# Linq EF查询的一种通用过滤方法
我有各种类型的EF实体,它们都有一个名为“Employee”的导航属性。生成报告时,用户可以选择根据不同的员工属性(成本中心、性别等)筛选报告 目前,我正在逐个筛选每个查询,例如:C# Linq EF查询的一种通用过滤方法,c#,linq,entity-framework,generic-method,C#,Linq,Entity Framework,Generic Method,我有各种类型的EF实体,它们都有一个名为“Employee”的导航属性。生成报告时,用户可以选择根据不同的员工属性(成本中心、性别等)筛选报告 目前,我正在逐个筛选每个查询,例如: var courses = context.Courses .Where(c => c.Employee.CostCenterID == ccID && c.Employee.Rank == rankID
var courses = context.Courses
.Where(c => c.Employee.CostCenterID == ccID
&& c.Employee.Rank == rankID
....
)
.ToList();
public partial class Course: IFilterable
{
}
真正的过滤器代码要长得多,但这只是一个提示。无论如何,有没有办法创建一个通用方法来过滤员工的结果?我将提供给此筛选方法的所有实体都将具有Employee
导航属性。我只需提供一个IQueryable
或ObjectSet
,然后获得一个过滤后的IQueryable
或ObjectSet
怎么做?我刚想出来!由于我们无法在泛型方法中添加约束来检查某个属性,因此我使用了一个接口:
public interface IFilterable
{
Employee Employee
{
get;
set;
}
}
public Expression<Func<TEntity, bool>> EmployeeFilterDelegateExp<TEntity>(
int costCenterId,
int rankId )
{
var parm = Expression.Parameter( typeof( TEntity ), "entity" );
var employeeProperty = Expression.Property( parm, "Employee" );
return ( Expression<Func<TEntity, bool>> )Expression.Lambda(
Expression.AndAlso(
Expression.Equal( Expression.Property( employeeProperty, "CostCenterID" ),
Expression.Constant( costCenterId ) ),
Expression.Equal( Expression.Property( employeeProperty, "Rank" ),
Expression.Constant( rankId ) ) ),
parm );
}
然后,我添加了分部类以继承具有Employee
导航属性的不同实体的上一个接口,例如:
var courses = context.Courses
.Where(c => c.Employee.CostCenterID == ccID
&& c.Employee.Rank == rankID
....
)
.ToList();
public partial class Course: IFilterable
{
}
然后创建了以下通用方法:
public static IQueryable<T> Filter<T>(this IQueryable<T> source, SearchCriteria sc)
where T : class, IFilterable
{
var filtered = source.Where(e => e.Employee.CostCenterID == sc.CostCenterID
&& e.Employee.Gender == sc.Gender);
return filtered;
}
注意:SearchCriteria
只是一个简单的类,它包含不同的员工属性
如果有更好的方法,请发布。如果要避免实现接口:
public interface IFilterable
{
Employee Employee
{
get;
set;
}
}
public Expression<Func<TEntity, bool>> EmployeeFilterDelegateExp<TEntity>(
int costCenterId,
int rankId )
{
var parm = Expression.Parameter( typeof( TEntity ), "entity" );
var employeeProperty = Expression.Property( parm, "Employee" );
return ( Expression<Func<TEntity, bool>> )Expression.Lambda(
Expression.AndAlso(
Expression.Equal( Expression.Property( employeeProperty, "CostCenterID" ),
Expression.Constant( costCenterId ) ),
Expression.Equal( Expression.Property( employeeProperty, "Rank" ),
Expression.Constant( rankId ) ) ),
parm );
}
公共表达式EmployeeFilterDelegateExp(
int costCenterId,
内特兰基德酒店
{
var parm=表达式参数(typeof(tenty),“entity”);
var employeeProperty=Expression.Property(parm,“Employee”);
return(Expression)Expression.Lambda(
安达尔索(
Expression.Equal(Expression.Property(employeeProperty,“CostCenterID”),
表达式.常量(costCenterId)),
Expression.Equal(Expression.Property(雇员财产,“等级”),
表达式.常数(rankId)),
帕尔姆);
}
用法:
var courses = context.Courses
.Where( EmployeeFilterDelegateExp<Course>( ccID, rankID ) )
.ToList();
var courses=context.courses
.Where(员工过滤器delegateexp(ccID,兰基德))
.ToList();
我认为您应该将此代码作为问题发布,而不是回答自己的问题并要求更好solutions@SergeyBerezovskiy当我问这个问题的时候,我不知道答案,我在发帖后就知道了。所以我不想做辅导之类的。你知道答案突然出现在你脑海中的那些时刻…@SergeyBerezovskiy,谢谢。我还发表了代码评论。如果属性实现映射到不同的属性,接口属性(Employee
)是否适用于LINQ to SQL或实体框架LINQ类?