2012-02-12 43 views
28

下面的测试与EF 4.2现在的工作与抛出EF下一个异常4.3实体框架4.3和最小起订量不能创建的DbContext嘲笑

System.ArgumentException:类型嘲笑必须是接口或者 抽象或非密封类。 ----> System.TypeLoadException: 来自程序集'DynamicProxyGenAssembly2,Version = 0.0.0.0, Culture = neutral,PublicKeyToken = null'的类型为'Castle.Proxies.DbContext43Proxy' 的方法'CallValidateEntity'重写了一个 在该组件中不可见。

[Test] 
public void CanCreateMoqTest() 
{ 
    // Arrange 
    Mock<DbContext43> mock; 

    // Act 
    mock = new Mock<DbContext43>(); 

    // Assert 
    Assert.NotNull(mock.Object); 
} 

public class DbContext43:DbContext 
{ 
} 

我应该怎么办?为我的DbContext43创建一个接口?

这是4.2和4.3之间的突变吗?

谢谢!

+4

使用存储库和工作单元模式,你不会有这个问题。您也不会将所有代码都连接到EF。 – TrueWill 2012-02-12 20:47:19

+11

存储库与DbContext有时是过度杀伤... – 2012-03-14 01:41:01

+2

我一直在深入包装我的EF代码存储库模式的路线。您最终创建了自己的数据访问框架,最终需要更多时间进行维护,而不是我所承认的。除非您正在构建由多个团队共享的企业框架,并且您有一个致力于维护基础架构的团队,否则我建议您不要将EF包装在存储库模式中。 – 2013-06-21 13:03:53

回答

38

感谢您的发现。这个问题是由我们从EF 4.2版本中剥离出来的InternalsVisibleTo属性引起的,但是留给了EF 4.3。这允许Moq(我们用于测试)查看EntityFramework.dll的内部。然而,由于你的程序集看不到那些内部结构,你最终会遇到异常。

我们计划在接下来的几个星期内发布EF 4.3的补丁,并将剥离InternalsVisibleTo,然后再次使用此版本。

更新:现已在今天发布的EF 4.3.1(和EF 5.0-beta1)中修复此问题。更新你的NuGet包以获得修复。有关详细信息,请参见http://blogs.msdn.com/b/adonet/archive/2012/02/29/ef4-3-1-and-ef5-beta-1-available-on-nuget.aspx

+0

所以,直到那些修复程序来了,我要降级到实体框架4.2 :( – 2012-02-21 13:31:38

+1

非常感谢亚瑟!超出了期望moq问题将得到如此迅速的解决! – 2012-03-02 22:10:18

5

这种异常通常表明您试图覆盖的成员不会作为给定程序集中公共接口的一部分公开(或者可能更精确 - 覆盖程序集看不到它)。如果我们take a look在的EntityFramework 4.3 CallValidateEntity实现:

internal virtual DbEntityValidationResult CallValidateEntity(
    DbEntityEntry entityEntry, IDictionary<object, object> items) 
{ 
    return this.ValidateEntity(entityEntry, items); 
} 

我们确实注意到,这种方法是internal,并因此落在非可覆盖类(非重写考虑没有InternalsVisibleTo属性被用于)。这自然是由适当的元数据条目匹配:

Method #20 (06000a03) 
------------------------------------------------------- 
    MethodName: CallValidateEntity (06000A03) 
    Flags  : [Assem] [Virtual] [HideBySig] [NewSlot] (000003c3) 

这是相当不清楚为什么起订量试图重写成员......考虑到它不应该看到它在首位。

在界面中包装上下文并仅公开实际使用的方法是一个可行的选项 - 它应该足以让您的测试通过。

+0

嗨,关于重建,我做了一些测试,创建了两个单独的项目,一个用于ef 4.2的nuget,另一个用于ef 4.3,所以我认为旧的代码不是问题。无论如何,困扰我的是,它正在使用ef 4.2 – 2012-02-12 15:07:55

+0

@RodrigoJuarez:你可以使用[ILSpy](http://wiki.sharpdevelop.net/ILSpy.ashx)来检查EF 4.2'CallValidateEntity'的实现。在EF 4.3中它是内部的,所以它不能被覆盖。为什么Moq试图这样做反正超越了我。也许问题在别处。 – 2012-02-12 15:11:21

+0

EF 4.2的代码是一样的,我怎样才能看到元数据?无论如何,我应该在Moq中寻找一些问题吗?随着接口我有问题解决,但我很好奇 – 2012-02-12 15:46:28