0

クラスTransactionのオブジェクトを更新しようとしています

    public int Id { get; set; }
    public System.DateTime Date { get; set; }
    public string Remarks { get; set; }
    public double Amount { get; set; }
    public Nullable<long> GroupId { get; set; }
    public long UserId { get; set; }

    public virtual ICollection<User> PaidForUsers { get; set; }
    public virtual User PaidByUser { get; set; }

要素PaidForUsersは、Userオブジェクトのコレクションです。

    public long Id { get; set; }
    public long UserId { get; set; }

ここで、Idは自動生成され、UserIdはコードによって提供されます。

私がやろうとしているのは、新しいトランザクションを作成するときはいつでも、ユーザーがデータベースにまだ存在していない場合にのみ、新しいユーザーを作成する必要があるということです。

現在、DbContext.Transactions.Add(new transaction)を使用しています。これにより、新しいトランザクションを作成するたびに、データベースに新しいユーザーが作成されることは明らかです。

私が現在採用している解決策は、同じことを行おうとするユーザーエンティティに対してのみカスタムストアドプロシージャを使用することです。しかし、その中で次のエラーが発生します

データベースへの変更は正常にコミットされましたが、オブジェクトコンテキストの更新中にエラーが発生しました。ObjectContextが一貫性のない状態になっている可能性があります。内部例外メッセージ:オブジェクトのキー値がObjectStateManager内の別のオブジェクトと競合しているため、AcceptChangesを続行できません。AcceptChangesを呼び出す前に、キー値が一意であることを確認してください。

これがストアドプロシージャです-

ALTER PROCEDURE [dbo].[InsertUser]
    (@UserId bigint )
AS
declare @val bigint
declare @countza int

SELECT @val= Id  FROM dbo.Users1 where UserId = @UserId
set @countza = @@Rowcount

    if @countza = 0
    begin
    insert into dbo.Users1 (UserId) values (@UserId)
    select [Id] from [dbo].[Users1] 
            where @@ROWCOUNT > 0 and [Id] = scope_identity() 

    end
    else
    begin
        SELECT  'Id' = @val
    end

誰かがこれを行うための最良の方法を教えてもらえますか?ストアドプロシージャを作成することは、それを実行する正しい方法ですか?

4

1 に答える 1

0

「通常の」状況では、正しい方法はLINQを使用することです。

UserId(一意である必要があると想定していますが、主キーではありません(つまりId))

var transaction = context.Transactions.Create();
var user = context.Users.SingleOrDefault(u => u.UserId == userId);
if (user != null)
    transaction.PaidForUsers.Add(user);
else
    transaction.PaidForUsers.Add(new User { UserId = userId });
context.Transactions.Add(transaction);
context.SaveChanges();

操作のパフォーマンスが非常に重要な場合、適切な方法はストアド プロシージャである可能性があります。

于 2012-05-14T15:32:57.547 に答える