我的用户应该能够配置过滤器以从数据库中获取结果。 我决定使用表达式树,以便灵活处理查询。但是我的表达式树存在问题,无法通过ReferenceCode进行过滤。
持续时间(TimeSpan)
DutDbId(Guid / FK)
TimeStamp(DateTime)
DUT(DeviceUnderTest)
AdminId(字符串/唯一)
DbId(Guid / PK)
ReferenceCode(string)
StartUps(List)
以下是等效linq中过滤器的一部分。但linq我无法使用,因为我不知道用户将定义多少个ReferenceCodes。:
//-------------------reference code filter---------------------------
var query = context.PumpStartUps.Where((p => p.DUT.ReferenceCode == "HKR566" ||
p.DUT.ReferenceCode == "HSH967" ||
.
.
.));
startUps = query.ToList();
对于过滤器的DeviceUnderTest部分进行过滤,我的解决方案是:
// --------------------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过滤:
答案 0 :(得分:1)
使用此:
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);
答案 1 :(得分:0)
如果您的代码数量有限,您可以随时说
var query = context.PumpStartUps.Where(p => codes.Contains(p.DUT.ReferenceCode))
直到大约2000个参数才能工作。如果你需要更多,那么你应该以某种方式将代码发送到临时表(或者更确切地说是返回表的函数,因为ef不支持临时表),并且因为构造超过2000次的表达式而不是会表现得很好。