Из пользовательского интерфейса динамический столбец приходит в качестве параметра в API и на основе параметра, который я должен получить данные из базы данных.Пример: в приведенном ниже коде, на основе столбца, если выполняется условие linq запроса.Теперь я хочу сделать его универсальным, чтобы он служил, если в будущем появятся новые условия столбца.
public List<string> GetFilteredTypeAhead(string searchText,string searchForRole,int fiscalyear,int fiscalPeriod)
{
if (searchForRole == "column1")
{
var accounts = (from a in _context.Account
where a.column1.StartsWith(searchText) && a.FiscalPeriod == fiscalPeriod && a.FiscalYear ==fiscalyear
group a.column1 by a.column2 into g
select g.Key).ToList();
return accounts;
}
else if(searchForRole == "column2")
{
var accounts = (from a in _context.Account
where a.column2.StartsWith(searchText) && a.FiscalPeriod == fiscalPeriod && a.FiscalYear == fiscalyear
group a.column2 by a.column2 into g
select g.Key).ToList();
return accounts;
}
else if (searchForRole == "column3")
{
var accounts = (from a in _context.Account
where a.column3.StartsWith(searchText) && a.FiscalPeriod == fiscalPeriod && a.FiscalYear == fiscalyear
group a.column3 by a.column3 into g
select g.Key).ToList();
return accounts;
}
else if (searchForRole == "column4")
{
var accounts = (from a in _context.Account
where a.column4.StartsWith(searchText) && a.FiscalPeriod.Equals(fiscalPeriod) && a.FiscalYear.Equals(fiscalyear)
group a.column4 by a.column4 into g
select g.Key).ToList();
return accounts;
}
else
{
return new List<string>();
}
}
Чтобы преобразовать его в универсальный.Я создал дерево выражений.
static IQueryable<T> ConvertToExpression<T>(IQueryable<T> query, string propertyValue, PropertyInfo propertyInfo, int fiscalyear, int fiscalPeriod)
{
ParameterExpression e = Expression.Parameter(typeof(T), "e");
MemberExpression m = Expression.MakeMemberAccess(e, propertyInfo);
ConstantExpression c = Expression.Constant(propertyValue, typeof(string));
MethodInfo mi = typeof(string).GetMethod("StartsWith", new Type[] { typeof(string) });
Expression call = Expression.Call(m, mi, c);
PropertyInfo propertyInfoFiscalPeriod = typeof(T).GetProperty("FiscalPeriod");
MemberExpression memberPropertyFiscalPeriod = Expression.Property(e, propertyInfoFiscalPeriod);
ConstantExpression right = Expression.Constant(fiscalPeriod);
Expression equalsFiscalPeriod = Expression.Equal(memberPropertyFiscalPeriod, Expression.Convert(right, typeof(Int16)));
PropertyInfo propertyInfoFiscalYear = typeof(T).GetProperty("FiscalYear");
MemberExpression memberPropertyFiscalYear = Expression.Property(e, propertyInfoFiscalYear);
right = Expression.Constant(fiscalyear);
Expression equalsFiscalYear = Expression.Equal(memberPropertyFiscalYear, Expression.Convert(right, typeof(Int16)));
Expression combineExpression = Expression.And(equalsFiscalPeriod, equalsFiscalYear);
Expression predicateBody = Expression.And(call, combineExpression);
Expression<Func<T, bool>> lambda = Expression.Lambda<Func<T, bool>>(predicateBody, e);
return query.Where(lambda);
}
И для его вызова я использовал код, подобный приведенному ниже, «searchForRole» в качестве параметра указывается как «column1», «column2» и т. Д.
PropertyInfo propertyInfo = typeof(Account).GetProperty(searchForRole);
IQueryable<Account> query = _context.Account;
query = ConvertToExpression(query, searchText, propertyInfo,fiscalyear,fiscalPeriod);
var list = query.ToList();
Теперьэто работает нормально, но результат с дублирующимися записями.Я хотел иметь несколько отдельных или группировать по переданному столбцу параметров.Простыми словами я хотел удалить условие if и сделать мой метод поиска универсальным.Пожалуйста, помогите.