c# - 将 "option(maxrecursion 0)"与 Entity Framework Entity Sql 一起使用

标签 c# sql-server entity-framework common-table-expression entity-sql

我有一个 SqlServer 函数,它根据输入执行循环选择和 cte,输入是一个带有 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) 与 entitySql 一起使用吗?

我知道我可以使用“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 interception并在运行之前将该选项添加到 EF 生成的 SQL。

为此,您需要实现 IDbCommandInterceptor interface ,并使用 DbInterception.Add(new YousCommandInterceptor());注册您的拦截器。

您的拦截器可以在查询发送到服务器之前添加该选项。 SQL查询在所选方法的命令参数中可用(您应该拦截ReaderExecuted(DbCommand, DbCommandInterceptionContext<DbDataReader>))

关于c# - 将 "option(maxrecursion 0)"与 Entity Framework Entity Sql 一起使用,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/35224211/

相关文章:

c# - SQL Server 超时故障排除

c# - Entity Framework v1 - 高流量网站高峰时段出现 "Timeout expired"异常

c# - SQL > Linq to Sql,SQL 查询有效,Linq to SQL 返回空数据集

c# - 通用 lambda 方法签名

c# - 更新图像而不闪烁 ASP.NET C#

c# - 在 Jquery 警报中显示表行的所有值

.net - 从数据库中获取大约一百万条记录的最佳方法是什么?

sql - 在 SQL Server 中评估 "value1 IS NOT DISTINCT FROM value2"的最佳方法

java - 为什么除非使用事务,否则删除表在 SQLServer 中不起作用?

c# - 为什么实体消失后仍然有效?