实体框架插入行没有我调用AddToObject()? [英] Entity Framework inserts row without me calling AddToObject()?
问题描述
int customerId =< from_somewhere_doesnt_matter> ;;
客户托管
if(int.TryParse(Request.QueryString [cid],out customerId)){
//更新现有客户
cus = db.Customers.Single(c => c.CustomerId == customerId);
cus.UpdatedByUser = user;
cus.Updated = DateTime.Now;
}
else {
//创建新客户
cus = new Customer();
cus.InsertedByUser = user;
cus.Inserted = DateTime.Now;
}
SetFields(cus);
db.SaveChanges();
SetFields()方法只是从相应的Web表单字段填充客户的不同属性。 / p>
我已经在生产中运行了这段代码已经有一段时间了,它一直工作正常。然而,最近一位用户告诉我,添加新用户并不奏效(不经常发生)。我检查了这一点,当然,我填写了表单并试图添加用户,但是只是重定向到用户列表,没有任何错误消息,没有新的用户。
我检查了代码,意识到在添加新用户时,我忘记添加了db.Users.AddObject(usr)。我添加了方法调用,并且用户被正确添加。然后我去了客户代码,只是为了检查我在这里调用AddObject-method的方式和时间,原来我没有!
我可能是盲人,但我已经搜索源代码,我不会在任何地方调用该方法,它仍然可以添加一个客户!我唯一可以想到的是,客户被添加,因为它引用另一个对象(当前用户),并以某种方式触发添加。用户不依赖于任何其他字段。
发生了什么!
提前感谢! / p>
原因可能是自动关联fixup。 EF 4.0的T4模板POCO生成器例如创建在属性设置器中调用的这样的方法。可能在您的代码中的这一行发生:
cus.InsertedByUser = user;
如果您的用户
实体具有客户(作为反向导航属性为 InsertedByUser
),则POCO生成器将创建一个修复方法,该方法执行类似于...
InsertedByUser.Customers.Add(this);
...其中这个
是 cus
在你的例子中。这在 InsertedByUser
属性的setter中调用。这意味着您的新创建的客户 cus
将自动添加到用户的
您指定的。 EF变更检测将认识到这一点,并将新客户放在客户
集合中中添加
状态到上下文中。当您调用 SaveChanges
时,将创建一个新的客户记录。
只是假设。您可以通过调试进入属性设置器来详细了解发生了什么。
Okay, so it's late and I'm tired, but this shouldn't be happening... or so I believe. I have the following code for an event handler for a button click where I create a new customer from a web form.
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();
The SetFields() method just populates the different properties for the customer from the corresponding web form fields.
I have been running this code in production for quite a while and it's been working fine. However, recently a user told me it doesn't work to add a new user (doesn't happen very often). I checked it, and sure enough, I filled in the form and tried to add the user but was just redirected back to the user list without any error message and without a new user.
I checked the code, and realised I had forgotten to add the db.Users.AddObject(usr) when adding a new user. I added the method call, and the user was added correctly. I then went to the customer code, just to check how and when I call the AddObject-method there, and it turns out I don't!
I might be blind, but I have searched the source code and I do not call the method anywhere and it still works to add a customer! The only thing I can think of is that the customer is added because it refers to another object (the current user), and that somehow triggers an add. The user does not depend on any other fields.
What is happening!?
Thanks in advance!
The reason might be automatic association fixup. The T4 Template POCO Generator of EF 4.0 for instance creates such methods which are called in the property setters. Possibly it happens in this line in your code:
cus.InsertedByUser = user;
If your User
entity has a collection of customers (as the inverse navigation property to InsertedByUser
) then the POCO Generator would create a fixup method which does something like ...
InsertedByUser.Customers.Add(this);
... where this
is cus
in your example. This is called in the setter for the InsertedByUser
property. This means that your new created customer cus
is automatically added to the Customers
collection of the user
which you assign. EF change detection will recognize this and put the new customer in Added
state into the context. When you call SaveChanges
a new customer record in the database is created.
Just a hypothesis. You could check in detail what's going on by debugging into the property setter.
这篇关于实体框架插入行没有我调用AddToObject()?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!