【问题标题】:Weird "assembly not referenced" error when trying to call a valid method overload尝试调用有效方法重载时出现奇怪的“未引用程序集”错误
【发布时间】:2014-12-08 02:47:08
【问题描述】:

我在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);
    }
}

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

类型“System.Data.Entity.DbContext”在一个程序集中定义,该程序集 没有被引用。您必须添加对程序集的引用 'EntityFramework,版本=6.0.0.0,文化=中性, 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
    ...
}  

我不明白的是,如果我将 Assembly A 中的方法签名更改为例如:

public static int GetPersonId(SqlConnection connection, string name, bool empty)

并将调用更改为:

var id = AssemblyA.GetPersonId(connection, name, true); // no error

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

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

DoStuff(10, 5);
DoStuff(10, 5.0f);

那么,尽管显然是合法的超载,为什么我的情况会出现错误?

请注意,从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) { }

        ...
}

我首先将 .NET 4.0 和 EF 6 代码用于现有数据库,并添加了一些自定义 ctor 重载。

【问题讨论】:

    标签: c# .net entity-framework overloading entity-framework-6


    【解决方案1】:

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

    在您的情况下,编译器需要引用 EntityDataContext 才能比较两个重载。您的调用与签名完全匹配,因此理论上您不需要它,但标准没有指定任何此类短路行为。

    【讨论】:

      猜你喜欢
      • 2014-12-09
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2016-04-21
      • 2023-03-07
      • 2018-06-21
      • 1970-01-01
      相关资源
      最近更新 更多