如何使用表达式树进行内部连接(过滤嵌套属性)?

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

我的用户应该能够配置过滤器以从数据库中获取结果。 我决定使用表达式树,以便灵活地处理查询。但是我对通过 ReferenceCode 过滤的表达式树有问题。

实体:

泵启动

待测设备

这是等效 linq 中过滤器的一部分。但是linq我不能用,因为我不知道用户会定义多少ReferenceCodes。:

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

对于通过DeviceUnderTest部分filter进行过滤,我的解决方案是:

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

如何以这种方式按 ReferenceCode 进行过滤:

使用这个:

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

如果代码量有限,可以随时说

var query = context.PumpStartUps.Where(p => codes.Contains(p.DUT.ReferenceCode))

这可以工作到大约 2000 个参数。如果您需要更多,那么您应该以某种方式将代码发送到临时 table(或者更确切地说是返回 table 的函数,因为 ef 不支持临时 tables),然后加入因为构建一个超过 2000 or 的表达式不会有很好的表现。