LINQ:将SQL WITH子句翻译为LINQ和Entity Framework

3
我有一个使用Entity Framework的应用程序。我想添加一个树形视图,按类别分组列出产品。我有一个旧的SQL查询,可以获取所有产品和类别,并将它们排列成父节点和子节点。我正在尝试将其翻译为使用EF的LINQ。但是SQL具有WITH子查询,我不熟悉如何使用。我已经尝试使用Linqer和LinqPad来解决问题,但它们在WITH子句上出现问题,我不确定如何解决。在LINQ中是否可能实现这种情况?
以下是查询:
declare @id int
set @id=0
WITH ChildIDs(id,parentid,type,ChildLevel) AS 
(
SELECT id,parentid,type,0 AS ChildLevel
FROM dbo.brooks_product 
WHERE id = @id
UNION ALL
SELECT e.id,e.parentid,e.type,ChildLevel + 1
FROM dbo.brooks_product AS e
    INNER JOIN ChildIDs AS d
    ON e.parentid = d.id 
   WHERE  showitem='yes' AND tribflag=1
)
SELECT ID,parentid,type,ChildLevel 
FROM ChildIDs
WHERE type in('product','productchild','productgroup','menu')
ORDER BY ChildLevel, type
OPTION (MAXRECURSION 10);

当我运行查询时,我得到的数据看起来像这样(这里被截断了几千行):
ID.....parentid.....type.....ChildLevel
35429..0............menu.....1
49205..0............menu.....1
49206..49205........menu.....2
169999.49206........product..3
160531.169999.......productchild..4

等等。


1
我认为这是不可能的。一般来说,我不知道如何在LINQ中干净地执行递归查询。如果您想要,您总是可以使用原始SQL,EF将仅将结果映射到指定类型(类似于Dapper)。 - Patryk Ćwiek
3个回答

3
WITH 块是 通用表达式,在本例中用于创建 递归查询
这在 Linq 中会非常困难,因为 Linq 无法很好地处理递归。如果您 需要 在一个结果集中获取所有数据,则存储过程会更容易。另一种选择是在 C#(而不是 Linq,而是使用递归函数)中进行递归,并进行多个往返。性能可能不会那么好,但如果结果集很小,可能并没有太大的区别(而且您将得到更好的对象模型)。

2

最终,我无法使其工作。最终我动态地编写了一个SQL查询,并将其直接发送到数据库。它可以正常运行,而且我不依赖于任何直接用户输入,因此不存在SQL注入的可能性。但这似乎是旧学派的做法!在我的程序的其余部分中,我使用的是EF和LINQ。

谢谢大家的回复!


1
您可以尝试使用LINQ to Entities来解决这个问题,但这是一个非常复杂的过程,我怀疑这将非常耗时。
在这种情况下,您可能更喜欢构建一个SQL视图或表值函数,返回您要查找的结果。然后将该视图或表值函数导入到您的EF模型中,您就可以直接使用LINQ从中提取数据。
在LINQ中查询视图与查询表没有任何区别。
要从LINQ中获取表值函数中的数据,您需要在函数名称后面传递函数的参数,如下所示:
var query = from tvf in _db.MyTableValuedFunction(parameters)
            select tvf;

编辑

如@thepirat000所建议的,表值函数支持在Entity Framework 5之前的版本中不可用。为了使用此功能,EF必须在.NET 4.5或更高版本下运行。


请注意,TVF支持是在Entity Framework 5版本中引入的。此外,您必须针对.NET Framework 4.5进行目标设置。 - thepirat000

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接