簡體   English   中英

在EntityFramework EntitySql中使用“option(maxrecursion 0)”

[英]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連接

請節省您的時間,不建議調用ExecuteStoreQueryAsQueryable ....我真的不想實現整個結果集,因為我只實現了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.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM