如何将重复的 where 子句表达式从 linq 拉到函数中?

Posted

技术标签:

【中文标题】如何将重复的 where 子句表达式从 linq 拉到函数中?【英文标题】:How can I pull a repeated where clause expression from linq into a function? 【发布时间】:2021-06-03 20:06:25 【问题描述】:

我有一个大型项目,其中有几十个 linq 语句,我正在通过检查多个字段以查看它们是否匹配或字段和比较字段都为空来查找匹配记录。

var testRecord = new  firstField = "bob", secondField = (string)null, thirdField = "ross" ;
var matchRecord = dataContext.RecordsTable.FirstOrDefault(vi =>
        (vi.first == testRecord.firstField || ((vi.first == null || vi.first == string.Empty) && testRecord.firstField == null))
        && (vi.second == testRecord.secondField || ((vi.second == null || vi.second == string.Empty) && testRecord.secondField == null))
        && (vi.third == testRecord.thirdField || ((vi.third == null || vi.third == string.Empty) && testRecord.thirdField == null)));
//do stuff with matchRecord 

理想情况下,我会用以下代码替换所有重复的代码(在我正在处理的系统中使用了大约 50 次)

Expression<Func<string, string, bool>> MatchesOrBothNull = (infoItem, matchItem) => (
                infoItem == matchItem || ((infoItem  == null || infoItem  == string.Empty) && matchItem == null));

var matchRecord = dataContext.RecordsTable.FirstOrDefault(vi =>
            MatchesOrBothNull(vi.first, testRecord.firstField)
            && MatchesOrBothNull(vi.second, testRecord.secondField)
            && MatchesOrBothNull(vi.third, testRecord.thirdField));
            
//do stuff with matchRecord 

我的问题是双重的:首先,是否已经有 match 或 both null 函数可用? (我看起来没有运气)。 其次,上面的代码块编译了,但是抛出“不支持对sql的翻译”的错误,有没有办法在where子句中有一个函数?我知道有翻译,因为如果我不将其拉入函数中,它就会起作用。我怎样才能得到翻译?

【问题讨论】:

【参考方案1】:

首先,您可以使用称为String.IsNullOrEmpty(vi.first) 的单个代码检查字符串是否为空或空。你需要一个这样的方法:

  public bool MatchesOrBothNull(string first,string second)
  if(first==second||String.IsNullOrEmpty(first)||String.IsNullOrEmpty(second))
  return true;
  else return false;
  

可以在where子句中使用

  var matchRecord = dataContext.RecordsTable.Where(vi =>
               MatchesOrBothNull(vi.first, testRecord.firstField)
            && MatchesOrBothNull(vi.second, testRecord.secondField)
            && MatchesOrBothNull(vi.third, testRecord.thirdField)
            ).FirstOrDefault();

【讨论】:

这给出了错误Method 'Boolean MatchesOrBothNull(System.String, System.String)' has no supported translation to SQL.,这是我要解决的问题。此外,仅使用 Where(vi =&gt; string.IsNullOrEmpty(vi.first)) 会引发类似的错误。

以上是关于如何将重复的 where 子句表达式从 linq 拉到函数中?的主要内容,如果未能解决你的问题,请参考以下文章

如何在 LINQ where 子句中传递 func 表达式?

如何在linq where子句中将int与字符串进行比较[重复]

linq to sql select和where的区别

C#图解教程 第十九章 LINQ

请教linq中orderby子句与where子句共存时排序失效问题

带有 lambda 表达式的 LINQ where 子句具有 OR 子句和返回不完整结果的空值