EntityFramework实体映射到数据库
在Entity Framework Code First与数据表之间的映射方式实现:
1、Fluent API映射
通过重写DbContext
上的OnModelCreating
方法来访问Code First Fluent API
例如:
public class BlogDbContext: DbContext { public BlogDbContext() : base("BlogDbContext") { } public DbSet<BlogUser> BlogUser{ get; set; } protected override void OnModelCreating(DbModelBuilder modelBuilder) { modelBuilder.Entity<BlogUser>().HasKey(k => k.BlogUserId) //主键 .Property(q => q.BlogName).IsRequired();//不能为空 } }
demo中的property方法用于为每个属于实体或复杂类型的属性配置特性。Property 方法用于获取给定属性的配置对象。配置对象上的选项特定于要配置的类型;例如,IsRequired表示不可为空。
- ToTable - TableAttribute:配置此实体类型映射到的表名
- HasColumnName - ColumnAttribute:配置用于存储属性的数据库列的名称
- HasForeignKey - ForeignKeyAttribute:将关系配置为使用在对象模型中的外键属性。如果未在对象模型中公开外键属性,则使用Map方法
- Ignore - NotMappedAttribute:从模型中排队某个属性,使该属性不会映射到数据库
- HasRequired:通过此实体类型配置必需关系。除非指定此关系,否则实体类型的实例将无法保存到数据库。数据库中的外键不可为null。
- HasOptional:从此实体类型配置可选关系。实体类型的实例将能保存到数据库,而无需指定此关系。数据库中的外键可为null。
- HasMany:从此实体类型配置一对多关系。
- WithOptional:将关系配置为required:optional。(required:0…1端的1,表示必需,不可为null;optional:0…1端的0,表示可选,可为null。下同)
- WithOptionalDependent:将关系配置为optional:optional。要配置的实体类型将成为依赖对象,且包含主体的外键。作为关系目标的实体类型将成为关系中的主体。
- WithOptionalPrincipal:将关系配置为optional:optional。要配置的实体类型将成为关系中的主体。作为关系目标的实体类型将成为依赖对象,且包含主体的外键。
- WithRequired:将关系的指定端配置为必需的,且在关系的另一端有导航属性。
- WithRequiredDependent:将关系配置为required:required。要配置的实体类型将成为依赖对象,且包含主体的外键。作为关系目标的实体类型将成为关系中的主体。
- WithRequiredPrincipal:将关系配置为required:required。要配置的实体类型将成为关系中的实体。作为关系目标的实体类型将成为依赖对象,且包含主体的外键。
- WillCascadeOnDelete:配置是否对关系启用级联删除。
- Map:将关系配置为使用未在对象模型中公开的外键属性。可通过指定配置操作来自定义列和表。如果指定了空的配置操作,则约定将生成列名。如果在对象模型中公开了外键属性,则使用 HasForeignKey 方法。并非所有关系都支持在对象模型中公开外键属性。
- MapKey:配置外键的列名。
- ToTable:配置外键列所在表的名称和架构
参考资料:https://msdn.microsoft.com/zh-cn/library/gg696117
如果这时候需要修改BlogUser这个实体,比如添加一个字段的时候直接运行就会报错,此时需要进行数据库更新迁移
建一个迁移类
using BlogDemo.Repositories; using System; using System.Collections.Generic; using System.Data.Entity.Migrations; using System.Linq; using System.Web; namespace BlogDemo.Migrations { public class Configuration:DbMigrationsConfiguration<BlogDbContext> { /// <summary> /// 初始化一个<see cref="MigrationsConfiguration"/>类型的新实例 /// </summary> public Configuration() { //启用自动迁移 AutomaticMigrationsEnabled = true; //获取或设置一个值表示如果在自动数据丢失是可以接受的 [慎重设置] AutomaticMigrationDataLossAllowed = true; } } }
同时也需要在Global.asax里面添加应用程序初始化的时候把数据库更新为最新的办法
protected void Application_Start() { //数据库初始化为最新的版本 Database.SetInitializer(new MigrateDatabaseToLatestVersion<BlogDbContext,Configuration>()); AreaRegistration.RegisterAllAreas(); // 默认情况下对 Entity Framework 使用 LocalDB //Database.DefaultConnectionFactory = new SqlConnectionFactory(@"Data Source=(localdb)\v11.0; Integrated Security=True; MultipleActiveResultSets=True"); RegisterGlobalFilters(GlobalFilters.Filters); RegisterRoutes(RouteTable.Routes); }
这个时候基本的操作可以实现,但是在实际的项目中数据表肯定不止一两张,几十张甚至上百张,如果按照这样的配置方法,需要配置映射关系的时候在 BlogDbContext的OnModelCreating进行配置,到后面在OnModelCreating方法中会添加很多关系
所以此时的解决方法就是新加一个映射类,在这个类中引用EntityTypeConfiguration,其实在BlogDbContext的OnModelCreating中有一句代码是modelBuilder.Entity<BlogUser>().HasKey(m => m.BlogUserId); haskey转到定义可看到
所以在这里引用EntityTypeConfiguration是为了可以在构造方法中写配置,如下:
public class BlogUserConfiguration : EntityTypeConfiguration<BlogUser>,IEntityMapper { public BlogUserConfiguration() { //设置主键 HasKey(m => m.BlogUserId); } }
这样我们就可以不用在OnModelCreating中配置,可以把之前的代码删掉,用modelBuilder.Configurations.Add(new BlogUserConfiguration());
这样我们就用了这个通用的接口替换了OnModelCreating方法
在BlogDbContext中的 public DbSet<BlogUser> BlogUser{ get; set; } 可以注释掉,然后直接用DbContext.Set<TEntity>()方法来实现指定实体的属性
如下:
var dbContext = new BlogDbContext(); IQueryable<BlogUser> blogUser= dbContext.Set<BlogUser>(); blogUser.ToList();
2、Data Annotation验证
所引用程序集:System.ComponentModel.DataAnnotations
Data Annotation主要是在实体类的属性上加入需要验证的条件
例如:
StringLength表示字符长度限制50位,如果超过此长度则提示"输入过长,不能超过50位";
[Required(ErrorMessage = "Name is required")]
public string Name { get; set; }
[Required(ErrorMessage = "Email is required")]
[RegularExpression(@"^\s*([A-Za-z0-9_-]+(\.\w+)*@([\w-]+\.)+\w{2,3})\s*$", ErrorMessage = "Email is invalid")]
public string Email { get; set; }
Required()表示这个属性是必填的,ErrorMessage的值是必填项没有填时,显示的错误提示信息
RegularExpression()是正则表达式验证,只有符合正则表达式的字符串才能通过验证
Fluent API和Data Annotation配置数据库映射参考博文
http://www.cnblogs.com/oppoic/p/ef_default_mapping_and_data_annotations_fluent_api.html