zoukankan      html  css  js  c++  java
  • CodeFirst建模:DataAnotation

    示例一

    新建一个控制台应用程序,并安装entityframework

    新建一个文件Blog.cs类,输入以下代码:

    using System.ComponentModel.DataAnnotations;
    using System.ComponentModel.DataAnnotations.Schema;
    
    namespace DataAnnotations
    {
        public class Blog
        {
            [Key]
            public int PrimaryTrackingKey { get; set; }
    
            [Required]
            public string Title { get; set; }
    
            [MaxLength(50)]
            public string BloggerName { get; set; }
    
            [NotMapped]
            public string BlogCode
            {
                get
                {
                    return Title.Substring(0, 1) + ":" + BloggerName.Substring(0, 1);
                }
            }
        }
    }

    这个示例就是演示代码中的4个标记,接下来生成DbContext类:

    using System.Data.Entity;
    
    namespace DataAnnotations
    {
        internal class TestContext : DbContext
        {
            public DbSet<Blog> Blogs { get; set; }
        }
    }

    程序的执行文件Program.cs如下:

    using System;
    
    namespace DataAnnotations
    {
        internal class Program
        {
            private static void Main(string[] args)
            {
                populate();
                retreive();
                Console.WriteLine("请按任意键结束!");
                Console.ReadKey();
            }
    
            private static void populate()
            {
                using (var context = new TestContext())
                {
                    var blog = new Blog { Title = "Hello World! ", BloggerName = "You are freshman." };
                    context.Blogs.Add(blog);
                    context.SaveChanges();
                }
            }//void
    
            private static void retreive()
            {
                using (var context = new TestContext())
                {
                    foreach (var blog in context.Blogs)
                    {
                        Console.WriteLine("{0}.Title = {1}, BloggerName = {2}", blog.PrimaryTrackingKey, blog.Title, blog.BloggerName);
                    }
                }
            }//void
        }
    }

    执行程序,并按任意键终止!

    可以在其生成的数据库中找到Blogs表,表的创建代码如下:

    CREATE TABLE [dbo].[Blogs] (
        [PrimaryTrackingKey] INT            IDENTITY (1, 1) NOT NULL,
        [Title]              NVARCHAR (MAX) NOT NULL,
        [BloggerName]        NVARCHAR (50)  NULL,
        CONSTRAINT [PK_dbo.Blogs] PRIMARY KEY CLUSTERED ([PrimaryTrackingKey] ASC)
    );

    此代码和Blog.cs代码对照,可以知道每个标记的含义。[Key]是PRIMARY KEY,[Required]是NOT NULL,[MaxLength(50)]中的数字对应NVARCHAR(50)中的数字,[NotMapped]表示这个属性不用保存在数据库中。

    这里要说明的是,整数类型的主键默认identity(1,1), string类型默认映射为nvarchar(max)。

    示例二

    这个示例演示复合主键与复合外键:

    模型文件为:

    using System.ComponentModel.DataAnnotations;
    using System.ComponentModel.DataAnnotations.Schema;
    
    namespace DataAnnotations
    {
        public class Passport
        {
            [Key]
            [Column(Order = 1)]
            [DatabaseGenerated(DatabaseGeneratedOption.None)]
            public int PassportNumber { get; set; }
    
            [Key]
            [Column(Order = 2)]
            public string IssuingCountry { get; set; }
    
            public DateTime Issued { get; set; }
            public DateTime Expires { get; set; }
        }
    
        public class PassportStamp
        {
            [Key]
            public int StampId { get; set; }
    
            public DateTime Stamped { get; set; }
            public string StampingCountry { get; set; }
    
            [ForeignKey(name: "Passport")]
            [Column(Order = 1)]
            public int PassportNumber { get; set; }
    
            [ForeignKey(name: "Passport")]
            [Column(Order = 2)]
            public string IssuingCountry { get; set; }
    
            public Passport Passport { get; set; }
        }
    }

    生成的数据库表的代码为:

    CREATE TABLE [dbo].[Passports] (
        [PassportNumber] INT            NOT NULL,
        [IssuingCountry] NVARCHAR (128) NOT NULL,
        [Issued]         DATETIME       NOT NULL,
        [Expires]        DATETIME       NOT NULL,
        CONSTRAINT [PK_dbo.Passports] PRIMARY KEY CLUSTERED ([PassportNumber] ASC, [IssuingCountry] ASC)
    );
    
    CREATE TABLE [dbo].[PassportStamps] (
        [PassportNumber]  INT            NOT NULL,
        [IssuingCountry]  NVARCHAR (128) NULL,
        [StampId]         INT            IDENTITY (1, 1) NOT NULL,
        [Stamped]         DATETIME       NOT NULL,
        [StampingCountry] NVARCHAR (MAX) NULL,
        CONSTRAINT [PK_dbo.PassportStamps] PRIMARY KEY CLUSTERED ([StampId] ASC),
        CONSTRAINT [FK_dbo.PassportStamps_dbo.Passports_PassportNumber_IssuingCountry] FOREIGN KEY ([PassportNumber], [IssuingCountry]) REFERENCES [dbo].[Passports] ([PassportNumber], [IssuingCountry])
    );
    
    
    GO
    CREATE NONCLUSTERED INDEX [IX_PassportNumber_IssuingCountry]
        ON [dbo].[PassportStamps]([PassportNumber] ASC, [IssuingCountry] ASC);

    复合键的Order是按着大小排序,并不是指序号。外键的顺序要与主键对应列位置一致。Order值不一定要相等。

    代码中使用[DatabaseGenerated(DatabaseGeneratedOption.None)]关闭了整数类型主键的Identity特性。另外两个选项为Computed,Identity。

    示例三

    模型代码

    using System.ComponentModel.DataAnnotations;
    using System.ComponentModel.DataAnnotations.Schema;
    
    namespace DataAnnotations
    {
        public class Blog
        {
            public int BlogId { get; set; }
    
            [Required]
            public string Title { get; set; }
    
            public BlogDetails BlogDetail { get; set; }
        }
    
        [ComplexType]
        public class BlogDetails
        {
            public DateTime? DateCreated { get; set; }
    
            [MaxLength(250)]
            public string Description { get; set; }
        }
    }

    没有主键,又没有引用其他实体的类为ComplexType,这里的标记是可以省略的。上下文代码

    using System.Data.Entity;
    
    namespace DataAnnotations
    {
        internal class TestContext : DbContext
        {
            public DbSet<Blog> Blogs { get; set; }
    
        }
    }

    上下文中只有Blog集合,没有细节集合。填充与读取代码

            private static void populate()
            {
                using (var context = new TestContext())
                {
                    var blog = new Blog
                    {
                        Title = "My First",
                        BlogDetail = new BlogDetails
                        {
                            DateCreated = DateTime.Now,
                            Description = "这里省略10000字!"
                        }
                    };
    
                    context.Blogs.Add(blog);
                    context.SaveChanges();
                }
            }//void
    
            private static void retreive()
            {
                using (var context = new TestContext())
                {
                    foreach (var b in context.Blogs)
                    {
                        Console.WriteLine("{0}.{1}", b.BlogId, b.Title);
    
                        var d = b.BlogDetail;
                        Console.WriteLine("{0}.{1}", d.DateCreated, d.Description);
                    }
                }
            }//void

    数据库表

    CREATE TABLE [dbo].[Blogs] (
        [BlogId]                 INT            IDENTITY (1, 1) NOT NULL,
        [Title]                  NVARCHAR (MAX) NOT NULL,
        [BlogDetail_DateCreated] DATETIME       NULL,
        [BlogDetail_Description] NVARCHAR (250) NULL,
        CONSTRAINT [PK_dbo.Blogs] PRIMARY KEY CLUSTERED ([BlogId] ASC)
    );

    复杂类型将与引用他的实体一起扁平到一个数据库表中,默认的列名为ComplexTypeName_PropertyName。

    示例四

    本例演示如何为表和表中的列改名,修改列的数据类型,模型:

    using System.ComponentModel.DataAnnotations.Schema;
    
    namespace DataAnnotations
    {
        [Table("InternalBlogs", Schema = "dbo")]
        public class Blog
        {
            public int BlogId { get; set; }
    
            [Column("BlogDescription", TypeName = "ntext")]
            public string Description { get; set; }
        }
    }

    对应的数据库表为:

    CREATE TABLE [dbo].[InternalBlogs] (
        [BlogId]          INT   IDENTITY (1, 1) NOT NULL,
        [BlogDescription] NTEXT NULL,
        CONSTRAINT [PK_dbo.InternalBlogs] PRIMARY KEY CLUSTERED ([BlogId] ASC)
    );

    可见,表的名称,列的名称与数据类型都发生的改变。

    示例五

    数据库通过并发检查和行版本来处理并发,模型代码为:

    using System.ComponentModel.DataAnnotations;
    
    namespace DataAnnotations
    {
        public class Blog
        {
            public int BlogId { get; set; }
    
            [ConcurrencyCheck]
            public string BloggerName { get; set; }
    
            [Timestamp]
            public Byte[] TimeStamp { get; set; }
        }
    }

    对应生成的数据库表代码为:

    CREATE TABLE [dbo].[Blogs] (
        [BlogId]      INT            IDENTITY (1, 1) NOT NULL,
        [BloggerName] NVARCHAR (MAX) NULL,
        [TimeStamp]   ROWVERSION     NOT NULL,
        CONSTRAINT [PK_dbo.Blogs] PRIMARY KEY CLUSTERED ([BlogId] ASC)
    );

    [Timestamp]对应生成了非空的行版本类型,标记了[ConcurrencyCheck]的BloggerName属性会在生成的更新数据库代码的Where子句中添加并发检查。

    When SaveChanges is called, because of the ConcurrencyCheck annotation on the BloggerName field, the original value of that property will be used in the update. The command will attempt to locate the correct row by filtering not only on the key value but also on the original value of BloggerName. 

  • 相关阅读:
    mybatis 绑定 statement 失败
    JDBC链接Mysql失败
    Mysql 链接数据库时区错误
    mybatis 延迟加载
    C++ 虚函数表解析
    运行错误:error while loading shared libraries: xxx.so.0:cannot open shared object file: No such file or
    QComboBox的activated与currentIndexChanged的区别
    QT 文件对话框(QFileDialog)
    VS2010 ERROR:c1xx fatal error c1083
    django 在字符串[str(list)]中精确查找
  • 原文地址:https://www.cnblogs.com/cuishengli/p/4722266.html
Copyright © 2011-2022 走看看