2011-07-10 74 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

相關問題