2

下面的代码搜索与关键字匹配s或在与关键字匹配的类别下的产品s

它工作但很乏味,我想知道是否有更短的方法可以做到这一点?

var products = context.Products.Where(x => 
                 x.Name.Contains(s) ||
                 x.Products_Categories.Any(pc => 
                     pc.Category.Name.Contains(s) || 
                     (pc.Category.Category1 != null && pc.Category.Category1.Name.Contains(s)) || 
                     (pc.Category.Category1 != null && pc.Category.Category1.Category1 != null && pc.Category.Category1.Category1.Name.Contains(s) || 
                     (pc.Category.Category1 != null && pc.Category.Category1.Category1 != null pc.Category.Category1.Category1.Category1 != null && &&pc.Category.Category1.Category1.Category1.Name.Contains(s))
               );

如果不明显:

Products_Categories是多对多的关系,aProduct可以是一个或多个Category

Category1是 的父类别Category

请注意,它已链接到数据库,因此我无法使用IsUnderCategory().
我目前不需要 Expression,因为此代码只使用一次。

4

2 回答 2

1

在 linq 中没有递归查询的捷径,在由 SQL 查询提供程序支持的 linq 中则更少。但是,在执行之前先将语句转换为 SQL 有一个好处:SQL 没有空引用的概念。null因此,您从语句中删除所有检查:

var products = context.Products.Where(x => 
                 x.Name.Contains(s) ||
                 x.Products_Categories.Any(pc => 
                     pc.Category.Name.Contains(s) || 
                     pc.Category.Category1.Name.Contains(s) || 
                     pc.Category.Category1.Category1.Name.Contains(s) || 
                     pc.Category.Category1.Category1.Category1.Name.Contains(s))
               );

它将被转换为具有许多外连接的 SQL 语句。如您所知,如果在外部联接表的字段没有记录时对其进行寻址,SQL 不会崩溃。

查询将是……可怕的。你必须假设层次结构的最大深度。改善这一点的唯一方法是在数据库中创建一个视图,该视图通过递归 SQL 查询返回产品的所有类别。

于 2013-04-04T07:40:14.840 回答
0

使用 EF 的另一种方法是使用 while 循环简单地迭代地查询所有类别的子类别。

完成后,您将拥有所有 ID。第一次,查询计划还没有完成,它需要一点时间,但它非常快,具体取决于你的数据库有多可怕。

然后,您可以使用转换为的方法查询具有任何类别 ID 列表的所有产品ContainsWHERE FieldName IN (1,2,3)

这种方法的优点是它不依赖于您拥有多少级别的子类别。它总是有效,而另一种选择会默默地失败。

于 2017-10-02T23:05:32.847 回答