Search code examples
c#entity-frameworkinner-joinexpression-trees

How to inner join(filtering for nested properties) with expression tree?


My users should be able to configure a filter to get a result from the database. I decided to use an expression tree, to be flexible with the query. But I have problems with the expression tree for filtering by ReferenceCode.

Entities:

PumpStartUp

  • Duration (TimeSpan)

  • DutDbId (Guid/FK)

  • TimeStamp (DateTime)

  • DUT (DeviceUnderTest)

DeviceUnderTest

  • AdminId (string/unique)

  • DbId (Guid/PK)

  • ReferenceCode (string)

  • StartUps (List)

Here is a part of the filter in equivalent linq. But linq I can't use, because I don't know how many ReferenceCodes will be defined by the user.:

//-------------------reference code filter---------------------------
var query = context.PumpStartUps.Where((p => p.DUT.ReferenceCode == "HKR566" ||
                                             p.DUT.ReferenceCode == "HSH967" ||
                                             .
                                             .
                                             .));
startUps = query.ToList();

For filtering by DeviceUnderTest part of the filter, my solution is:

// --------------------duts filter-----------------------------------
Expression dutsExpression = null;
Expression psuExpression = Expression.Parameter(typeof(PumpStartUp), "psu");
Expression psuDutIdExpression = Expression.Property(psuExpression, "DutDbId");

foreach (var dut in filter.Duts)
{
    DeviceUnderTest deviceUnderTest = context.DevicesUnderTest.Where(d => d.AdminId == dut.Id).Single();
    Expression dutIdExpression = Expression.Constant(deviceUnderTest.DbId);
    Expression dutExpression = Expression.Equal(pumpStartUpDutIdExpression, dutIdExpression);
    if (dutsExpression == null)
    {
        dutsExpression = dutExpression;
    }
    else
    {
        dutsExpression = Expression.Or(dutsExpression, dutExpression);
    }
}

How can I filter by ReferenceCode in that manner:


Solution

  • Use this:

    var dutExpression = Expression.Property(psuExpression, "DUT");
    var referenceCodeExp = = Expression.Property(dutExpression, "ReferenceCode ");
    var constExpr = Expression.Constant("HKR566");
    var eqExp = Expression.Equal(referenceCodeExp , constExpr);
    dutsExpression = Expression.Or(dutsExpression, eqExp);