4

こんにちは私は、データベースに保存されている他のすべてのエンティティとオブジェクトを比較するlinqクエリを持っています。名と姓は必須フィールドなので、nullをチェックする必要はありません。しかし、通りの場合、私はこれらのチェックをしなければなりません。

両方のフィールドがnullまたは空の文字列であるか、同じであるかを照合したいと思います。以下のlinqクエリは正常に機能しています。

しかし、私はさまよっていましたが、それをより読みやすくする方法はありません。たとえば、Bool FieldsAreEqualOrBothNullOrEmpty(r.street、request.street)のようなカスタム関数を使用します

それを行う方法とそれが可能かどうかを理解することはできません。

var same = 
   from r in db.Requests
   where r.firstName.ToLower() == request.firstName.ToLower()
      && r.lastName.ToLower() == request.lastName.ToLower()

      //Seems long to just compare two fields
      && ( string.IsNullOrEmpty(r.street) && string.IsNullOrEmpty(request.street) ) 
         || r.street.ToLower() == request.street.ToLower()

      select r;
return same;
4

3 に答える 3

2

私は単純化します:

var same = 
   from r in db.Requests
   where r.firstName.ToLower() == request.firstName.ToLower()
      && r.lastName.ToLower() == request.lastName.ToLower()
   select r;

if(string.IsNullOrEmpty(request.street)) {
    same = same.Where(r => string.IsNullOrEmpty(r.street));
} else {
    string street = request.street.ToLower();
    same = same.Where(r => r.street.ToLower() == street);
}

これの良いところは、それぞれの場合にクエリを単純に保つことです。必要に応じて、最初の2つに同様のロジックを使用できます。また、式ベースのユーティリティメソッドに移動することもできます。未テスト:

public static IQueryable<T> FieldsAreEqualOrBothNullOrEmpty<T>(
    this IQueryable<T> source,
    Expression<Func<T, string>> member, string value)
{
    Expression body;
    if (string.IsNullOrEmpty(value))
    {
        body = Expression.Call(
            typeof(string), "IsNullOrEmpty", null, member.Body);
    }
    else
    {
        body = Expression.Equal(
            Expression.Call(member.Body, "ToLower", null),
            Expression.Constant(value.ToLower(), typeof(string)));
    }

    return source.Where(Expression.Lambda<Func<T,bool>>(
        body, member.Parameters));
}

それから:

var same = db.Requests
           .FieldsAreEqualOrBothNullOrEmpty(x => x.firstName, request.firstName)
           .FieldsAreEqualOrBothNullOrEmpty(x => x.lastName, request.lastName)
           .FieldsAreEqualOrBothNullOrEmpty(x => x.street, request.street);
于 2012-10-24T08:23:55.403 に答える
1

適切なStringComparisonを使用して、 String.Equalsを呼び出すことができますが、大文字と小文字は区別されません。

string.equals(r.street, request.street, StringComparison.OrdinalIgnoreCase);

すべての言語で確実に機能するとは限らず、大文字と小文字を無視する比較を使用するよりも低速であるため、比較のために文字列を小文字に変換することはお勧めできません。たとえば、この回答を参照してください

于 2012-10-24T08:24:02.410 に答える
1

文字列に拡張メソッドを作成するのはどうですかIsEqualOrBothNullOrEmpty-

public static class Extensions
{
   public static bool IsEqualOrBothNullOrEmpty(this string firstValue,
                           string secondValue)
   {
      return string.IsNullOrEmpty(firstValue) &&
               string.IsNullOrEmpty(secondValue)
                  || firstValue.ToLower() == secondValue.ToLower();
    }
}

そして、このようにクエリで使用します-

var same = 
   from r in db.Requests
   where r.firstName.ToLower() == request.firstName.ToLower()
      && r.lastName.ToLower() == request.lastName.ToLower()
      && r.street.IsEqualOrBothNullOrEmpty(request.Street)

      select r;
return same;
于 2012-10-24T08:29:52.300 に答える