支持,我有一个班级:
public class PersonalInfo
{
public string Firsname {get;set;}
public string Lastname {get;set;}
public string Email {get;set;}
public string Phone {get;set;}
}
数据来自档案。 而且,我需要通过此属性从文件中选择数据:
private IList<PersonalInfo> FindByPersonalData(string firstName, string lastName, string email, string phone)
{
...
}
多个属性可以为空,但如果填充,则按其搜索。我可以检查每一个组合,但它很难看。什么是最好的解决方案?
感谢
答案 0 :(得分:5)
典型的子查询是在每个字段上使用短路。对数据结构做一些假设,看起来像这样:
var result = from p in PersonalInfoList
where (string.IsNullOrEmpty(firstName) || firstName == p.FirstName)
&& (string.IsNullOrEmpty(lastName) || lastName == p.LastName)
&& (string.IsNullOrEmpty(email) || email == p.Email)
&& (string.IsNullOrEmpty(phone) || phone == p.Phone)
select p
或者,取决于您的Linq偏好:
var result = PersonalInfoList.Where(p =>
(string.IsNullOrEmpty(firstName) || firstName == p.FirstName)
&& (string.IsNullOrEmpty(lastName) || lastName == p.LastName)
&& (string.IsNullOrEmpty(email) || email == p.Email)
&& (string.IsNullOrEmpty(phone) || phone == p.Phone))
因此,如果任何参数为null / empty,则将跳过与数据的比较。
答案 1 :(得分:1)
您可以更优雅地完成任务,累积过滤器表达式,如下所示:
Expression<Func<PersonalInfo, bool>> filterExperssion = PredicateExtensions.True<PersonalInfo>();
if (!String.IsNullOrEmpty(firstName))
filterExperssion = filterExperssion.And(p => p.FirstName == firstName);
if (!String.IsNullOrEmpty(lastName))
......
你需要这个小类助手来构建谓词
public static class PredicateExtensions
{
public static Expression<Func<T, bool>> True<T>() { return f => true; }
public static Expression<Func<T, bool>> False<T>() { return f => false; }
public static Expression<Func<T, bool>> Or<T>(this Expression<Func<T, bool>> expression1, Expression<Func<T, bool>> expression2)
{
var invokedExpression = Expression.Invoke(expression2, expression1.Parameters.Cast<Expression>());
return Expression.Lambda<Func<T, bool>>
(Expression.Or(expression1.Body, invokedExpression), expression1.Parameters);
}
public static Expression<Func<T, bool>> And<T>(this Expression<Func<T, bool>> expression1,
Expression<Func<T, bool>> expression2)
{
var invokedExpression = Expression.Invoke(expression2, expression1.Parameters.Cast<Expression>());
return Expression.Lambda<Func<T, bool>>
(Expression.And(expression1.Body, invokedExpression), expression1.Parameters);
}
}
答案 2 :(得分:0)
@Dan Puzey的asnwer非常适合这种情况。但很高兴知道你可以逐步构建linq查询:
var result = source_list as IEnumerable<IPersonalInfo>;
if (!String.IsNullOrEmpty(firstName))
result = result.Where(p => p.FirstName == firstName);
if (!String.IsNullOrEmpty(lastName))
result = result.Where(p => p.LastName == lastName);
... other ifs for other fields ...
return result.ToList();