使用IQueryable <TEntity>代替DbSet <TEntity>问题

xtm*_*tmq 6 iqueryable entity-framework-4 c#-4.0 dbcontext

我偶然发现了下一个问题...我有数据库上下文:

// For support unit testing... 
public interface IDbContext : IDisposable
{
   IQueryable<Hardware> Hardwares { get; }
   IQueryable<ProviderHardware> ProviderHardwares { get; }
}

// Real DbContext (EF 4.0, Code First)
public class PrimaryDbContext : DbContext, IDbContext
{
   public DbSet<Hardware> Hardwares { get; set; }
   public DbSet<ProviderHardware> ProviderHardwares { get; set; }

   IQueryable<Hardware> IDbContext.Hardwares
     { get { return Hardwares; } }
   IQueryable<ProviderHardware> IDbContext.ProviderHardwares
     { get { return ProviderHardwares; } } 
   ...
}
Run Code Online (Sandbox Code Playgroud)

我尝试获取ProviderHardwares表中不存在的所有硬件:

var hardwaresRemoved = db.Hardwares.Where(i => (i.IsAvailable == true) &&
   (db.ProviderHardwares.Count(j => j.Article == i.Article) == 0)).ToList();
Run Code Online (Sandbox Code Playgroud)

如果我严格使用PrimaryDbContext,例如"PrimaryDbContext db = new PrimaryDbContext();" 一切正常.但如果我隐式使用它"IDbContext db = new PrimaryDbContext();" 我得到一个例外:

无法创建"ConfiguratorMvcApplication.DomainModels.ProviderHardware"类型的常量值.在此上下文中仅支持原始类型(例如Int32,String和Guid').

总结一下,我无法替换IQueryable上的DbSet.在这种情况下我如何使用单元测试?我希望有人已经解决了这个问题......非常感谢!

Mig*_*oso -2

我建议你最好保留 DbSets 并进行集成测试, 包括数据库。

因为,尽管使用数据库模拟通过单元测试可能有点用,但使用真实数据库进行测试会更好(但这不是单元测试)。

在 ClassInitialize 上擦除数据库和/或创建用于测试的初始数据。

如果您使用连接字符串创建 App.config 文件,则可以拥有一个单独的测试数据库,如果您使用 EF Code First,则可以免费获得它。

此致。