单元测试、Linq to SQL 和围绕数据上下文进行工作
我一直在研究以下内容,看起来使用编译查询可以获得很大的好处...... http://blogs.msdn.com/ricom/archive/2008/01/14/performance-quiz-13-linq-to-sql-compiled-query-cost-solution.aspx
我的问题是我想对我的查询进行单元测试,但是编译的查询需要一个从 DataContext 派生的类的具体实例(这特别难以模拟)...因此我想出了以下代码,我想知道是否任何人都知道我是否仍然应该获得编译查询的性能优势...
private static readonly Func<IDatabase, IActionParameters, ISportProgramMapper, IQueryable<ISportProgram>> _GetQueryUnCompiled =
(db, parameters, mapper) => from x in db.SportProgramDataSource.ThatHaveActiveSports()
where x.SportProgramId == parameters.Id
select mapper.FromDataToEntity(x);
private static readonly Func<Database, IActionParameters, ISportProgramMapper, IQueryable<ISportProgram>> _GetQuery = CompiledQuery.Compile<Database, int, ISportProgramMapper, IQueryable<ISportProgram>>((db, parameters, mapper) => _GetQueryUnCompiled(db, parameters, mapper));
public IActionResult<ISportProgram> Get(IActionParameters parameters)
{
Check.Argument("parameters").ThatValue(parameters).IsNotNull();
IDatabase db = this.CreateDatabase();
ISportProgramMapper mapper = this.CreateMapper<ISportProgramMapper>();
Database typedDb = db as Database;
var result = typedDb != null ? _GetQuery(typedDb, parameters, mapper).FirstOrDefault() : _GetQueryUnCompiled(db, parameters, mapper).FirstOrDefault();
return this.CreateActionResult(result);
}
请注意,在单元测试场景中,我的数据库不会是数据库类型,这意味着它将调用未编译的版本,在生产场景中它将是数据库类型并且将运行编译后的版本。
干杯 安东尼
更新: 好吧,即使我重构代码,以便我当前位于 DAL 中的方法使用返回 IQueryable 的存储库,基本问题仍然存在,使用编译查询的存储库版本将包装包含原始查询的版本,以与我现在正在做的类似的方式...使用 _GetQuery 调用 _GetQueryUnCompiled 的模式我仍然可以获得性能优势吗?
I have been looking at the following and it would appear that there are great benefits to be gained by using compiled queries...
http://blogs.msdn.com/ricom/archive/2008/01/14/performance-quiz-13-linq-to-sql-compiled-query-cost-solution.aspx
My problem is that I want to unit test my queries, but compiled queries need a concrete instance of a class that derives from DataContext (which is particularly difficult to mock out)... Thus I have come up with the following code and I was wondering if any knows whether I should still get the performance benefits of compiled queries...
private static readonly Func<IDatabase, IActionParameters, ISportProgramMapper, IQueryable<ISportProgram>> _GetQueryUnCompiled =
(db, parameters, mapper) => from x in db.SportProgramDataSource.ThatHaveActiveSports()
where x.SportProgramId == parameters.Id
select mapper.FromDataToEntity(x);
private static readonly Func<Database, IActionParameters, ISportProgramMapper, IQueryable<ISportProgram>> _GetQuery = CompiledQuery.Compile<Database, int, ISportProgramMapper, IQueryable<ISportProgram>>((db, parameters, mapper) => _GetQueryUnCompiled(db, parameters, mapper));
public IActionResult<ISportProgram> Get(IActionParameters parameters)
{
Check.Argument("parameters").ThatValue(parameters).IsNotNull();
IDatabase db = this.CreateDatabase();
ISportProgramMapper mapper = this.CreateMapper<ISportProgramMapper>();
Database typedDb = db as Database;
var result = typedDb != null ? _GetQuery(typedDb, parameters, mapper).FirstOrDefault() : _GetQueryUnCompiled(db, parameters, mapper).FirstOrDefault();
return this.CreateActionResult(result);
}
Note in a unit test scenario my db wont be of type Database which means it will call the uncompiled version, in a prod scenario it will be of type Database and will run the compiled version.
Cheers
Anthony
Update:
Ok even if I do refactor the code so that my method which is currently in the DAL uses a repository that returns an IQueryable the underlying question still remain, the version of the repository that uses the compiled queries would wrap a version that contains the raw query, in a similar fashion to what I am doing at the moment... with the pattern of having the _GetQuery call _GetQueryUnCompiled do I still get a performance benefit??
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(1)
只是想一想,您可以重构为仅通过分层来使用
IEnumerable
吗?这样您就可以将数据库代码与查询分开测试吗?Just a thought, can you refactor to use
IEnumerable<>
only by layering? This way you can test you DB code separately from your queries?