我正在嘗試使用 SomeModel 的 IEnumerable 的請求來過濾這種偽結構(field1、field2、field3)的物體的 dbset,其中 SomeModel 包含對(field1、field2)(相同的欄位子集)
我試過了
var ordersList3 = await _dbContext.MyEntities.
AsNoTracking().
Where(a => request.Contains(new SomeModel() { field1 = a.field1, field2 = a.field2})).
ToListAsync();
但它不起作用
您能否建議通過包含欄位子集的模型串列來過濾 dbset 的正確方法?
uj5u.com熱心網友回復:
我不知道這對你來說是否必要,但有時你需要直接寫下運算式。因為這可能很有趣,所以你去吧:
public static Expression<Func<PseudoStructure, bool>> GetPredicate<PseudoStructure>(
IEnumerable<PseudoStructure> request) {
var parameter = Expression.Parameter(typeof(PseudoStructure), "o");
var expression = request.Aggregate(
(Expression)null,
(acc, next) => MakeBinary(
acc,
CompareInstances(parameter, next),
ExpressionType.Or));
return Expression.Lambda<Func<PseudoStructure, bool>>(expression, parameter);
}
此方法生成一個 Expression<Func<PseudoStructure, bool>>,它由檢查實體相等性的運算式組成:
private static Expression CompareInstances<PseudoStructure>(
ParameterExpression parameter,
PseudoStructure constant)
=> typeof(PseudoStructure)
.GetFields()
.Select(fieldInfo => Expression.Equal(
Expression.Constant(fieldInfo.GetValue(constant)),
Expression.Field(parameter, fieldInfo)))
.Aggregate(
(Expression)null,
(expression, binaryExpression) => MakeBinary(expression, binaryExpression, ExpressionType.And)
);
}
}
請注意,相等意味著欄位值相等。MakeBinary 是 Expression.MakeBinary 的簡單包裝器:
private static Expression MakeBinary(Expression left, Expression right, ExpressionType expressionType)
=> left == null || right == null ?
left ?? right
: Expression.MakeBinary(expressionType, left, right);
您可以像這樣使用它:
public struct Foo
{
public int A;
public decimal B;
public decimal C;
}
var values = new List<Foo> {
new Foo {A = 1, B = 2, C = 3},
new Foo {A = 4, B = 5, C = 6},
new Foo {A = 7, B = 8, C = 9},
new Foo {A = 10, B = 11, C = 12}
};
var expression =
GetPredicate(new[] {
new Foo {A = 1, B = 2, C = 3},
new Foo {A = 10, B = 11, C = 12}
});
var result = values.AsQueryable().Where(expression).ToList();
uj5u.com熱心網友回復:
您收到錯誤是因為物體框架無法轉換為 sql 查詢運算式。這是由于 where 子句中的謂詞造成的。正確的實作是:
var ordersList3 = await _dbContext.MyEntities.
AsNoTracking().
Where(a => request.Any(r => r.field1 == a.field1 && r.field2 == a.field2})).
ToListAsync();
轉載請註明出處,本文鏈接:https://www.uj5u.com/qita/380493.html
