LinqToSql - 扩展方法解析

时间:2018-01-27 14:12:20

标签: c# linq extension-methods overload-resolution

我理解在编译时解析期间优先考虑实例方法而不是扩展方法。但对于LinqToSQL(或LinqtoXXX):

Table<Order> orders = context.Orders
var query = orders.Where(o=>o.name=="xyz")

解决上述WhereQueryable方法的决定因素是什么?尽管Table<Order>同时实现了IEnumerabe<T>IQueryable<T>

public sealed class Table<TEntity> : IQueryable<TEntity>, IQueryable, 
                                         IEnumerable<TEntity>, IEnumerable,
                                         ITable<TEntity>, ITable,
                                         IQueryProvider, 
                                         IListSource
        where TEntity : class
    {
        // ...
    }

1 个答案:

答案 0 :(得分:0)

EntityFramework使用IQueryable为context.Orders启用Linq-To-Sql。

  

不同之处在于IQueryable是允许的界面   LINQ-to-SQL(LINQ.-to-anything真的)可以工作。所以,如果你进一步   在IQueryable上优化您的查询,该查询将在中执行   数据库,如果可能的话。

     

对于IEnumerable案例,它将是LINQ-to-object,意思是   必须加载与原始查询匹配的所有对象   来自数据库的内存。

有关详细信息,请参阅:Returning IEnumerable<T> vs. IQueryable<T>

编辑29/01/2018

如果您的类具有为2个接口定义的相同名称的扩展方法 以下是结果:

public interface IA
{
    void SayHello();
}
public interface IB
{
    void SayHello();
}

public class AB: IA,IB
{
    //If two interfaces have methods with same signature, 
    //They can both be implemented by prefixing interface name for one of them.
    void IA.SayHello()
    {
        Console.WriteLine("Hello A");
    }

    void IB.SayHello()
    {
        Console.WriteLine("Hello B");
    }

    public void SayHello()
    {
        Console.WriteLine("Hello AB");
    }
}

public static class MyClassExt
{
    public static void SayBye(this IA a)
    {
        Console.WriteLine("Bye from A");
    }

    public static void SayBye(this IB b)
    {
        Console.WriteLine("Bye from B");
    }

    public static void SayBye(this AB ab)
    {
        Console.WriteLine("Bye from AB");
    }
}

var obj = new AB();

obj.SayHello(); //Hello AB
((IA)obj).SayHello(); //Hello A
((IB)obj).SayHello(); //Hello B

obj.SayBye(); //Bye AB
((IA)obj).SayBye(); //Bye A
((IB)obj).SayBye(); // Bye B

您还可以在Test inheritence and extension methods.linq

获取LinqPad脚本