2012-08-08 66 views
0

Supposse,我有一個類:添加斷言,如果物業充滿

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) 
{ 
... 
} 

幾個屬性可以是空的,但如果他們填補然後通過它們進行搜索。我可以檢查每個組合,但它很醜。什麼是最好的解決方案?
謝謝

+1

linq to objects or linq to sql? – devundef 2012-08-08 10:22:57

+1

@devundef - OP提到數據來自文件。似乎沒有ORM參與。 – Oded 2012-08-08 10:25:08

+0

@devundef - 在這種情況下,我沒有使用ORM。 – user1260827 2012-08-08 10:32:57

回答

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)) 

因此,如果任何參數爲空/空,與比較數據將被跳過。

+0

我在發佈問題之前嘗試了此代碼。這是行不通的,請參閱演示https://compilify.net/3b/107 – user1260827 2012-08-08 11:24:36

+0

爲什麼它不起作用?您鏈接的代碼不會返回記錄,因爲它正在查找'FirstName ==「Test」',但您將'FirstName'設置爲'「Test2」'。 – 2012-08-08 11:28:04

+0

對不起,我發現錯誤。對於Phone,我有一個'MaskedTextBox',它包含數字分隔符,即使它是空的。謝謝。 – user1260827 2012-08-08 11:42:44

0

在這種情況下@Dan Puzey的asnwer很適合。但是是很好的瞭解,你可以incrementaly構建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(); 
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); 
       } 
      }