2009-08-14 61 views
1

是否有預構建的ModelBinder可以與LINQ一起使用從DataContext獲取對象並在HTTP Post上更新它?ASP.NET MVC,LINQ和ModelBinders

例如,目前我的代碼塊:

[AcceptVerbs (HttpVerbs.Post)] 
public ActionResult Edit (Project project) 
{ 
    var projectService = Factory.GetService<IProjectService>(); 
    project = projectService.GetProject (project.ProjectId); 

    UpdateModel<Project> (project); 

    if (!ModelState.IsValid) 
     return View (project); 

    project = projectService.SaveProject (project); 

    return RedirectToAction ("Details", new { id = project.ProjectId }); 
} 

(IProjectService包紮呼叫到LINQ數據上下文)

爲了實際經由LINQ執行更新到數據庫數據上下文,我需要再次獲取項目實例,然後更新該實例。

任何嘗試簡單地保存項目實例而不先從數據上下文中獲取結果都不會將任何內容寫回數據庫 - 我假設因爲LINQ數據上下文對它沒有做任何事情的對象一無所知用它。

在Projects表類上使用Attach方法或者btw不起作用,它會引發異常。

回答

3

你應該看看邁克哈德洛的(新BSD)實施SutekiShop

在那裏你會發現一個DataBindAttribute和BindUsingAttribute,如果我理解正確,你就可以做你想做的事情。請注意DataBindAttribute.Fetch屬性是如何用來重新綁定傳入數據的,或者不是(從HttpPost)重新綁定到LINQ實體。

我使用ASP.NET MVC和LINQ-To-SQL對這個模式進行了跟蹤。它的作品非常漂亮。

這裏的源:http://www.google.com/codesearch?hl=en&lr=&q=DataBind+package%3Ahttp%3A%2F%2Fsutekishop.googlecode.com&sbtn=Search

+0

就是這樣,謝謝羅伯特! – Kieron 2009-08-19 07:44:18

+0

SutekiShop有很多優秀的代碼,很高興它爲你工作。 – 2009-08-19 13:55:55

0

我認爲您傳遞給該方法的項目是您想要執行UpdateModel的項目,不是嗎?

否則,您嘗試使用預先存在的值更新而不是新的值。

只是一個想法,

代碼切出以下

[AcceptVerbs (HttpVerbs.Post)] 
public ActionResult Edit (Project project) 

    UpdateModel<Project> (project); 

    if (!ModelState.IsValid) 
      return View (project); 

    var projectService = Factory.GetService<IProjectService>(); 

    project = projectService.SaveProject (project); 

    return RedirectToAction ("Details", new { id = project.ProjectId }); 
} 
+0

項目,而不是projectToUpdate是使用ModelBinder的 – 2009-08-14 13:38:27

+0

的問題,我不解釋很好的一個,就是那個來自粘合劑項目實例是一切都很好,除了從它由MVC FW構建的事實來看,並沒有從DataContext中檢索。更新該實例時,DataContext基本上什麼也不做,可能是因爲它對該對象一無所知。 – Kieron 2009-08-14 13:51:50

0

你需要爲你做的,然後與已經在項目更改的屬性來更新它恢復原始項目更新然後提交更新請求。

編輯

試試這個代碼,我發現:

public static void CloneProperties(this object origin, ref object destination) 
{ 
    if (destination == null) throw new ArgumentNullException("destination", "Destination object must first be instantiated."); 
    foreach (var destinationProperty in destination.GetType().GetProperties()) 
    { 
     if (origin != null && destinationProperty.CanWrite) 
     { 
      origin.GetType().GetProperties().Where(x => x.CanRead && (x.Name == destinationProperty.Name && x.PropertyType == destinationProperty.PropertyType)) .ToList() .ForEach(x => destinationProperty.SetValue(destination, x.GetValue(origin, null), null)); 
     } 
    } 
} 
+0

是的,這就是我正在做的 - 我想要的可能是創建一個ModelBinder,它可以爲我做到這一點......簡單地說,我不必每次都在控制器中進行操作。 如果我稍後更改爲另一個ORM,我將執行不需要的額外獲取。我需要做的活頁夾是刪除/恢復原來的。有什麼想法嗎? – Kieron 2009-08-14 14:13:06

+0

http://msdn.microsoft.com/en-us/library/bb896248.aspx – Gregoire 2009-08-14 14:38:58

+0

@格雷戈裏,我試着使用Attach方法回來,但它引發了一個關於對象的異常已經存在(我假設它檢查基礎就是PK)。 – Kieron 2009-08-14 14:56:20