Ham*_*d F 8 c# expression-trees sql-like
例如:x => x.Name ="g"
我有这样的代码块
public Expression<Func<TEntity, bool>> SearchExpression()
{
var c = new ConstantExpression[_paramList.Count];
var b = new BinaryExpression[_paramList.Count];
BinaryExpression comparisonExpression = null;
var entity = Expression.Parameter(typeof(TEntity));
for (int i = 0; i < _paramList.Count; i++)
{
var value = Convert.ChangeType(_paramList[i].Item2 /*"g"*/, _paramList[i].Item3 /*System.String*/);
c[i] = Expression.Constant(value); //"g"
// PROBLEM IS HERE
b[i] = Expression.Equal(Expression.Property(entity, _paramList[i].Item1 /*Name*/, c[i]);
// PROBLEM IS HERE
}
_paramList.Clear();
comparisonExpression = b.Aggregate(Expression.And);
return Expression.Lambda<Func<TEntity, bool>>(comparisonExpression, entity);
}
Run Code Online (Sandbox Code Playgroud)
像魅力一样工作,但我需要Expression.Like (喜欢"g"不等于"g")
Expression.Like(Expression.Property(entity, _paramList[i].Item1), c[i])
Run Code Online (Sandbox Code Playgroud)
但是C#表达式树不支持Like方法
更新:
我写了这样的东西:
Expression.Call(Expression.Property(entity, _paramList[i].Item1),
typeof(String).GetMethod("Contains"), new Expression[] { c[i] });
Run Code Online (Sandbox Code Playgroud)
但我需要BinaryExpression而不是MethodCallExpression
您可以通过在方法调用上添加一个 equals 表达式来使您的代码工作,如下所示:
b[i] = Expression.Equal(
Expression.Call(Expression.Property(entity, _paramList[i].Item1),
typeof (String).GetMethod("Contains"),
new Expression[] {c[i]}), Expression.Constant(true));
Run Code Online (Sandbox Code Playgroud)
在伪代码中,这读作:
b[i] = entity => entity.someProperty.Contains(c[i]) == true;
Run Code Online (Sandbox Code Playgroud)
这将为您返回一个二进制表达式。
这个答案没有考虑您的数组和“and”聚合,但这应该被视为一个单独的问题。
考虑这个类:
class MyEntity { string Name { get; set; } }
Run Code Online (Sandbox Code Playgroud)
我们要查询的是:
select ... from MyEntity where Name like '%query%';
Run Code Online (Sandbox Code Playgroud)
以下方法是上述查询模式的一般实现:
static Expression<Func<TEntity, bool>> Like<TEntity>(string propertyName, string queryText)
{
var parameter = Expression.Parameter(typeof (TEntity), "entity");
var getter = Expression.Property(parameter, propertyName);
//ToString is not supported in Linq-To-Entities, throw an exception if the property is not a string.
if (getter.Type != typeof (string))
throw new ArgumentException("Property must be a string");
//string.Contains with string parameter.
var stringContainsMethod = typeof (string).GetMethod("Contains", new[] {typeof (string)});
var containsCall = Expression.Call(getter, stringContainsMethod,
Expression.Constant(queryText, typeof (string)));
return Expression.Lambda<Func<TEntity, bool>>(containsCall, parameter);
}
Run Code Online (Sandbox Code Playgroud)
如果您想要query%or的模式,%query可以使用string.StartsWithandstring.EndsWith代替Contains。
此外,如果您调整签名,则可以在多个调用之间共享参数。
如果属性的数据类型不是字符串,当前实现将引发异常。看看这个答案/sf/answers/230494141/将数字转换为字符串。
| 归档时间: |
|
| 查看次数: |
3169 次 |
| 最近记录: |