none
LINQ: Einfügen von BinaryExpressions in LambdaExpressions RRS feed

  • Frage

  • Liebe Foristen,
    für Datenbankabfragen via EntityFramework würde ich gern die Where-Bedingung dynamisch generieren:

    t =>
    	t.Levels.Any(l =>
    		l.LevelDetails.Any(
    			ld.LevelDate > DbFunctions.AddDays(t.TestDate, 1)
    		)
    	)
    

    Beispielsweise zur dynamischen Erzeugung der vorstehenden Bedingung (= predicate) würde ich gern etwas in der folgenden Art tun:

    Expression<Func<LevelDetail, DateTime?>> left = 
    	ld => ld.LevelDate;
    Expression<Func<Test, DateTime?>> right = 
    	t => DbFunctions.AddDays(t.TestDate, 1);
    
    BinaryExpression expr = 
    	Expression.GreaterThan(
    		((LambdaExpression)left).Body,
    		((LambdaExpression)right).Body
    	);
    Expression<Func<Test, bool>> predicate = 
    	t =>
    		t.Levels.Any(l =>
    			l.LevelDetails.Any( expr )
    		);
    
    class Test
    {
    	public DateTime TestDate { get; set; }
    	public virtual ICollection<Level> Levels { get; set; }
    }
    class Level
    {
    	public virtual ICollection<LevelDetail> LevelDetails { get; set; }
    }
    class LevelDetail
    {
    	public DateTime LevelDate { get; set; }
    }

    Ist dies möglich?

    Donnerstag, 17. August 2017 15:22

Alle Antworten

  • Hallo,
    schau mal ob Dir das hier reicht:
    https://docs.microsoft.com/en-us/dotnet/csharp/programming-guide/concepts/expression-trees/how-to-use-expression-trees-to-build-dynamic-queries

    Grüße Alexander

    Donnerstag, 17. August 2017 15:27
  • Danke für das Feedback. Das prinzipielle Erstellen der Predicates funktioniert. Hierfür nutze ich einen Workaround, der LinqKit und PredicateBuilder nutzt.

    Das hier dargestelltes Problem liegt darin, dass eine BinaryExpression erzeugen werden soll, bei der Left und Right unterschiedliche ExpressionParameter nutzen, nämlich in diesem Fall vom Typ LevelDetail ( = ld) und vom Typ Test ( = t). Dies gelingt nur, wenn der Methode Expression.GreaterThan() statt der jeweiligen LambdaExpressions  nur jeweils deren Bodies übergeben werden. Die Frage für mich ist daher, ob und wenn ja, wie es möglich ist, die so erzeugte BinaryExpression (= expr) in die LambdaExpression des Predicates einzufügen: ... l.LevelDetails.Any( expr )


    • Bearbeitet MinimalPark Donnerstag, 17. August 2017 17:06
    Donnerstag, 17. August 2017 16:56