简体   繁体   English

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

[英]Use “option(maxrecursion 0)” with EntityFramework EntitySql

I have a SqlServer function that performs a recrusive select with cte based on an input, which is a csv string with ids. 我有一个SqlServer函数,它根据输入执行带有cte的recrusive选择,这是一个带有id的csv字符串。

Unfortunately I can't use "option(maxrecursion 0)" inside my function, it must be used when the function is executed. 不幸的是我不能在我的函数中使用“option(maxrecursion 0)”,它必须在执行函数时使用。 The problem is that I can't find how to use this option with EntityFramework's EntitySql. 问题是我无法找到如何在EntityFramework的EntitySql中使用此选项。

Considering my function is called MyRecursiveFunction , here are some code snippets: 考虑到我的函数名为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);
}

Anyone knows how to use option(maxrecursion 0) with entitySql ? 任何人都知道如何使用option(maxrecursion 0)

I know I can use the "ExecuteStoreQuery" to perform any sql query I want, but I do need an IQueryable, since this return of "ExecuteMyFunction" will be joined with another IQueryable before materialization . 我知道我可以使用“ExecuteStoreQuery”来执行我想要的任何sql查询,但我确实需要一个IQueryable,因为“ExecuteMyFunction”的返回将在实现之前与另一个IQueryable连接

Please save your time and do not suggest calling ExecuteStoreQuery along with AsQueryable .... I really don't want to materialize the whole result set since I'll materialize only 10 results for paging . 请节省您的时间,不建议调用ExecuteStoreQueryAsQueryable ....我真的不想实现整个结果集,因为我只实现了10个分页结果

Here is a representation of my TVF: 这是我的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
)

The only thing that you can do is to use EF interception and add that option to the EF generated SQL before running it. 您唯一能做的就是使用EF拦截并在运行之前将该选项添加到EF生成的SQL中。

To do so, you need to implement the IDbCommandInterceptor interface , and use DbInterception.Add(new YousCommandInterceptor()); 为此,您需要实现IDbCommandInterceptor接口 ,并使用DbInterception.Add(new YousCommandInterceptor()); to register your interceptor. 注册你的拦截器。

Your interceptor can add the option before the query is sent to the server. 您的拦截器可以在将查询发送到服务器之前添加该选项。 The SQL query is available in the command parameter of the chosen method ( you should intercept ReaderExecuted(DbCommand, DbCommandInterceptionContext<DbDataReader>) ) SQL查询在所选方法的命令参数中可用(您应该拦截ReaderExecuted(DbCommand, DbCommandInterceptionContext<DbDataReader>)

OPTION(MAXRECURSION 0) is specific to the SQL Server syntax, I don't think EntitySql would ever support this kind of specific syntax. OPTION(MAXRECURSION 0)特定于SQL Server语法,我不认为EntitySql会支持这种特定的语法。 This would make the abstraction too coupled with the underlying data store, and make difficult to support other database servers. 这将使抽象与底层数据存储过于耦合,并且难以支持其他数据库服务器。

If you're reaching some recursion limit, maybe it's a good idea to review your design, as dropping the limit should make your problems even worse. 如果你达到一些递归限制,也许最好审查你的设计,因为降低限制应该会让你的问题变得更糟。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM