C#,Linq2Sql:是否可以将两个查询值连接成一个?
我有一个可查询的,其中我使用了各种and语句将集合缩小到某个集合。现在我需要添加一种C#,Linq2Sql:是否可以将两个查询值连接成一个?,c#,linq-to-sql,lambda,expression-trees,iqueryable,C#,Linq To Sql,Lambda,Expression Trees,Iqueryable,我有一个可查询的,其中我使用了各种and语句将集合缩小到某个集合。现在我需要添加一种Where | | wherebeen。换言之,我不能像现在这样把它们连在一起,因为这将作为一个And。那么,我该怎么做呢 我看到两种可能性: 从我拥有的一个查询文件创建两个查询文件,一个使用Where,另一个使用WhereBetween然后将它们连接起来。不知道这是否可能?此外,虽然不是在我的特殊情况下,你很可能会以重复的结束 以某种方式将Where表达式和在wherebeen中创建的表达式与某种类型的Or合并
Where | | wherebeen
。换言之,我不能像现在这样把它们连在一起,因为这将作为一个And。那么,我该怎么做呢
我看到两种可能性:
Where
,另一个使用WhereBetween
然后将它们连接起来。不知道这是否可能?此外,虽然不是在我的特殊情况下,你很可能会以重复的结束Where
表达式和在wherebeen
中创建的表达式与某种类型的Or合并如前所述,我甚至不确定第一种方法是否可行。如果是的话,我不确定这是一个好方法 第二,我可以将其视为一种选择,但不能完全确定所有细节。下面是我另一个问题中的
WhereBetween
方法,我现在使用它,效果非常好:
public static IQueryable<TSource> WhereBetween<TSource, TValue>(
this IQueryable<TSource> source,
Expression<Func<TSource, TValue>> selector,
IEnumerable<Range<TValue>> ranges)
{
var param = Expression.Parameter(typeof(TSource), "x");
var member = Expression.Invoke(selector, param);
Expression body = null;
foreach (var range in ranges)
{
var filter = Expression.AndAlso(
Expression.GreaterThanOrEqual(member,
Expression.Constant(range.A, typeof(TValue))),
Expression.LessThanOrEqual(member,
Expression.Constant(range.B, typeof(TValue))));
body = body == null ? filter : Expression.OrElse(body, filter);
}
return body == null ? source : source.Where(
Expression.Lambda<Func<TSource, bool>>(body, param));
}
public static IQueryable在哪之间(
这是可靠的消息来源,
表达式选择器,
(可数范围)
{
var param=表达式参数(typeof(TSource),“x”);
var member=Expression.Invoke(选择器,参数);
表达式体=null;
foreach(范围中的var范围)
{
var filter=Expression.AndAlso(
表达式.GreaterThanOrEqual(成员,
表达式常数(范围A,类型(TValue)),
表达式.LessThanOrEqual(成员,
表达式常数(范围B,类型(TValue));
body=body==null?过滤器:Expression.OrElse(body,filter);
}
返回正文==null?源:源。其中(
Lambda(body,param)表达式;
}
我想我可以把它的表达式构建部分提取到一个新方法中。也许是这样的:
public static IQueryable<TSource> WhereBetween<TSource, TValue>(
this IQueryable<TSource> source,
Expression<Func<TSource, TValue>> selector,
IEnumerable<Range<TValue>> ranges)
{
return source.Where(WhereBetween(selector, ranges));
}
public static Expression<Func<TSource, bool>> WhereBetween<TSource, TValue>(
Expression<Func<TSource, TValue>> selector,
IEnumerable<Range<TValue>> ranges)
{
var param = Expression.Parameter(typeof(TSource), "x");
var member = Expression.Invoke(selector, param);
Expression body = null;
foreach (var range in ranges)
{
var filter = Expression.AndAlso(
Expression.GreaterThanOrEqual(member,
Expression.Constant(range.A, typeof(TValue))),
Expression.LessThanOrEqual(member,
Expression.Constant(range.B, typeof(TValue))));
body = body == null ? filter : Expression.OrElse(body, filter);
}
return body == null
? ø => true
: Expression.Lambda<Func<TSource, bool>>(body, param);
}
public static IQueryable在哪之间(
这是可靠的消息来源,
表达式选择器,
(可数范围)
{
返回源。其中(其中(选择器、范围));
}
公共静态表达式(
表达式选择器,
(可数范围)
{
var param=表达式参数(typeof(TSource),“x”);
var member=Expression.Invoke(选择器,参数);
表达式体=null;
foreach(范围中的var范围)
{
var filter=Expression.AndAlso(
表达式.GreaterThanOrEqual(成员,
表达式常数(范围A,类型(TValue)),
表达式.LessThanOrEqual(成员,
表达式常数(范围B,类型(TValue));
body=body==null?过滤器:Expression.OrElse(body,filter);
}
返回正文==null
ø=>正确
:表达式.Lambda(主体,参数);
}
然后,我可以使用这个新方法来获取表达式,而不是queryable。因此,让我们假设我有,在这两者之间(ø=>ø.Id,someRange)
,例如ø=>ø.SomeValue==null
。如何将这两者与Or结合起来?我在看表达式。OrElse
在where-ween
方法中使用,我想这可能是我需要的,或者这可能是表达式。或者。但是我对这个表达的东西非常不稳定,所以我不确定在这里选择什么,或者即使我在正确的轨道上:p
有人能给我一些指点吗 这里有两个选项-Queryable.Union
或表达式组合。我通常倾向于后者,通过OrElse
——这(至少使用LINQ到SQL)可以使用2个表达式(见下文)——但无论哪种情况,它都应该是组合的:
using(var ctx = new DataClasses1DataContext())
{
ctx.Log = Console.Out;
Expression<Func<Customer, bool>> lhs =
x => x.Country == "UK";
Expression<Func<Customer, bool>> rhs =
x => x.ContactName.StartsWith("A");
var arr1 = ctx.Customers.Where(
lhs.OrElse(rhs)).ToArray();
var arr2 = ctx.Customers.Where(lhs)
.Union(ctx.Customers.Where(rhs)).ToArray();
}
那个吵架的事可能是什么,对吗?(当然是任何字符串)考虑sql性能之类的问题,在WHERE
子句中使用联合或或是否更有效?非常好。这个问题不断地出现(变化中),你的OrElse可能是解决所有问题的灵丹妙药。是的,它可能是“row”、“x”或“Fred”。重新性能:您需要对其进行配置。。。不同的查询行为不同。总的来说,或将是更有效的,但有一些情况下,工会证明是更好的;以及两个单独的查询更好的情况。表达的东西慢慢但稳步地开始有意义了,呵呵。看起来它会工作,虽然我要到星期一才能完全测试出来。可能会坚持使用OR,因为它通常更有效=)再次感谢您!
static Expression<Func<T, bool>> OrElse<T>(
this Expression<Func<T, bool>> lhs,
Expression<Func<T, bool>> rhs)
{
var row = Expression.Parameter(typeof(T), "row");
var body = Expression.OrElse(
Expression.Invoke(lhs, row),
Expression.Invoke(rhs, row));
return Expression.Lambda<Func<T, bool>>(body, row);
}