LINQ:将SQL WITH子句转换为LINQ和Entity Framework

时间:2014-03-14 14:12:30

标签: c# sql linq entity-framework

我有一个使用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

等等。

3 个答案:

答案 0 :(得分:1)

您可以使用LINQ to Entities解决这个问题,但这非常重要,我怀疑它会非常耗时。

在这种情况下,您可能更喜欢构建一个SQL视图或表值函数,它返回您正在查找的结果。然后将该视图或表值函数导入到EF模型中,您可以使用LINQ直接从中提取数据。

在LINQ中查询视图与查询表没什么不同。

要从LINQ中的表值函数获取数据,可以在函数名称后面传递函数的参数,如下所示:

var query = from tvf in _db.MyTableValuedFunction(parameters)
            select tvf;

修改

正如@ thepirat000所建议的那样,在版本5之前的实体框架版本中不提供表值函数支持。为了使用此功能,EF必须在.NET 4.5或更高版本下运行。

答案 1 :(得分:1)

WITH阻止是Common Table Expression,在这种情况下用于创建recursive query

在Linq中,这将是非常困难,因为Linq在递归方面不能很好地发挥作用。如果需要一个结果集上的所有数据,则存储过程将更容易。另一种选择是在C#中进行递归(不是在Linq中,而是递归函数)并进行多次往返。性能不会那么好,但是如果结果集很小,它可能没什么区别(并且你会得到一个更好的对象模型)。

答案 2 :(得分:1)

在一天结束时,我无法让它发挥作用。我最终动态地编写了一个SQL查询并将其直接发送到数据库。它工作正常,我不依赖任何直接用户输入,因此没有SQL注入的机会。但它似乎老了!对于我的其他程序,我使用的是EF和LINQ。

感谢您的回复!