实体框架插入行没有我调用AddToObject()
本文关键字:AddToObject 调用 没有我 框架 插入 实体 | 更新日期: 2023-09-27 18:01:54
好吧,现在很晚了,我也很累,但这不应该发生……至少我是这么认为的。我有一个事件处理程序的一个按钮点击,我从一个web表单创建一个新的客户下面的代码。
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)。我添加了方法调用,并且正确地添加了用户。然后我转到客户代码,只是为了检查如何以及何时调用那里的addoobject方法,结果发现我没有调用!我可能是盲目的,但我已经搜索了源代码,我没有在任何地方调用该方法,它仍然可以添加客户!我能想到的唯一一件事是,客户被添加是因为它引用了另一个对象(当前用户),并且以某种方式触发了添加。用户不依赖于任何其他字段。
发生什么事了?
提前感谢!
原因可能是自动关联修复。例如,EF 4.0的T4模板POCO生成器创建了在属性设置中调用的方法。可能发生在代码中的这一行:
cus.InsertedByUser = user;
如果你的User
实体有一个客户集合(作为InsertedByUser
的逆导航属性),那么POCO生成器将创建一个固定方法,它做的事情像…
InsertedByUser.Customers.Add(this);
…在你的例子中,this
是cus
。这是在InsertedByUser
属性的setter中调用的。这意味着您新创建的客户cus
将自动添加到您分配的user
的Customers
集合中。EF变更检测将识别这一点,并将处于Added
状态的新客户放入上下文中。当您调用SaveChanges
时,将在数据库中创建一个新的客户记录。
只是一个假设。您可以通过调试属性设置器来详细检查发生了什么。
设置
cus.InsertedByUser = user;
您的客户将被添加到用户中。表示多对一的另一端的客户集合。这会给EF一个对象的句柄,这个句柄随后会被添加到上下文中并保存,因为它是新的。