我有一個SelectionCriteria類用於構建基於PredicateBuilder的實體框架查詢表達式。在其限制內,它工作正常。我想擴展它,以便它可以查詢一個字段是否包含一個子字符串。我的問題是,我看不到如何構建所需的表達式對象。在表達式樹中調用lambda表達式
我的實際課程支持和,或和,但不是,但它們與我的問題無關。所以,我已經簡化我的例子代碼只處理一個單一的二進制運算:
public class SelectionCriteria
{
public SelectionComparison selectionComparison { get; set; }
public string fieldName { get; set; }
public object fieldValue { get; set; }
public Expression<Func<T, bool>> constructSinglePredicate<T>()
{
var type = typeof(T);
if (type.GetProperty(this.fieldName) == null && type.GetField(this.fieldName) == null)
throw new MissingMemberException(type.Name, this.fieldName);
ExpressionType operation;
if (!operationMap.TryGetValue(this.selectionComparison, out operation))
throw new ArgumentOutOfRangeException("selectionComparison", this.selectionComparison, "Invalid filter operation");
var parameter = Expression.Parameter(type);
var member = Expression.PropertyOrField(parameter, this.fieldName);
var value = (this.fieldValue == null) ? Expression.Constant(null) : Expression.Constant(this.fieldValue, this.fieldValue.GetType());
try
{
var converted = (value.Type != member.Type)
? (Expression) Expression.Convert(value, member.Type)
: (Expression) value;
var comparison = Expression.MakeBinary(operation, member, converted);
var lambda = Expression.Lambda<Func<T, bool>>(comparison, parameter);
return lambda;
}
catch (Exception)
{
throw new InvalidOperationException(
String.Format("Cannot convert value \"{0}\" of type \"{1}\" to field \"{2}\" of type \"{3}\"", this.fieldValue,
value.Type, this.fieldName, member.Type));
}
}
private static Dictionary<SelectionComparison, ExpressionType> operationMap =
new Dictionary<SelectionComparison, ExpressionType>
{
{ SelectionComparison.Equal, ExpressionType.Equal },
{ SelectionComparison.GreaterThan, ExpressionType.GreaterThan },
};
}
public enum SelectionComparison
{
Equal,
GreaterThan,
Contains,
};
用法很簡單:
var criteria = new SelectionCriteria
{
selectionComparison = SelectionComparison.GreaterThan,
fieldName = "worktobegindate",
fieldValue = DateTime.Now.AddDays(-2)
};
var predicate = criteria .constructPredicate<job>();
var jobs = myDbContext.jobs.Where(predicate);
所以,我的問題 - 我需要一個方法,像我constructSinglePredictate()以上,返回一個表達式並應用一個.Contains(給定一個字符串來比較它,將Contains()應用到一個字符串是很簡單的,但我很難理解如何在一個表達式中做同樣的事情。
想法?