简体   繁体   English

如何使用EF执行带有输入和输出参数的存储过程?

[英]How to execute stored procedure with input and output parameters using EF?

I am using EF code first approach and I have created stored procedure using migration as following:我正在使用 EF 代码优先方法,并且我使用迁移创建了存储过程,如下所示:

public override void Up()
    {
        Sql(@"CREATE TYPE IdsList AS TABLE   
                    ( 
                    Id Int
                    )
                    GO

                    Create Procedure getChildIds(
                    @IdsList dbo.IdsList ReadOnly
                    )
                    As
                    Begin
                    WITH RecursiveCTE AS
                    (
                        SELECT Id
                        FROM dbo.PhysicalObjects
                        WHERE ParentId in (Select * from @IdsList)
                        --Where Id=108
                        UNION ALL

                        SELECT t.Id
                        FROM dbo.PhysicalObjects t
                        INNER JOIN RecursiveCTE cte ON t.ParentId = cte.Id
                    )
                    SELECT * FROM RecursiveCTE
                    End");
    }

    public override void Down()
    {
        Sql(@"Drop Type IdsList
                Go
                Drop Procedure getChildIds");
    }

Now If I go to sql server management studio and execute the following scripts:现在如果我去 sql server management studio 并执行以下脚本:

Declare @Ids dbo.IdsList

Insert into @Ids
SELECT 1

Exec getChildIds @Ids

It will execute successfuly, but Now I am trying to execute that stored procedure as following:它将成功执行,但现在我正在尝试执行该存储过程,如下所示:

 var idsList = new SqlParameter {ParameterName = "idsList",  Value = new int[] { 1,2,3,4,5} };

 var idParams = new SqlParameter("idParams", SqlDbType.Structured)
            {
                Direction = System.Data.ParameterDirection.Output
            };

var results = dbContext.Database.SqlQuery<int>("getChildIds @idsList, @idParams out", idsList,idParams) ;

var idsResult = (List<int>)idParams.Value;

It does not return anything.它不返回任何东西。

So how I could execute stored procedure with input and output parameters of type Table?那么如何使用 Table 类型的输入和输出参数来执行存储过程呢?

I have solved it this way.我是这样解决的。

First of all I have updated my stored procedure to return Ids as following:首先,我更新了我的存储过程以返回 Id,如下所示:

 public override void Up()
    {
        Sql(@"CREATE TYPE IdsList AS TABLE   
                    ( 
                    Id Int
                    )
                    GO

                    Create Procedure getChildIds(
                    @IdsList dbo.IdsList ReadOnly
                    )
                    As
                    Begin
                    WITH RecursiveCTE AS
                    (
                        SELECT Id
                        FROM dbo.PhysicalObjects
                        WHERE ParentId in (Select * from @IdsList)
                        UNION ALL

                        SELECT t.Id
                        FROM dbo.PhysicalObjects t
                        INNER JOIN RecursiveCTE cte ON t.ParentId = cte.Id
                    )
                    SELECT Id From RecursiveCTE
                    End");
    }

    public override void Down()
    {
        Sql(@" Drop Procedure getChildIds
               Go
               Drop Type IdsList
               ");
    }

And here how I have solved executing stored procedure using entity framework:在这里,我如何解决使用实体框架执行存储过程的问题:

 var dataTable = new DataTable();
 dataTable.TableName = "idsList";
 dataTable.Columns.Add("Id", typeof(int));
 dataTable.Rows.Add(1);
 dataTable.Rows.Add(2);

  SqlParameter idsList = new SqlParameter("idsList", SqlDbType.Structured);
  idsList.TypeName = dataTable.TableName;
  idsList.Value = dataTable;

  var results = dbContext.Database.SqlQuery<int>("exec getChildIds @idsList", idsList).ToList();

I hope my code will help others having the same issue我希望我的代码能帮助其他有同样问题的人

The best solution for using user's procedures/functions and build-in functions in SQL is this library - https://github.com/Dixin/EntityFramework.Functions在 SQL 中使用用户过程/函数和内置函数的最佳解决方案是这个库 - https://github.com/Dixin/EntityFramework.Functions

It has great and easy implementation.它具有出色且易于实施的功能。 Also it allows to follow code first approach它还允许遵循代码优先的方法

In your case you need to use Table-valued function在您的情况下,您需要使用表值函数

Define model定义模型

[ComplexType]
public class IdModel
{
     public int Id { get; set; }
}

Declare Type and Convention in DbContext在 DbContext 中声明类型和约定

protected override void OnModelCreating(DbModelBuilder modelBuilder)
{
    modelBuilder.Conventions.Add(new FunctionConvention<DbContext>());

    modelBuilder.ComplexType<IdModel>();

    base.OnModelCreating(modelBuilder);
}

Define function in DbContext在 DbContext 中定义函数

[Function(FunctionType.TableValuedFunction, nameof(ufnGetChildIds), Schema = "dbo")]
public IQueryable<IdModel> ufnGetChildIds([Parameter(DbType = "IdModel", Name = "IdsList")]List<IdModel> IdsList)
{
    ObjectParameter IdsListParameter = new ObjectParameter("IdsList", IdsList);

    return this.ObjectContext().CreateQuery<IdModel>(
        $"[{nameof(this.ufnGetChildIds)}](@{nameof(IdsList)})", IdsListParameter);
}

And use it from your DbContext并从您的 DbContext 使用它

[TestMethod]
public void CallTableValuedFunction()
{
    using (DbContext database = new DbContext())
    {
        IQueryable<IdModel> employees = database.ufnGetChildIds(new List<IdModel> { new IdModel { Id = 1 }});
    }
}

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

相关问题 使用带有选定输入参数的EF调用存储过程 - Calling stored procedure using EF with selected input parameters EF Core,如何使用输入和输出参数调用存储过程? - EF Core, how to call stored procedure with input and output params? 如何在 Dot Net Core 3.1 中使用 FromSqlInterpolated/Database.ExecuteSqlInterpolated 执行带输出参数的存储过程? - How to execute stored procedure with Output parameters using FromSqlInterpolated/Database.ExecuteSqlInterpolated in Dot Net Core 3.1? 使用EF6将参数传递给存储过程 - Passing parameters to stored procedure using EF6 具有输出/输入参数返回计数的存储过程 - Stored procedure with output / input parameters return count 无法为带有输出参数的EF 6调用存储过程编写代码? - Not able to code for EF 6 calling stored procedure with output parameters? 如何从存储过程 EF Core 3.1 中获取多个 OUTPUT 参数 - How to get Multiple OUTPUT parameters from stored procedure EF Core 3.1 如何使用带有单个输入参数的EntityFramework在webApi中执行存储过程 - How to execute a stored Procedure in a webApi using EntityFramework with a single input parameter 如何使用实体框架执行存储过程并从存储过程获取输出 - How to execute stored procedure and get output from the stored procedure using Entity Framework 在 C# 中使用存储过程输出参数 - Using stored procedure output parameters in C#
 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM