实体框架,控制新对象的创建

时间:2012-05-14 13:42:16

标签: entity-framework controls createobject

我正在尝试更新类事务

的对象
    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是用户对象

的集合
    public long Id { get; set; }
    public long UserId { get; set; }

此处Id是自动生成的,UserId将由代码提供。

我想要做的是,每当我创建一个新事务时,只有当用户不在数据库中时才应该创建一个新用户。

我目前正在使用DbContext.Transactions.Add( new transaction )。每次创建新事务时,这显然会在数据库中创建一个新用户。

我目前采用的解决方案是仅对尝试执行相同操作的用户实体使用自定义存储过程。但是我也得到了以下错误

已成功提交对数据库的更改,但更新对象上下文时发生错误。 ObjectContext可能处于不一致状态。内部异常消息:AcceptChanges无法继续,因为对象的键值与ObjectStateManager中的另一个对象冲突。在调用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

有人能说出最好的方法是什么?创建存储过程是正确的方法吗?

1 个答案:

答案 0 :(得分: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();

如果您的操作对性能非常重要,那么正确的方法可能是存储过程。