gpt4 book ai didi

c# - 针对多个属性构建动态 where 子句

转载 作者:行者123 更新时间:2023-12-02 18:18:36 25 4
gpt4 key购买 nike

我拥有的是 List<string> IndexFields其中包含属性名称列表。

我的问题是我需要根据列表中的元素构建一个 where 子句。

到目前为止我已经;

var sitem = List1.Where(p => (p.GetType().GetProperty(IndexFields[0])
.GetValue(p, null) as string) == "red").FirstOrDefault();

但这只允许我指定一个属性。我需要的是一个可以根据 List<string> IndexFields 中的所有名称进行构建的构建器。列表。

最佳答案

在运行时创建动态查询的最灵活方法是使用表达式 API:

例如:-

var type = typeof(T);
var properties = IndexFields.Select(x => type.GetProperty(x));

// x
var paramter = Expression.Parameter(type);

// x.Foo, x.Bar, ...
var leftHandSides = properties.Select(
x => Expression.Property(parameter, x));

// "Baz"
var rightHandSide = Expression.Constant(...);

// x.Foo == "Baz", x.Bar = "Baz", ...
var equalityExpressions = leftHandSides.Select(
x => Expression.Equal(x, rightHandSide));

// x.Foo == "Baz" && x.Bar == "Baz" && ...
var aggregatedExpressions = equalityExpressions.Aggregate(
(x, y) => Expression.AndAlso(x, y));

// x => x.Foo == "Baz" && x.Bar == "Baz" && ...
var lambda = Expression.Lambda<Func<T,bool>>(
aggregatedExpressions, parameter)

var item = List1.Where(lambda).FirstOrDefault();

像这样构建查询的一个巨大优势是结果表达式仍然可以是例如转换为 SQL 以与 Entity Framework 一起使用,而在 lambda 体内使用反射确实有限制。

不过,我确实建议在使用表达式框架之前花一些时间来真正理解它。如果您能了解正在发生的事情,从长远来看,它可以为您节省大量时间。

您可以阅读更多内容,例如:-

<小时/>

但是,如果您正在寻找更快、更脏的东西,您可以继续将这些 Where 子句链接到 foreach 中:-

IEnumerable<T> query = List1;

foreach (var property in IndexFields)
{
// The variable "property" gets hoisted out of local context
// which messes you up if the query is being evaluated with
// delayed execution.

// If you're working in C# 6 though, you don't need to do this.
var localProperty = property;

query = query.Where(
p => (p.GetType().GetProperty(localProperty)
.GetValue(p, null) as string) == "red");
}

var sitem = query.FirstOrDefault();

关于c# - 针对多个属性构建动态 where 子句,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/17106934/

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