EF CodeFirst学习笔记2

本文介绍了Entity Framework CodeFirst中DataAnnotation特性的使用方法,包括如何通过这些特性自定义数据库表和字段的属性,例如主键、表名、列名、外键等。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

CodeFirst我们在使用的时候,会需要一些配置,通过DataAnnotation特性和Fluent Api两种方法来实现

今天我们就来讲下DataAnnotation特性的使用

EF Code-First提供了一个可以用在领域类或其属性上的DataAnnotation特性集合,DataAnnotation特性会覆盖默认的EF约定。

DataAnnotation存在于两个命名空间里:

System.ComponentModel.DataAnnotationsSystem.ComponentModel.DataAnnotations.Schema

注意: DataAnnotations只提供了一部分的配置选项,全部的配置选项在Fluent API中。

 

System.ComponentModel.DataAnnotations 包含的特性:

Attribute描述
Key标记一个属性,其将会在关系表中被映射成主键
Timestamp标记一个属性,其将会在数据库中被映射成一个不为null的tiamestamp(时间戳)列
ConcurrencyCheck这个属性允许你标记一个或多个属性,被标记的属性将会在用户编辑或删除entity的时候进行并发检查
Required强制约束,该属性必须有数据,不能为null(同样适用MVC)
MinLength确保数组或字符串长度达到最小长度
MaxLength数据库中列的长度的最大值
StringLength在数据字段中指定字符允许的最大长度和最小长度

System.ComponentModel.DataAnnotations.Schema 包含的特性:

Attribute描述
Table指定被映射的类在数据库生成的表名
Column指定被映射的属性在表中的列名和数据类型
Index在指定列上创建索引(仅EF6.1以上版本支持)
ForeignKey给导航属性指定外键属性
NotMapped标记的属性不会被映射到数据库
DatabaseGenerated指定的属性将会映射成数据库表中的计算列,所以这个属性应是只读的。也可以用在把属性映射成标识列(自增长列)
InverseProperty当两个类之间包含多重关系的时候,默认约定会排列组合他们的导航属性组合并一一创建外键,InverseProperty可以标记实际的主外键关系,从而过滤掉因排列组合出来的无用外键
ComplexType标记一个类为复杂类型

 重要的特性稍微描述下

1.Key

设置表的主键,CodeFirst默认会将带有Id的事整型类型的字段设置成主键,如果我们要自定义那么可以使用Key来实现

    [Table("Emp")]//默认约定是以s结尾如Emps生成表
    public class Emp
    {
        [Key]
        public string empid { get; set; }
        public string empname { get; set; }
        public int? age { get; set; }
        [ForeignKey("dep")]
        public string depid { get; set; }
        public string tel { get; set; }
        public string duty { get; set; }




        public Dep dep { get; set; }
    }

这样数据库中就会将empid设置为主键

我们也可以设置混合主键,如

    [Table("Emp")]//默认约定是以s结尾如Emps生成表
    public class Emp
    {
        [Key]
        [Column(Order=1)]
        public string empid { get; set; }
        [Key]
        [Column(Order=2)]
        public string empname { get; set; }
        public int? age { get; set; }
        [ForeignKey("dep")]
        public string depid { get; set; }
        public string tel { get; set; }
        public string duty { get; set; }




        public Dep dep { get; set; }
    }

这样数据库中就会出现组合主键了

2.Table

默认情况下CodeFirst约定表名是加s来建的

如上述代码我们不设置

[Table("Emp")]//默认约定是以s结尾如Emps生成表

则数据库中的表明就会是Emps,我们使用了Table特性来配置的话,表明就会是Emp了。

3.Column

默认情况下表的列是跟属性名一样的,也就是说属性为empid则表的列名就是empid

如果我们要将列名特别设置下就可以使用此配置

如:

    [Table("Emp")]//默认约定是以s结尾如Emps生成表
    public class Emp
    {
        [Key]
        public string empid { get; set; }
        public string empname { get; set; }
        public int? age { get; set; }
        [ForeignKey("dep")]
        public string depid { get; set; }
        [Column("phone")]
        public string tel { get; set; }
        public string duty { get; set; }




        public Dep dep { get; set; }
    }

如上图,因为我们将属性tel特别是指了特性[column("phone")]所以数据库中表的列名为phone

4.ForeignKey

外键设置

[Table("Emp")]//默认约定是以s结尾如Emps生成表
    public class Emp
    {
        [Key]
        public string empid { get; set; }
        public string empname { get; set; }
        public int? age { get; set; }
        [ForeignKey("dep")]
        public string depid { get; set; }
        [Column("phone")]
        public string tel { get; set; }
        public string duty { get; set; }




        public Dep dep { get; set; }
    }

[Table("Dep")]
    public class Dep
    {
        [Key]
        public string depid { get; set; }
        public string depname { get; set; }
        public string upid { get; set; }
        public string manager { get; set; }
        public string assistant { get; set; }
    }

上述代码中我们定义了两个模型,人员和部门,n:1的关系,设定了表Dep的主键depid为Emp的外键 系统自动会生成Dep_depid的外键名,当然上述代码不加特性,系统也会自动判断加上外键的。

5.NotMapped

这个比较简单就是不需要进行映射的属性加上此特性就可以了

    [Table("Emp")]//默认约定是以s结尾如Emps生成表
    public class Emp
    {
        [Key]
        public string empid { get; set; }
        public string empname { get; set; }
        public int? age { get; set; }
        //[ForeignKey("dep")]
        public string depid { get; set; }
        [Column("phone")]
        public string tel { get; set; }
        [NotMapped]
        public string duty { get; set; }



        public Dep dep { get; set; }
    }

大家可以看到我们的属性duty就没有生成数据库表中的列

6.ConcurrencyCheck

当EF执行Update语句时,有此特性的字段会进行并发检查

using System.ComponentModel.DataAnnotations;

public class Student
{
    public Student()
    { 
        
    }

    public int StudentId { get; set; }
     
    [ConcurrencyCheck]
    public string StudentName { get; set; }
}
exec sp_executesql N'UPDATE [dbo].[Students]
SET [StudentName] = @0
WHERE (([StudentId] = @1) AND ([StudentName] = @2))
',N'@0 nvarchar(max) ,@1 int,@2 nvarchar(max) ',@0=N'Steve',@1=1,@2=N'Bill'
go            
      

上述代码执行的时候会对ConcurrencyCheck特性的列进行检查

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值