0

私はクラスを持っているとします:

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

いくつかのプロパティは空にすることができますが、それらが入力されている場合はそれらで検索します。すべての組み合わせをチェックできますが、見苦しいです。最善の解決策は何ですか?
ありがとう

4

3 に答える 3

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 /空の場合、データとの比較はスキップされます。

于 2012-08-08T10:26:06.573 に答える
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);
                }
            }
于 2012-08-08T10:50:46.133 に答える
0

この場合、@DanPuzeyの回答が適切です。ただし、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();
于 2012-08-08T10:27:57.760 に答える