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 A是Assembly 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来比较两个重载.您的呼叫完全匹配签名,理论上您不应该这样,但标准没有指定任何此类短路行为.