Wat*_* v2 7 .net c# entity-framework
创建具有Entity Framework模型和对象上下文的类库.然后向解决方案添加新的控制台应用程序.从控制台应用程序,引用具有您的模型的项目.
现在在控制台应用中输入:
static void Main(string[] args)
{
using (var context = new ExperimentalDbContext())
{
}
Console.ReadKey();
}
Run Code Online (Sandbox Code Playgroud)
在构建时,您将收到报告错误:
"System.Data.Entity.DbContext"类型在未引用的程序集中定义.你必须添加对程序集EntityFramework的引用... yada yada yada ...
现在,我在过去几年中已经多次这样做了,但每当我收到此错误时,我再一次无助地在互联网上搜索我当时忘记的解决方案.
解决此问题需要您在ConsoleClient项目中安装EntityFramework NuGet包.
所以,我的问题不在于修复是什么,而是为什么?因为它没有任何意义!
仅仅为了完整起见,我使用的是实体框架的v6.1.3.但是,多年来我在早期版本中也多次看到过这个错误.
更新
看来,这个问题只有当你使用的using代码块,是为了呼吁Dispose上IDisposable秒.
要测试该假设,请使用以下代码创建一个控制台应用程序,该应用程序在同一解决方案中引用ClassLibrary1,该解决方案在同一解决方案中引用ClassLibrary2:
using ClassLibrary1;
using System;
namespace TestHypothesis1
{
class Program
{
// Testing the hypothesis presented in this answer: http://stackoverflow.com/a/38130945/303685
// This seems to be the behavior with just (or may be even others I haven't tested for)
// IDisposable.
// anotherFoo instance is created just fine, but the moment I uncomment
// the using statement code, it shrieks.
static void Main(string[] args)
{
//using (var foo = new Foo())
//{
// foo.Gar = "Gar";
// Console.WriteLine(foo.Gar);
//}
var anotherFoo = new Foo() { Gar = "Another gar" };
Console.WriteLine(anotherFoo.Gar);
Console.ReadKey();
}
}
}
using ClassLibrary2;
using System;
namespace ClassLibrary1
{
public class Foo: Bar, IDisposable
{
public string Gar { get; set; }
public void Dispose()
{
throw new NotImplementedException();
}
}
}
namespace ClassLibrary2
{
public class Bar
{
public string Name { get; set; }
}
}
Run Code Online (Sandbox Code Playgroud)
并且您将观察到编译器仅针对第一个实例Foo而不是第二个实例的实例化而抱怨缺少引用.
但奇怪的是,在第一个EntityFramework示例中,如果您从控制台应用程序中删除了对EntityFramework.dll的引用并将其中的代码更改Main为此,它仍会抱怨缺少引用.
static void Main(string[] args)
{
var context = new ExperimentalDbContext();
Console.ReadKey();
context.Dispose();
}
Run Code Online (Sandbox Code Playgroud)
另外,如果你注释掉context.Dispose()上面代码片段的最后一行的调用,代码仍然可以正常工作,即使它抛出一个InvalidOperationException但是,我推测,这是由于在迭代器完成之前处理的上下文的竞争条件它的MoveNext电话.
static void Main(string[] args)
{
var context = new ExperimentalDbContext();
Console.ReadKey();
// context.Dispose();
}
Run Code Online (Sandbox Code Playgroud)
所以,新的附加问题现在变成:
这个using语句的实现方式是什么让编译器在链接引用中停止了?
最初的问题也仍然存在.
又一次更新
现在看来问题可能会进一步归结为对IDisposable.Dispose方法的调用,因此问题不在于using语句的实现.这using句话似乎是一种无辜的保证,Dispose将被召唤而不是别的.
因此,在上面的Foo示例中,如果anotherFoo.Dispose在最后插入一个调用,编译器会再次开始抱怨.像这样:
using ClassLibrary1;
using System;
namespace TestHypothesis1
{
class Program
{
// Testing the hypothesis presented in this answer: http://stackoverflow.com/a/38130945/303685
// This seems to be the behavior with just (or may be even others I haven't tested for)
// IDisposable.
// anotherFoo instance is created just fine, but the moment I uncomment
// the using statement code, it shrieks.
// Final update:
// The trigger for the error seems to be the call to the Dispose method and not
// particularly the implementation of the using statement, which apparently, simply
// ensures that Dispose is called, as is also well-known and documented.
static void Main(string[] args)
{
//using (var foo = new Foo())
//{
// foo.Gar = "Gar";
// Console.WriteLine(foo.Gar);
//}
var anotherFoo = new Foo() { Gar = "Another gar" };
Console.WriteLine(anotherFoo.Gar);
anotherFoo.Dispose();
Console.ReadKey();
}
}
}
Run Code Online (Sandbox Code Playgroud)
那么,最后一个问题,总结如下:
为什么Dispose停止编译器能够链接汇编引用的调用?
我想我们现在正在某个地方.
我不认为它特定于 DbContext,但或多或少是因为类库中引用的依赖 DLL 没有转移到控制台应用程序。因此,当您构建时,编译器只知道控制台应用程序中的引用,而不知道对 EntityFramework 的链接引用。它抱怨的唯一原因是编译器对using语句进行检查以确保该类是 of IDisposable,而它知道这一点的唯一方法是它是否解析 EntityFramework 库内的引用。
事实证明我仍然认为这是对的。在您的示例中,如果您忘记了 IDisposable,只是尝试在控制台应用程序中使用该类的属性Name,Bar您会发现出现异常,表明它不知道该属性,因为它位于未引用的程序集中。
未引用的程序集错误示例:
(inside Main)
Console.WriteLine(anotherFoo.Name);
Run Code Online (Sandbox Code Playgroud)
就其价值而言,您实际上可以引用具有嵌套引用的库,并且永远不会在应用程序中包含这些嵌套引用,只要调用代码实际上从未到达引用或需要嵌套库的代码路径即可。这可能是错误的一个简单来源,特别是对于部署/发布场景。想象一个场景,您的发布不包含应用程序所需的所有库,但需要深度嵌套库的代码路径很少被调用。然后有一天,您接到一个电话,说“应用程序坏了!” 人们立即倾向于说“但是什么都没有改变!自从上次以来我们就没有部署过!” 这是在测试、QA、部署后等过程中拥有良好代码覆盖率的重要原因之一。