2013-02-28 103 views
3

我對EF沒有太多瞭解,但必須做一些錯誤修正。出現一個錯誤,如下所示:實體框架:使用篩選的子記錄獲取父記錄

  • 獲取父記錄使用ObjectContext
  • 改變一些財產
  • 保存更改

的問題是Get parent record更具體(EF LINQ查詢)只獲得父母的活躍孩子。

這是當前黑客

var data = 
    (from q in Context.Questions.Include("Status").Include("Category") 
    where q.Id == id 
    select q).SingleOrDefault(); 

var atts = Context.Answers.Where(a => a.qId == id && a.active); // 1 
data.Answers.Clear(); // 2 
foreach (var att in atts) 
{ 
    data.Answers.Add(att); // 3 
} 

會發生什麼:

  1. 從數據庫
  2. 因爲延遲加載的獲取活動子記錄,所有附件都來自取出數據庫。然後集合被立即清除。在所有活動記錄(EF跟蹤標記這些記錄爲「刪除」?)
  3. 循環並且再次將它們添加到集合(EF跟蹤標記這些記錄爲「插入」?)

我更新時出現以下異常:The operation failed: The relationship could not be changed because one or more of the foreign-key properties is non-nullable. When a change is made to a relationship, the related foreign-key property is set to a null value. If the foreign-key does not support null values, a new relationship must be defined, the foreign-key property must be assigned another non-null value, or the unrelated object must be deleted.

我假設發生了一個非常普遍的錯誤,因爲EF對清除集合感到困惑,然後又添加了一些相同的記錄。

我的問題:我只得到了積極的子記錄,並讓他們在一個「不變」狀態,以便在任何時候,EF能夠決定刪除並重新插入我的記錄怎麼辦。顯然,我也不想在更新時丟失非活動記錄。

沒有答案(是嗎?):在SO和谷歌經常被發現,但不能得到這個工作:

Context.ContextOptions.LazyLoadingEnabled = false; 

var data = 
    (from q in Context.Questions.Include("Status").Include("Category") 
    where q.qId == id 
    select new 
    { 
     Question = q, 
     Answers = q.Answer.Where(a => a.active) 
    }).ToArray().Select(q => q.Question).FirstOrDefault(); 

return data; // Does not contain the answers... :(

回答

2

您可以顯式加載屬性而不是加載它,然後清除它。這將防止不需要的對象加載到對象圖中,因此當您斷開非活動實體時不會收到錯誤。

var data = 
    (from q in Context.Questions.Include("Status").Include("Category") 
    where q.Id == id 
    select q).SingleOrDefault(); 

Context.Entry(data).Collection(b => b.Answers).Query() 
    .Where(a => a.active) 
    .Load(); 
+0

不幸的是'Entry'是在'DbContext'中定義的,它是從項目中使用的ObjectContext派生的。 – Laoujin 2013-02-28 14:41:05

+0

嘗試將您的ObjectContext轉換爲DbContext。參見[objectcontext-does-not-contain-a-definition-for-entry](http://stackoverflow.com/questions/11032683/objectcontext-does-not-contain-a-definition-for-entry-and-no -extension-metho) – 2013-02-28 14:44:01

+0

你想使用Include()和Load()嗎?我想如果你使用Load(),那麼你不需要Include()。也許我錯了。 – 2013-02-28 14:49:58

0

呼叫data.Answers.Clear()是不夠的,因爲它僅刪除你的問題和答案之間的關聯。如果您還想刪除這些答案,則還需要從上下文中刪除它們。

foreach(var answer in data.Answers) { 
    Context.DeleteObject(answer); 
} 

data.Answers.Clear(); 
+0

我不想刪除任何東西。我想'得到'一個問題和所有它的主動答案。 – Laoujin 2013-02-28 14:16:11

+0

您正在清除問題的答案,以便答案的ForeignKey設置爲NULL,除非該屬性可以爲空,否則不允許 – Jehof 2013-02-28 14:18:54

+0

清除答案是對錯誤負責的醜陋黑客。 '我不想刪除任何東西'。如果我可以在沒有任何刪除/清除的情況下實現主動答案的問題,那就太棒了。 – Laoujin 2013-02-28 14:42:43

相關問題