使用 IQueryable而是 DbSet问题
我偶然发现了下一个问题...我有数据库上下文:
// 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; } }
...
}
并且我尝试获取 ProviderHardwares 表中不存在的所有硬件:
var hardwaresRemoved = db.Hardwares.Where(i => (i.IsAvailable == true) &&
(db.ProviderHardwares.Count(j => j.Article == i.Article) == 0)).ToList();
如果我严格使用 PrimaryDbContext,例如“PrimaryDbContext db = new PrimaryDbContext();”一切正常。但如果我隐式使用它“IDbContext db = new PrimaryDbContext();”我得到一个例外:
无法创建类型的常量值 “ConfiguratorMvcApplication.DomainModels.ProviderHardware”。仅有的 支持基本类型(“例如 Int32、String 和 Guid”) 在此背景下。
总结一下,我无法替换 IQueryable 上的 DbSet。在这种情况下我如何使用单元测试?我希望有人已经解决了这个问题...... 预先非常感谢!
i stumbled to the next problem... I have database context:
// 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; } }
...
}
And i try get all hardwares, which doesnt exists in ProviderHardwares table:
var hardwaresRemoved = db.Hardwares.Where(i => (i.IsAvailable == true) &&
(db.ProviderHardwares.Count(j => j.Article == i.Article) == 0)).ToList();
If i use PrimaryDbContext strictly such as "PrimaryDbContext db = new PrimaryDbContext();" all work fine. But if i use it implicitly "IDbContext db = new PrimaryDbContext();" that i get an exception:
Unable to create a constant value of type
'ConfiguratorMvcApplication.DomainModels.ProviderHardware'. Only
primitive types ('such as Int32, String, and Guid') are supported in
this context.
Summarize, i can't replace a DbSet on an IQueryable. And how i can use unit testing in this case? I hope someone have resolved this problem yet...
Thank in advance very much!
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(2)
我最终为每个 DbSet 提供了两个属性:一个是 IQueryable 类型,另一个是 DbSet 类型。 IQueryable 属性在接口中定义,它将调用中继到具体实现(DbSet 类型的属性),如下所示:
有了这个设置,我就能够让模拟正常工作,并且可以对代码进行单元测试。
这对于OP来说绝对太晚了,但这也许可以帮助那些像我一样遇到同样问题的人。
I ended up having two properties for each DbSet: one of type IQueryable, and one of type DbSet. The IQueryable property is defined in the interface, and it relays the calls to the concrete implementation (property of type DbSet), as follows:
Having this setup, I was able to get mocking to work correctly and could unit test the code.
This is definitely too late for the OP, but maybe this helps someone who is struggling with the same question, as I did.
我建议您最好保留 DbSets 并进行集成测试包括数据库。
因为,尽管使用数据库模拟通过单元测试可能有点用,但使用真实数据库进行测试会更好(但这不是单元测试)。
在 ClassInitialize 上擦除数据库和/或创建用于测试的初始数据。
如果您使用连接字符串创建 App.config 文件,则可以拥有一个单独的测试数据库,如果您使用 EF Code First,则可以免费获得它。
此致。
I suggest you better keep DbSets and do INTEGRATION TESTING including the database.
Because, although passing a unit test with a mock of a DB could be somewhat usefull, you are going to be better off testing with real database (but it's not unit testing).
On the ClassInitialize erase the database and/or create the initial data for testing.
If you create an App.config file with a connection string you can have a separate test database, and if you are using EF Code First, you get it for free.
Best regards.