2012-12-27 106 views
23

前言2015年2月如果您仍在使用实体框架EDMX,请使用实体框架代码优先考虑自己的忙和结账。不同之处在于您的表格是从您的模型类创建的,而不是在您的模型类使用表创建的EDMX中创建的。这是一个简单易行的解决方案,这个问题甚至不存在!使用实体框架数据模型添加验证属性

Getting Started with Entity Framework 6 Code First using MVC 5

我有一个现有的SQL数据库,我使用ADO.NET Enity数据模型的模型。我正在尝试在我的MVC应用程序中构建一些CRUD功能。

在所有关于这个主题的教程中,他们从头开始构建模型并将属性添加到模型类中。例如:

[Required] 
    [StringLength(10)] 
    public string Name { get; set; } 

然而,模型类是自动生成的,所以我想改变他们来说是一个坏主意(和将被写入了反正如果数据库模型被刷新)。

我将如何添加验证属性?

+1

您应该将数据注释放在viewModel属性 –

+0

现在阅读有关此,谢谢。 – Mason240

+0

http://stackoverflow.com/a/16737247/900284这个演示如何使它 –

回答

34

您可以创建一个部分类,从EF生成的类分开,元数据存储在

//Contact.cs - The original auto-generated file 
[System.ComponentModel.DataAnnotations.MetadataType(typeof(ContactMetadata))] 
public partial class Contact 
{ 
    public int ContactID { get; set; } 
    public string ContactName { get; set; } 
    public string ContactCell { get; set; } 
} 

//ContactMetadata.cs - New, seperate class 

using System.ComponentModel; 
using System.ComponentModel.DataAnnotations; 
internal sealed class ContactMetadata 
{ 
    [Required(ErrorMessage = "Name is required.")] 
    [StringLength(5)] 
    public string ContactName; 
} 
+14

其实你不应该尝试修改原始的自动生成的文件,只需创建另一个文件,因为** partial **关键字将使它像魅力一样工作。 –

+0

噢,是的,我同意。我将每个类放在独立的Metatdata文件夹中的文件中。 – Mason240

+1

编译器会生成警告,说明ContactName“永远不会分配给,并且始终具有其默认值null”;对这些默认属性是否安全? – Brad

17

Mason240回答运作良好,我将尽力改善它。你可以创建一个新的ContactDataAnnotations。 CS类:

//ContactDataAnnotations.cs - A new file 
using System.ComponentModel; 
using System.ComponentModel.DataAnnotations; 

[MetadataType(typeof(ContactMetadata))] 
public partial class Contact 
{ 
    // No field here 
} 

internal sealed class ContactMetadata 
{ 
    [Required(ErrorMessage = "Name is required.")] 
    [StringLength(5)] 
    public string ContactName {get; set; } 
} 

这样,您就可以通过重新EF联系人类不接触DataAnnotations - 和没有警告,顺便说一句。

+0

这很有用。 –

4

这已被正确回答,但我想补充一点,我总是发现嵌套的元数据对我来说似乎有点干净,恕我直言。

[MetadataType(typeof(ProductDescription.Metadata))] 
public partial class ProductDescription 
{ 
    sealed class Metadata 
    { 
     [Key] 
     public long id { get; set; } 
     [Display(Name = "Title")] 
     public string title { get; set; } 
     // ... 
    } 
} 

我还注意到将元数据保留为类的一个附加好处。该属性仅适用于正确的类,以防止在复制类时可能出现的错误(创建类似错误)。如果在重命名重复的类时忘记更改属性中的类名称,则会发生该错误。

4

我知道这已被标记回答,但我想清除一些东西了。

@SteveCav说:“这个成员不止一次定义”。我有同样的错误。花费数小时试图弄清楚。

要最终修正它,你必须在同一个Assembly中创建一个单独的文件类(我想这已经在这里提到了)。但是我想强调的是,这个类应该与表示内部类的部分类嵌套。

然后你用Annotation类装饰这个内部类。像这样:

//ContactMap.cs - Present in the same namespace as Contact.cs 
[System.ComponentModel.DataAnnotations.MetadataType(typeof(ContactMap))] 
partial class Contact // Present in the ContactMap class. This represent the Inner Class 
{ 
} 

//ContactMap.cs - This represent the outer class 

using System.ComponentModel; 
using System.ComponentModel.DataAnnotations; 
public class ContactMetadata 
{ 
    [Required(ErrorMessage = "Name is required.")] 
    [StringLength(5)] 
    public string ContactName; 
} 

希望这更清楚或更容易理解。

3

这里提供的答案有所不同,允许您在不同的程序集和名称空间中使用类。我实际上没有用EF测试过,但是我将它用于Swagger codegen API模型类。

简而言之:继承模型类并在继承的类上添加元数据。另一个好处是,使用Swagger codegen,您可以直接使用API​​模型而无需映射,对于初始表单,您可以使用受保护的默认ctor。

[MetadataType(typeof(LocalAssemblyModelMetadata))] 
public class LocalAssemblyModel : IO.Swagger.Model.OtherAssemblyModel 
{ 
    public LocalAssemblyModel() : base()  { } 
} 



public sealed class LocalAssemblyModelMetadata 
{ 
    [Required(ErrorMessage = "BaseclassProperty is mandatory.")] 
    public string BaseclassProperty { get; set; } 
} 
相关问题