使用EF6 + SQL Server 2008 R2 + .NET Fx 4.5。
我需要在我的实体及其相关实体的多个字段中搜索特定字符串,并返回在任何字段中找到搜索字符串的记录。这是相关的代码:
Dim Query = MyDB.items.AsQueryable()
Query = Query.Where(Function(r) _
r.stock_no.Contains(searchString) OrElse _
r.serial_number.Contains(searchString) OrElse _
r.catalog_item.description.Contains(searchString) OrElse _ r.catalog_item.category.Contains(searchString) OrElse _
r.item_status.name.Contains(searchString) OrElse _
r.notes.Contains(searchString))
If r.issued_to_company_id.HasValue Then 'This is a nullable field (0-1 relation)
Query = Query.OR_FUNCTION(Function(r) r.issued_to_company.name.Contains(searchString))
End If
问题是LINQ中没有 OR_FUNCTION 。您可以通过调用Where
对象上的另一个Query
来模拟可选的 AND_FUNCTION ,但我需要在此处执行OR。
我也尝试在谓词中使用If
和IIf
,但如果不引入编译或运行时错误,似乎无法做到这一点。这样做的正确方法是什么?
答案 0 :(得分:2)
第一种方式
棘手的方法是使用A OR B
等于NOT(NOT A AND NOT B)
的逻辑规则:
' Assuming QueryAll holds all values
Query = QueryAll.Where(Function(r) _
Not r.stock_no.Contains(searchString) Andalso _
Not r.serial_number.Contains(searchString) Andalso _
Not r.catalog_item.description.Contains(searchString) Andalso _ Not r.catalog_item.category.Contains(searchString) Andalso _
Not r.item_status.name.Contains(searchString) Andalso _
Not r.notes.Contains(searchString))
' Query will hold all rows which DO NOT contain searchString.
Query = Query.Where(Function(r) Not r.issued_to_company.name.Contains(searchString))
' Here you should choose all elements in QueryAll which are not in Query.
' The result would be all rows containing searchString.
第二种方式
如何使用predicate
构建PredicateBuilder
而不是在Where子句中使用它?
Dim pred = PredicateBuilder.True(Of MyClass)()
pred = pred.And(Function(m As MyClass) m.SomeProperty = someValue)
pred = pred.Or(Function(m As MyClass) m.SomeProperty = someValue)
代码取自here。
第三种方式
另一种可能的方法是使用Expression Trees to Build Dynamic Queries
答案 1 :(得分:1)
找到它。您实际上可以使用新的内联If
语法在上面的查询中包含可选的Or
。就像这样:
Query = Query.Where(Function(r) _
r.stock_no.Contains(searchString) OrElse _
r.serial_number.Contains(searchString) OrElse _
r.catalog_item.description.Contains(searchString) OrElse _
r.catalog_item.category.Contains(searchString) OrElse _
r.item_status.name.Contains(searchString) OrElse _
r.notes.Contains(searchString) OrElse _
If(r.catalog_item.manufacturer_id.HasValue, r.catalog_item.manufacturer_company.name.Contains(searchString), True))
请注意,这适用于Option Strict
on,即If
可以将返回值的类型推断为boolean。 @ ilanS的答案也很好,但这个答案看起来更简单,更自然。