尝试调用有效方法重载时出现奇怪的"程序集未引用"错误

w12*_*128 18 .net c# entity-framework overloading entity-framework-6

我正在使用方法重载Assembly A:

public static int GetPersonId(EntityDataContext context, string name)
{
    var id = from ... in context... where ... select ...;
    return id.First(); 
}

public static int GetPersonId(SqlConnection connection, string name)
{
    using (var context = new EntityDataContext(connection, false))
    {
        return GetPersonId(context, name);
    }
}
Run Code Online (Sandbox Code Playgroud)

当我尝试从第二次重载调用时Assembly B,VS会产生以下编译时错误:

"System.Data.Entity.DbContext"类型在未引用的程序集中定义.您必须添加对程序集'EntityFramework,Version = 6.0.0.0,Culture = neutral,PublicKeyToken = ...'的引用.

Assembly B参考Assembly A.实体框架仅在引用Assembly AAssembly B不使用它.来自的呼叫Assembly B如下:

using (SqlConnection connection = new SqlConnection(connectionString))
{
    connection.Open();                               
    var id = AssemblyA.GetPersonId(connection, name); // compiler error
    ...
}  
Run Code Online (Sandbox Code Playgroud)

我不明白的是,该错误消失,如果我改变方法签名Assembly A来.例如:

public static int GetPersonId(SqlConnection connection, string name, bool empty)
Run Code Online (Sandbox Code Playgroud)

并将通话更改为:

var id = AssemblyA.GetPersonId(connection, name, true); // no error
Run Code Online (Sandbox Code Playgroud)

为什么我的代码在第一种情况下没有编译?它似乎与实体框架无关,因为错误表明了这一点.我一直认为C#允许方法重载,方法签名只在参数类型上有所不同.例如,我可以按预期运行以下代码而不会出现问题:

static void DoStuff(int a, int b) { ... }
static void DoStuff(int a, float b) { ... }

DoStuff(10, 5);
DoStuff(10, 5.0f);
Run Code Online (Sandbox Code Playgroud)

那么,尽管有明显的合法超载,为什么我会在我的情况下得到错误?

请注意,从Assembly B我调用内部使用的其他方法没有问题EntityDataContext,唯一的区别是这些方法没有重载.


背景

EntityDataContext继承EF的DbContext:

public partial class EntityDataContext : DbContext
{
        public EntityDataContext() : base("name=EntityDataContext") { }

        public EntityDataContext(DbConnection connection, bool contextOwnsConnection) 
            : base(connection, contextOwnsConnection) { }

        ...
}
Run Code Online (Sandbox Code Playgroud)

我首先使用带有EF 6代码的.NET 4.0到现有数据库,并添加了一些自定义ctor重载.

Cor*_*son 10

C#标准规定通过比较每个匹配的签名来确定哪个更合适,从而执行重载决策(第7.5.3节).它没有说明缺少引用时会发生什么,所以我们必须推断它仍然需要比较那些未引用的类型.

在您的情况下,编译器需要一个引用EntityDataContext来比较两个重载.您的呼叫完全匹配签名,理论上您不应该这样,但标准没有指定任何此类短路行为.