我正在使用PredicateBuilder来构建可重用表达式作为对象的返回值。例如:
public interface ISurveyEligibilityCriteria
{
Expression<Func<Client, bool>> GetEligibilityExpression();
}
我想要进行自动化测试,以确定某个特定表达式是否可以通过实体框架转换为T-SQL(即它在执行&#34;时不会抛出NotSupportedException
。 。我无法在互联网上找到任何东西 - 这是否可能(似乎应该如此)?
答案 0 :(得分:2)
您可以创建一个包含表达式的LINQ语句,然后检查它是否可以在不实际执行的情况下进行翻译:
var connString = @"server=x;database=x";
using(var db = new MyContext(connString))
{
// ToString() shows the generated SQL string.
var sql = db.Entities.Where(generatedExpression).ToString();
Assert.IsTrue(sql.StartsWith("SELECT");
}
在Assert
中,您可以测试您希望成为生成的SQL字符串一部分的任何内容,但当然如果表达式无法翻译,则测试将失败,因为例如抛出NotSupportedException
。
您可以将其包装成一个方便的扩展方法:
public static class EntityFrameworkExtensions
{
public static void CompilePredicate<T>(this DbContext context, Expression<Func<T, bool>> predicate)
where T : class
{
context.Set<T>().Where(predicate).ToString();
}
}
然后在你的测试中:
// act
Action act = () => context.CompilePredicate(predicate);
// assert
act.ShouldNotThrow();
答案 1 :(得分:1)
一个非常简单的解决方案是执行它:
using (var context = ...)
{
// The query will return null, but will be executed.
context.Clients.Where(GetEligibilityExpression())
.Where(() => false)
.SingleOrDefault();
}
在旧版本的EF(或使用ObjectContext
)中,您可以尝试&#34;手动&#34;使用CompiledQuery.Compile
编译查询,但DbContext
不支持。