簡體   English   中英

在Entity Framework代碼優先中使用輸出參數調用存儲過程時出錯

[英]Error on calling stored procedure with output param in Entity Framework code-first

從實體框架(使用代碼優先方法)調用ExecuteStoreQuery時遇到以下錯誤。

數據讀取器具有多個字段。 多個字段對於EDM原語或枚舉類型無效。

但是我的插入/更新操作反映在數據庫中。

對這個問題有想法嗎?

這是C#編寫的代碼

long Id=0;

SqlParameter paramoutput = new SqlParameter()
{
   ParameterName = "Result",
   Value = "",
   SqlDbType = System.Data.SqlDbType.BigInt,
   Size = 100,
   Direction = System.Data.ParameterDirection.Output
};

var mydata = (dataContext as IObjectContextAdapter).ObjectContext
             .ExecuteStoreQuery<long>("exec Save @MarkupId, @ApiId, @MainBranchId, @Title, @Markup, @IsPercentage, @IsDomestic, @CreatedOn, @CreatedBy, @ModifiedOn, @ModifiedBy, @IsActive, @Result out",
                 new SqlParameter("@MarkupId", generalMarkupModel.Id),
                 new SqlParameter("@ApiId", generalMarkupModel.ApiId),
                 new SqlParameter("@MainBranchId", generalMarkupModel.MainBranchId),
                 new SqlParameter("@Title", generalMarkupModel.Title),
                 new SqlParameter("@Markup", generalMarkupModel.Markup),
                 new SqlParameter("@IsPercentage", generalMarkupModel.IsPercentage),
                 new SqlParameter("@IsDomestic", generalMarkupModel.IsDomestic),
                 new SqlParameter("@IsActive", generalMarkupModel.IsActive),
                 new SqlParameter("@CreatedOn", DateTime.Now),
                 new SqlParameter("@CreatedBy", "ajc"),
                 new SqlParameter("@ModifiedOn", DateTime.Now),
                 new SqlParameter("@ModifiedBy", "ajm"),
                 paramoutput);

Id = Convert.ToInt64(paramoutput.Value.ToString());
return Id;

該存儲過程執行insert操作,並將@@identity設置為輸出參數。

這是我的存儲過程:

ALTER PROCEDURE  mypocedurename-here
 @MarkupId bigint,          
 @ApiId int,           
 @MainBranchId int,            
 @Title varchar(50),                    
 @Markup float ,  
 @IsPercentage bit,  
 @IsDomestic bit,
 @CreatedOn datetime, 
 @CreatedBy varchar(50),
 @ModifiedOn datetime, 
 @ModifiedBy varchar(50), 
 @IsActive bit,
 @Result bigint OUTPUT              

AS            
BEGIN            

  INSERT INTO GeneralMarkups            
  ( 
    ApiId,            
   MainBranchId, 
   Title,           
   Markup,            
   IsPercentage ,          
   IsDomestic ,  
   IsActive ,               
   CreatedOn,   
   CreatedBy,  
   ModifiedOn,
   ModifiedBy           
  )            
  VALUES            
  (
    @ApiId,            
   @MainBranchId,            
   @Title,            
   @Markup ,          
   @IsPercentage ,  
   @IsDomestic,
   @IsActive ,          
   @CreatedOn,
   @CreatedBy,  
   @ModifiedOn,
   @ModifiedBy          

  )
  select @Result=@@IDENTITY    

END

首先,您的過程沒有選擇任何結果。 因此,您需要選擇一些內容(因為您指定了類型為long的return-result-set)。 因此,更改proc的最后一行:

-- instead of select @Result=@@IDENTITY 
-- use these lines:
SET @Result = @@IDENTITY
SELECT @Result Result 

現在,您可以通過過程調用獲取選定的值。 意味着執行方法時,將從結果中獲取新的ID(作為mydata參數-應該對其進行迭代)。

但是仍然存在一個錯誤。 您將無法使此行正常工作:

Id = Convert.ToInt64(paramoutput.Value.ToString());

因為您的輸出參數沒有值(它為null ),除非您迭代查詢結果。 意味着paramoutput.Value將為null直到您在查詢上調用一種迭代器方法為止。 所以:

SqlParameter paramoutput = new SqlParameter()
{
   ParameterName = "Result",
   // Value = "", no need
   SqlDbType = System.Data.SqlDbType.BigInt,
   // Size = 100, no need
   Direction = System.Data.ParameterDirection.Output
};

var mydata = (dataContext as IObjectContextAdapter).ObjectContext
             .ExecuteStoreQuery<long>("exec Save @MarkupId, @ApiId, @MainBranchId, @Title, @Markup, @IsPercentage, @IsDomestic, @CreatedOn, @CreatedBy, @ModifiedOn, @ModifiedBy, @IsActive, @Result out",
                 new SqlParameter("@MarkupId", generalMarkupModel.Id),
                 new SqlParameter("@ApiId", generalMarkupModel.ApiId),
                 new SqlParameter("@MainBranchId", generalMarkupModel.MainBranchId),
                 new SqlParameter("@Title", generalMarkupModel.Title),
                 new SqlParameter("@Markup", generalMarkupModel.Markup),
                 new SqlParameter("@IsPercentage", generalMarkupModel.IsPercentage),
                 new SqlParameter("@IsDomestic", generalMarkupModel.IsDomestic),
                 new SqlParameter("@IsActive", generalMarkupModel.IsActive),
                 new SqlParameter("@CreatedOn", DateTime.Now),
                 new SqlParameter("@CreatedBy", "ajc"),
                 new SqlParameter("@ModifiedOn", DateTime.Now),
                 new SqlParameter("@ModifiedBy", "ajm"),
                 paramoutput);

// here, the mydata, is of type ObjectResult<long> which you should iterate it to get underlying IDataReader iterated and closed. Then you can use output parameters. So, add this line:
var returnedId = mydata.FirstOrDefault();
// now, the output parameter is available:
Id = Convert.ToInt64(paramoutput.Value.ToString());

請考慮我添加到代碼(和新行)中的注釋。

畢竟,為什么還要傳遞輸出參數並選擇相同的結果呢? 其中一個應該做這項工作,而另一個則是多余的。 是不是 還是我看不到東西?

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

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