• 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。

  • 相关阅读:
    模拟赛QAQ
    复习计划
    luogu P1080 国王游戏
    [NOIP2012T3]开车旅行
    luogu P1967 货车运输
    同余方程组的扩展欧几里得解法
    luogu P1476 休息中的小呆
    GRYZY #13. 拼不出的数
    GRYZY- #10. 财富
    GRYZY #8. 公交车
  • 原文地址:https://www.cnblogs.com/cuishengli/p/4723467.html
Copyright © 2020-2023  润新知