C# 实体框架插入行而不调用AddToObject()?

C# 实体框架插入行而不调用AddToObject()?,c#,asp.net,entity-framework,C#,Asp.net,Entity Framework,好吧,现在很晚了,我很累,但这不应该发生。。。至少我相信是这样。我有一个按钮点击事件处理程序的以下代码,在这里我从web表单创建了一个新客户 int customerId = <from_somewhere_doesnt_matter>; Customer cust; if (int.TryParse(Request.QueryString["cid"], out customerId)) { // update existing customer cus = db

好吧,现在很晚了,我很累,但这不应该发生。。。至少我相信是这样。我有一个按钮点击事件处理程序的以下代码,在这里我从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();
intcustomerid=;
客户客户;
if(int.TryParse(Request.QueryString[“cid”],out customerId)){
//更新现有客户
cus=db.Customers.Single(c=>c.CustomerId==CustomerId);
cus.UpdatedByUser=用户;
cus.Updated=DateTime.Now;
}
否则{
//创建新客户
cus=新客户();
cus.InsertedByUser=用户;
cus.Inserted=DateTime.Now;
}
设置域(CU);
db.SaveChanges();
SetFields()方法只是从相应的web表单字段填充客户的不同属性

我已经在生产环境中运行这段代码很长一段时间了,它工作得很好。然而,最近一位用户告诉我,添加一个新用户不起作用(这种情况并不经常发生)。我检查了它,果然,我填写了表单并尝试添加用户,但被重定向回用户列表,没有任何错误消息,也没有新用户

我检查了代码,意识到我在添加新用户时忘记添加db.Users.AddObject(usr)。我添加了方法调用,用户添加正确。然后我转到客户代码,只是为了检查如何以及何时在那里调用AddObject方法,结果发现我没有

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

发生了什么事

提前谢谢

当您设置

cus.InsertedByUser = user;

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

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

cus.InsertedByUser = user;
如果您的
用户
实体有一组客户(作为
InsertedByUser
的反向导航属性),则POCO生成器将创建一个修复方法,该方法类似于

InsertedByUser.Customers.Add(this);
。。。其中,
在您的示例中,此
cus
。这在setter中为
InsertedByUser
属性调用。这意味着您新创建的客户
cus
将自动添加到您分配的
用户的
客户
集合中。EF变更检测将识别这一点,并将新客户置于
Added
状态。调用
SaveChanges
时,将在数据库中创建新的客户记录


只是一个假设。您可以通过在属性setter中调试来详细检查正在进行的操作。

这是正确的代码吗?尤其是
cus=新客户()?一定是这样。但是真的很困惑。。。很显然,我只能将一个答案标记为正确答案,即使这也是正确的!