gpt4 book ai didi

c# - 按动态属性过滤

转载 作者:行者123 更新时间:2023-11-30 16:37:11 25 4
gpt4 key购买 nike

我有一个动态过滤 List 的通用方法,我最近将我的项目更新为 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.'

这是我的方法

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 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);
}

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; }
}

将它与您发布的代码一起使用:

    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;
}

关于c# - 按动态属性过滤,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/59097131/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com