在线观看不卡亚洲电影_亚洲妓女99综合网_91青青青亚洲娱乐在线观看_日韩无码高清综合久久

鍍金池/ 教程/ C#/ ASP.Net MVC數(shù)據(jù)注解
ASP.Net MVC簡介
ASP.Net MVC過濾器
ASP.Net MVC視圖
ASP.Net MVC安全
ASP.Net MVC手腳架
ASP.Net MVC控制器
ASP.Net MVC與SQL Server數(shù)據(jù)庫操作
ASP.Net MVC NuGet包管理
ASP.Net MVC入門程序
ASP.Net MVC Razor
ASP.Net MVC Bootstrap
ASP.Net MVC單元測試
ASP.Net MVC動作
ASP.Net MVC模式
ASP.Net MVC選擇器
ASP.Net MVC開發(fā)環(huán)境配置
ASP.Net MVC生命周期
ASP.Net MVC模型綁定
ASP.Net MVC自托管(本地主機部署)
ASP.Net MVC驗證
ASP.Net MVC緩存
ASP.Net MVC數(shù)據(jù)模型
ASP.Net MVC路由
ASP.Net MVC教程
ASP.Net MVC助手
ASP.Net MVC數(shù)據(jù)注解
ASP.Net MVC Web API

ASP.Net MVC數(shù)據(jù)注解

DataAnnotations用于配置模型類,它將突出顯示最常用的配置。 DataAnnotations也被許多.NET應(yīng)用程序所理解,例如ASP.NET MVC,它允許這些應(yīng)用程序利用相同的注釋來進行客戶端驗證。DataAnnotation屬性重寫默認(rèn)的Code-First約定。

System.ComponentModel.DataAnnotations包括以下影響列的可空性或大小的屬性。

  • Key
  • Timestamp
  • ConcurrencyCheck
  • Required
  • MinLength
  • MaxLength
  • StringLength

System.ComponentModel.DataAnnotations.Schema命名空間包括以下影響數(shù)據(jù)庫模式的屬性。

  • Table
  • Column
  • Index
  • ForeignKey
  • NotMapped
  • InverseProperty

1. 鍵(Key)

實體框架(Entity Framework或簡稱為EF )依賴于具有用于跟蹤實體的鍵值的每個實體。 Code First依賴的其中一個約定是它如何暗示哪個屬性是每個Code First類中的鍵。

約定是尋找一個名為Id的屬性,或者將類名和Id結(jié)合起來的屬性,比如StudentId。 該屬性將映射到數(shù)據(jù)庫中的主鍵列。學(xué)生,課程和入學(xué)課程遵循這個約定。

現(xiàn)在讓假設(shè)Student類使用名稱StdntID而不是ID。 當(dāng)Code First找不到符合此約定的屬性時,它將拋出一個異常,因為Entity Framework要求必須具有一個鍵屬性。

可以使用鍵注釋來指定哪個屬性將被用作EntityKey。

下面來看看包含StdntIDStudent類。 它不遵循默認(rèn)的Code First約定,所以要處理這個問題,添加了Key屬性,使StdntID列成為主鍵。

public class Student{
   [Key]
   public int StdntID { get; set; }
   public string LastName { get; set; }
   public string FirstMidName { get; set; }
   public DateTime EnrollmentDate { get; set; }

   public virtual ICollection<Enrollment> Enrollments { get; set; }
}

在運行應(yīng)用程序并查看SQL Server資源管理器中的數(shù)據(jù)庫時,您將看到現(xiàn)在Students表中的主鍵是:StdntID。

實體框架(Entity Framework)也支持復(fù)合鍵。 復(fù)合鍵是由多個屬性組成的主鍵。例如,有一個DrivingLicense類,其主鍵是LicenseNumberIssuingCountry的組合。

public class DrivingLicense{
   [Key, Column(Order = 1)]
   public int LicenseNumber { get; set; }

   [Key, Column(Order = 2)]
   public string IssuingCountry { get; set; }
   public DateTime Issued { get; set; }
   public DateTime Expires { get; set; }
}

當(dāng)有組合鍵時,實體框架要求你定義鍵屬性的順序??梢允褂?code>Column注釋來指定順序。

2. 時間戳(Timestamp)

Code First會將Timestamp屬性視為ConcurrencyCheck屬性,但它也將確保Code First生成的數(shù)據(jù)庫字段不可空。

使用rowversiontimestamp字段進行并發(fā)檢查更為常見。但是,不要使用ConcurrencyCheck注釋,只要屬性的類型是字節(jié)數(shù)組,就可以使用更具體的TimeStamp注釋。在給定的類中只能有一個時間戳屬性。

下面來看一個簡單的例子,將TimeStamp屬性添加到Course類中。參考以下代碼 -

public class Course{
   public int CourseID { get; set; }
   public string Title { get; set; }
   public int Credits { get; set; }
   [Timestamp]
   public byte[] TStamp { get; set; }

   public virtual ICollection<Enrollment> Enrollments { get; set; }
}

如上例所示,Timestamp屬性應(yīng)用于Course類的Byte []屬性。 所以,Code First 將在Courses表中創(chuàng)建一個時間戳列TStamp

3. ConcurrencyCheck

ConcurrencyCheck注釋允許在用戶編輯或刪除實體時標(biāo)記一個或多個要用于數(shù)據(jù)庫并發(fā)檢查的屬性。如果一直在使用EF Designer,那么這將與將屬性的“并發(fā)性模式”設(shè)置為“固定”一致。

下面來看看一個簡單的例子,通過將它添加Title屬性到Course類中來了解ConcurrencyCheck是如何工作的。

public class Course{
   public int CourseID { get; set; }

   [ConcurrencyCheck]
   public string Title { get; set; }
   public int Credits { get; set; }

   [Timestamp, DataType("timestamp")]
   public byte[] TimeStamp { get; set; }

   public virtual ICollection<Enrollment> Enrollments { get; set; }
}

在上面的Course類中,ConcurrencyCheck屬性應(yīng)用于現(xiàn)有的Title屬性。 Code First將在update命令中包含Title列來檢查以下代碼所示的樂觀并發(fā)。

exec sp_executesql N'UPDATE [dbo].[Courses]
   SET [Title] = @0
   WHERE (([CourseID] = @1) AND ([Title] = @2))
   ',N'@0 nvarchar(max) ,@1 int,@2 nvarchar(max)
',@0 = N'Maths',@1 = 1,@2 = N'Calculus'
go

4. Required

Required注釋告訴實體框架(Entity Framework)需要一個特定的屬性。下面來看看Student類,其中必需的id被添加到FirstMidName屬性中。 Required屬性將強制Entity Framework 確保該屬性中包含數(shù)據(jù)。

public class Student{
   [Key]
   public int StdntID { get; set; }

   [Required]
   public string LastName { get; set; }

   [Required]
   public string FirstMidName { get; set; }
   public DateTime EnrollmentDate { get; set; }

   public virtual ICollection<Enrollment> Enrollments { get; set; }
}

可以在上面的Student類的示例中看到Required屬性應(yīng)用于FirstMidNameLastName。 因此,Code First將在Students表中創(chuàng)建一個NOT NULLFirstMidNameLastName列,如下圖所示。

5. MaxLength

MaxLength屬性用于指定其他屬性驗證。它可以應(yīng)用于類的字符串或數(shù)組類型的屬性。 Entity FrameworkCode First 將設(shè)置MaxLength屬性中指定的列的大小。

下面來看看MaxLength(24)屬性應(yīng)用于Title屬性的以下Course類。

public class Course{
   public int CourseID { get; set; }
   [ConcurrencyCheck]
   [MaxLength(24)]

   public string Title { get; set; }
   public int Credits { get; set; }

   public virtual ICollection<Enrollment> Enrollments { get; set; }
}

當(dāng)運行上述應(yīng)用程序時,Code-First將在Coursed表中創(chuàng)建一個nvarchar(24)列標(biāo)題,如以下屏幕截圖所示。

現(xiàn)在當(dāng)用戶設(shè)置包含超過24個字符的標(biāo)題時,Entity Framework將拋出EntityValidationError異常。

6. MinLength

MinLength屬性可指定其他屬性驗證,就像上面使用的MaxLength屬性一樣。 MinLength屬性也可以與MaxLength屬性一起使用,如下面的代碼所示。

public class Course{
   public int CourseID { get; set; }
   [ConcurrencyCheck]
   [MaxLength(24) , MinLength(5)]
   public string Title { get; set; }
   public int Credits { get; set; }

   public virtual ICollection<Enrollment> Enrollments { get; set; }
}

如果在MinLength屬性中將Title屬性的值設(shè)置為小于指定的長度或大于MaxLength屬性中的指定長度,則EF將拋出EntityValidationError異常。

7. StringLength

StringLength還允許指定其他屬性驗證,如MaxLength。 不同的是StringLength屬性只能應(yīng)用于Domain類的字符串類型屬性。參考以下示例代碼 -

public class Course{
   public int CourseID { get; set; }
   [StringLength (24)]
   public string Title { get; set; }
   public int Credits { get; set; }

   public virtual ICollection<Enrollment> Enrollments { get; set; }
}

Entity Framework還驗證StringLength屬性的屬性值。 現(xiàn)在,如果用戶設(shè)置標(biāo)題(Title),其中包含超過24個字符,那么EF將拋出EntityValidationError異常。

8. Table

默認(rèn)代碼第一個約定創(chuàng)建一個與類名相同的表名。 如果讓Code First創(chuàng)建數(shù)據(jù)庫,則還可以更改正在創(chuàng)建的表的名稱??梢宰?em>Code First使用現(xiàn)有的數(shù)據(jù)庫表。 但并不總是這樣,有時類的名稱與數(shù)據(jù)庫中表的名稱不能總是相匹配。

Table屬性重寫此默認(rèn)約定。 對于給定的域類,EF Code First將在Table屬性使用指定的名稱來創(chuàng)建一個表。

下面來看看一個類名為Student的例子,按照慣例,Code First假定這將映射到一個名為Students的表。 如果不是這種情況,可以使用Table屬性指定表的名稱,如以下代碼所示 指定要創(chuàng)建的表名稱為:StudentInfo -

[Table("StudentsInfo")]
public class Student{
   [Key]
   public int StdntID { get; set; }

   [Required]
   public string LastName { get; set; }

   [Required]
   public string FirstMidName { get; set; }
   public DateTime EnrollmentDate { get; set; }

   public virtual ICollection<Enrollment> Enrollments { get; set; }
}

現(xiàn)在可以看到Table屬性將表指定為StudentsInfo。 生成表時,如下圖所示的表名StudentInfo。

不僅可以指定表名,還可以使用以下代碼使用Table屬性指定表的模式。

[Table("StudentsInfo", Schema = "Admin")]

public class Student{
   [Key]
   public int StdntID { get; set; }

   [Required]
   public string LastName { get; set; }

   [Required]
   public string FirstMidName { get; set; }
   public DateTime EnrollmentDate { get; set; }

   public virtual ICollection<Enrollment> Enrollments { get; set; }
}

在上面的例子中,表被指定為Admin模式。 現(xiàn)在,Code First將在Admin模式中創(chuàng)建StudentsInfo表,如以下屏幕截圖所示。

9. Column

Column屬性也與Table屬性相同,但Table屬性覆蓋表行為,而Column屬性覆蓋列行為。 默認(rèn)代碼第一個約定創(chuàng)建一個與屬性名相同的列名。

如果讓Code First創(chuàng)建數(shù)據(jù)庫,并且還希望更改表中列的名稱。Column屬性重寫此默認(rèn)約定。 EF Code First將在給定類屬性的Column屬性中創(chuàng)建一個具有指定名稱的列。

下面來看看下面的例子,其中屬性名為FirstMidName,按照慣例,Code First假定這將映射到一個名為FirstMidName的列。 如果不是要映射到FirstMidName列時,可以使用Column屬性指定其它列的名稱,如以下代碼所示。

public class Student{
   public int ID { get; set; }
   public string LastName { get; set; }

   [Column("FirstName")]
   public string FirstMidName { get; set; }
   public DateTime EnrollmentDate { get; set; }

   public virtual ICollection<Enrollment> Enrollments { get; set; }
}

現(xiàn)在可以看到Column屬性將列指定為FirstName。 生成表后,可以看到列名為FirstName,如以下屏幕截圖所示。

10. Index

Index屬性是在Entity Framework 6.1中引入的。

注 - 如果您使用的是早期版本,則本節(jié)中的信息不適用。

可以使用Index屬性在一列或多列上創(chuàng)建索引。將屬性添加到一個或多個屬性將導(dǎo)致EF在創(chuàng)建數(shù)據(jù)庫時在數(shù)據(jù)庫中創(chuàng)建相應(yīng)的索引。

在大多數(shù)情況下,索引使數(shù)據(jù)的檢索更快,更高效。但是,使用索引重載表或視圖可能會不愉快地影響其他操作(如插入或更新)的性能。

索引是實體框架中的新功能,可以通過減少從數(shù)據(jù)庫查詢數(shù)據(jù)所需的時間來提高Code First應(yīng)用程序的性能。

可以使用Index屬性將索引添加到數(shù)據(jù)庫,并覆蓋默認(rèn)的“唯一”和“群集”設(shè)置,以獲得最適合您的方案的索引。默認(rèn)情況下,索引將被命名為IX_<屬性名稱>

讓我們來看看以下代碼,其中Index屬性被添加到CourseCredits列上。

public class Cours{
   public int CourseID { get; set; }
   public string Title { get; set; }
   [Index]
   public int Credits { get; set; }

   public virtual ICollection<Enrollment> Enrollments { get; set; }
}

可以看到Index屬性應(yīng)用于Credits屬性。 現(xiàn)在,當(dāng)表生成時,將在索引中看到名稱為IX_Credits的索引。

默認(rèn)情況下,索引是非唯一的,但是可以使用IsUnique命名參數(shù)來指定索引應(yīng)該是唯一的。 以下示例引入了一個唯一索引,如下面的代碼所示。

public class Course{
   public int CourseID { get; set; }
   [Index(IsUnique = true)]

   public string Title { get; set; }
   [Index]

   public int Credits { get; set; }

   public virtual ICollection<Enrollment> Enrollments { get; set; }
}

11. ForeignKey

Code First約定將處理模型中最常見的關(guān)系。 例如,通過更改Student類中的key屬性名稱,創(chuàng)建了與Enrollment類的關(guān)系問題。

public class Enrollment{
   public int EnrollmentID { get; set; }
   public int CourseID { get; set; }
   public int StudentID { get; set; }
   public Grade? Grade { get; set; }
   public virtual Course Course { get; set; }
   public virtual Student Student { get; set; }
}

public class Student{
   [Key]
   public int StdntID { get; set; }
   public string LastName { get; set; }
   public string FirstMidName { get; set; }
   public DateTime EnrollmentDate { get; set; }

   public virtual ICollection<Enrollment> Enrollments { get; set; }
}

在生成數(shù)據(jù)庫時,Code First會在Enrollment類中看到StudentID屬性,并按照約定將其識別為類名稱加ID,作為Student類的外鍵。但是Student類中沒有StudentID屬性,而是Student類中的StdntID屬性。

解決方法是在Enrollment中創(chuàng)建導(dǎo)航屬性,并使用ForeignKey DataAnnotation來幫助Code First了解如何構(gòu)建兩個類之間的關(guān)系,如以下代碼所示。

public class Enrollment{
   public int EnrollmentID { get; set; }
   public int CourseID { get; set; }
   public int StudentID { get; set; }
   public Grade? Grade { get; set; }
   public virtual Course Course { get; set; }

   [ForeignKey("StudentID")]
   public virtual Student Student { get; set; }
}

現(xiàn)在可以看到ForeignKey屬性應(yīng)用于導(dǎo)航屬性。

12. NotMapped

Code First的約定在默認(rèn)情況下,每個屬于受支持?jǐn)?shù)據(jù)類型的屬性都包含gettersetter,它們在數(shù)據(jù)庫中表示。 但是在應(yīng)用中并不總是這樣。 NotMapped屬性將覆蓋此默認(rèn)約定。 例如,可能在Student類中有一個屬性,例如FatherName,但不需要存儲它到數(shù)據(jù)庫表。 那么可以將NotMapped屬性應(yīng)用于您不希望在數(shù)據(jù)庫中創(chuàng)建列的FatherName屬性。 以下是代碼。

public class Student{
   [Key]
   public int StdntID { get; set; }
   public string LastName { get; set; }
   public string FirstMidName { get; set; }
   public DateTime EnrollmentDate { get; set; }
   [NotMapped]
   public int FatherName { get; set; }

   public virtual ICollection<Enrollment> Enrollments { get; set; }
}

可以看到NotMapped屬性應(yīng)用于FatherName屬性。 現(xiàn)在,當(dāng)生成表時,將看到FatherName列不會在數(shù)據(jù)庫中創(chuàng)建,但它存在于Student類中。

Code First 不會為沒有gettersetter的屬性創(chuàng)建一個列。

13. InverseProperty

在類之間有多個關(guān)系時使用InverseProperty。 在Enrollment類中,可能想要跟蹤注冊“當(dāng)前課程”的人員和注冊“以前課程”的人員。

我們?yōu)?code>Enrollment類添加兩個導(dǎo)航屬性。

public class Enrollment{
   public int EnrollmentID { get; set; }
   public int CourseID { get; set; }
   public int StudentID { get; set; }
   public Grade? Grade { get; set; }

   public virtual Course CurrCourse { get; set; }
   public virtual Course PrevCourse { get; set; }
   public virtual Student Student { get; set; }
}

同樣,還需要添加這些屬性引用Course類。 Course類的導(dǎo)航屬性返回到Enrollment類,其中包含當(dāng)前和以前的所有注冊。

public class Course{
   public int CourseID { get; set; }
   public string Title { get; set; }
   [Index]

   public int Credits { get; set; }
   public virtual ICollection<Enrollment> CurrEnrollments { get; set; }
   public virtual ICollection<Enrollment> PrevEnrollments { get; set; }
}

如果外鍵屬性未包含在上述類中所示的特定類中,Code First會創(chuàng)建{Class Name} _ {Primary Key}外鍵列。 生成數(shù)據(jù)庫表時,您將看到許多外鍵,如以下屏幕截圖所示。

正如所看到的Code First 無法自己匹配兩個類的屬性。 用于Enrollments的數(shù)據(jù)庫表應(yīng)該有一個用于CurrCourse的外鍵和一個用于PrevCourse的外鍵,但Code First 將創(chuàng)建四個外鍵屬性,即 -

  • CurrCourse_CourseID
  • PrevCourse_CourseID
  • Course_CourseID
  • Course_CourseID1

要解決這些問題,可以使用InverseProperty注解來指定屬性的對齊方式。

public class Course{
   public int CourseID { get; set; }
   public string Title { get; set; }

   [Index]
   public int Credits { get; set; }

   [InverseProperty("CurrCourse")]
   public virtual ICollection<Enrollment> CurrEnrollments { get; set; }

   [InverseProperty("PrevCourse")]
   public virtual ICollection<Enrollment> PrevEnrollments { get; set; }
}

正如上面所看到的那樣,當(dāng)InverseProperty屬性通過指定它所屬的Enrollment類的哪個引用屬性應(yīng)用于上述Course類時,Code First將生成數(shù)據(jù)庫表,并在Enrollments表中創(chuàng)建兩個外鍵列,如以下屏幕截圖所示。

我們建議執(zhí)行上述示例以便更好地理解。