[英]Use “option(maxrecursion 0)” with EntityFramework EntitySql
我有一個SqlServer函數,它根據輸入執行帶有cte的recrusive選擇,這是一個帶有id的csv字符串。
不幸的是我不能在我的函數中使用“option(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)
?
我知道我可以使用“ExecuteStoreQuery”來執行我想要的任何sql查詢,但我確實需要一個IQueryable,因為“ExecuteMyFunction”的返回將在實現之前與另一個IQueryable連接 。
請節省您的時間,不建議調用ExecuteStoreQuery
和AsQueryable
....我真的不想實現整個結果集,因為我只實現了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
)
您唯一能做的就是使用EF攔截並在運行之前將該選項添加到EF生成的SQL中。
為此,您需要實現IDbCommandInterceptor
接口 ,並使用DbInterception.Add(new YousCommandInterceptor());
注冊你的攔截器。
您的攔截器可以在將查詢發送到服務器之前添加該選項。 SQL查詢在所選方法的命令參數中可用(您應該攔截ReaderExecuted(DbCommand, DbCommandInterceptionContext<DbDataReader>)
)
OPTION(MAXRECURSION 0)
特定於SQL Server語法,我不認為EntitySql會支持這種特定的語法。 這將使抽象與底層數據存儲過於耦合,並且難以支持其他數據庫服務器。
如果你達到一些遞歸限制,也許最好審查你的設計,因為降低限制應該會讓你的問題變得更糟。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.