zoukankan      html  css  js  c++  java
  • EF Code First DataAnnotations

    Data annotation特性是在.NET 3.5中引进的,给ASP.NET web应用中的类提供了一种添加验证的方式。Code First允许你使用代码来建立实体框架模型,同时允许用Data annotation特性来配置类和属性的某些特性。

    其实在前面的几篇文章中,有用到几个,在这一篇里,进行一次比较全面的介绍

    Key

    EF框架要求每个实体必须有主键字段,他需要根据这个主键字段跟踪实体。CodeFirst方法在创建实体时,也必须指定主键字段,默认情况下属性被命名为ID、id或者[ClassName]Id,将映射为数据表中的主键如果没有类似的命名,并且也未显示指明主键,则生成失败,引发异常。如果想要自定义主键列名,则可以使用Key注释

     [Key]
    publicint MyId { get; set; }

    Required

    当要求数据库在字段,不能为空时

    [Required]
    publicstring BookTitle { get; set; }

    MaxLength 、MinLength

    设置数据库字段的长度范围

       [MaxLength(10),MinLength(6)]
    publicstring Password { get; set; }

    NotMapped

    当创建数据表时,用此属性修饰的属性,不会被创建为数据表字段

        [NotMapped]
    publicint MyProperty { get; set; }

    ComplexType

    Complex属性是将一个对象做为另一个对象的属性。映射到数据库中则子对象表现为多个属性字段。具体可参考:EF框架step by step(6)—处理实体complex属性

        [ComplexType]
    publicclass Publisher
    {
    publicstring PublisherName { get; set; }
    publicstring PublisherAddress { get; set; }
    } 

    ConcurrencyCheck

    并发检查允许你标识一个或者多个属性在实体更新时,要进行检查是否与原实体一致。并发检查依懒于OriginalValue,在WEB应用程序中,通常是某一用户获取数据实体后,会与数据库断开连接,这时,如果另一用户也获得了实体并进行了更新新操作,那么当最初用户进行再更新时,会自动进行并发检查,根据被标识ConcurrencyCheck属性的OriginalValue,判断原实体是否存在。如果不存在,则在SaveChanges方法是会引发一个异常。

    下面的例子是Book实体的BookTitle属性被标识为ConcurrencyCheck

        [Required,ConcurrencyCheck]
    publicstring BookTitle { get; set; }

    则下面代码模拟并发现象:

    复制代码
            Book book = db.Books.Find(1);
    //显示表明数据实体被修改
    db.Entry(book).State = System.Data.EntityState.Modified;
    db.Entry(book).Property(b
    => b.BookTitle).OriginalValue ="DataAnnotations";

    //这么代码会引发异常
    db.SaveChanges();
    复制代码

    引发异常如下图:

    用SQL Profile监控,数据库执行了如下

    update[dbo].[MyBook]
    set[BookTitle]=@0
    where (([MyId]=@1) and ([BookTitle]=@2))
    ', N'@0nvarchar(4000),@1int,@2nvarchar(4000)',
    @0 = N
    'EF4.1 Code First', @1 = 1, @2 = N'DataAnnotations'

    TimeStamp 与 DatabaseGenerated

    TimeStamp是比ConcurrencyCheck更通用的监控并发的字段,在实体中通常一个类型为字节数组的字段表示,一个实体类只能有一个TimeStamp字段,并且他通常与DatabaseGenerated联合使用,DatabaseGenerated表明是由数据库自动生成,他需要DatabaseGeneratedOption枚举来做为数据库生成时参数,DatabaseGeneratedOption枚举包含三个值 Computed 由数据库自动计算,Identity自动增长,None数据库不做处理。

            [Timestamp,DatabaseGenerated(DatabaseGeneratedOption.Computed)]
    public Byte[] TimeStamp { get; set; }

    TimeStamp与ConcurrencyCheck用法类似

    复制代码
            Book book = db.Books.Find(1);

    //模拟另一个用户对同一数据实体进行更新
    db.Database.ExecuteSqlCommand("update mybook set Booktitle='EF' where MyId=1");

    book.BookTitle
    ="New Title";
    db.SaveChanges();
    复制代码
    同样,在SaveChanges()时,也会引发DbUpdateConcurrencyException。

    Table

    CodeFirst 方法默认以实体类名复数形式做为数据表名,Table注释允许自定义表名

        [Table("MyBook")]
    publicclass Book

    Column

    CodeFirst 方法默认以实体类属性名做为列名,Column注释允许自定列名及数据类型

       [Column("BlogDescription", TypeName ="ntext")]
    publicstring Description { get; set; }

    好,来个综合示例,看一下运行结果,对照理解一下 

    复制代码
        [Table("MyBook")]
    publicclass Book
    {
    [Key]
    publicint MyId { get; set; }

    [MaxLength(
    10), MinLength(6)]
    publicstring KeyWord { get; set; }

    [Required,MaxLength(
    50)]
    publicstring BookTitle { get; set; }

    [NotMapped]
    publicint MyProperty { get; set; }

    public Publisher Publisher { get; set; }

    [Column(
    "BlogDescription", TypeName ="ntext")]
    publicstring Description { get; set; }

    [Timestamp,DatabaseGenerated(DatabaseGeneratedOption.Computed)]
    public Byte[] TimeStamp { get; set; }

    }
    [ComplexType]
    publicclass Publisher
    {
    publicstring PublisherName { get; set; }
    publicstring PublisherAddress { get; set; }
    }
    复制代码

    生成数据表如图:

     
     
  • 相关阅读:
    android数据恢复
    UVA 690 Pipeline Scheduling
    2017 国庆湖南 Day4
    2017 国庆湖南 Day5
    2017 国庆湖南 Day6
    2017国庆 清北学堂 北京综合强化班 Day1
    2017 国庆湖南Day2
    bzoj 2962 序列操作
    UVA 818 Cutting Chains
    UVA 211 The Domino Effect
  • 原文地址:https://www.cnblogs.com/qidian10/p/3116149.html
Copyright © 2011-2022 走看看