dapper中的动态查询

时间:2015-11-02 18:19:55

标签: c# linq dapper

我正在尝试使用this。我已经写了一个单元测试作为10的启动器,如此:

[Fact]
public void TestOredGuids()
{
    // Arrange
    const string expectedSql = "SELECT * FROM Products WHERE SomeExternalForeignKey = @SomeExternalForeignKey OR Name = SomeExternalForeignKey = @SomeExternalForeignKey";

    // Act
    var result = DynamicQuery.GetDynamicQuery<Product>("Products", p => p.SomeExternalForeignKey == new Guid("28D3BCFB-9472-4141-BD88-BE5E7E1230F0") || p.SomeExternalForeignKey == new Guid("0F0DBA45-F842-4E46-9ED4-F50B5BCF0509"));

    // Assert

}

internal class Product
{
    public string Name { get; set; }
    public decimal Price { get; set; }
    public DateTime ExpiryDate { get; set; }
    public int CategoryId { get; set; }
    public Guid SomeExternalForeignKey { get; set; }
}

不幸的是,我总是得到:

Additional information: 'System.Linq.Expressions.NewExpression' does not contain a definition for 'Value'
在WalkTree方法中

。我错误地使用了GetDynamicQuery吗?

如果对于dapper有任何其他动态sql映射器的实现,我会很感激任何指针。谢谢!

1 个答案:

答案 0 :(得分:1)

从我在您尝试使用的组件的源代码中看到的内容,它期望表达式的右操作数为ConstantExpression(尽管由于某些未知原因,作者正在使用{{1}并期望一个dynamic属性,所以为了使它工作,修改你的代码如下

Value

更新:事实证明上述情况也不起作用,因为它产生的闭包不是var someExternalForeignKey1 = new Guid("28D3BCFB-9472-4141-BD88-BE5E7E1230F0"); var someExternalForeignKey2 = new Guid("0F0DBA45-F842-4E46-9ED4-F50B5BCF0509"); var result = DynamicQuery.GetDynamicQuery<Product>("Products", p => p.SomeExternalForeignKey == someExternalForeignKey1 || p.SomeExternalForeignKey == someExternalForeignKey2); 。为了使其工作(以及您的原始代码),以下是ConstantExpression类的必要修改

DynamicQuery

但请注意,整个类(如作者所述)只是一个示例,例如,每个属性只映射一个参数(因此一个值),所以为了使它真正有用,private static void WalkTree(BinaryExpression body, ExpressionType linkingType, ref List<QueryParameter> queryProperties) { if (body.NodeType != ExpressionType.AndAlso && body.NodeType != ExpressionType.OrElse) { string propertyName = GetPropertyName(body); var propertyValue = GetPropertyValue(body.Right); string opr = GetOperator(body.NodeType); string link = GetOperator(linkingType); queryProperties.Add(new QueryParameter(link, propertyName, propertyValue, opr)); } else { WalkTree((BinaryExpression)body.Left, body.NodeType, ref queryProperties); WalkTree((BinaryExpression)body.Right, body.NodeType, ref queryProperties); } } private static object GetPropertyValue(Expression source) { var constantExpression = source as ConstantExpression; if (constantExpression != null) return constantExpression.Value; var evalExpr = Expression.Lambda<Func<object>>(Expression.Convert(source, typeof(object))); var evalFunc = evalExpr.Compile(); var value = evalFunc(); return value; } 方法需要额外的工作。您可以尝试this一个。希望有所帮助。