4

您好我有一个 linq 查询,我将一个对象与存储在我的数据库中的所有其他实体进行比较。名字和姓氏是必填字段,因此我不必检查是否为空。但就街道而言,我必须进行这些检查。

如果两个字段都是空字符串或空字符串或者它们相同,我想匹配。下面的 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);
}

这样做的好处是它在每种情况下都使查询保持简单。如果您愿意,可以对前两个使用类似的逻辑,也可以将其移至基于表达式的实用程序方法。未经测试:

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 回答