代码之家  ›  专栏  ›  技术社区  ›  fyjham

LinqToSql选择一个类,然后执行更多查询

  •  3
  • fyjham  · 技术社区  · 14 年前

    IQueryable<T> 并在其他方法中应用附加过滤器。

    问题是我不知道如何传递信息 var 数据类型并保持其强类型,如果我尝试将其放入自己的类中(例如: .Select((a,b) => new MyClass(a,b)) )以后尝试添加时出错 Where 子句,因为我的类没有到SQL的翻译。我有没有办法做到以下一点:

    1. 使我的类映射到SQL?
    2. 使 变量 数据类型实现一个接口(这样我就可以像传递接口一样传递它)?

    例子:

    public void Main()
    {
        using (DBDataContext context = new DBDataContext())
        {
          var result = context.TableAs.Join(
             context.TableBs,
             a => a.BID,
             b => b.ID,
            (a,b) => new {A = a, B = b}
          );
          result = addNeedValue(result, 4);
       }
    }
    
    private ???? addNeedValue(???? result, int value)
    {
        return result.Where(r => r.A.Value == value);
    }
    

    PS:我知道在我的例子中,我可以很容易地将函数展平,但在实际情况中,如果我尝试的话,它将是一个绝对的混乱。

    4 回复  |  直到 14 年前
        1
  •  2
  •   Fyodor Soikin    14 年前

    new { A = a, B = b } 只需创建一个具有这些属性的类并适当地命名它。那么您的查询将具有 IQueryable<your type>

    public class MyClass 
    { 
        public int A { get; set; }
        public int B { get; set; }
    }
    
    public void Main()
    {
        using (DBDataContext context = new DBDataContext())
        {
          var result = context.TableAs.Join(
             context.TableBs,
             a => a.BID,
             b => b.ID,
            (a,b) => new MyClass {A = a, B = b}
          );
          result = addNeedValue(result, 4);
       }
    }
    
    private IQueryable<MyClass> addNeedValue(IQueryable<MyClass> result, int value)
    {
        return result.Where(r => r.A.Value == value);
    }
    
        2
  •  1
  •   Marc Gravell    14 年前

    这里有两种不同的方法;第一个应用过滤器 之前 Join 之后 连接,使用中间投影(并将其更改为 谓词,而不是在内部应用它)。

    Expression.Invoke

    如果您想运行这个示例,我已经使用了Northwind(因为这是我在本地使用的):

    using System;
    using System.Linq;
    using System.Linq.Expressions;
    using ConsoleApplication1; // my data-context's namespace
    static class Program
    {
        public static void Main()
        {
            using (var context = new TestDataContext())
            {
                context.Log = Console.Out; // to check it has worked
                IQueryable<Order> lhs = context.Orders;
                IQueryable<Order_Detail> rhs = context.Order_Details;
                // how ever many predicates etc here
                rhs = addBeforeJoin(rhs, 4);
    
                var result = lhs.Join(rhs,
                       a => a.OrderID,
                       b => b.OrderID,
                      (a, b) => new { A = a, B = b }
                );
                // or add after
                result = result.Where(row => row.B, addAfterJoin(100));
                Console.WriteLine(result.Count());
            }
        }
    
        private static IQueryable<Order_Detail> addBeforeJoin(IQueryable<Order_Detail> query, int value)
        {
            return query.Where(r => r.Quantity >= value);
        }
        private static Expression<Func<Order_Detail, bool>> addAfterJoin(int value)
        {
            return r => r.Quantity <= value;
        }
        private static IQueryable<TSource> Where<TSource, TProjection>(
            this IQueryable<TSource> source,
            Expression<Func<TSource, TProjection>> selector,
            Expression<Func<TProjection, bool>> predicate)
        {
            return source.Where(
                Expression.Lambda<Func<TSource, bool>>(
                Expression.Invoke(predicate, selector.Body),
                selector.Parameters));
        }
    
    }
    
        3
  •  0
  •   Kirk Broadhurst    14 年前

    如果它是SQL/linqtosql知道的类型,那么您可能能够做到这一点。

    IQueryable<ResultSetRow>

        4
  •  0
  •   Joe Enos    14 年前

    我绝对不推荐使用它,但是如果您使用的是.NET4.0,那么您可以在这里使用dynamic。