在实体框架代码优先中使用输出参数调用存储过程时出错
本文关键字:参数 输出 调用 存储过程 出错 框架 实体 代码 | 更新日期: 2023-09-27 17:55:21
从实体框架调用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
的返回结果集)。因此,更改进程的最后一行:
-- 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());
请考虑我添加到代码(和新行)中的注释。
毕竟,为什么要传递输出参数并选择相同的结果?其中一个应该完成这项工作,另一个是多余的。不是吗?还是有什么我看不见的东西?