requêtes dynamiques dans dapper

c# dapper linq

Question

J'essaie de travailler avec ça . J'ai écrit un test unitaire pour 10 personnes comme ça:

[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; }
}

Malheureusement, je reçois toujours:

Additional information: 'System.Linq.Expressions.NewExpression' does not contain a definition for 'Value'

dans la méthode WalkTree. Est-ce que j'utilise GetDynamicQuery à tort?

S'il existe d'autres implémentations de mappeurs SQL dynamiques comme ceci pour dapper, j'apprécierais n'importe quels pointeurs. Merci!

Réponse populaire

D'après ce que je vois dans le code source du composant que vous essayez d'utiliser, le bon opérande de l'expression doit être une expression constante (même si pour une raison inconnue, l'auteur utilise la dynamic et attend une propriété Value ). ça marche, modifie ton code comme suit

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);

Mise à jour: Il s'avère que ce qui précède ne fonctionne pas non plus, car il produit bien sûr une fermeture qui n’est pas ConstantExpression . Pour le faire fonctionner (ainsi que votre code d'origine), voici les modifications requises de la classe 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;
}

Mais notez que toute la classe (comme l'auteur écrit) est juste un exemple, et par exemple des cartes un seul paramètre (donc une valeur) par propriété, donc pour le rendre vraiment utile, la GetDynamicQuery méthode a besoin de travail supplémentaire. Vous pourriez essayer celui- ci à la place. J'espère que cela pourra aider.




Sous licence: CC-BY-SA with attribution
Non affilié à Stack Overflow
Est-ce KB légal? Oui, apprenez pourquoi
Sous licence: CC-BY-SA with attribution
Non affilié à Stack Overflow
Est-ce KB légal? Oui, apprenez pourquoi