2009-08-19 59 views
4

我正在學習ASP.NET MVC。我正在關注asp.net的基本教程之一。由於我並不總是遵循教程,所以我決定使用GUID作爲標識列而不是整數。一切工作正常,直到我通過MVC應用程序添加新記錄到數據庫。當我添加新記錄時,它插入了一個空白的GUID而不是生成的GUID。這裏是處理插入代碼隱藏的段:使用GUID作爲與ASP.NET MVC的數據庫中的ID

[AcceptVerbs(HttpVerbs.Post)] 
public ActionResult Create([Bind(Exclude = "id")]Movie movieToCreate) 
{ 
    try 
    { 
     _entities.AddToMovieSet(movieToCreate); 
     _entities.SaveChanges(); 

     return RedirectToAction("Index"); 
    } 
    catch 
    { 
     return View(); 
    } 
} 

[Bind(Exclude = "id")]「線忽略」的ID列,因爲它是自動生成。在教程中,ID是自動遞增的,但我認爲這是因爲它是一個整數。我嘗試在此方法中添加一行:

[AcceptVerbs(HttpVerbs.Post)] 
public ActionResult Create([Bind(Exclude = "id")]Movie movieToCreate) 
{ 
    try 
    { 
     movieToCreate.id = Guid.NewGuid(); 
     _entities.AddToMovieSet(movieToCreate); 
     _entities.SaveChanges(); 

     return RedirectToAction("Index"); 
    } 
    catch 
    { 
     return View(); 
    } 
} 

但是,ID仍然是空的GUID。任何人都可以向我提供一些信息,說明這是爲什麼,也許如何解決它?

+0

顯然刪除'[Bind(Exclude)]'並保留'Guid.NewGuid()'修復了這個問題。我仍然想知道爲什麼ID自動增加,但GUID不是自動生成的。 – Anders 2009-08-19 19:58:24

+0

這兩個值都是在服務器上生成的。但EF只能看到int,因爲SQL Server提供程序從服務器返回生成的ints,但沒有生成ID。如果你放棄了上下文並重新查詢,你會看到兩者。 – 2009-08-20 01:57:39

+0

...但不生成ID。 - > ...但不生成GUID。 – 2009-08-20 01:58:17

回答

6

您可以使用自定義ModelBinder。我瞭解了關於here的那些。

public class MyClassBinder : DefaultModelBinder { 
    protected override object CreateModel(ControllerContext controllerContext, ModelBindingContext bindingContext, Type modelType) { 
     var model = (Movie)base.CreateModel(controllerContext, bindingContext, modelType); 
     model.id = Guid.NewGuid(); 
     return model; 
    } 
} 

和你的動作控制器將是:

[AcceptVerbs(HttpVerbs.Post)] 
public ActionResult MyAction(Movie movieToCreate) { 
    // movie should have a new guid in the id 
    _entities.AddToMovieSet(movieToCreate); 
    _entities.SaveChanges(); 
} 

而且你需要註冊在Global.asax中的粘結劑:

protected void Application_Start() { 
    RegisterRoutes(RouteTable.Routes); 
    ModelBinders.Binders.Add(typeof(Movie), new MyClassBinder()); 
} 
+0

我會在自己的文件中創建這個活頁夾嗎?如果是這樣,應該在哪裏放置?在我的控制器相同的目錄中?感謝您的信息和鏈接! – Anders 2009-08-19 20:24:32

+1

我把我的自定義活頁夾放在我的MVC應用程序的Models文件夾中的一個名爲Binders的文件夾中。 – 2009-08-19 20:32:15

+0

非常好,謝謝你! – Anders 2009-08-19 21:01:52

0

在.net 3.5的SQL Server EF提供商SP1無法檢索服務器生成的GUID,因爲SQL Server的陳舊版本無法支持該功能。所以你需要生成GUID客戶端,直到這個限制被修復。

可以在模型聯編程序中執行此操作,正如swilliams所示,但恕我直言聯編程序只應綁定請求中的數據。所以我在我的模型層上做。但無論哪種方式將工作。

+0

你能否詳細說明你的方法?當我正在學習時,我想知道我可以使用的所有選項。謝謝! – Anders 2009-08-19 21:02:31

+2

簡單,真的。在插入新記錄時,在調用SaveChanges()之前,我使用代碼(使用Guid.NewGuid())設置ID。所有這些都是在與包含控制器和視圖的程序集分離的模型程序集內完成的。 – 2009-08-19 21:07:36

+0

所以基本上我通過從Movie參數中刪除[Bind(Execute)]來做什麼? – Anders 2009-08-19 21:28:23

1

SQL數據庫中的ID字段的類型是什麼?它是唯一標識符嗎? 如果不是,請將其更改爲uniqueidentifier並使其自動生成。 結賬this文章。

+0

他已經做到了;仔細閱讀這個問題。 EF的SQL Server提供程序不會將自動生成的GUID轉發給客戶端。 – 2009-08-19 21:08:34

+0

哎喲...我的壞.. – Sorantis 2009-08-19 21:50:17

0

你可以像下面一樣更新你的Create Action,並且給它新的guid。然後它會自動轉移到後置操作。所有代碼將如下所示:

public ActionResult Create() 
{ 
    Movie movietocreate = new Movie(); 

    movietocreate.id = Guid.NewGuid(); //you set the new guid here 

    return View(movietocreate); 
} 

[AcceptVerbs(HttpVerbs.Post)] 
public ActionResult Create(Movie movieToCreate) 
{ 
    try 
    { 
     _entities.AddToMovieSet(movieToCreate); 
     _entities.SaveChanges(); 

     return RedirectToAction("Index"); 
    } 
    catch 
    { 
      return View(); 
    } 
} 
相關問題