有人员和搜索对象的列表。搜索对象是对主列表进行搜索。
public class Person
{
public string FirstName { get; set; }
public string LastName { get; set; }
public DateTime DOB { get; set; }
public int Zip { get; set; }
public string OtherDetails { get; set; }
}
public class SearchParam
{
public string FirstName { get; set; }
public string LastName { get; set; }
public DateTime? DOB { get; set; }
}
我正在使用SearchParam
对象在List<Person>
上进行搜索。
我的搜索功能如下:
List<Person> GetResult(SearchParam search, List<Person> persons)
{
if (search == null && persons == null)
{
if (!string.IsNullOrWhiteSpace(search.FirstName)
&& string.IsNullOrWhiteSpace(search.LastName)
&& !search.DOB.HasValue
)
{
return persons.Where(p => p.FirstName.ToUpper().StartsWith(search.FirstName.ToUpper())).ToList();
}
if (string.IsNullOrWhiteSpace(search.FirstName)
&& !string.IsNullOrWhiteSpace(search.LastName)
&& !search.DOB.HasValue
)
{
return persons.Where(p => p.LastName.ToUpper().StartsWith(search.LastName.ToUpper())).ToList();
}
if (string.IsNullOrWhiteSpace(search.FirstName)
&& string.IsNullOrWhiteSpace(search.LastName)
&& search.DOB.HasValue
)
{
return persons.Where(p => p.DOB.Equals(search.DOB)).ToList();
}
if (!string.IsNullOrWhiteSpace(search.FirstName)
&& !string.IsNullOrWhiteSpace(search.LastName)
&& !search.DOB.HasValue
)
{
return persons.Where(p => p.FirstName.ToUpper().StartsWith(search.FirstName.ToUpper())
&& p.LastName.ToUpper().StartsWith(search.LastName.ToUpper())).ToList();
}
if (!string.IsNullOrWhiteSpace(search.FirstName)
&& !string.IsNullOrWhiteSpace(search.LastName)
&& search.DOB.HasValue
)
{
return persons.Where(p => p.FirstName.ToUpper().StartsWith(search.FirstName.ToUpper())
&& p.LastName.ToUpper().StartsWith(search.LastName.ToUpper())
&& p.DOB.Equals(search.DOB)).ToList();
}
return persons;
}
else
{
return persons;
}
}
此代码“ GetResult”正在工作,但对此我不满意。 我应该如何处理列表和搜索对象中的空值,并尽量减少此方法中的代码行?
答案 0 :(得分:2)
使用Linqs流水线
var workingList = persons;
if(searchParam.FirstName != null)
workingList = workingList.Where(p=>p.FirstName.Startswith(searchParam.FirstName));
if(searchParam.LastName != null)
workingList = workingList.Where(p=>p.LAstName.StartsWith(searchParam.LastName));
etc.
最后
return workingList.ToList();
即一次组装一个过滤器,然后最后进行枚举
答案 1 :(得分:1)
我建议使用少于return
的方法。
这是我的尝试:
/// <summary>
/// Returns a filtered list of persons
/// </summary>
/// <param name="search">Filters. Only filters that are set (not null or empty) are applied</param>
/// <param name="persons">List to filter</param>
/// <returns>Filtered list or a new list of all persons if no filters provided</returns>
/// <exception cref="ArgumentNullException"> Thrown if 'search' or 'persons' is null </exception>
static List<Person> Filter(SearchParam search, IEnumerable<Person> persons)
{
if( search == null ) throw new ArgumentNullException(nameof(search));
if (persons == null) throw new ArgumentNullException(nameof(persons));
IEnumerable<Person> filtered = persons;
if( !string.IsNullOrEmpty(search.FirstName))
{
filtered = filtered.Where( p => string.Compare( p.FirstName, search.FirstName, StringComparison.CurrentCultureIgnoreCase ) == 0);
}
if (!string.IsNullOrEmpty(search.LastName))
{
filtered = filtered.Where(p => string.Compare(p.LastName, search.LastName, StringComparison.CurrentCultureIgnoreCase) == 0);
}
if (search.DOB.HasValue)
{
//This filter should probably allow searching only by year, etc.
filtered = filtered.Where(p =>p.DOB == search.DOB);
}
return filtered.ToList();
}
和示例
List<Person> l = new List<Person>();
l.Add(new Person
{
FirstName = "Prashant",
DOB = new DateTime(1990, 01, 02)
});
l.Add(new Person
{
FirstName = "TymTam",
LastName = "No Choc",
DOB = new DateTime(1977, 01, 02)
});
l.Add(new Person
{
FirstName = "Melissa",
LastName = "No Choc",
DOB = new DateTime(1977, 01, 02)
});
var filter = new SearchParam()
{
LastName = "No CHOC",
DOB = new DateTime(1977, 01, 02)
};
var filtered = Filter(filter, l);
foreach( var f in filtered)
{
Console.WriteLine($"{f.FirstName} {f.LastName} ({f.DOB})");
}
结果:
TymTam No Choc (2/01/1977 00:00:00)
Melissa No Choc (2/01/1977 00:00:00)
别忘了单元测试!
答案 2 :(得分:0)
您可以使用以下代码最小化if-else
子句和嵌套块:
public static List<Person> GetResult(SearchParam search, List<Person> persons)
{
if (search == null || persons == null)
{
return persons;
}
var ignoreCase = StringComparison.CurrentCultureIgnoreCase;
var firstNamePrefix = string.IsNullOrWhiteSpace(search.FirstName) ? "" : search.FirstName;
var lastNamePrefix = string.IsNullOrWhiteSpace(search.LastName) ? "" : search.LastName;
return persons.Where(p => p.FirstName.StartsWith(firstNamePrefix, ignoreCase))
.Where(p => p.LastName.StartsWith(lastNamePrefix, ignoreCase))
.Where(p => p.DOB.Equals(search.DOB ?? p.DOB))
.ToList();
}
P.S。我冒昧地将您的第一个条件取反,即检查参数是否为null。