我尝试使用context.Database.ExecuteSqlCommand
从EF调用存储过程,因为我的一个参数是数据表。
以下是程序的参数:
ALTER PROCEDURE [mySchema].[myProc]
@customerId INT,
@indicatorTypeId INT,
@indicators [mySchema].[IndicatorList] READONLY,
@startDate DATETIME,
@endDate DATETIME
这是调用存储过程的c#代码:
var indicatorsDt = new DataTable();
indicatorsDt.Columns.Add("Date", typeof(DateTime));
indicatorsDt.Columns.Add("Ongoing", typeof(int));
indicatorsDt.Columns.Add("Success", typeof(int));
indicatorsDt.Columns.Add("Warning", typeof(int));
indicatorsDt.Columns.Add("Error", typeof(int));
indicatorsDt.Columns.Add("Other", typeof(int));
var customerIdParam = new SqlParameter("customerId", SqlDbType.Int);
customerIdParam.Value = customerId;
var typeIdParam = new SqlParameter("indicatorTypeId", SqlDbType.Int);
typeIdParam.Value = typeId;
var startDateParam = new SqlParameter("startDate", SqlDbType.DateTime);
startDateParam.Value = startDate;
var endDateParam = new SqlParameter("endDate", SqlDbType.DateTime);
endDateParam.Value = endDate;
foreach (var indicator in indicators)
{
indicatorsDt.Rows.Add(indicator.Date, indicator.Ongoing,
indicator.Success, indicator.Warning,
indicator.Error, indicator.Other);
}
var tableParameter = new SqlParameter("indicators", SqlDbType.Structured);
tableParameter.Value = indicatorsDt;
tableParameter.TypeName = "MySchema.IndicatorList";
context.Database.ExecuteSqlCommand("exec MySchema.MyProc", customerIdParam, typeIdParam, tableParameter, startDateParam, endDateParam);
正如您所看到的,提供了所有参数,它们都没有空值,但我总是得到SqlException
:
程序或功能' UpdateIndicators'期望参数 ' @ customerId',未提供。
我无法弄清楚我错过了什么。使用SqlParameter
是错误的吗?参数在ExecuteSqlCommand
中以相同的顺序提供,即使它不重要。
提前感谢。
答案 0 :(得分:0)
试试这个:
var customerIdParam = new SqlParameter("@customerId", SqlDbType.Int);
答案 1 :(得分:0)
以下是我目前使用参数调用存储过程的方法。用您自己的参数名称/值替换参数名称/值。请记住,您可能必须按照存储过程中声明的顺序列出参数。
创建一个SqlParameter数组:
SqlParameter[] parameters = new SqlParameter[] {
new SqlParameter("@ParamName1", Value1),
new SqlParameter("@ParamName2", Value2),
new SqlParameter("@ParamName3", Value3),
new SqlParameter("@ParamName4", Value4),
new SqlParameter("@ParamName5", Value5)
};
然后调用您的存储过程:
_context.Database.ExecuteSqlCommand(DbHelper.GenerateCommandText("SpName", parameters), parameters);
这是DbHelper代码:
public class DbHelper
{
public static string GenerateCommandText(string storedProcedure, SqlParameter[] parameters)
{
string CommandText = "EXEC {0} {1}";
string[] ParameterNames = new string[parameters.Length];
for (int i = 0; i < parameters.Length; i++)
{
ParameterNames[i] = parameters[i].ParameterName;
}
return string.Format(CommandText, storedProcedure, string.Join(",", ParameterNames));
}
}
答案 2 :(得分:0)
这有效:
var bookIdParameter = new SqlParameter();
bookIdParameter.ParameterName = "@BookId";
bookIdParameter.Direction = ParameterDirection.Output;
bookIdParameter.SqlDbType = SqlDbType.Int;
var authors = context.Database.ExecuteSqlCommand("usp_CreateBook @BookName, @ISBN, @BookId OUT",
new SqlParameter("@BookName", "Book"),
new SqlParameter("@ISBN", "ISBN"),
bookIdParameter);
答案 3 :(得分:0)
存储库
public async Task<int> ExecuteStoredProcedure(string sqlQuery,int user_id, T entity, params object[] parameters)
{
const int ENTITY_ID_INDEX = 19;
var result= _context.Database.ExecuteSqlCommand(sqlQuery, parameters);
var history = _context.History.AddAsync(new History { CreatedDate = DateTime.Now, EventId = Events.CREATE_EVENT_ID, ObjectId =Convert.ToInt32(((SqlParameter) parameters[ENTITY_ID_INDEX]).Value), ObjectStr = JsonConvert.SerializeObject(entity), ObjectName = entity.GetType().Name, UserId = user_id });
_context.SaveChanges();
return result;
}
存储过程
ALTER PROCEDURE [dbo].[spInboxDocumentAdd]
@DocumentTypeId int,
@DocumentKindId int,
@DocumentKindCode nvarchar(50),
@RegistrationDate datetime,
@ApplicantId int,
@ApplicantAddress nvarchar(255),
@ApplicantFullName nvarchar(255),
@DocumentDate datetime,
@DocumentNumber nvarchar(255),
@IsForInformation bit,
@IsForControl bit,
@DeadlineDate datetime,
@ReminderDate datetime,
@SummaryId int,
@UserId int,
@Note nvarchar(255),
@Mail nvarchar(255),
@Account nvarchar(10),
@RegistrationNumber nvarchar(50) Output,
@CurrentId int
AS
Declare @OrderNumber int,@CreatedDate datetime, @RegistrationNumberIn nvarchar(50), @Deleted bit
SET @CreatedDate=SYSDATETIME();
SET @OrderNumber=ISNULL((SELECT MAX(OrderNumber)+1 FROM dbo.InboxDocuments WHERE DocumentKindId=@DocumentKindId AND YEAR(CreatedDate)=YEAR(@CreatedDate)),0);
IF (@OrderNumber IS NULL)
BEGIN
SET @OrderNumber=0;
END
SET @RegistrationNumberIn=CONVERT(nvarchar(50),@DocumentKindCode+'/'+CONVERT(nvarchar(50),@OrderNumber)+'-'+CONVERT(nvarchar(50),YEAR(@CreatedDate)));
SET @Deleted=0;
INSERT INTO [dbo].[InboxDocuments]
([DocumentTypeId]
,[DocumentKindId]
,[OrderNumber]
,[RegistrationDate]
,[RegistrationNumber]
,[CreatedDate]
,[ApplicantId]
,[ApplicantAddress]
,[ApplicantFullName]
,[DocumentDate]
,[DocumentNumber]
,[IsForInformation]
,[IsForControl]
,[DeadlineDate]
,[ReminderDate]
,[SummaryId]
,[Deleted]
,[UserId]
,[Note]
,[Mail]
,[Account])
VALUES
(
@DocumentTypeId,
@DocumentKindId,
@OrderNumber,
@RegistrationDate,
@RegistrationNumberIn,
@CreatedDate,
@ApplicantId,
@ApplicantAddress,
@ApplicantFullName,
@DocumentDate,
@DocumentNumber,
@IsForInformation,
@IsForControl,
@DeadlineDate,
@ReminderDate,
@SummaryId,
@Deleted,
@UserId,
@Note,
@Mail,
@Account
);
SET @CurrentId= @@IDENTITY;
SET @RegistrationNumber=@RegistrationNumberIn;
SELECT @RegistrationNumber;
RETURN @CurrentId;
控制器
private string CreateInboxDocument(InboxDocuments inboxDocument, string documentKindCode, int user_id)
{
const int REGISTRATION_DATE_INDEX = 18;
const int ENTITY_ID = 19;
SqlParameter DocumentTypeId = new SqlParameter();
DocumentTypeId.ParameterName = "@DocumentTypeId";
DocumentTypeId.SqlDbType = SqlDbType.Int;
DocumentTypeId.Direction = ParameterDirection.Input;
DocumentTypeId.Value = inboxDocument.DocumentTypeId;
SqlParameter DocumentKindId = new SqlParameter();
DocumentKindId.ParameterName = "@DocumentKindId";
DocumentKindId.SqlDbType = SqlDbType.Int;
DocumentKindId.Direction = ParameterDirection.Input;
DocumentKindId.Value = inboxDocument.DocumentKindId;
SqlParameter DocumentKindCode = new SqlParameter();
DocumentKindCode.ParameterName = "@DocumentKindCode";
DocumentKindCode.SqlDbType = SqlDbType.VarChar;
DocumentKindCode.Size = 50;
DocumentKindCode.Direction = ParameterDirection.Input;
DocumentKindCode.Value = documentKindCode;
SqlParameter RegistrationDate = new SqlParameter();
RegistrationDate.ParameterName = "@RegistrationDate";
RegistrationDate.SqlDbType = SqlDbType.DateTime;
RegistrationDate.Direction = ParameterDirection.Input;
RegistrationDate.Value = inboxDocument.RegistrationDate;
SqlParameter ApplicantId = new SqlParameter();
ApplicantId.ParameterName = "@ApplicantId";
ApplicantId.SqlDbType = SqlDbType.Int;
ApplicantId.Direction = ParameterDirection.Input;
ApplicantId.Value = inboxDocument.ApplicantId;
SqlParameter ApplicantAddress = new SqlParameter();
ApplicantAddress.ParameterName = "@ApplicantAddress";
ApplicantAddress.SqlDbType = SqlDbType.VarChar;
ApplicantAddress.Size = 50;
ApplicantAddress.Direction = ParameterDirection.Input;
ApplicantAddress.Value = documentKindCode;
SqlParameter ApplicantFullName = new SqlParameter();
ApplicantFullName.ParameterName = "@ApplicantFullName";
ApplicantFullName.SqlDbType = SqlDbType.VarChar;
ApplicantFullName.Size = 50;
ApplicantFullName.Direction = ParameterDirection.Input;
ApplicantFullName.Value = documentKindCode;
SqlParameter DocumentDate = new SqlParameter();
DocumentDate.ParameterName = "@DocumentDate";
DocumentDate.SqlDbType = SqlDbType.DateTime;
DocumentDate.Direction = ParameterDirection.Input;
DocumentDate.Value = inboxDocument.RegistrationDate;
SqlParameter IsForInformation = new SqlParameter();
IsForInformation.ParameterName = "@IsForInformation";
IsForInformation.SqlDbType = SqlDbType.Bit;
IsForInformation.Direction = ParameterDirection.Input;
IsForInformation.Value = inboxDocument.IsForInformation;
SqlParameter IsForControl = new SqlParameter();
IsForControl.ParameterName = "@IsForControl";
IsForControl.SqlDbType = SqlDbType.Bit;
IsForControl.Direction = ParameterDirection.Input;
IsForControl.Value = inboxDocument.IsForControl;
SqlParameter DeadlineDate = new SqlParameter();
DeadlineDate.ParameterName = "@DeadlineDate";
DeadlineDate.SqlDbType = SqlDbType.DateTime;
DeadlineDate.Direction = ParameterDirection.Input;
DeadlineDate.Value = inboxDocument.DeadlineDate;
SqlParameter ReminderDate = new SqlParameter();
ReminderDate.ParameterName = "@ReminderDate";
ReminderDate.SqlDbType = SqlDbType.DateTime;
ReminderDate.Direction = ParameterDirection.Input;
ReminderDate.Value = inboxDocument.RegistrationDate;
SqlParameter UserId = new SqlParameter();
UserId.ParameterName = "@UserId";
UserId.SqlDbType = SqlDbType.Int;
UserId.Direction = ParameterDirection.Input;
UserId.Value = inboxDocument.UserId;
SqlParameter Note = new SqlParameter();
Note.ParameterName = "@Note";
Note.SqlDbType = SqlDbType.VarChar;
Note.Size = 255;
Note.Direction = ParameterDirection.Input;
Note.Value = inboxDocument.Note;
SqlParameter Mail = new SqlParameter();
Mail.ParameterName = "@Mail";
Mail.SqlDbType = SqlDbType.VarChar;
Mail.Size = 255;
Mail.Direction = ParameterDirection.Input;
Mail.Value = inboxDocument.Mail;
SqlParameter Account = new SqlParameter();
Account.ParameterName = "@Account";
Account.SqlDbType = SqlDbType.VarChar;
Account.Size = 255;
Account.Direction = ParameterDirection.Input;
Account.Value = inboxDocument.Account;
SqlParameter CurrentId = new SqlParameter();
CurrentId.ParameterName = "@CurrentId";
CurrentId.SqlDbType = SqlDbType.Int;
CurrentId.Direction = ParameterDirection.Output;
CurrentId.Value = 0;
SqlParameter DocumentNumber = new SqlParameter();
DocumentNumber.ParameterName = "@DocumentNumber";
DocumentNumber.SqlDbType = SqlDbType.VarChar;
DocumentNumber.Size = 50;
DocumentNumber.Direction = ParameterDirection.Output;
DocumentNumber.Value = inboxDocument.DocumentNumber;
SqlParameter RegistrationNumber = new SqlParameter();
RegistrationNumber.ParameterName = "@RegistrationNumber";
RegistrationNumber.SqlDbType = SqlDbType.VarChar;
RegistrationNumber.Size = 50;
RegistrationNumber.Direction = ParameterDirection.Output;
RegistrationNumber.Value = "";
SqlParameter SummaryId = new SqlParameter();
SummaryId.ParameterName = "@SummaryId";
SummaryId.SqlDbType = SqlDbType.Int;
SummaryId.Direction = ParameterDirection.Input;
SummaryId.Value = inboxDocument.SummaryId;
using (var unitOfWork = new UnitOfWork(new DbContext.ApplicationDbContext(workflow_optionsBuilder.Options)))
{
SqlParameter[] @params = new SqlParameter[] { DocumentTypeId, DocumentKindId, DocumentKindCode, RegistrationDate, ApplicantId, ApplicantAddress, ApplicantFullName, DocumentDate, DocumentNumber, IsForInformation, IsForControl, DeadlineDate, ReminderDate, SummaryId, UserId, Note, Mail, Account, RegistrationNumber, CurrentId };
var row_affected = unitOfWork.InboxDocuments.ExecuteStoredProcedure("exec @CurrentId=spInboxDocumentAdd @DocumentTypeId, @DocumentKindId, @DocumentKindCode, @RegistrationDate, @ApplicantId, @ApplicantAddress, @ApplicantFullName, @DocumentDate, @DocumentNumber, @IsForInformation, @IsForControl, @DeadlineDate, @ReminderDate,@SummaryId, @UserId, @Note, @Mail, @Account,@RegistrationNumber OUTPUT, @CurrentId", user_id, inboxDocument, @params);
CurrentDocumentId = Convert.ToInt32(@params[ENTITY_ID].Value);
return @params[REGISTRATION_DATE_INDEX].Value.ToString();
}
}
答案 4 :(得分:-2)
您缺少正在执行的SQL字符串中的参数。尝试使用&#34; @&#34;创建参数。在名称前面,然后将ExecuteSqlCommand调用更改为:
context.Database.ExecuteSqlCommand("exec MySchema.MyProc @customerId, @indicatorTypeId, @indicators, @startDate, @endDate", customerIdParam, typeIdParam, tableParameter, startDateParam, endDateParam);