Initial implementation for nested property selector. Not null safe.

sean-m-patch-1
Sean McArde 2023-11-02 12:52:32 -07:00
parent 54ba5be48a
commit 8c548fcd38
2 changed files with 43 additions and 21 deletions

View File

@ -26,6 +26,7 @@ namespace McRule.Tests {
public int? number { get; set; }
public bool stillWithUs { get; set; }
public string[] tags { get; set; }
public People? relatedTo { get; set; }
public People(string name, string kind, int? number, bool stillWithUs, string[] tags = null)
{
@ -326,6 +327,23 @@ namespace McRule.Tests {
var failedGenerator = new FailedExpressionGeneratorBase();
Assert.Throws<NotImplementedException>(() => { _ = eans.GeneratePredicateExpression<People>(failedGenerator); });
}
[Test]
public void SelectPropertyOfMemberObject() {
var filter = vikings.GetPredicateExpression<People>()?.Compile();
// This should be the two Vikings: Lars then Ragnar, in that order
var folks = peoples.Where(filter).OrderBy(x => x.name);
// We specify that Lars is related to Ragnar
folks.First().relatedTo = folks.Skip(1).First();
var testMembersProperty = ("People", "relatedTo.name", "Ragnar").ToFilterRule().GetPredicateExpression<People>().Compile();
Assert.NotNull(folks);
Assert.True(testMembersProperty(folks.First()));
}
}
internal class FailedExpressionGeneratorBase : ExpressionGeneratorBase

View File

@ -91,7 +91,9 @@ public static partial class PredicateExpressionPolicyExtensions
// Bind to the property by name and make the constant value
// we'll be passing into the Contains() call
var parameter = Expression.Parameter(typeof(T), "x");
var opLeft = Expression.Property(parameter, property);
Expression opLeft = parameter;
foreach (string p in property.Split(".")) opLeft = Expression.PropertyOrField(opLeft, p);
var opRight = Expression.Constant(value);
// Create generic method which is bound with the Call Expression below
@ -281,7 +283,9 @@ public abstract class ExpressionGeneratorBase : ExpressionGenerator
public Expression<Func<T, bool>> GetPredicateExpressionForType<T>(string property, string value)
{
var parameter = Expression.Parameter(typeof(T), "x");
var opLeft = Expression.Property(parameter, property);
Expression opLeft = parameter;
foreach (string p in property.Split(".")) opLeft = Expression.PropertyOrField(opLeft, p);
(bool literalFound, LiteralValue? processedValue) = GetStringValueLiteral(value);
var opRight = Expression.Constant(value);
Expression? comparison = null;