我有一个SqlServer函数,它根据输入执行带有cte的recrusive选择,这是一个带有id的csv字符串。
不幸的是我无法使用"选项(maxrecursion 0)"在我的函数中,必须在执行函数时使用它。问题是我无法在EntityFramework的EntitySql中找到如何使用此选项。
考虑到我的函数名为MyRecursiveFunction
,这里有一些代码片段:
public virtual IQueryable<MyFunctionReturnType> ExecuteMyFunction(IObjectContextAdapter objContextAdapter, string csvIds)
{
var idsParam = new ObjectParameter("idsParam", csvIds);
// This is the original one, that works, but has no "option(maxrecursion 0)"
return objContextAdapter.CreateQuery<MyFunctionReturnType>("[MyRecursiveFunction](@idsParam)", idsParam);
// gives me an error of incorrect syntax near "option"
return objContextAdapter.CreateQuery<MyFunctionReturnType>("select VALUE tblAlias from [MyRecursiveFunction](@idsParam) as tblAlias OPTION(MAXRECURSION 0)", idsParam);
// Also gives me syntax error:
return objContextAdapter.CreateQuery<MyFunctionReturnType>("MyRecursiveFunction(@idsParam) option(maxrecursion 0)", idsParam);
}
任何人都知道如何将option(maxrecursion 0)
与entitySql一起使用?
我知道我可以使用&#34; ExecuteStoreQuery&#34;执行我想要的任何sql查询,但我确实需要一个IQueryable,因为这回复了&#34; ExecuteMyFunction&#34;将在实现之前加入另一个IQueryable 。
请节省您的时间,不建议与ExecuteStoreQuery
一起致电AsQueryable
....我真的不想实现整个结果集,因为我&#39; ll只实现10个分页结果。
以下是我的TVF的代表:
-- Consider that I have the given table for executing this function.
-- This table has a foreign key to itself, as the data represents a tree, like an organization chart
CREATE TABLE MyTable
(
Id INT,
ParentId INT, -- FK to 'MyTable'.'Id',
Name VARCHAR(400)
)
-- Here is my function definition:
CREATE FUNCTION MyRecursiveFunction (@idsParam VARCHAR(MAX))
RETURNS TABLE
AS
RETURN
(
-- create a cte for recursively getting the data
with myCte (id, parentId) as
(
SELECT tbl.Id, tbl.ParentId FROM MyTable AS tbl
-- This function just transform the varchar into a table of "Value"
INNER JOIN [dbo].[SplitTextIntoTableOfInt](@idsParam, ',') AS ids ON a.ParentId = ids.Value
UNION ALL
SELECT a.Id, a.ParentId FROM myCte AS parent
INNER JOIN MyTable tbl ON tbl.ParentId = parent.Id
)
SELECT * FROM myCte -- I can't use 'option(maxrecursion 0)' in here
)
答案 0 :(得分:4)
您唯一能做的就是使用EF interception并在运行之前将该选项添加到EF生成的SQL中。
为此,您需要实现IDbCommandInterceptor
interface,并使用DbInterception.Add(new YousCommandInterceptor());
注册您的拦截器。
您的拦截器可以在将查询发送到服务器之前添加该选项。 SQL查询在所选方法的命令参数中可用(您应该拦截ReaderExecuted(DbCommand, DbCommandInterceptionContext<DbDataReader>)
)
答案 1 :(得分:1)
OPTION(MAXRECURSION 0)
特定于SQL Server语法,我不认为EntitySql会支持这种特定的语法。这将使抽象与底层数据存储过于耦合,并且难以支持其他数据库服务器。
如果您达到某个递归限制,也许最好还是检查一下您的设计,因为降低限制会让您的问题更加严重。