我有以下方法:
protected override List<Contractor> GetSearchResults()
{
List<User> users = UnitOfWork.UserRepository.Get(
user =>
(!String.IsNullOrEmpty(FirstName) && user.FirstName.Contains(FirstName)) &&
(!String.IsNullOrEmpty(LastName) && user.LastName.Contains(LastName)))
.ToList();
return users ;
}
这只是一个&#34;简化&#34;例。实际上我还有一些&#34;列&#34;为了我的条件。
两个&#34;条件&#34;与and-operator(&amp;&amp;)链接。这意味着:
这不是我想要的。使用or-operator(||)更改代码,如
protected override List<Contractor> GetSearchResults()
{
List<User> users = UnitOfWork.UserRepository.Get(
user =>
(!String.IsNullOrEmpty(FirstName) && user.FirstName.Contains(FirstName)) ||
(!String.IsNullOrEmpty(LastName) && user.LastName.Contains(LastName)))
.ToList();
return users ;
}
没有提供所需的解决方案,因为:
那么,我想要什么?
例如,如果我必须跟踪数据库中的记录:
我期待以下结果:
我的条件不符合这些要求,我不知道如何&#34;简单地&#34;改变它们。
这会更合适吗?
protected override List<Contractor> GetSearchResults()
{
List<User> users = UnitOfWork.UserRepository.Get(
user =>
(String.IsNullOrEmpty(FirstName) || (!String.IsNullOrEmpty(FirstName) && user.FirstName.Contains(FirstName))) &&
(String.IsNullOrEmpty(LastName) || (!String.IsNullOrEmpty(LastName) && user.LastName.Contains(LastName))))
.ToList();
return users ;
}
这似乎有效。但随着越来越多的专栏,它肯定看起来很难看,很难阅读。有没有办法简化这项任务?
答案 0 :(得分:0)
我想你可以将最后一段代码简化为:
List<User> users = UnitOfWork.UserRepository.Get(
user =>
( String.IsNullOrEmpty( FirstName ) || user.FirstName.Contains( FirstName ) ) &&
( String.IsNullOrEmpty( LastName ) || user.LastName.Contains( LastName ) )
).ToList();
答案 1 :(得分:0)
首先,您可以创建一个辅助函数来从主代码中获取条件
public bool FilterColumn(string columnData, string filterData)
{
return String.IsNullOrEmpty(filterData) || columnData.Contains(filterData);
}
然后可以像这样使用
List<User> users = UnitOfWork.UserRepository.Get(
user => FilterColumn(user.FirstName, FirstName) &&
FilterColumn(user.LastName, LastName)).ToList()
假设此代码受到用户输入的限制,您还可以使用反射来帮助一点(假设过滤器在类中是本地的,如示例中所示)
private bool FilterColumn(User user, string columnName)
{
var filterValue = (string) GetType ().GetProperty (columnName).GetValue (this);
var userValue = (string) GetType ().GetProperty (columnName).GetValue (user);
return string.IsNullOrWhiteSpace (userValue) || userValue.Contains (filterValue);
}
然后你可以创建一个聚合函数来收集列
public bool FilterByColumnNames(User user, params string[] columns)
{
return columns.Aggregate (true, (result, columnValue) => FilterColumn (user, columnValue));
}
此方法可以按如下方式使用
var result = FilterByColumnNames(User user, "FirstName", "LastName");
现在,这不是非常重构,所以我们将使用表达式构建一些更多的辅助函数
public String ToColumnName(Expression<Func<User,string>> column)
{
return ((MemberExpression)column.Body).Member.Name;
}
public bool FilterByColumns(User user, params Expression<Func<User,string>>[] columns)
{
return FilterByColumnNames (user, columns.Select (ToColumnName).ToArray());
}
然后可以像这样使用
var x = FilterByColumns (User,
u => u.FirstName,
u => u.LastName);
现在,这是一个未经优化的版本,如果性能问题,您可以深入研究表达式以创建查找的优化版本,但对于大多数绑定到用户类型的事情,这应该足够快。 / p>