日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 编程资源 > 编程问答 >内容正文

编程问答

EntityFramework Code-First—领域类配置之DataAnnotations

發布時間:2023/12/2 编程问答 25 豆豆
生活随笔 收集整理的這篇文章主要介紹了 EntityFramework Code-First—领域类配置之DataAnnotations 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.

本文出自:https://www.cnblogs.com/tang-tang/p/5510574.html

?

一、摘要

  EF Code-First提供了一個可以用在領域類或其屬性上的DataAnnotation特性集合,DataAnnotation特性會覆蓋默認的EF約定。

  DataAnnotation存在于兩個命名空間里:

            System.ComponentModel.DataAnnotations

            System.ComponentModel.DataAnnotations.Schema

  注意:?DataAnnotations只提供了一部分的配置選項,全部的配置選項在Fluent API中。

?

二、System.ComponentModel.DataAnnotations 包含的特性:

?

Attribute描述
Key標記一個屬性,其將會在關系表中被映射成主鍵
Timestamp標記一個屬性,其將會在數據庫中被映射成一個不為null的tiamestamp(時間戳)列
ConcurrencyCheck這個屬性允許你標記一個或多個屬性,被標記的屬性將會在用戶編輯或刪除entity的時候進行并發檢查
Required強制約束,該屬性必須有數據,不能為null(同樣適用MVC)
MinLength確保數組或字符串長度達到最小長度
MaxLength數據庫中列的長度的最大值
StringLength在數據字段中指定字符允許的最大長度和最小長度

?

三、System.ComponentModel.DataAnnotations.Schema 包含的特性:

?

Attribute描述
Table指定被映射的類在數據庫生成的表名
Column指定被映射的屬性在表中的列名和數據類型
Index在指定列上創建索引(僅EF6.1以上版本支持)
ForeignKey給導航屬性指定外鍵屬性
NotMapped標記的屬性不會被映射到數據庫
DatabaseGenerated指定的屬性將會映射成數據庫表中的計算列,所以這個屬性應是只讀的。也可以用在把屬性映射成標識列(自增長列)
InverseProperty當兩個類之間包含多重關系的時候,默認約定會排列組合他們的導航屬性組合并一一創建外鍵,InverseProperty可以標記實際的主外鍵關系,從而過濾掉因排列組合出來的無用外鍵
ComplexType標記一個類為復雜類型

?

?

四、特性詳細介紹

  1、Key

    Key特性應用在類的屬性上。Code-First默認約定將名稱是"Id"或者{類名}+"Id"的屬性創建為一個主鍵列,Key特性覆寫了默認約定,我們可以把任何想要成為的主鍵的屬性標記為Key而不管它是什么名稱。

    代碼如下:

using System.ComponentModel.DataAnnotations;public class Student {public Student(){ }[Key]public int StudentKey { get; set; }public string StudentName { get; set; } }

    結果如下:

?

    我們也可以用用Key特性和Column特性創建混合主鍵,如下代碼所示:

using System.ComponentModel.DataAnnotations; public class Student {public Student(){ }[Key][Column(Order=1)]public int StudentKey1 { get; set; }[Key][Column(Order=2)]public int StudentKey2 { get; set; }public string StudentName { get; set; } }

    結果如下:

    注:當Key特性應用在單整型類型的屬性上時,會將其創建為一個標識列,而混合鍵無論它是不是整型類型,都不會創建標識列。Key特性除了無符號整型(unsinged integers),可以應用在如string、datatime、decimal等任何數據類型上。

?

  2、TimeStamp

    TimeStamp特性只能用在數據類型為byte array的屬性上,TimeStamp特性會在數據庫表中創建一個timestamp屬性的列,Code-First自動使用TimeStamp列進行并發檢查。

    (關于并發檢查,可以參考Gyoung的筆記:Entity Framework 并發處理)

    代碼如下:

using System.ComponentModel.DataAnnotations; public class Student {public Student(){ }public int StudentKey { get; set; }public string StudentName { get; set; }[TimeStamp]public byte[] RowVersion { get; set; } }

    結果如下::

?

  3、ConcurrencyCheck

    當EF對表執行update命令時,Code-First會把標記了ConcurrencyCheck特性的列中的值插入到SQL語句的“where”子句中來進行并發檢查。

    如下代碼:

using System.ComponentModel.DataAnnotations; public class Student {public Student(){}public int StudentId { get; set; }[ConcurrencyCheck]public string StudentName { get; set; } }

?    如上所示,StudentName屬性上標記了ConcurrencyCheck特性,所以Code-First會在update命令中把StudentName列包含進去以進行樂觀并發檢查(有關樂觀并發和悲觀并發,上面Gyoung的筆記有介紹,這里就不多討論)。如下代碼所示:

exec sp_executesql N'UPDATE [dbo].[Students] SET [StudentName] = @0 WHERE (([StudentId] = @1) AND ([StudentName] = @2)) ',N'@0 nvarchar(max) ,@1 int,@2 nvarchar(max) ',@0=N'Steve',@1=1,@2=N'Bill' go

    注意:TimeStamp特性只能用在single byte數組屬性上,然而ConcurrencyCheck特性可以用在任何數量和任何數據類型的屬性上。

  

  4、Required

    應用了Required特性的屬性,將會在數據庫表中創建一個不為null的列,需要留意的是,Required也是MVC的驗證特性。

    ? 代碼如下:

using System.ComponentModel.DataAnnotations;public class Student {public Student(){ }public int StudentID { get; set; }[Required]public string StudentName { get; set; }}

    在數據庫中,StudentName列已經被創建成不為空。

    

  5、MaxLength

    Maxlength特性用在String或array類型的屬性上,EF Code-First將會把列的大小設置成指定值。值得注意的是,Maxlength也是MVC的驗證特性。

    ? 代碼如下:

using System.ComponentModel.DataAnnotations;public class Student {public Student(){ }public int StudentID { get; set; }[MaxLength(50)]public string StudentName { get; set; }}

    因為StudentName屬性被指定了[Maxlength(50)]特性,所以在數據庫中StudentName列被創建成nvarchar(50)。

    Entity Framework也會驗證被標記了MaxLength特性的屬性的值,如果該值大于被標記的最大值,EF將會拋出EntityValidationError。

?

  6、MinLength

    MinLength特性是EF的一個驗證特性,其在數據庫模式中不起作用。如果我們對標記了MinLength特性的屬性賦值(string或者array),其長度小于指定的最小值,那么EF仍然會拋出EntityValidationError。

    MinLength特性可以和MaxLength特性一起使用,如下代碼所示:

using System.ComponentModel.DataAnnotations;public class Student {public Student(){ }public int StudentID { get; set; }[MaxLength(50),MinLength(2)]public string StudentName { get; set; }}

    ?如上代碼所示,StudentName屬性取值指定了只能是2-50個字符長度之間。

?

  7、StringLength

    StringLength應用在string類型的屬性上,EF Code-First將會用StringLength指定的長度設置列的大小。和Required以及Maxlength一樣,StringLength也是MVC的驗證特性。

    看下面的代碼:

using System.ComponentModel.DataAnnotations;public class Student {public Student(){}public int StudentID { get; set; }[StringLength(50)]public string StudentName { get; set; }}

    根據代碼中StudentName屬性的[StringLength(50)]特性,在數據庫中,將會創建一個nvarchar(50)的列,如下所示:

    同理,EF也將會驗證StringLength特性中的值,如果用戶輸入的值大于指定的長度,將會拋出EntityValidationError。

?

  8、Table

    Table特性應用在類上,默認的Code-First約定將會創建一個和類名同名的表名,Table特性覆寫默認的約定,EF Code-First將會創建一個以Table特性里指定的字符串為名稱的表。

    代碼如下:

using System.ComponentModel.DataAnnotations.Schema;[Table("StudentMaster")] public class Student {public Student(){ }public int StudentID { get; set; }public string StudentName { get; set; }}

    如上所示,Student類上應用了Table["StudentMaster"]特性,所以Code-First會覆寫默認的約定,創建一個名稱為StudentMaster的表名

    我們也可以用Table特性為表指定一個架構名,代碼如下所示:

using System.ComponentModel.DataAnnotations.Schema;[Table("StudentMaster", Schema="Admin")] public class Student {public Student(){ }public int StudentID { get; set; }public string StudentName { get; set; }}

    數據庫如下,Code-First將會在Admin架構下創建一個StudentMaster表

?

  9、Column

    Column特性應用在類的屬性上,和Table特性一樣,如果不指定Column特性的值,將會默認創建和屬性同名的列,否則就會創建指定的值。

    看如下代碼:

using System.ComponentModel.DataAnnotations.Schema;public class Student {public Student(){ }public int StudentID { get; set; }[Column("Name")]public string StudentName { get; set; }}

    如上所示,Column["Name"]特性應用在StudentName屬性上,所以Code-First將會創建一個以"Name"為名的列來代替默認的"StudentName"列名。數據庫如下:

    我們也可以使用Column特性為列指定排序(order)和類型(type),代碼如下:

    

using System.ComponentModel.DataAnnotations.Schema;public class Student {public Student(){ }public int StudentID { get; set; }[Column("Name", Order=1, TypeName="varchar")]public string StudentName { get; set; }}

    上面的代碼在數據庫Students表中創建了一個屬性為varchar,排序第一的列Name

?

  10、ForeignKey

    ForeignKey特性應用在類的屬性上。默認的Code-First約定預料外鍵屬性名與主鍵屬性名匹配,如下代碼:

public class Student {public Student(){ }public int StudentID { get; set; }public string StudentName { get; set; }//Foreign key for Standardpublic int StandardId { get; set; }public Standard Standard { get; set; } }public class Standard {public Standard(){ }public int StandardId { get; set; }public string StandardName { get; set; }public ICollection<Student> Students { get; set; }} }

    如上代碼所示,Student類包含了外鍵屬性StandardId,其又是Standard類的主鍵屬性,這樣,Code-First將會在Students表中創建一個StandardId外鍵列。

    ForeignKey特性覆寫了默認約定,我們可以把外鍵屬性列設置成不同名稱,代碼如下:

public class Student {public Student(){ }public int StudentID { get; set; }public string StudentName { get; set; }//Foreign key for Standardpublic int StandardRefId { get; set; }[ForeignKey("StandardRefId")]public Standard Standard { get; set; } }public class Standard {public Standard(){ }public int StandardId { get; set; }public string StandardName { get; set; }public ICollection<Student> Students { get; set; }}

    如上代碼所示,Student類包含了StandardRefId外鍵屬性,我們使用ForeignKey["StandardRefId"]特性指定在Standard導航屬性上,所以Code-First將會把StandardRefId作為外鍵,生成數據庫如下所示:

    ForeignKey特性也可以用在外鍵屬性上,只要指定好它的導航屬性,即Standard屬性,如下所示:

public class Student {public Student(){ }public int StudentID { get; set; }public string StudentName { get; set; }//Foreign key for Standard [ForeignKey("Standard")]public int StandardRefId { get; set; }public Standard Standard { get; set; } }public class Standard {public Standard(){ }public int StandardId { get; set; }public string StandardName { get; set; }public ICollection<Student> Students { get; set; }}

    這段代碼和上面把ForeignKey特性定義在Standard屬性上的效果是一樣的,在數據庫生成的Students表都創建了StandardRefId外鍵列。

?

  11、NotMapped

    NotMapped特性用在類的屬性上,默認Code-First約定會為那些所有包含了getter和setter的屬性創建列,

    ? NotMapped可以覆寫默認的約定,讓那些標記了NotMapped特性的屬性不會在數據庫里創建列。代碼如下:

using System.ComponentModel.DataAnnotations;public class Student {public Student(){ }public int StudentId { get; set; }public string StudentName { get; set; }[NotMapped]public int Age { get; set; } }

    如上代碼所示,NotMapped特性應用在Age屬性上,所以Code-First不會在Students表中創建Age列。

    Code-First也不會為那些沒有getter和setter的屬性創建列,在下面代碼例子中,Code-First不會為FirstName和Age創建列。

using System.ComponentModel.DataAnnotations;public class Student {public Student(){ }private int _age = 0;public int StudentId { get; set; }public string StudentName { get; set; }public string FirstName { get{ return StudentName;} }public string Age { set{ _age = value;} }}

?

  12、InverseProperty

    我們已經知道,如果類中沒有包含外鍵屬性,Code-First默認約定會創建一個{類名}_{主鍵}的外鍵列。當我們類與類之間有多個關系的時候,就可以使用InverseProperty特性。

    ? 代碼如下:

public class Student {public Student(){ }public int StudentID { get; set; }public string StudentName { get; set; }public Standard CurrentStandard { get; set; }public Standard PreviousStandard { get; set; } }public class Standard {public Standard(){ }public int StandardId { get; set; }public string StandardName { get; set; }public ICollection<Student> CurrentStudents { get; set; }public ICollection<Student> PreviousStudents { get; set; }}}

    如上代碼所示,Student類包含了兩個Standard類的導航屬性,同樣的,Standard類包含了兩個Student類的集合導航屬性,Code-First將會為這種關系創建4個列。如下所示:

    InverseProperty覆寫了這種默認約定并且指定對齊屬性,下面的代碼在Standard類中使用InverseProperty特性修復這個問題。

public class Student {public Student(){ }public int StudentID { get; set; }public string StudentName { get; set; }public Standard CurrentStandard { get; set; }public Standard PreviousStandard { get; set; } }public class Standard {public Standard(){ }public int StandardId { get; set; }public string StandardName { get; set; }[InverseProperty("CurrentStandard")]public ICollection<Student> CurrentStudents { get; set; }[InverseProperty("PreviousStandard")]public ICollection<Student> PreviousStudents { get; set; }}}

    如上代碼所示,我們在CurrentStudents和PreviousStudents屬性上應用了InverseProperty特性,并且指定哪個Student類的引用屬性屬于它,所以現在,Code-First在Student表中僅僅會創建兩個外鍵了。如下圖所示:

    當然,如果你想改外鍵名稱,我們就給導航屬性加上ForeignKey特性,如下代碼所示:

public class Student {public Student(){ }public int StudentID { get; set; }public string StudentName { get; set; }public int CurrentStandardId { get; set; }public int PreviousStandardId { get; set; }[ForeignKey("CurrentStandardId")]public Standard CurrentStandard { get; set; }[ForeignKey("PreviousStandardId")]public Standard PreviousStandard { get; set; } }public class Standard {public Standard(){}public int StandardId { get; set; }public string StandardName { get; set; }[InverseProperty("CurrentStandard")]public ICollection<Student> CurrentStudents { get; set; }[InverseProperty("PreviousStandard")]public ICollection<Student> PreviousStudents { get; set; }}

    

    上面的代碼將會創建出下面的數據庫表和列,我們可以看出,外鍵的名稱已經改變了。

    

?

  到此,DataAnnotation已經介紹完了,如果有什么不明白,或者我沒講清楚的地方,請大家留言~如有錯誤,也希望大神指出,不甚感激!

?

轉載于:https://www.cnblogs.com/JamelAr/p/10469543.html

總結

以上是生活随笔為你收集整理的EntityFramework Code-First—领域类配置之DataAnnotations的全部內容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。