【问题标题】:Database First Validation数据库首次验证
【发布时间】:2013-07-31 22:13:42
【问题描述】:

我有一个自动生成的实体框架模型。它是使用数据库优先方法生成的。 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?我的模型似乎不知道最大长度约束。如何让它知道?

【问题讨论】:

    标签: entity-framework ef-database-first


    【解决方案1】:

    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 文件)时,这个代码都会被覆盖,你会失去你的属性。

    为避免这种情况,您应该使用一些与自动生成的类具有相同名称和相同命名空间的部分类来扩展您的类。如果您需要示例来告诉您如何操作,请告诉我将其放在答案中。

    【讨论】:

    • 关闭...但是,据我了解,它不起作用。编译器会说:“错误 2 'Registrant' 类型已经包含 'mid_initial' 的定义......)。需要用 MetadataType 属性标记类 Registrant 并创建另一个类进行验证。stackoverflow.com/questions/25722866/…
    【解决方案2】:

    MVC 与 EF 无关,因此不会隐式尝试使用 EF 验证来验证模型以填充其 ModelState。

    我现在能想到四个基本的解决方案:

    • 自己连接它们,例如使用 MVC 过滤器、DbContext.GetValidationErrors 和 ModelState。
    • 查找并使用已经这样做的第三方代码。
    • 使用 MVC 可以使用的工具单独验证代码,例如使用 DataAnnotations。您可以尝试通过修改 EF T4 模板来自动生成它们。请注意,这在技术上仍然是多余的(代码将被验证两次,一次由 MVC,一次由 EF)。
    • 为 MVC 提交一个补丁,以便它可以显式支持 EF(作为 soft 依赖项)并使其正常工作(两个项目都是开源的)——或者因为他们已经做到了,所以对我投反对票所以我从来不知道。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2018-04-29
      • 1970-01-01
      相关资源
      最近更新 更多