2012-03-14 55 views
2

我在MVC 3應用程序中使用實體框架4.3和Code-First。我有一個POST操作獲取實體作爲其參數,然後將實體標記爲已修改以更新數據庫。它是一個文檔實體,它具有對文件類型的引用。EF4.3代碼優先,MVC,加入POST後的延遲加載操作

[HttpPost] 
public ActionResult Example(Document model) 
{ 
    // fileType is null, as expected 
    var fileType = model.FileType; 

    // attach and mark the entity as modified, save changes 
    Context.Entry(model).State = EntityState.Modified; 
    Context.SaveChanges(); 

    // fileType is still null? 
    fileType = model.FileType; 

    return View(model); 
} 

將一個實體附加到上下文之後,我不應該能夠在該實體上延遲加載屬性嗎?

有趣的是,當我在控制檯應用程序中嘗試這個時,它似乎工作。

static void Main() 
{ 
    // create a new context 
    var context = new Context(); 

    // get the first document and detach it 
    var doc = context.Documents.First(); 
    context.Entry(doc).State = EntityState.Detached; 

    // fileType is null, as expected 
    var fileType = doc.FileType; 

    // dispose and create a new context 
    context.Dispose(); 
    context = new Context(); 

    // attach the entity and mark it as modified 
    context.Entry(doc).State = EntityState.Modified; 

    // fileType is not null, which is the desired outcome 
    fileType = doc.FileType; 
} 

回答

6

的問題是,傳遞給POST方法的實體不是代理,大概是因爲它是實體Framewortk之外使用正常的「新」運算符創建。

這裏有幾個選項。首先,您可以使用DbSet.Create方法修改MVC控制器以創建代理實例。我聽說有可能以這種方式修改MVC控制器,但從來沒有嘗試過。例如,而不是這樣做的:

var doc = new Document(); 

控制器,你會怎麼做:

var doc = context.Documents.Create(); 

的創建方法讓EF創建延遲加載代理,如果實體有相應的虛擬屬性,在你的情況下,它看起來像它。

第二種可能更簡單的選擇是不使用延遲加載,而是使用顯式加載API。例如,要加載的文件類型:

var fileType = context.Entry(doc).Reference(d => d.FileType).Load(); 

不太可能延遲加載,這需要一個明確的參考範圍內,但在你的情況應該沒問題。

+3

謝謝!使用你的解釋,我能夠找到一個簡單的解決方案來實現一個生成代理的模型聯編程序。這裏是幫助我的文章的鏈接。 http://bit.ly/ydCjOm – user326502 2012-03-14 04:30:40

+0

@ user326502感謝您的鏈接。超級有用 – 2015-03-19 09:33:09