Использование GUID в качестве идентификатора в базе данных с ASP.NET MVC - PullRequest
5 голосов
/ 19 августа 2009

Я изучаю ASP.NET MVC. Я следую одному из основных руководств по asp.net . Поскольку я не всегда следую инструкциям к письму, я решил использовать GUID в качестве столбца идентификации вместо целого числа. Все работало нормально, пока я не дошел до точки добавления новой записи в базу данных через приложение MVC. Когда я добавил новую запись, он вставил пустой GUID вместо сгенерированного. Вот фрагмент кода, который обрабатывает вставку:

[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")] игнорирует столбец идентификатора, поскольку он генерируется автоматически. В учебнике идентификатор увеличивается автоматически, но я думаю, что это потому, что это целое число. Я попытался добавить строку к этому методу:

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

Но идентификатор все еще пустой GUID. Может кто-нибудь предоставить мне некоторую информацию о том, почему это так и, возможно, как решить эту проблему?

Ответы [ 4 ]

6 голосов
/ 20 августа 2009

Вы можете использовать собственный 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;
    }
}

И ваш контроллер действий будет:

[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());
}
1 голос
/ 20 августа 2009

Какой тип поля идентификатора в базе данных SQL? Это уникальный идентификатор? Если нет, измените его на uniqueidentifier и сделайте его автоматически созданным. Ознакомьтесь с этой статьей.

1 голос
/ 20 августа 2009

Поставщик SQL Server EF в .NET 3.5 с пакетом обновления 1 (SP1) не может получить сгенерированные сервером идентификаторы GUID, так как архаичные версии SQL Server не могут это поддерживать. Поэтому вам нужно сгенерировать GUID на стороне клиента, пока это ограничение не будет исправлено.

Вы можете сделать это в связывателе модели, как предполагает swilliams, но связыватели IMHO должны связывать только данные в запросе. Так что я делаю это на своем уровне модели. Но в любом случае будет работать.

0 голосов
/ 12 мая 2011

Вы также можете обновить свое действие «Создать действие» следующим образом и дать ему новое руководство. Затем он будет автоматически перенесен в действие post. Код all будет выглядеть так:

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