Code First:Data Anotation (2)

示例一

本例演示与索引有关的内容,模型:

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的索引。

User类演示了如何定义一个唯一索引,注意这里没有指定索引的名称,系统按照格式IX_PropertyName生成索引名称。

Cell类演示多列索引,给每个列指定相同的名称,如果有索引选项要修改,只需要在第一个属性上指定。

对字符串string类型的属性建立索引,需要指定其长度,长度不能大于某个值。

 示例二

本例演示外键,模型代码:

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框架默认为外键列添加索引,以加快检索速度。

现在,将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。

原文地址:https://www.cnblogs.com/cuishengli/p/4723467.html