EF Code First DataAnnotations

本文全面介绍了DataAnnotation特性在.NET3.5中的应用,包括主键、验证、长度限制、并发检查、表名和列名自定义等,通过实例展示了如何在实体类中使用这些特性,以及它们在数据库操作中的作用。

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; }
}
复制代码

生成数据表如图:

 
 
<think>好的,我现在需要介绍EF Code First中的字段非空设置。首先,EF Code First是Entity Framework的一种开发模式,允许通过类定义来生成数据库结构。字段非空通常涉及数据验证和数据库约束。 首先,用户可能想知道如何在模型类中设置属性为非空。在C#中,值类型(如int、DateTime)默认非空,而引用类型(如string)可为空。但使用C# 8.0的可空引用类型后,string默认不可空,可能需要显式处理。 然后,数据注解(Data Annotations)和Fluent API是常用的配置方法。例如,[Required]特性可以将属性标记为必填。或者在DbContext的OnModelCreating中使用Fluent API的IsRequired()方法。 接下来需要考虑数据库迁移。修改模型后,需通过Add-Migration和Update-Database命令更新数据库架构,确保字段的NOT NULL约束正确应用。 可能遇到的问题包括迁移冲突、现有数据与新约束不兼容。例如,若已有记录的该字段为NULL,添加非空约束会导致错误。解决方案包括设置默认值或分步迁移。 另外,代码中的验证逻辑也需要处理,比如在保存数据前检查属性是否为空,避免运行时异常。EF会在SaveChanges时验证[Required]属性,但前端验证同样重要。 最后,可能需要解释可空引用类型对EF Core的影响,以及如何与数据库约束协同工作。确保开发者理解模型配置和数据库结构之间的关系,避免误解导致的数据不一致。</think>在 Entity Framework (EF) 的 **Code First** 模式中,字段的**非空(Non-Nullable)**约束是保证数据完整性的关键配置。以下是逐步说明: --- ### 一、基础概念 1. **Code First** EF 的开发模式之一,通过编写 C# 类定义模型,自动生成数据库结构。 2. **字段非空** 表示数据库表的某列不允许存储 `NULL` 值,对应代码中属性的不可为空性。 --- ### 二、配置字段非空的方法 #### 方法 1:使用数据注解(Data Annotations) 在模型类的属性上添加 `[Required]` 特性: ```csharp public class Product { public int Id { get; set; } [Required] // 标记为必填字段 public string Name { get; set; } [Required] public decimal Price { get; set; } } ``` - **效果**:生成数据库表中 `Name` 和 `Price` 列均为 `NOT NULL`。 #### 方法 2:使用 Fluent API 在 `DbContext` 的 `OnModelCreating` 方法中配置: ```csharp protected override void OnModelCreating(ModelBuilder modelBuilder) { modelBuilder.Entity<Product>() .Property(p => p.Name) .IsRequired(); // 设为非空 } ``` - **优势**:更灵活,可集中管理配置。 --- ### 三、处理可空引用类型(C# 8.0+) 1. **启用可空引用类型** 在 `.csproj` 文件中添加: ```xml <Nullable>enable</Nullable> ``` 2. **默认行为** - `string` 类型默认视为不可空(需显式初始化为非 `null`)。 - 若允许空值,需显式声明为 `string?`。 --- ### 四、数据库迁移 1. **生成迁移** 运行命令生成迁移文件: ```bash Add-Migration AddProductRequiredFields ``` 2. **更新数据库** 应用迁移以修改表结构: ```bash Update-Database ``` - 若已有数据违反非空约束,需手动修复或设置默认值。 --- ### 五、常见问题与解决 #### 问题 1:迁移时报错(字段包含 NULL 值) - **场景**:为已有字段添加 `[Required]` 后,迁移失败。 - **解决**: 1. 先允许字段为空,更新数据库。 2. 手动填充现有记录的该字段值。 3. 重新应用非空约束。 #### 问题 2:代码未触发验证 - **检查点**: - 确保模型属性已正确标记 `[Required]`。 - 调用 `SaveChanges()` 前检查 `ModelState.IsValid`(在 MVC 中)。 --- ### 六、总结 | 方法 | 适用场景 | 注意事项 | |---------------|----------------------------|----------------------------| | 数据注解 | 简单模型,少量配置 | 需引用 `System.ComponentModel.DataAnnotations` | | Fluent API | 复杂模型,集中管理配置 | 需在 `DbContext` 中配置 | | 可空引用类型 | C# 8.0+ 项目 | 需显式处理 `null` 赋值 | 通过合理配置非空约束,可以确保数据有效性并减少运行时异常。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值