LINQ:在一个类别下选择产品,包括子类别
下面的代码搜索与关键字LINQ:在一个类别下选择产品,包括子类别,linq,entity-framework,Linq,Entity Framework,下面的代码搜索与关键字s匹配的产品,或在与关键字s匹配的类别下的产品 这是工作,但乏味,我想知道是否有一个较短的方法来做到这一点 var products = context.Products.Where(x => x.Name.Contains(s) || x.Products_Categories.Any(pc => pc.Category.Name.Contains
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\u Categories
是一种多对多关系,Product
可以位于一个或多个类别中
类别1
是类别的父类别
请注意,它链接到数据库,因此我无法使用类似于IsUnderCategory()
我现在不需要表达式,因为这段代码只使用了一次。在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不会崩溃
查询将是。。。可怕的你必须假设层次结构的最大深度。改进这一点的唯一方法是在数据库中创建一个视图,该视图按顺序返回产品的所有类别。使用EF的另一种方法是使用while循环迭代查询所有类别的子类别
完成后,您将拥有所有ID。第一次,查询计划还没有完成,需要一段时间,但是它非常快,这取决于您的数据库有多庞大
然后您可以只使用Contains
方法,该方法被转换为其中FieldName位于(1,2,3)
这种方法的优点是它不依赖于您有多少级别的子类别。它总是在另一个备选方案以静默方式失败时工作。看起来您应该在数据库中创建一个视图,以获取关于类别的分层数据(使用公共表表达式),并使用该视图而不是类别
表本身进行查询。