本例演示與索引有關的內容,模型:數據庫
using System.ComponentModel.DataAnnotations; using System.ComponentModel.DataAnnotations.Schema; namespace DataAnnotations { public class Post { public int Id { get; set; } public string Title { get; set; } [Index("PostRatingIndex")] public int BlogId { get; set; } } public class User { public int UserId { get; set; } [Index(IsUnique = true)] [StringLength(200)] public string Username { get; set; } public string DisplayName { get; set; } } public class Cell { public int Id { get; set; } public string Content { get; set; } [Index("IX_Location", 1, IsUnique = true)] public int Row { get; set; } [Index("IX_Location", 2)] [StringLength(5)] public string Column { get; set; } } }
生成的數據庫表代碼爲:框架
------------------------------------------ CREATE TABLE [dbo].[Posts] ( [Id] INT IDENTITY (1, 1) NOT NULL, [Title] NVARCHAR (MAX) NULL, [BlogId] INT NOT NULL, CONSTRAINT [PK_dbo.Posts] PRIMARY KEY CLUSTERED ([Id] ASC) ); GO CREATE NONCLUSTERED INDEX [PostRatingIndex] ON [dbo].[Posts]([BlogId] ASC); GO ------------------------------------------ CREATE TABLE [dbo].[Users] ( [UserId] INT IDENTITY (1, 1) NOT NULL, [Username] NVARCHAR (200) NULL, [DisplayName] NVARCHAR (MAX) NULL, CONSTRAINT [PK_dbo.Users] PRIMARY KEY CLUSTERED ([UserId] ASC) ); GO CREATE UNIQUE NONCLUSTERED INDEX [IX_Username] ON [dbo].[Users]([Username] ASC); GO ------------------------------------------ CREATE TABLE [dbo].[Cells] ( [Id] INT IDENTITY (1, 1) NOT NULL, [Content] NVARCHAR (MAX) NULL, [Row] INT NOT NULL, [Column] NVARCHAR (5) NULL, CONSTRAINT [PK_dbo.Cells] PRIMARY KEY CLUSTERED ([Id] ASC) ); GO CREATE UNIQUE NONCLUSTERED INDEX [IX_Location] ON [dbo].[Cells]([Row] ASC, [Column] ASC); GO
Post類演示了在BlogId上定義一個名爲PostRatingIndex的索引。spa
User類演示瞭如何定義一個惟一索引,注意這裏沒有指定索引的名稱,系統按照格式IX_PropertyName生成索引名稱。翻譯
Cell類演示多列索引,給每一個列指定相同的名稱,若是有索引選項要修改,只須要在第一個屬性上指定。code
對字符串string類型的屬性創建索引,須要指定其長度,長度不能大於某個值。blog
本例演示外鍵,模型代碼:索引
using System.Collections.Generic; using System.ComponentModel.DataAnnotations; using System.ComponentModel.DataAnnotations.Schema; namespace DataAnnotations { public class Blog { [Key] public int PrimaryKey { get; set; } public string Title { get; set; } //導航屬性 public virtual ICollection<Post> Posts { get; set; } } public class Post { public int Id { get; set; } public string Content { get; set; } //外鍵 public int BlogId { get; set; } //導航屬性 [ForeignKey("BlogId")] public Blog Blog { get; set; } } }
這裏,Blog的主鍵沒有遵照主鍵的命名約定,在Post類的導航屬性Blog上指定外鍵屬性,其參數"BlogId"指的是Post類成員BlogId是外鍵列。文檔
生成的數據庫代碼:字符串
----------------------------------------------------------------------------------------- CREATE TABLE [dbo].[Blogs] ( [PrimaryKey] INT IDENTITY (1, 1) NOT NULL, [Title] NVARCHAR (MAX) NULL, CONSTRAINT [PK_dbo.Blogs] PRIMARY KEY CLUSTERED ([PrimaryKey] ASC) ); ----------------------------------------------------------------------------------------- CREATE TABLE [dbo].[Posts] ( [Id] INT IDENTITY (1, 1) NOT NULL, [Content] NVARCHAR (MAX) NULL, [BlogId] INT NOT NULL, CONSTRAINT [PK_dbo.Posts] PRIMARY KEY CLUSTERED ([Id] ASC), CONSTRAINT [FK_dbo.Posts_dbo.Blogs_BlogId] FOREIGN KEY ([BlogId]) REFERENCES [dbo].[Blogs] ([PrimaryKey]) ON DELETE CASCADE ); GO CREATE NONCLUSTERED INDEX [IX_BlogId] ON [dbo].[Posts]([BlogId] ASC);
EF框架默認爲外鍵列添加索引,以加快檢索速度。get
如今,將Post類中的ForeignKey標記從導航屬性移動到外鍵屬性上,微調代碼:
public class Post { public int Id { get; set; } public string Content { get; set; } //外鍵 [ForeignKey("MyBlog")] public int BlogId { get; set; } //導航屬性 public Blog MyBlog { get; set; } }
再次查看生成的數據庫表:
CREATE TABLE [dbo].[Posts] ( [Id] INT IDENTITY (1, 1) NOT NULL, [Content] NVARCHAR (MAX) NULL, [BlogId] INT NOT NULL, CONSTRAINT [PK_dbo.Posts] PRIMARY KEY CLUSTERED ([Id] ASC), CONSTRAINT [FK_dbo.Posts_dbo.Blogs_BlogId] FOREIGN KEY ([BlogId]) REFERENCES [dbo].[Blogs] ([PrimaryKey]) ON DELETE CASCADE ); GO CREATE NONCLUSTERED INDEX [IX_BlogId] ON [dbo].[Posts]([BlogId] ASC);
可見生成的代碼是同樣的,因而可知,外鍵標記就是在依賴表中創建外鍵屬性與導航屬性之間對應關聯的。
示例三
本示例演示反轉屬性註解,此註解用於兩個實體間有多個關係的狀況,如一個文檔有建立者,有更新者,這二者都是人。此時以下定義模型:
using System.Collections.Generic; using System.ComponentModel.DataAnnotations; using System.ComponentModel.DataAnnotations.Schema; namespace DataAnnotations { public class Person { public int Id { get; set; } [Index(IsUnique =true),StringLength(50)] public string Name { get; set; } //導航屬性 [InverseProperty("CreatedBy")] public List<Document> CreatedDocuments { get; set; } [InverseProperty("UpdatedBy")] public List<Document> UpdatedDocuments { get; set; } } public class Document { public int Id { get; set; } public string Content { get; set; } //導航屬性 public Person CreatedBy { get; set; } public Person UpdatedBy { get; set; } } }
在Person類的CreatedDocuments上有標記[InverseProperty("CreatedBy")],而且此屬性是Document類型的集合,則能夠翻譯成Person類的CreatedDocuments導航屬性是Document類的CreatedBy導航屬性的反屬性。
下面是生成的數據庫:
CREATE TABLE [dbo].[People] ( [Id] INT IDENTITY (1, 1) NOT NULL, [Name] NVARCHAR (50) NULL, CONSTRAINT [PK_dbo.People] PRIMARY KEY CLUSTERED ([Id] ASC) ); GO CREATE UNIQUE NONCLUSTERED INDEX [IX_Name] ON [dbo].[People]([Name] ASC); -------------------------------------------------------------------------------------- CREATE TABLE [dbo].[Documents] ( [Id] INT IDENTITY (1, 1) NOT NULL, [Content] NVARCHAR (MAX) NULL, [CreatedBy_Id] INT NULL, [UpdatedBy_Id] INT NULL, CONSTRAINT [PK_dbo.Documents] PRIMARY KEY CLUSTERED ([Id] ASC), CONSTRAINT [FK_dbo.Documents_dbo.People_CreatedBy_Id] FOREIGN KEY ([CreatedBy_Id]) REFERENCES [dbo].[People] ([Id]), CONSTRAINT [FK_dbo.Documents_dbo.People_UpdatedBy_Id] FOREIGN KEY ([UpdatedBy_Id]) REFERENCES [dbo].[People] ([Id]) ); GO CREATE NONCLUSTERED INDEX [IX_CreatedBy_Id] ON [dbo].[Documents]([CreatedBy_Id] ASC); GO CREATE NONCLUSTERED INDEX [IX_UpdatedBy_Id] ON [dbo].[Documents]([UpdatedBy_Id] ASC);
EF在外鍵表Documents中生成外鍵列的名字爲:導航屬性_Id。