Таким образом, значение attribute
определяет, какое свойство вы хотите выбрать. По-видимому, все эти свойства являются строковыми свойствами.
При значении operatorValue
вы хотите выбрать действие с выбранным строковым свойством: равно, неравно, содержит и т. Д. c.
Мне кажется, что у вас есть enum OperatorValue, что-то вроде этого:
enum OperatorValue
{
Equals,
NotEquals,
StartsWith,
Contains,
}
Я напишу методы расширения, аналогичные уже существующим Queryable.Where . См. методы расширения, демистифицированные
Преобразование строки queryOperator
в OperatorValue
:
public static OperatorValue ToOperatorValue(this string queryOperator)
{
// TODO: exception if input null
return Enum.Parse(typeof(OperatorValue), queryOperator);
// TODO: decide what to do if queryOperator has not existing enum value
}
Использование:
string queryOperatorTxt = ...
OperatorValue operator = queryOperatorTxt.ToOperatorValue();
Конечно, мы также нужен метод для преобразования строкового атрибута в propertySelector:
public static Expression<Func<Person, string>> ToPropertySelector(this string attributeTxt)
{
// TODO: check incorrect parameters
Expression<Func<Person, string>> propertySelector;
switch (attributeTxt)
{
case "LastName":
propertySelector = (person) => person.PrimaryName;
break;
case "FirstName":
propertySelector = (person) => person.SecondaryName;
break;
... etc
default:
// TODO: decide what to do with unknown attributeTxt
}
}
использование:
string attributeTxt = ...
Expression<Func<Person, string>> propertySelector = attributeTxt.ToPropertySelector();
Теперь, когда мы знаем, как преобразовать queryOperator и атрибут, мы можем создать расширение для the Where:
public static IQueryable<Person> Where(
this IQueryable<Person> source,
Expression<Func<Person, string>> propertySelector,
OperatorValue operator,
string value)
{
// TODO: exceptions if incorrect parameters
switch (operator)
{
case OperatorValue.Equals:
return source.Where(item => propertySelector(item) == value);
case OperatorValue.NotEquals:
return source.Where(item => propertySelector(item) != value);
case OperatorValue.StartsWith:
return source.Where(item => propertySelector(item).StartsWith(value);
case OperatorValue.Contains:
return source.Where(item => propertySelector(item).Contains(value);
default:
// TODO
}
}
Соберите все вместе:
IQueryable<Person> dataSet = db.Persons;
string attributeTxt = ...
string queryOperatorTxt = ...
string value = ...
Expression<Func<Person, string>> propertySelector = attributeTxt.ToPropertySelector();
OperatorValue operation = queryOperatorTxt.ToOperatorValue();
IQueryable<Person> queryPersons = dataSet.Where(propertySelector, operation);
Ну, разве это не похоже на аккуратный оператор LINQ!