例如:-
// This one will be converted to SQL no problem
Expression<Func<Foo, bool>> predicate = x => x.Name = "Foo";
// This one will throw a NotSupportedException because the QueryProvider
// doesn't support reference comparisons
Expression<Func<Foo, bool>> predicate = x => x == someOtherFoo;
// This one doesn't work because the query provider can't
// handle IsAwesome()
Expression<Func<Foo, bool>> predicate = x => x.IsAwesome();
我正在寻找一种在运行前测试它的方法,最好是在与数据库隔离的自动化测试中。
我花了一些时间在 MSDN 上搜索,试图找到如何实例化我自己的 QueryProvider,但我的 Google-fu 今天似乎让我失望了。
提前致谢!
最佳答案
您需要一个模型来执行此操作,但不需要数据库。您可以将模型创建为 EDMX,但使用 Code First 可能更容易。为确保创建或使用 Code First 模型不需要数据库连接,您需要提供 Code First 通常从数据库获取的一些信息。本帖http://blog.oneunicorn.com/2012/04/21/code-first-building-blocks/展示了如何使用 DbModelBuilder 来执行此操作以及如何从模型创建 DbContext。你最终会得到这样的代码:
var modelBuilder = new DbModelBuilder();
modelBuilder.Entity<Foo>();
var model = modelBuilder.Build(
new DbProviderInfo("System.Data.SqlClient", "2008")).Compile();
您可能希望缓存模型对象而不是为每个不同的测试重新创建它。
您还应该禁用数据库初始化程序以防止 DbContext 尝试连接到数据库。例如,在使用上下文之前进行如下调用:
Database.SetInitializer<FooContext>(null);
现在您可以在任何查询上使用 ToString 来查看它将生成什么 SQL。如果 LINQ 无法处理表达式,那么您将得到一个异常。例如,这将打印查询:
using (var context = new FooContext(model))
{
Expression<Func<Foo, bool>> predicate = x => x.Name == "Foo";
Console.WriteLine(context.Foos.Where(predicate));
}
这将抛出:
using (var context = new FooContext(model))
{
var someOtherFoo = new Foo();
Expression<Func<Foo, bool>> predicate = x => x == someOtherFoo;
Console.WriteLine(context.Foos.Where(predicate));
}
显然,如果您正在编写测试,您将不仅仅是打印到控制台,而是执行某种断言/检查。
关于c# - 是否可以测试给定表达式是否可以转换为 SQL *而无需*连接到 SQL 数据库?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/13072304/