我试图使用动态查询库选择以某些内容开头的字段,但仅限于使用列名和字段作为变量。我尝试过:
var x = myqueriable.Where("" + X1 + " LIKE @0 and " + X2 + "= @1 ", Y1 + "%", Y2);
我有错误:“ system.Linq.Dynamic.ParseException:预期为布尔类型的表达式>
有没有办法实现上述目标?
答案 0 :(得分:1)
var x = myQueryable.Where(y => y.StartsWith(param0));
答案 1 :(得分:0)
您需要构建动态的lambda表达式,例如
p => p.Property.StartsWith("some prefix");
您可以使用内置的Expressions API在没有外部库的情况下执行此操作。请参阅此扩展方法:
public static class QueryableExt
{
public static Expression<Func<T, bool>> BuildLambda<T>(this IQueryable<T> input, string propertyName, string startsWith)
{
var elemenType = input.ElementType;
var property = elemenType.GetProperty(propertyName);
if (property == null)
throw new ArgumentException($"There is no property {propertyName} in {elemenType.Name}");
if (property.PropertyType != typeof(string))
throw new ArgumentException($"Expected string property but actual type is {property.PropertyType.Name}");
var startsWithMethod = typeof(string).GetMethod("StartsWith", new[] { typeof(string) });
var p = Expression.Parameter(elemenType, "p"); // p => ...
var memberExpression = Expression.Property(p, property); // ... p.Propery
var startsWithValue = Expression.Constant(startsWith); // "some prefix"
var startsWithExpression = Expression.Call(memberExpression, startsWithMethod, startsWithValue); // ... p.Property.StartsWith("some prefix")
var result = Expression.Lambda<Func<T, bool>>(startsWithExpression, p); // p => p.Property.StartsWith("some prefix")
return result;
}
}
请注意,BuildLambda
比字符串连接更安全类型:此方法实际上检查propertyName
是否存在并具有有效的类型。现在您可以像使用它
var x = myqueriable.Where(myqueriable.BuildLambda(X, Y))
答案 2 :(得分:0)
使用System.Linq.Dynamic.Core时,您应该可以使用 StartsWith()。
示例代码:
var result = Entity1s.Where("Url.StartsWith(\"x\")");
这被翻译成SQL,例如:
-- Region Parameters
DECLARE @p0 NVarChar(1000) = 'x%'
-- EndRegion
SELECT [t0].[Id], [t0].[Url], [t0].[Rating]
FROM [Entity1] AS [t0]
WHERE [t0].[Url] LIKE @p0