2012-12-27 169 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; } 
} 
相關問題