これは私が使用しているサンプルのストアドプロシージャです
CREATE PROCEDURE [dbo].[CreateCustomer]
@firstName nvarchar(50) = null,
@lastName nvarchar(50) = null,
@emailAddress nvarchar(50),
@contactNumber varchar(15) =null,
@street1 nvarchar(50) = null,
@street2 nvarchar(50) = null,
@city nvarchar(50) = null,
@State nvarchar(50)= null,
@Country nvarchar(50)=null,
@postalCode varchar(5) = null,
@middleName nvarchar(50),
@password nvarchar(50),
@membershipExpieryDate datetime,
@status int OUT
AS
BEGIN TRY
BEGIN TRANSACTION
SAVE TRANSACTION initialP
DECLARE @lastAccessed datetime = GETDATE()
DEClARE @uniqueCustomerID UNIQUEIDENTIFIER= NEWID()
BEGIN TRANSACTION
INSERT INTO Customers(CustomerID, FirstName, LastName, EmailAddress, LastAccessed, ContactNumber,
Street1, Street2, City, State, Country, PostalCode, MiddleName, Password, MembershipExpieryDate)
VALUES(@uniqueCustomerID,@firstName, @lastName, @emailAddress, @lastAccessed, @contactNumber, @street1, @street2,
@city, @State, @Country, @postalCode, @middleName, @password, @membershipExpieryDate)
INSERT INTO Roles(CustomersCustomerID,Role) VALUES(@uniqueCustomerID,'V')
COMMIT
SELECT CustomerID, FirstName, LastName, EmailAddress, LastAccessed, ContactNumber,
Street1, Street2, City, State, Country, PostalCode, MiddleName, MembershipExpieryDate FROM Customers WHERE EmailAddress = @emailAddress
SET @status =1
COMMIT
END TRY
BEGIN CATCH
IF(@@TRANCOUNT > 0)
BEGIN
ROLLBACK TRANSACTION initialP
END
SET @status =2
END CATCH
そして、これは私がクエリデータを取得するために使用しているコードです:
ObjectParameter status = new ObjectParameter("status", typeof(int));
var dataSet = Entity.CreateCustomer(newCustomer.FirstName, newCustomer.LastName,
newCustomer.EmailAddress, newCustomer.ContactNumber, newCustomer.Street1, newCustomer.Street2,
newCustomer.City, newCustomer.State, newCustomer.Country, newCustomer.PostalCode, newCustomer.MiddleName,
newCustomer.Password, newCustomer.MembershipExpieryDate, status);
ただし、このストアドプロシージャを実行すると、トランスカウントの不一致というエラーが発生します。私が知っているように、trans count
は発生すると1ずつbegin transaction
増加し、発生すると1つ減少しcommit
ます。複合型を返す可能性があるため、関数importで関数を既にマップしました。
これで問題がわかりません。私にはそれは大丈夫のようです。私はこれを正しくやっているかどうか、いくつかの詳細で天気を知りたいです。ありがとう。
編集:これは私がサンプルコードを書くことによって見つけたものです。私は最初、トランスアクションを開始してコミットすることだと思いました。そうではありません。commitステートメントの前でも挿入される値を選択できます(間違っている場合は修正してください)。3つの列(test1の一意の識別子、test2 int、test3 int)を持つテストテーブルを作成し、ストアドプロシージャ呼び出しTestを作成しました。以下に示します。
CREATE PROCEDURE dbo.TestForCommit
(
@test11 int,
@test111 int,
@status int OUTPUT
)
AS
begin try
declare @test1 uniqueidentifier = NEWID()
begin transaction
insert into TestT1(Test1, Test11, Test111) values(@test1, @test11, @test111)
commit
select Test1, Test11, Test111 from TestT1 where Test1 = @test1
SET @status = 1
end try
begin catch
Rollback Transaction
set @status =2
end catch
/* SET NOCOUNT ON */
RETURN
エンティティモデルので機能インポートを作成し、次のように使用しました。
ObjectParameter status = new ObjectParameter("status", typeof(int));
SchoolEntities test = new SchoolEntities();
var dataSet = test.TestForCommit(1, 1, status);
//A:
//(XXXXXXXXXXXXX)Console.WriteLine((int)status.Value);
foreach (var item in dataSet)
{
TestForCommit_Result t = item;
Console.WriteLine("{0} , {1} , {2}", t.Test1, t.Test11, t.Test111);
}
//B:
Console.WriteLine((int)status.Value);
Console.ReadLine();
この//A:部分が問題を引き起こしています。これにより、null参照例外が発生します。ただし、// B:パーツは機能しており、ステータス値を示しています。私はまだそれがそのように機能している理由を探しています。ありがとう!!