c# - 是否可以测试给定表达式是否可以转换为 SQL *而无需*连接到 SQL 数据库?

标签 c# entity-framework

例如:-

// 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/

相关文章:

c# - HTMLAgilityPack QuerySelectorAll 抛出异常,可能 Fizzler dll 版本不匹配?

c# - Expression.Reduce() 是做什么的?

c# - 如何在 Datalist 中使用 HiddenField 获取动态 id

c# - 按字符串给定的类型获取对象列表

c# - 如何对具有不同架构的数据库执行 LINQ 查询?

c# - 从 xml 获取属性

c# - 更改 dataGridView CellFormatting 中单元格的文本

entity-framework - EF 代码首先从数据库 0..1 到许多关系

c# - Entity Framework 脚本生成

c# - 未使用 EF 代码优先方法映射表