好的,这里是一个2018年的更新:端到端解决方案,描述如何在没有nuget包的情况下从Entity Framework调用带有表参数的存储过程。
我正在使用EF 6.xx、SQL Server 2012和VS2017。
1. 表值参数
假设您有一个简单的表类型定义如下(只有一列):
go
create type GuidList as table (Id uniqueidentifier)
2. 您的存储过程
以及一个带有多个参数的存储过程,例如:
go
create procedure GenerateInvoice
@listIds GuidList readonly,
@createdBy uniqueidentifier,
@success int out,
@errorMessage nvarchar(max) out
as
begin
set nocount on;
begin try
begin tran;
select @success = 1
select @errorMessage = ''
end try
begin catch
if @@trancount > 0
begin
rollback tran;
end
declare @errmsg nvarchar(max)
set @errmsg =
(select 'ErrorNumber: ' + cast(error_number() as nvarchar(50))+
'ErrorSeverity: ' + cast(error_severity() as nvarchar(50))+
'ErrorState: ' + cast(error_state() as nvarchar(50))+
'ErrorProcedure: ' + cast(error_procedure() as nvarchar(50))+
'ErrorLine: ' + cast(error_number() as nvarchar(50))+
'error_message: ' + cast(error_message() as nvarchar(4000))
)
print @errmsg
select @success = 0
select @errorMessage = @message
return;
end catch;
if @@trancount > 0
begin
commit tran;
end
end
go
3. 使用此存储过程的 SQL 代码
在 SQL 中,您可以使用以下代码:
declare @p3 dbo.GuidList
insert into @p3 values('f811b88a-bfad-49d9-b9b9-6a1d1a01c1e5')
exec sp_executesql N'exec GenerateInvoice @listIds, @CreatedBy, @success',N'@listIds [dbo].[GuidList] READONLY,@CreatedBy uniqueidentifier',@listIds=@p3,@CreatedBy='FFFFFFFF-FFFF-FFFF-FFFF-FFFFFFFFFFFF'
4. 使用此存储过程的 C# 代码
以下是如何从 Entity Framework(在 WebAPI 中)调用该存储过程的方法:
[HttpPost]
[AuthorizeExtended(Roles = "User, Admin")]
[Route("api/BillingToDo/GenerateInvoices")]
public async Task<IHttpActionResult> GenerateInvoices(BillingToDoGenerateInvoice model)
{
try
{
using (var db = new YOUREntities())
{
var tableSchema = new List<SqlMetaData>(1)
{
new SqlMetaData("Id", SqlDbType.UniqueIdentifier)
}.ToArray();
var table = new List<SqlDataRecord>();
for (int i = 0; i < model.elements.Count; i++)
{
var tableRow = new SqlDataRecord(tableSchema);
tableRow.SetGuid(0, model.elements[i]);
table.Add(tableRow);
}
SqlParameter[] parameters =
{
new SqlParameter
{
SqlDbType = SqlDbType.Structured,
Direction = ParameterDirection.Input,
ParameterName = "listIds",
TypeName = "[dbo].[GuidList]",
Value = table
},
new SqlParameter
{
SqlDbType = SqlDbType.UniqueIdentifier,
Direction = ParameterDirection.Input,
ParameterName = "createdBy",
Value = CurrentUser.Id
},
new SqlParameter
{
SqlDbType = SqlDbType.Int,
Direction = ParameterDirection.Output,
ParameterName = "success"
},
new SqlParameter
{
SqlDbType = SqlDbType.NVarChar,
Size = -1,
Direction = ParameterDirection.Output,
ParameterName = "errorMessage"
}
};
await db.Database.ExecuteSqlCommandAsync(TransactionalBehavior.DoNotEnsureTransaction,
"exec GenerateInvoice @listIds, @createdBy, @success out, @errorMessage out", parameters);
int retValue;
if (parameters[2].Value != null && Int32.TryParse(parameters[2].Value.ToString(), out retValue))
{
if (retValue == 1)
{
return Ok("Invoice generated successfully");
}
}
string retErrorMessage = parameters[3].Value?.ToString();
return BadRequest(String.IsNullOrEmpty(retErrorMessage) ? "Invoice was not generated" : retErrorMessage);
}
}
catch (Exception e)
{
return BadRequest(e.Message);
}
}
}
希望这能有所帮助!