Первая Проверка Базы Данных


У меня есть автоматически сгенерированная модель структуры сущностей. Он был создан с использованием первого подхода к базе данных. Столбец mid_initial имеет ограничение, определенное базой данных, которое ограничивает столбец максимальной длиной в 3 символа.

//------------------------------------------------------------------------------
// <auto-generated>
//    This code was generated from a template.
//
//    Manual changes to this file may cause unexpected behavior in your application.
//    Manual changes to this file will be overwritten if the code is regenerated.
// </auto-generated>
//------------------------------------------------------------------------------

namespace Agency.DataAccess.RegistrationModel
{
    using System;
    using System.Collections.Generic;

    public partial class Registrant
    {
        public Registrant()
        {
        }

        public int id { get; set; }
        public string fname { get; set; }
        public string mid_initial { get; set; }
        public string lname { get; set; }
    }
}

Когда я пытаюсь создать модель с mid_initial больше 3 символов, недопустимое состояние ModelState.IsValid возвращает true. Из-за этого db.SaveChanges затем вызывается, который затем поднимает DbEntityValidationException.

[HttpPost]
public ActionResult Create(Registrant registrant)
{    
    try
    {
        if (ModelState.IsValid)
        {
            Debug.WriteLine("Entity was valid.");
            db.Registrants.Add(registrant);
            db.SaveChanges();
            return RedirectToAction("Index");
        }

        return View("Create", registrant);
    }
    catch (DbEntityValidationException e)
    {
        foreach (var eve in e.EntityValidationErrors)
        {
            Debug.WriteLine("Entity of type "{0}" in state "{1}" has the following validation errors:",
                eve.Entry.Entity.GetType().Name, eve.Entry.State);
            foreach (var ve in eve.ValidationErrors)
            {
                Debug.WriteLine("- Property: "{0}", Error: "{1}"",
                    ve.PropertyName, ve.ErrorMessage);
            }
        }
        return View(registrant);
    }
}

Почему метод ModelState.IsValid возвращает true? Казалось бы, что моя модель не знает о максимальном ограничении длины. Как мне сделать это осознанным?

2 5

2 ответа:

EF db-first не может выводить ограничения из базы данных.

Используйте атрибут аннотации данных MaxLenght:

public partial class Registrant
{
    public Registrant()
    {
    }

    public int id { get; set; }
    public string fname { get; set; }
    [MaxLength(3, ErrorMessage = "")]
    public string mid_initial { get; set; }
    public string lname { get; set; }
}

Примечание: этот класс создается автоматически и каждый раз, когда вы обновляете и сохраняете свою модель (.EDMX file), этот код будет перезаписан, и вы потеряете свои атрибуты.

Чтобы избежать этого, вы должны расширить свои классы некоторыми разделяемыми классами с тем же именем и тем же пространством имен, что и ваши автоматически созданные классы. Если вам нужны примеры, чтобы показать вам, как, скажите мне, чтобы поставьте его в ответ.

MVC является EF-агностиком и как таковой не пытается имплицитно проверить модель, используя EF validation для заполнения ее ModelState.

У вас есть четыре основных решения, которые я могу придумать прямо сейчас:
  • подключайте их самостоятельно, например, используя фильтры MVC, DbContext.GetValidationErrors и ModelState.
  • Найдите и используйте сторонний код, который уже делает это.
  • проверьте код отдельно, используя средства, которые может использовать MVC, например, используя DataAnnotations. Вы может попытаться сгенерировать их автоматически, изменив шаблон EF T4. Обратите внимание, что это все еще технически избыточно (код будет проверен дважды, один раз MVC, один раз EF).
  • отправьте патч для MVC, чтобы он мог поддерживать EF явно (какмягкая зависимость) и заставить все это просто работать (оба проекта с открытым исходным кодом) - или понизить меня, потому что они уже сделали это, и я никогда не знал об этом.