实体框架插入行没有我调用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方法,结果发现我没有调用!

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

发生什么事了?

提前感谢!

实体框架插入行没有我调用AddToObject()

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

cus.InsertedByUser = user;

如果你的User实体有一个客户集合(作为InsertedByUser的逆导航属性),那么POCO生成器将创建一个固定方法,它做的事情像…

InsertedByUser.Customers.Add(this);

…在你的例子中,thiscus。这是在InsertedByUser属性的setter中调用的。这意味着您新创建的客户cus将自动添加到您分配的userCustomers集合中。EF变更检测将识别这一点,并将处于Added状态的新客户放入上下文中。当您调用SaveChanges时,将在数据库中创建一个新的客户记录。

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

设置

cus.InsertedByUser = user;

您的客户将被添加到用户中。表示多对一的另一端的客户集合。这会给EF一个对象的句柄,这个句柄随后会被添加到上下文中并保存,因为它是新的。