C# 按动态特性筛选
我有一种动态过滤C# 按动态特性筛选,c#,linq,C#,Linq,我有一种动态过滤列表的通用方法,我最近将我的项目更新为NetCore 3.0,之后该方法就不起作用了 这是我在调用方法时得到的错误 System.InvalidOperationException: 'The LINQ expression 'Where<Provincia>( source: OrderBy<Provincia, string>( source: DbSet<Provincia>, keySelect
列表
的通用方法,我最近将我的项目更新为NetCore 3.0
,之后该方法就不起作用了
这是我在调用方法时得到的错误
System.InvalidOperationException: 'The LINQ expression 'Where<Provincia>(
source: OrderBy<Provincia, string>(
source: DbSet<Provincia>,
keySelector: (p) => p.Identificador),
predicate: (p) => p.GetType().GetProperty((Unhandled parameter: __prop_0)).GetValue(
obj: (object)p,
index: null).ToString() == (Unhandled parameter: __value_1))' could not be translated. Either rewrite the query in a form that can be translated, or switch to client evaluation explicitly by inserting a call to either AsEnumerable(), AsAsyncEnumerable(), ToList(), or ToListAsync(). See https://go.microsoft.com/fwlink/?linkid=2101038 for more information.'
System.invalidoOperationException:“LINQ表达式”其中(
资料来源:OrderBy(
资料来源:DbSet,
键选择器:(p)=>p.identificator),
谓词:(p)=>p.GetType().GetProperty((未处理的参数:_prop_0)).GetValue(
对象:(对象)p,
索引:null)。无法转换ToString()=(未处理的参数:_值_1))'。以可以翻译的形式重写查询,或者通过插入对AsEnumerable()、AsAsAsAsyncEnumerable()、ToList()或ToListSync()的调用显式切换到客户端计算。看见https://go.microsoft.com/fwlink/?linkid=2101038 了解更多信息。”
这是我的方法
public static IQueryable<T> FilerByProperties(string properiesFilter, IQueryable<T> query)
{
if (properiesFilter == null) properiesFilter = "";
string[] properties = properiesFilter.Split(";");
for (int i = 0; i < properties.Length; i++)
{
if(!properiesFilter.IsNullOrEmpty())
{
int pocisionProp = properties[i].ToString().IndexOf('=');
string prop = properties[i].Substring(0, pocisionProp);
string value = properties[i].Substring(pocisionProp + 1);
if (typeof(T).GetProperty(prop) != null)
{
query = query.Where(x => x.GetType().GetProperty(prop).GetValue(x, null).ToString() == value);
}
}
}
return query;
}
public静态IQueryable filerbyproperty(字符串属性过滤器,IQueryable查询)
{
如果(properiesFilter==null)properiesFilter=“”;
string[]properties=propertiesfilter.Split(“;”);
for(int i=0;ix.GetType().GetProperty(prop).GetValue(x,null).ToString()==value);
}
}
}
返回查询;
}
我就是这样用的
public override Task<PagedResultDto<ProvinciaDto>> GetAllAsync(PagedAndSortedRequest input)
{
var lista = new List<Provincia>();
var query = Repository.GetAllIncluding(x => x.Pais);
query = CreateFilteredQuery(input);
query = ApplySorting(query, input);
query = FilterHelper<Provincia>.FilerByProperties(input.FilterProperties, query);
lista = query
.Skip(input.SkipCount)
.Take(input.MaxResultCount)
.ToList();
var result = new PagedResultDto<ProvinciaDto>(query.Count(), ObjectMapper.Map<List<ProvinciaDto>>(lista));
return Task.FromResult(result);
}
公共覆盖任务GetAllAsync(PagedAndSortedRequest输入)
{
var lista=新列表();
var query=Repository.GetAllIncluding(x=>x.Pais);
query=CreateFilteredQuery(输入);
查询=应用排序(查询,输入);
query=FilterHelper.FilerByProperties(input.FilterProperties,查询);
lista=查询
.Skip(输入.SkipCount)
.Take(input.MaxResultCount)
.ToList();
var result=new PagedResultDto(query.Count(),ObjectMapper.Map(lista));
返回Task.FromResult(结果);
}
在input.FilterProperties
中,我收到“PaisId=1”,在这种情况下,我需要过滤Provincias
其中有“PaisId=1”
我希望你能帮助我。Lambda表达式在这里应该能帮到你 助手类
public static class ExpressionBuilder
{
public static Expression<Func<T, bool>> GetExpression<T>(IList<DynamicFilter> filters)
{
if (filters.Count == 0)
return null;
ParameterExpression param = Expression.Parameter(typeof(T), "t");
Expression exp = null;
if (filters.Count == 1)
{
exp = GetExpression<T>(param, filters[0]);
}
else if (filters.Count == 2)
{
exp = GetExpression<T>(param, filters[0], filters[1]);
}
else
{
while (filters.Count > 0)
{
var f1 = filters[0];
var f2 = filters[1];
exp = exp == null
? GetExpression<T>(param, filters[0], filters[1])
: Expression.AndAlso(exp, GetExpression<T>(param, filters[0], filters[1]));
filters.Remove(f1);
filters.Remove(f2);
if (filters.Count == 1)
{
exp = Expression.AndAlso(exp, GetExpression<T>(param, filters[0]));
filters.RemoveAt(0);
}
}
}
return Expression.Lambda<Func<T, bool>>(exp, param);
}
private static Expression GetExpression<T>(ParameterExpression param, DynamicFilter filter)
{
MemberExpression member = Expression.Property(param, filter.PropertyName);
ConstantExpression constant = Expression.Constant(filter.Value);
return Expression.Equal(member, constant);
}
private static BinaryExpression GetExpression<T>(ParameterExpression param, DynamicFilter filter1, DynamicFilter filter2)
{
Expression bin1 = GetExpression<T>(param, filter1);
Expression bin2 = GetExpression<T>(param, filter2);
return Expression.AndAlso(bin1, bin2);
}
}
public class DynamicFilter
{
public string PropertyName { get; set; }
public object Value { get; set; }
}
公共静态类ExpressionBuilder
{
公共静态表达式GetExpression(IList筛选器)
{
如果(filters.Count==0)
返回null;
ParameterExpression param=表达式参数(typeof(T),“T”);
表达式exp=null;
如果(filters.Count==1)
{
exp=GetExpression(参数,过滤器[0]);
}
else if(filters.Count==2)
{
exp=GetExpression(参数,过滤器[0],过滤器[1]);
}
其他的
{
而(filters.Count>0)
{
var f1=过滤器[0];
var f2=过滤器[1];
exp=exp==null
?GetExpression(参数、筛选器[0]、筛选器[1])
:Expression.AndAlso(exp,GetExpression(param,filters[0],filters[1]);
过滤器。移除(f1);
过滤器。移除(f2);
如果(filters.Count==1)
{
exp=Expression.AndAlso(exp,GetExpression(param,filters[0]);
过滤器。移除(0);
}
}
}
返回表达式.Lambda(exp,param);
}
私有静态表达式GetExpression(ParameterExpression param,DynamicFilter筛选器)
{
MemberExpression member=Expression.Property(param,filter.PropertyName);
ConstantPression常数=表达式常数(filter.Value);
返回表达式.Equal(成员,常量);
}
私有静态二进制表达式GetExpression(ParameterExpression param、DynamicFilter filter1、DynamicFilter filter2)
{
表达式bin1=GetExpression(参数,过滤器1);
表达式bin2=GetExpression(参数,过滤器2);
返回表达式.AndAlso(bin1,bin2);
}
}
公共类动态过滤器
{
公共字符串PropertyName{get;set;}
公共对象值{get;set;}
}
将其与您发布的代码一起使用:
public static IQueryable<T> FilerByProperties(string properiesFilter, IQueryable<T> query)
{
if (properiesFilter == null) properiesFilter = "";
string[] properties = properiesFilter.Split(";");
var filters = new List<DynamicFilter>();
for (int i = 0; i < properties.Length; i++)
{
if (!properiesFilter.IsNullOrEmpty())
{
int pocisionProp = properties[i].ToString().IndexOf('=');
string prop = properties[i].Substring(0, pocisionProp);
object value = properties[i].Substring(pocisionProp + 1);
if (typeof(T).GetProperty(prop) != null)
{
var badWayBuySomeWay = 0;
if(Int32.TryParse(value.ToString(), out badWayBuySomeWay))
{
value = badWayBuySomeWay;
}
var filter = new DynamicFilter { PropertyName = prop, Value = value };
filters.Add(filter);
}
}
}
if (filters.Count > 0)
{
var deleg = ExpressionBuilder.GetExpression<T>(filters).Compile();
return query.Where(deleg).AsQueryable();
}
return query;
}
public静态IQueryable filerbyproperty(字符串属性过滤器,IQueryable查询)
{
如果(properiesFilter==null)properiesFilter=“”;
string[]properties=propertiesfilter.Split(“;”);
var filters=新列表();
for(int i=0;i0)
{
var deleg=ExpressionBuilder.GetExpression(filters.Compile();
返回query.Where(deleg.AsQueryable();
}
返回查询;
}
错误消息包含一个指向某些文档的链接,这些文档非常全面地描述了正在发生的事情,并建议您可以对此采取一些措施。我已经实现了您的解决方案