Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/csharp/320.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C#,Linq2Sql:是否可以将两个查询值连接成一个?_C#_Linq To Sql_Lambda_Expression Trees_Iqueryable - Fatal编程技术网

C#,Linq2Sql:是否可以将两个查询值连接成一个?

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合并

我有一个可查询的,其中我使用了各种and语句将集合缩小到某个集合。现在我需要添加一种
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);
    }