Linq to Entities Where Or 子句
Linq to Entities Where Or clause
已阅读类似问题的其他回复,但我无法使用 PredicateBuilder,也无法复制其源代码。我正在尝试我在这里阅读的内容:
<https://blogs.msdn.microsoft.com/meek/2008/05/02/linq-to-entities-combining-predicates/
但由于我是新手,在将我正在阅读的内容翻译成我正在申请的内容时遇到了问题。我创建了一个 L2E 查询,并尝试将一系列 OR 子句附加到 WHERE:
所以作为简化的片段(这个片段将与之前已经定义的 WHERE 子句进行 AND 运算):
if (firstParm == "realtor")
query = query.Where(x=> x.A == "realtor");
现在尝试或:
if (secondParm == "clown")
// how to add this one as an OR to the above query:
query = query.OR(x=> x.fool == "clown");
我知道这也可以用 Union 来完成,但语法不清楚:
query = query.Union(x=> x.fool == "clown"); // ??
我也参考过:
Combining two expressions (Expression<Func<T, bool>>)
Unable to create a compound Expression<Func<string, bool>> from a set of expressions
不过,我还是 LINQ 的新手,尤其是表达式树,所以需要更多的填充。
或者你可以试试
if (secondParm == "clown")
{
query = query.Where(x=> x.fool == "clown" || x.fool==x.fool);
}
或
if (secondParm == "clown")
{
query = query.Where(x=> x.fool == "clown" || true );
}
有两种生成表达式的方法。
用编译器来做。
Expression<Func<Person, bool>> = p => p.LastName.Contains("A");
限制:可以这种方式生成的唯一表达式是 LambdaExpression
的实例。另外,提取部分表达式并与其他部分组合起来相当复杂。
使用 System.Linq.Expressions.Expression
处的静态方法。
为了生成动态表达式,您可以选择不同的编译器生成的表达式:
// using Record and Records as a placeholder for the actual record type and DbSet property
Expression<Func<Record,bool>> expr;
if (firstParam == "realtor") {
if (secondParam == "clown") {
expr = x => x.A == "realtor" || x.fool == "clown";
} else {
expr = x => x.A == "realtor";
}
} else {
if (secondParam == "clown") {
expr = x => x.fool="clown";
} else {
expr = x => false;
}
}
var ctx = new MyDbContext();
var qry = ctx.Records.Where(expr).Select(x => new {x.A, x.fool});
或者,您可以使用静态方法动态创建表达式:
(将 using System.Linq.Expressions;
和 using static System.Linq.Expressions.Expression;
添加到文件顶部。)
Expression expr;
var parameter = Parameter(typeof(Record));
if (firstParam == "realtor") {
expr = Equals(
MakeMemberAccess(parameter, typeof(Record).GetProperty("A")),
Constant("realtor")
);
}
if (secondParam == "clown") {
var exprClown = Equals(
MakeMemberAccess(parameter, typeof(Record).GetProperty("fool")),
Constant("clown")
);
if (expr == null) {
expr = exprClown;
} else {
expr = Or(expr, exprClown);
}
}
var lambda = Lambda<Func<Record,bool>>(expr, new [] {parameter});
var ctx = new MyDbContext();
var qry = ctx.Records.Where(lambda).Select(x => new {x.A, x.fool});
给定一个编译时类型未知的查询,因此引用它的任何变量都必须是 IQueryable
,而不是 IQueryable<T>
:
IQueryable qry = ctx.GetQuery(); //dynamically built query here
var parameter = Parameter(qry.ElementType);
if (firstParam == "realtor") {
expr = Equals(
MakeMemberAccess(parameter, qry.ElementType.GetProperty("A")),
Constant("realtor")
);
}
if (secondParam == "clown") {
var exprClown = Equals(
MakeMemberAccess(parameter, qry.ElementType.GetProperty("fool")),
Constant("clown")
);
if (expr == null) {
expr = exprClown;
} else {
expr = Or(expr, exprClown);
}
}
var lambda = Lambda(expr, new [] {parameter});
//Since we don't have access to the TSource type to be used by the Where method, we have
//to invoke Where using reflection.
//There are two overloads of Queryable.Where; we need the one where the generic argument
//is Expression<Func<TSource,bool>>, not Expression<Func<TSource,int,bool>>
var miWhere = typeof(Queryable).GetMethods().Single(mi => {
mi.Name == "Where" &&
mi.GetParameters()[1].ParameterType.GetGenericArguments()[0].GetGenericArguments().Length == 2
});
qry = miWhere.Invoke(null, new [] {qry, lambda});
已阅读类似问题的其他回复,但我无法使用 PredicateBuilder,也无法复制其源代码。我正在尝试我在这里阅读的内容:
<https://blogs.msdn.microsoft.com/meek/2008/05/02/linq-to-entities-combining-predicates/
但由于我是新手,在将我正在阅读的内容翻译成我正在申请的内容时遇到了问题。我创建了一个 L2E 查询,并尝试将一系列 OR 子句附加到 WHERE:
所以作为简化的片段(这个片段将与之前已经定义的 WHERE 子句进行 AND 运算):
if (firstParm == "realtor")
query = query.Where(x=> x.A == "realtor");
现在尝试或:
if (secondParm == "clown")
// how to add this one as an OR to the above query:
query = query.OR(x=> x.fool == "clown");
我知道这也可以用 Union 来完成,但语法不清楚:
query = query.Union(x=> x.fool == "clown"); // ??
我也参考过:
Combining two expressions (Expression<Func<T, bool>>)
Unable to create a compound Expression<Func<string, bool>> from a set of expressions
不过,我还是 LINQ 的新手,尤其是表达式树,所以需要更多的填充。
或者你可以试试
if (secondParm == "clown")
{
query = query.Where(x=> x.fool == "clown" || x.fool==x.fool);
}
或
if (secondParm == "clown")
{
query = query.Where(x=> x.fool == "clown" || true );
}
有两种生成表达式的方法。
用编译器来做。
Expression<Func<Person, bool>> = p => p.LastName.Contains("A");
限制:可以这种方式生成的唯一表达式是
LambdaExpression
的实例。另外,提取部分表达式并与其他部分组合起来相当复杂。使用
System.Linq.Expressions.Expression
处的静态方法。
为了生成动态表达式,您可以选择不同的编译器生成的表达式:
// using Record and Records as a placeholder for the actual record type and DbSet property
Expression<Func<Record,bool>> expr;
if (firstParam == "realtor") {
if (secondParam == "clown") {
expr = x => x.A == "realtor" || x.fool == "clown";
} else {
expr = x => x.A == "realtor";
}
} else {
if (secondParam == "clown") {
expr = x => x.fool="clown";
} else {
expr = x => false;
}
}
var ctx = new MyDbContext();
var qry = ctx.Records.Where(expr).Select(x => new {x.A, x.fool});
或者,您可以使用静态方法动态创建表达式:
(将 using System.Linq.Expressions;
和 using static System.Linq.Expressions.Expression;
添加到文件顶部。)
Expression expr;
var parameter = Parameter(typeof(Record));
if (firstParam == "realtor") {
expr = Equals(
MakeMemberAccess(parameter, typeof(Record).GetProperty("A")),
Constant("realtor")
);
}
if (secondParam == "clown") {
var exprClown = Equals(
MakeMemberAccess(parameter, typeof(Record).GetProperty("fool")),
Constant("clown")
);
if (expr == null) {
expr = exprClown;
} else {
expr = Or(expr, exprClown);
}
}
var lambda = Lambda<Func<Record,bool>>(expr, new [] {parameter});
var ctx = new MyDbContext();
var qry = ctx.Records.Where(lambda).Select(x => new {x.A, x.fool});
给定一个编译时类型未知的查询,因此引用它的任何变量都必须是 IQueryable
,而不是 IQueryable<T>
:
IQueryable qry = ctx.GetQuery(); //dynamically built query here
var parameter = Parameter(qry.ElementType);
if (firstParam == "realtor") {
expr = Equals(
MakeMemberAccess(parameter, qry.ElementType.GetProperty("A")),
Constant("realtor")
);
}
if (secondParam == "clown") {
var exprClown = Equals(
MakeMemberAccess(parameter, qry.ElementType.GetProperty("fool")),
Constant("clown")
);
if (expr == null) {
expr = exprClown;
} else {
expr = Or(expr, exprClown);
}
}
var lambda = Lambda(expr, new [] {parameter});
//Since we don't have access to the TSource type to be used by the Where method, we have
//to invoke Where using reflection.
//There are two overloads of Queryable.Where; we need the one where the generic argument
//is Expression<Func<TSource,bool>>, not Expression<Func<TSource,int,bool>>
var miWhere = typeof(Queryable).GetMethods().Single(mi => {
mi.Name == "Where" &&
mi.GetParameters()[1].ParameterType.GetGenericArguments()[0].GetGenericArguments().Length == 2
});
qry = miWhere.Invoke(null, new [] {qry, lambda});