C# 正在尝试编写通用筛选器IQueryable
我正在尝试编写一个通用过滤器。 我的数据库中几乎每个表都使用这个过滤器。我需要一个通用的Equals过滤器,这样我就可以应用到我的所有表,而无需到处重复我的代码 :我有以下代码:C# 正在尝试编写通用筛选器IQueryable,c#,asp.net-mvc,generics,iqueryable,C#,Asp.net Mvc,Generics,Iqueryable,我正在尝试编写一个通用过滤器。 我的数据库中几乎每个表都使用这个过滤器。我需要一个通用的Equals过滤器,这样我就可以应用到我的所有表,而无需到处重复我的代码 :我有以下代码: public static IQueryable<T> ApplyFilterModel<T>(this IQueryable<T> source, FilterDTO filterModel) { var type = typeof(T); if(filterMo
public static IQueryable<T> ApplyFilterModel<T>(this IQueryable<T> source, FilterDTO filterModel)
{
var type = typeof(T);
if(filterModel.SelectedCompanyId != 0)
{
var property = type.GetProperty("iCompanyId");
var parameter = Expression.Parameter(type, "p");
var propertyAccess = Expression.MakeMemberAccess(parameter, property);
var orderByExp = Expression.Lambda(propertyAccess, parameter);
var resultExp = Expression.Call(typeof(Queryable), "Equals", new[] { type, property.PropertyType }, source.Expression, Expression.Quote(orderByExp));
source = source.Provider.CreateQuery<T>(resultExp);
}
return source;
}
我得到这个错误:
我做错了什么
如果iCompanyId==filterModel.SelectedCompanyId
这是我如何调用过滤器的:
telematicDevices.ApplyFilterModel(model.FilterDTO);
如果远程通信设备是DB(实体框架)中的IQueryable,您不能应用.Where语句吗
//Interface we need to access property
public interface ICompanySpecific
{
public int iCompanyId { get; }
}
对于每个具有iCompanyId的对象,创建一个分部类来指定接口
public partial class Person : ICompanySpecific
{
//No code is needed because Person already has the iCompanyId property
}
现在您可以将其用于Person或实现ICompanySpecific的任何类型
public static IQueryable<T> ApplyFilterModel<T>(this IQueryable<T> source, FilterDTO filterModel)
: where T: ICompanySpecific
{
return source.Where(o => o.iCompanyId == filterModel.SelectedCompanyId);
}
公共静态IQueryable ApplyFilterModel(此IQueryable源,FilterTo filterModel)
:其中T:i公司特定
{
返回source.Where(o=>o.iCompanyId==filterModel.SelectedCompanyId);
}
您不能应用.Where语句吗
//Interface we need to access property
public interface ICompanySpecific
{
public int iCompanyId { get; }
}
对于每个具有iCompanyId的对象,创建一个分部类来指定接口
public partial class Person : ICompanySpecific
{
//No code is needed because Person already has the iCompanyId property
}
现在您可以将其用于Person或实现ICompanySpecific的任何类型
public static IQueryable<T> ApplyFilterModel<T>(this IQueryable<T> source, FilterDTO filterModel)
: where T: ICompanySpecific
{
return source.Where(o => o.iCompanyId == filterModel.SelectedCompanyId);
}
公共静态IQueryable ApplyFilterModel(此IQueryable源,FilterTo filterModel)
:其中T:i公司特定
{
返回source.Where(o=>o.iCompanyId==filterModel.SelectedCompanyId);
}
您可以尝试以下方法:
public static IQueryable<T> ApplyFilterModel<T>(this IQueryable<T> source, FilterDTO filterModel)
{
var type = typeof(T);
if(filterModel.SelectedCompanyId != 0)
{
var parameterExp = Expression.Parameter(type, "type");
var propertyExp = Expression.Property(parameterExp, "iCompanyId");
var constExp = Expression.Constant(filterModel.SelectedCompanyId, typeof(int)); // I'm assuming that SelectedCompanyId is an int.
var equalExp = Expression.Equal(propertyExp, constExp);
var lambda = Expression.Lambda<Func<T, bool>>(equalExp, constExp);
source = source.Provider.Where(lambda);
}
return source;
public static IQueryable<T> ApplyFilterModel<T>(this IQueryable<T> source,
FilterDTO filterModel)
{
return Queryable.Equals<T, int>(source, p => p.iCompanyId);
}
公共静态IQueryable ApplyFilterModel(此IQueryable源,FilterTo filterModel)
{
var类型=类型(T);
如果(filterModel.SelectedCompanyId!=0)
{
var parameterExp=Expression.Parameter(类型,“type”);
var propertyExp=Expression.Property(参数exp,“iCompanyId”);
var constExp=Expression.Constant(filterModel.SelectedCompanyId,typeof(int));//我假设SelectedCompanyId是一个int。
var equalExp=表达式.Equal(propertyExp,constExp);
var lambda=表达式.lambda(equalxp,constExp);
source=source.Provider.Where(lambda);
}
返回源;
}您可以尝试以下方法:
public static IQueryable<T> ApplyFilterModel<T>(this IQueryable<T> source, FilterDTO filterModel)
{
var type = typeof(T);
if(filterModel.SelectedCompanyId != 0)
{
var parameterExp = Expression.Parameter(type, "type");
var propertyExp = Expression.Property(parameterExp, "iCompanyId");
var constExp = Expression.Constant(filterModel.SelectedCompanyId, typeof(int)); // I'm assuming that SelectedCompanyId is an int.
var equalExp = Expression.Equal(propertyExp, constExp);
var lambda = Expression.Lambda<Func<T, bool>>(equalExp, constExp);
source = source.Provider.Where(lambda);
}
return source;
public static IQueryable<T> ApplyFilterModel<T>(this IQueryable<T> source,
FilterDTO filterModel)
{
return Queryable.Equals<T, int>(source, p => p.iCompanyId);
}
公共静态IQueryable ApplyFilterModel(此IQueryable源,FilterTo filterModel)
{
var类型=类型(T);
如果(filterModel.SelectedCompanyId!=0)
{
var parameterExp=Expression.Parameter(类型,“type”);
var propertyExp=Expression.Property(参数exp,“iCompanyId”);
var constExp=Expression.Constant(filterModel.SelectedCompanyId,typeof(int));//我假设SelectedCompanyId是一个int。
var equalExp=表达式.Equal(propertyExp,constExp);
var lambda=表达式.lambda(equalxp,constExp);
source=source.Provider.Where(lambda);
}
返回源;
}您正在创建的表达式,如果以静态方式写出,将如下所示:
public static IQueryable<T> ApplyFilterModel<T>(this IQueryable<T> source, FilterDTO filterModel)
{
var type = typeof(T);
if(filterModel.SelectedCompanyId != 0)
{
var parameterExp = Expression.Parameter(type, "type");
var propertyExp = Expression.Property(parameterExp, "iCompanyId");
var constExp = Expression.Constant(filterModel.SelectedCompanyId, typeof(int)); // I'm assuming that SelectedCompanyId is an int.
var equalExp = Expression.Equal(propertyExp, constExp);
var lambda = Expression.Lambda<Func<T, bool>>(equalExp, constExp);
source = source.Provider.Where(lambda);
}
return source;
public static IQueryable<T> ApplyFilterModel<T>(this IQueryable<T> source,
FilterDTO filterModel)
{
return Queryable.Equals<T, int>(source, p => p.iCompanyId);
}
公共静态IQueryable ApplyFilterModel(此IQueryable源,
过滤器到过滤器模型)
{
返回Queryable.Equals(source,p=>p.iCompanyId);
}
您实际上要做的是创建此的动态版本:
public static IQueryable<T> ApplyFilterModel<T>(this IQueryable<T> source,
FilterDTO filterModel)
{
return Queryable.Where<T, int>(source,
p => p.iCompanyId == filterModel.SelectedCompanyId);
}
公共静态IQueryable ApplyFilterModel(此IQueryable源,
过滤器到过滤器模型)
{
返回可查询的。其中(源、,
p=>p.iCompanyId==filterModel.SelectedCompanyId);
}
filterModel.SelectedCompanyId
进行比较的属性。这意味着使用Expression.Equals
传递投影属性和表示要与之比较的值的常量表达式使用Where
而不是Equals
。Call
Call。(或者,就此而言,只调用Where
作为方法,而不是构建表示该调用的表达式,因为它将通过实现将自身表示为表达式。)这是假设你不想让你的生活变得简单,这不仅简单得多,而且还允许静态输入。你正在创建的表达式,如果是静态写出来的,看起来像这样:
public static IQueryable<T> ApplyFilterModel<T>(this IQueryable<T> source, FilterDTO filterModel)
{
var type = typeof(T);
if(filterModel.SelectedCompanyId != 0)
{
var parameterExp = Expression.Parameter(type, "type");
var propertyExp = Expression.Property(parameterExp, "iCompanyId");
var constExp = Expression.Constant(filterModel.SelectedCompanyId, typeof(int)); // I'm assuming that SelectedCompanyId is an int.
var equalExp = Expression.Equal(propertyExp, constExp);
var lambda = Expression.Lambda<Func<T, bool>>(equalExp, constExp);
source = source.Provider.Where(lambda);
}
return source;
public static IQueryable<T> ApplyFilterModel<T>(this IQueryable<T> source,
FilterDTO filterModel)
{
return Queryable.Equals<T, int>(source, p => p.iCompanyId);
}
公共静态IQueryable ApplyFilterModel(此IQueryable源,
过滤器到过滤器模型)
{
返回Queryable.Equals(source,p=>p.iCompanyId);
}
您实际上要做的是创建此的动态版本:
public static IQueryable<T> ApplyFilterModel<T>(this IQueryable<T> source,
FilterDTO filterModel)
{
return Queryable.Where<T, int>(source,
p => p.iCompanyId == filterModel.SelectedCompanyId);
}
公共静态IQueryable ApplyFilterModel(此IQueryable源,
过滤器到过滤器模型)
{
返回可查询的。其中(源、,
p=>p.iCompanyId==filterModel.SelectedCompanyId);
}
filterModel.SelectedCompanyId
进行比较的属性。这意味着使用Expression.Equals
传递投影属性和表示要与之比较的值的常量表达式使用Where
而不是Equals
。Call
Call。(或者,就此而言,只调用Where
作为方法,而不是构建表示该调用的表达式,因为它将通过实现将自身表示为表达式。)这是假设你不想让你的生活变得简单,这不仅简单得多,而且还允许静态输入。如何?我的数据库中几乎每个表都使用这个过滤器。我需要一个通用的Equals过滤器,这样我就可以应用到我所有的表,而无需重复我的代码。在这里,我为你的基类添加了一个带有通用约束的代码示例。但我不知道,可能是汽车、人或员工。如果我使用:where T:People我不能将其用于CarsIs是否存在包含iCompanyId的基类或接口?@psibernetic使用
partial
类将允许他添加到生成的类中(例如,通过添加要实现的接口),而不会在重新生成类型时将其删除。如何?这