【问题标题】:Entity Framework : Use stored procedure to return raw table result实体框架:使用存储过程返回原始表结果
【发布时间】:2017-11-15 04:11:46
【问题描述】:

在 EF 中是否可以像在经典 ADO.net 中那样使用存储过程返回原始 DataTable/DataSet 而不是返回映射/翻译的实体?

【问题讨论】:

    标签: entity-framework datatable ado.net dataset


    【解决方案1】:

    EF 建立在 ADO.NET 之上,因此无论何时需要,您都可以直接访问 DbContext 的 DbConnection 并直接使用它。例如

            using (var db = new MyDbContext())
            {
                db.Database.Connection.Open();
                var con = (SqlConnection)db.Database.Connection;
                var cmd = new SqlCommand("exec MyProc", con);
                DataTable dt = new DataTable();
                using (var rdr = cmd.ExecuteReader())
                {
                    dt.Load(rdr);
                }
                //. . .
    

    【讨论】:

      【解决方案2】:

      是的,这是可能的。

      下面我描述了我是如何做到这一点的。存储过程是数据库的一部分。因此,最好将存储过程添加到访问您的数据库并创建数据库模型的类中:您的 dbContext。

      public class MyDbContext : DbContext
      {
          // TODO: add DbSet properties
      
          #region stored procedures
          // TODO (1): add a function that calls the stored procedure
          // TODO (2): add a function to check if the stored procedure exists
          // TODO (3): add a function that creates the stored procedure
          // TODO (4): make sure the stored procedure is created when the database is created
          #endregion stored procedure
      }
      

      TODO(1):调用存储过程的过程:

      private const string MyStoredProcedureName = ...;
      private const string myParamName1 = ...;
      private const string myParamName2 = ...;
      
      public void CallMyStoredProcedure(MyParameters parameters)
      {
          object[] functionParameters = new object[]
          {
              new SqlParameter(myParamName1, parameters.GetParam1Value(),
              new SqlParameter(myParamName2, parameters.GetParam2Value(),
              ... // if needed add more parameters
          };
          const string sqlCommand = @"Exec " + MyStoredProcedureName
              + "  @" + myParamName1
              + ", @" + myParamName2
              ... // if needed add more parameters
              ;
          this.Database.ExecutSqlCommand(sqlComman, functionParameters);
      }
      

      TODO(2)检查存储过程是否存在

      // returns true if MyStoredProcedure exists
      public bool MyStoredProcedureExists()
      {
          return this.ProcedureExists(MyStoredProcedureName);
      }
      
      // returns true if stored procedure with procedureName exists
      public bool StoredProcedureExists(string procedureName)
      {
          object[] functionParameters = new object[]
          {
              new SqlParameter(@"procedurename", procedureName),
          };
          string query = @"select [name] from sys.procedures where name= @procedurename";
          return this.Database.SqlQuery<string>(query, functionParameters)
              .AsEnumerable()                       // bring to local memory
              .Where(item => item == procedureName) // take only the procedures with desired name
              .Any();                               // true if there is such a procedure
      }
      

      TODO(3)创建存储过程:

      public void CreateProcedureUpdateUsageCosts(bool forceRecreate)
      {
          bool storedProcedureExists = this.MyStoredProcedureExists();
      
          // only create (or update) if not exists or if forceRecreate:
          if (!storedProcedureExists || forceRecreate)
          {  // create or alter:
              Debug.WriteLine("Create stored procedures");
      
              // use a StringBuilder to create the SQL command that will create the
              // stored procedure
              var x = new StringBuilder();
      
              // ALTER or CREATE?
              if (!storedProcedureExists)
              {
                  x.Append(@"CREATE");
              }
              else
              {
                  x.Append(@"ALTER");
              }
      
              // procedure name:
              x.Append(@" procedure ");
              x.AppendLine(MyStoredProcedureName);
      
              // parameters: (only as an example)
              x.AppendLine(@"@ReportPeriod int,");
              x.AppendLine(@"@CustomerContractId bigint,");
              x.AppendLine(@"@CallType nvarChar(80),");
              // etc.
      
              // code
              x.AppendLine(@"as");
              x.AppendLine(@"begin");
              // only as example some of my procedure
              x.AppendLine(@"Merge [usagecosts]");
              x.AppendLine(@"Using (Select @ReportPeriod as reportperiod,");
              x.AppendLine(@"              @CustomerContractId as customercontractId,");
              ...
              x.AppendLine(@"end");
      
              // execute the created SQL command
              this.Database.ExecuteSqlCommand(x.ToString());
          }
      }
      

      TODO(4)确保在创建数据库的时候创建了存储过程

      在 MyDbContext 中:

      protected override void OnModelCreating(DbModelBuilder modelBuilder)
      {
          // TODO: if needed add fluent Api to build model
      
          // create stored procedure
          this.CreateProcedureUpdateUsageCosts(true);
      }
      

      用法:

      using (var dbContext = new MyDbContext(...))
      {
         MyParameters parms = FillMyParameters();
         dbContext.CallMyStoredProcedure(parms);
      }
      

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 2015-02-05
        • 1970-01-01
        • 2012-05-07
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2015-05-14
        相关资源
        最近更新 更多