asp.net-mvc 使用 GUID 作为 ASP.NET MVC 数据库中的 ID

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/1302267/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-09-07 23:47:05  来源:igfitidea点击:

Using a GUID as the ID in a database with ASP.NET MVC

asp.net-mvcguid

提问by Anders

I am learning ASP.NET MVC. I am following one of the basic tutorials on asp.net. Since I do not always follow the tutorials to the letter, I decided to use a GUID as the identity column instead of an integer. Everything was working fine until I got up to the point of adding a new record to the database through the MVC application. When I added the new record, it inserted a blank GUID instead of a generated one. Here is the segment of code-behind that handles the insertion:

我正在学习 ASP.NET MVC。我正在关注asp.net上的基本教程之一。由于我并不总是严格按照教程进行操作,因此我决定使用 GUID 作为标识列而不是整数。一切正常,直到我开始通过 MVC 应用程序向数据库添加新记录。当我添加新记录时,它插入了一个空白 GUID 而不是生成的 GUID。这是处理插入的代码隐藏段:

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

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

The [Bind(Exclude = "id")]line 'ignores' the ID column, since it is autogenerated. In the tutorial, the ID is auto-incremented but I think that is because it is an integer. I tried adding a line to this method:

[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();
    }
}

But the id is still an empty GUID. Can anyone provide me with some information on why this is and perhaps how to resolve it?

但 id 仍然是一个空的 GUID。任何人都可以向我提供一些关于为什么会这样以及如何解决它的信息吗?

回答by swilliams

You could use a custom ModelBinder. I learned about those over here.

您可以使用自定义 ModelBinder。我在这里了解到了那些。

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;
    }
}

And your action controller would be:

你的动作控制器将是:

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

And you would need to register the binder in Global.asax:

您需要在 Global.asax 中注册活页夹:

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

回答by Craig Stuntz

The SQL Server EF provider in .NET 3.5 SP1 cannot retrieve server-generated GUIDs, since archaic versions of SQL Server couldn't support that. So you need to generate the GUID client-side, until this limitation is fixed.

.NET 3.5 SP1 中的 SQL Server EF 提供程序无法检索服务器生成的 GUID,因为 SQL Server 的过时版本无法支持。所以你需要在客户端生成 GUID,直到这个限制被修复。

You cando this in a model binder, as swilliams suggests, but IMHO binders should only bind data in the request. So I do it on my model tier. But either way will work.

正如 swilliams 所建议的那样,您可以在模型绑定器中执行此操作,但恕我直言,绑定器应该只绑定请求中的数据。所以我在我的模型层上做。但无论哪种方式都会奏效。

回答by Sorantis

What is the type of ID field in SQL database? Is it uniqueidentifier? If not, change it to uniqueidentifier and make it autogenerated. Check out thisarticle.

SQL数据库中ID字段的类型是什么?它是唯一标识符吗?如果没有,请将其更改为 uniqueidentifier 并使其自动生成。看看这篇文章。

回答by Arno 2501

You could as well update your get Create Action as follow and give it the new guid at this point. Then it would be automatically transferred to the post action. The the all code would look like that :

您也可以按如下方式更新您的 get 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();
    }
}