实体框架 4 的内存数据库

Posted

技术标签:

【中文标题】实体框架 4 的内存数据库【英文标题】:In-Memory DB for Entity Framework 4 【发布时间】:2011-05-11 02:20:45 【问题描述】:

有谁知道与 .NET 4/EF 4 配合良好的内存数据库?具体来说,我正在考虑进行单元测试,这样每个设置都可以轻松创建数据库,并使用默认值填充它,并且每次拆卸都可以快速销毁它。

我听说过 SQLite doesn't support .NET 4,其他人在使用它代替 SQLServer 时遇到了麻烦(这是应用程序在发布模式下运行的内容)。

过去,我使用 DevExpress XPO ORM,它有一个内置的内存数据库,非常适合单元测试。

【问题讨论】:

Testing EF SQL Server based application with in-memory SQLite?的可能重复 @Craig Stuntz - 我不想模拟我的存储库,我现在可以毫无困难地做到这一点,我希望用内存中的数据库替换实际的数据库......这样我不仅可以测试服务,还可以测试生成数据库表并将默认数据插入数据库的代码。 对于正在阅读此问题的人,SQLite 现在通过此网站支持 .NET 4 和 .NET 4.5:system.data.sqlite.org/index.html/doc/trunk/www/downloads.wiki 【参考方案1】:

如果您的模型具有数据库生成的密钥(通常在 EF4 中使用 [DatabaseGenerated(DatabaseGeneratedOption.Identity)] 注释指定),您将在使用 CE4 进行单元测试时遇到问题,因为 CE4 不支持这一点。

但我找到了一个简单的解决方法,无需修改我的生产代码(在 SQL 2008 上运行)。我创建了我的 DbContext 的代理子类,并在其中覆盖 OnModelCreating 以删除注释,并覆盖 SaveChanges 以手动设置 ID:

public class TestContext : MyDbContext

  protected override void OnModelCreating(System.Data.Entity.DbModelBuilder modelBuilder)
  
    modelBuilder.Entity<MyEntity>().Property(e => e.Id)
      .HasDatabaseGeneratedOption(DatabaseGeneratedOption.None);

    base.OnModelCreating(modelBuilder);
  

  public override int SaveChanges()
  
    foreach (var entry in ChangeTracker.Entries<MyEntity>().Where(e => e.State == EntityState.Added))
    
      entry.Entity.Id = Guid.NewGuid();
    
    return base.SaveChanges();
  

通过这些细微的调整,我现在可以在 CE4 中对在生产环境中在 SQL 2008 下运行的相同存储库代码进行单元测试。

如果您使用的是整数 ID 而不是 GUID,这里有一个很好的扩展方法,可以直接插入到上述解决方案中:http://enigmadomain.wordpress.com/2010/01/06/sql-compact-identity-columns-and-entity-framework/

【讨论】:

【参考方案2】:

SQL CE 将为您完成这项工作。它是一个在进程中运行的嵌入式数据库。它适用于 EF4(包括 Code First)。获取它的最简单方法是直接为其安装 NuGet 包。有两个 NuGet 包 - 一个仅包含 SQL CE,另一个包含与 EF Code First CTP4 一起使用的 SQL CE。

【讨论】:

是的,确实如此。看看 Scott Gu 的这篇文章:weblogs.asp.net/scottgu/archive/2010/06/30/…。那篇文章的关键是这一部分:“SQL CE 数据库引擎然后在您的应用程序的内存中运行。当您的应用程序关闭时,数据库会自动卸载。” 不太正确,我已经测试了在 ram 磁盘上托管了一个 CE db,查询速度提高了大约 50%。 CE 仍然倾向于比它应该(和我预期的那样)更严重地打击文件系统。 不管它可能会或可能不会命中文件系统的次数,它是否完全完成@SnOrfus 所寻求的?与 EF4/.NET 4 配合使用,快速设置/拆卸数据库,与单元测试一起工作,轻松填充种子数据等。 不幸的是,我必须取消将其标记为已接受的答案。 Ce 和 EF 可以一起使用,但它绝不是对为 Sql Server 设计的 EF 模型进行单元测试的有用工具。需要对 EF 模型进行太多关键修改,这样您最终会为测试环境而不是生产环境建模。更好的 EF 支持和内存数据库仅在目前只有 CTP 的 Ce 4 中提供,并且仍然存在一些使其不值得的问题。【参考方案3】:

如果切换到 EF CTP4 对您来说没有问题,那么是这样的:

EF4 CTP4 SQL CE 4 CTP

它会在您编写单元测试时为您生成内存中的数据库(代码优先)。

【讨论】:

以上是关于实体框架 4 的内存数据库的主要内容,如果未能解决你的问题,请参考以下文章

实体框架是不是有内存提供程序?

最小的 Web API 和播种内存中实体框架数据库

带有内存测试双倍的模拟实体框架

实体框架核心错误? SaveChanges 抛出选择

实体框架 TypeUsage 对象

避免实体框架查询返回的列表中的内存泄漏