码迷,mamicode.com
首页 > 其他好文 > 详细

Entity Framework 4.1 之二 : 覆盖默认的约定

时间:2017-02-19 15:33:34      阅读:176      评论:0      收藏:0      [点我收藏+]

标签:标识   har   动态   asc   简介   key   其他   collect   功能   

原文名称:Entity Framework 4.1: Override conventions (2)
 
 
在这篇文章中,我将讨论如何覆盖默认的约定。
我们已经看过了在 EF4.1 Code First 中模型与数据库中的默认约定。当这些约定不能满足我们的时候,我们有两种不同的途径来覆盖这些约定:
  • 拦截模型的构建器,使用流畅的 API 来修改模型
  • 为我们的模型增加标签
在未来的版本中,我们还将有能力增加或者删除约定,现在还没有提供这个能力。
对于我们基本的例子,我们使用下面所示的订单类。
public class Order
{
public int OrderID { get ; set ; }
public string OrderTitle { get ; set ; }
public string CustomerName { get ; set ; }
public DateTime TransactionDate { get ; set ; }
}
 

构建器

我们从模型的构建器开始吧。为了使用模型构建器,我们必须重写 DbContext 的一个方法 OnModelCreating.
protected override void OnModelCreating(DbModelBuilder modelBuilder)
{
base .OnModelCreating(modelBuilder);
// Map schemas
modelBuilder.Entity < Order > ().ToTable( " efdemo.Order " );
}
默认情况下,EF 将实体映射到数据库中 dbo 架构下的同名表上,这里我将订单映射到数据库中 efdemo 架构下的 Order 表。
模型构建器提供了一种流畅的 API 方式,由于方法返回同样的对象,意味着可以使用链式的方法将操作连接在一起。下面是另外一个例子。
modelBuilder.Entity < Order > ().Property(x => x.OrderID)
.HasDatabaseGeneratedOption(DatabaseGeneratedOption.Identity)
.IsRequired()
.HasColumnName(
" TheOrderID " );
 在这里,我们对属性 OrderID 做了三件事:
  • 标识它是标识列,自增长的列
  • 必须的列,非空
  • 映射到数据库中的 TheOrderID
这里,我们将涉及 EF4.1 的强大的功能:通过 Lambda 表达式,可以逐条定义属性,而不是使用字符串来标识属性,这有以下的优势:
  • 有智能提示
  • 有编译时的错误检查
  • 属性的类型是已知的,你可以在之后定义,例如,只有字符串可以有最大或最小长度。
那么,通常我们重写什么约定呢?看一下 Order 类,下面的情况不太符合默认约定:
  • 表必须属于 dbo Schema
  • OrderID 是主键,但不是自增长的类型
  • 所有其他列是非空的
  • 字符串列的长度是 128
 我们可以通过模型构建器重写这些约定:
// Map schemas
modelBuilder.Entity < Order > ().ToTable( " efdemo.Order " );
// Identity Column
modelBuilder.Entity < Order > ().Property(x => x.OrderID)
.HasDatabaseGeneratedOption(DatabaseGeneratedOption.Identity);
// String columns
modelBuilder.Entity < Order > ().Property(x => x.OrderTitle)
.IsRequired()
.HasMaxLength(
64 );
modelBuilder.Entity
< Order > ().Property(x => x.CustomerName)
.IsRequired()
.HasMaxLength(
32 );
// Date Columns
modelBuilder.Entity < Order > ().Property(x => x.TransactionDate)
.IsRequired();
 看起来有点冗长,但是不用修改模型,纯粹的 POCO.

使用标注

现在,我们在看一下另外一种方式,使用标签。
这种方式的代码要少得多,感觉更加自然,通过标签来说明属性。唯一的问题是你的类不再 POCO,虽然使用的类并没有来自 EF,而是 System.ComponentModel.DataAnnotations , .NET 的验证模块。看一下例子吧。
public class Order
{
public int OrderID { get ; set ; }

[Required]
[StringLength(
32 , MinimumLength = 2 )]
public string OrderTitle { get ; set ; }

[Required]
[StringLength(
64 , MinimumLength = 5 )]
public string CustomerName { get ; set ; }

[Required]
public DateTime TransactionDate { get ; set ; }
}
 
这里我们告诉模型构建器将 OrderTitle 映射到非空的长度为32 的 nvarchar 列,最小长度为 2没有映射到架构中,但是将被用来验证。
这个例子我给出了一些业务标注,也可以加上一些技术标注。
public class Order
{
[Key]
[DatabaseGenerated(DatabaseGeneratedOption.Identity)]
public int OrderNumber { get ; set ; }

}
 
这里我们强制 OrderNumber 属性作为主键,而且是一个自增长的列。
还可以使用 OnModelCreated 或者其他的标签来覆盖约定,有一些限制需要注意,例如(这是我注意到的):
  • 表名不支持使用标签进行标注
  • 最小长度在 OnModelCreated 中不支持
  • 正则表达式在 OnModelCreated 中不支持
着比较好理解,OnModelCreated 属于表映射,(正则或者最小长度不能在数据库中表示),标注支持常见的验证。
我的原则:
  • 使用标注来丰富模型的验证规则
  • 使用 OnModelCreated 来完成数据库的约束(主键,自增长,表名,列类型等等)
这些方式可以使你的模型更加丰富而且保持 POCO,你可以到处重用你的模型,还能从验证规则中获得好处。
 

参考页面:

http://www.yuanjiaocheng.net/mvc/mvc-models.html

http://www.yuanjiaocheng.net/ASPNET-CORE/core-views.html

http://www.yuanjiaocheng.net/webapi/web-api-gaisu.html

http://www.yuanjiaocheng.net/CSharp/Csharp-Generics-collection.html

http://www.yuanjiaocheng.net/webapi/test-webapi.html

http://www.yuanjiaocheng.net/Linq/linq-tutorials.html

http://www.yuanjiaocheng.net/CSharp/first.html

http://www.yuanjiaocheng.net/webapi/web-api-controller.html

http://www.yuanjiaocheng.net/CSharp/csharp-dynamic-type.html

http://www.yuanjiaocheng.net/CSharp/csharp-generic-sortlist.html

http://www.yuanjiaocheng.net/mvc/create-first-mvc.html

Entity Framework 4.1 之二 : 覆盖默认的约定

标签:标识   har   动态   asc   简介   key   其他   collect   功能   

原文地址:http://www.cnblogs.com/dongqidongqi/p/6415751.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!