新人学Linqvar r = ctx.User;
var r1 = r.OrderBy(x => x.Id);
var r2 = r.OrderBy(deledgte(User x) { return x.Id;});r1 和 r2,数据结果一样,但是类型不一致r.GetType().Name = DataQuery~1;
r1.GetType().Name = DataQuery~1;
r2.GetType().Name = OrderedEnumabled~2;谁能分析下原因?r1的Lambda表达式不应该就是r2的委托吗?为什么结果类型会不一样呢?

解决方案 »

  1.   

    这要看r是什么类型 是否实现了IQueryable 如果是使用linq to sql就是 这种情况下lamda表达式被编译成expression tree,而不是delegate, 所以r1用了linq to sql, 而r2只不过是把数据库中的数据在内在中查询
      

  2.   

    顶上。
    HOHO,这个原因我仔细研究了一下发现可能比较说得通的解释是这样的。
    var r = ctx.User;  
    r同时实现了IEnumerable和IQueryable接口,这两个接口都实现了OrderBy的扩展方法。
    但是他们两者对于OrderBy的定义不同:
    这是IEnumerable的public static IOrderedEnumerable<TSource> OrderBy<TSource, TKey>(
        this IEnumerable<TSource> source,
        Func<TSource, TKey> keySelector
    )这是IQuerable的public static IOrderedQueryable<TSource> OrderBy<TSource, TKey>(
        this IQueryable<TSource> source,
        Expression<Func<TSource, TKey>> keySelector
    )然后我再来看你的两个调用:
    var r1 = r.OrderBy(x => x.Id); 
    这里的x=>x.Id是一个Lambda表达式,它的类型是Expression<TDelegate>。
    var r2 = r.OrderBy(deledgte(User x) { return x.Id;}); 
    这里的deledgte(User x) { return x.Id;}是一个委托,它的类型自然就是Func<....>写到这里你应该明白了,这就是一个重载函数的选择问题。在存在相同参数个数的情况下,C#编译器选择的是类型更接近的那个重载函数,第一个是IQueryable的OrderBy,它返回的是IOrderedQueryable,而第二个则返回IOrderedEnumerable。
      

  3.   

    var r1 = r.OrderBy(x => x.Id);
    var r2 = r.OrderBy(deledgte(User x) { return x.Id;}); 
    第一个属于隐式的声明x x可以属于任何类型只要这个x有id属性
    第二个就很明白了显示的指定了属于User