2011-07-10 48 views
0

好吧,所以迟到了,我累了,但这不应该发生......或者我相信。我有一个按钮点击事件处理程序的代码,我从Web表单创建一个新客户。实体框架在没有我调用AddToObject()的情况下插入行?

int customerId = <from_somewhere_doesnt_matter>; 
Customer cust; 

if (int.TryParse(Request.QueryString["cid"], out customerId)) { 
    // update existing customer 
    cus = db.Customers.Single(c => c.CustomerId == customerId); 
    cus.UpdatedByUser = user; 
    cus.Updated = DateTime.Now; 
    } 
else { 
    // create new customer 
    cus = new Customer(); 
    cus.InsertedByUser = user; 
    cus.Inserted = DateTime.Now; 
} 

SetFields(cus); 
db.SaveChanges(); 

SetFields()方法只是从相应的Web表单域填充客户的不同属性。

我一直在生产中运行此代码很长一段时间,它一直工作正常。但是,最近一位用户告诉我,添加新用户无效(不经常发生)。我检查了它,果然,我填写了表单并试图添加用户,但是只是重定向回用户列表,没有任何错误消息,也没有新用户。

我检查了代码,并且意识到我忘记了在添加新用户时添加了db.Users.AddObject(usr)。我添加了方法调用,并且用户被正确添加。然后,我去了客户代码,只是为了检查如何以及何时在那里调用AddObject方法,事实证明我不知道!

我可能会失明,但我搜索了源代码,并且我没有在任何地方调用该方法,它仍然可以添加一个客户!我能想到的唯一的事情就是添加了客户,因为它引用了另一个对象(当前用户),并以某种方式触发了添加。用户不依赖任何其他字段。

发生了什么!?

在此先感谢!

+0

这是确切的代码? ESP。 'cus = new Customer();'? –

回答

0

原因可能是自动关联修复。例如,EF 4.0的T4模板POCO生成器创建了在属性设置器中调用的这种方法。也许它发生在这一行代码:

cus.InsertedByUser = user; 

如果您User实体有客户的集合(如逆导航属性InsertedByUser),那么POCO发生器会产生这确实有点像修正方法.. 。

InsertedByUser.Customers.Add(this); 

...其中this是你的榜样cus。这在InsertedByUser属性的setter中被调用。这意味着您创建的新客户cus会自动添加到您分配的userCustomers集合中。 EF更改检测将识别此并将新客户置于上下文中Added状态。当您致电SaveChanges时,会创建数据库中的新客户记录。

只是一个假设。您可以通过调试属性设置器来详细检查发生了什么。

+0

这就是它。真的令人困惑,但...谢谢:) – joscarsson

0

当您设置

cus.InsertedByUser = user; 

您的客户将被添加到user.Customers集合,表示的另一端多到一个。这给EF提供了一个对象的句柄,该句柄将被添加到上下文中并且因为它是新的而被保存起来。

+0

显然,我只能标记一个答案作为正确的答案,即使这是正确的,如welll :)感谢您的答复! – joscarsson

相关问题