SELECT userID from users WHERE
(name='name1' AND username='username1') OR
(name='name2' AND username='username2') OR
(name='name3' AND username='username3') OR
..........
(name='nameN' AND username='usernameN')
public static IQueryable<TEntity> Where<TEntity>(
this IQueryable<TEntity> source,
IEnumerable<WhereSpecifier> orClauses) where TEntity : class
{
if (!orClauses.Any()) return source.Where(t => false);
Type type = typeof (TEntity);
ParameterExpression parameter = null;
Expression predicate = Expression.Constant(false, typeof (bool));
ParameterExpression whereEnt = Expression.Parameter(type, "WhereEnt");
foreach (WhereSpecifier orClause in orClauses)
{
Expression selector;
if (orClause.Selector != null) {
selector = orClause.Selector;
parameter = orClause.Parameter;
}
else
{
parameter = whereEnt;
Type selectorResultType;
selector = GenerateSelector<TEntity>(parameter, orClause.Column,
out selectorResultType);
}
Expression clause = selector.CallMethod(orClause.Method,
MakeConstant(selector.Type, orClause.Value), orClause.Modifiers);
predicate = Expression.Or(predicate, clause);
}
var lambda = Expression.Lambda(predicate, whereEnt);
var resultExp = Expression.Call(typeof (Queryable), "Where", new[] {type},
source.Expression, Expression.Quote(lambda));
return source.Provider.CreateQuery<TEntity>(resultExp);
}
生成选择器:
public static Expression GenerateSelector<TEntity>(
ParameterExpression parameter, string propertyName,
out Type resultType) where TEntity : class
{
// create the selector part, but support child properties
PropertyInfo property;
Expression propertyAccess;
if (propertyName.Contains('.'))
{
// support to be sorted on child fields.
String[] childProperties = propertyName.Split('.');
property = typeof (TEntity).GetProperty(childProperties[0]);
propertyAccess = Expression.MakeMemberAccess(parameter, property);
for (int i = 1; i < childProperties.Length; i++)
{
property = property.PropertyType.GetProperty(childProperties[i]);
propertyAccess = Expression
.MakeMemberAccess(propertyAccess, property);
}
}
else
{
property = typeof (TEntity).GetProperty(propertyName);
propertyAccess = Expression.MakeMemberAccess(parameter, property);
}
resultType = property.PropertyType;
return propertyAccess;
}
WHereSpecifier:
public class WhereSpecifier
{
public WhereSpecifier(string column, CheckMethod method, string value,
CheckMethodModifiers modifiers)
{
Modifiers = modifiers;
Value = value;
Column = column;
Method = method;
}
public WhereSpecifier(string column, CheckMethod method, string value)
: this(column, method, value, CheckMethodModifiers.None)
{
}
public Expression Selector { get; set; }
public ParameterExpression Parameter { get; set; }
public string Column { get; set; }
public CheckMethod Method { get; set; }
public CheckMethodModifiers Modifiers { get; set; }
public string Value { get; set; }
}
用法:
var column = typeof(TEntity).Name + "ID";
var where = from id in SelectedIds
select new WhereSpecifier(column, CheckMethod.Equal, id.ToString());
return GetTable().Where(where);
7条答案
按热度按时间vwoqyblh1#
你可以使用一个叫做PredicateBuilder的漂亮的东西。
5uzkadbs2#
这位助手可能会帮助你。
以及:
lx0bsm1f3#
注意:这是从我现有的东西修改而来的,所以它可能不能开箱即用。但这将是一个很好的起点。
生成选择器:
WHereSpecifier:
用法:
68de4m5k4#
我尝试了@艾格·帕夫利辛的解决方案,但我得到了
"The LINQ expression node type 'Invoke' is not supported in LINQ to Entities."
。根据this,您可以使用PredicateExtensions:
4smxwvx55#
不要忘记实体框架也理解entity sql,所以你可以在字符串中完成查询的这一部分,当你需要做动态的事情时,构建一个字符串是非常方便的。
dfty9e196#
我必须根据用户界面的选择动态构造“Where”子句的 predicate 。**“System.Dynamic.Linq'**允许从字符串构造 predicate 。
“System.Dynamic.Linq”是一个nuget包,请查看古特里对here主题的介绍。
wmvff8tz7#
我觉得这样太简单了: