Entityframework~Fluent Api配置数据模型与数据库结构关系
本次实例主要讲在 Entityframework 这个 ORM 框架中使用 Fluent Api 来完成对 POCO 类与数据库结构之间的映射配置。
构建 POCO 类
新建POCO (plain old c# object) :
Blog 类:
using System;
using System.Collections.Generic;
namespace CodeFirstSample
{
public partial class Blog
{
public int BlogId { get; set; }
public string Title { get; set; }
public string Content { get; set; }
public DateTime CreateTime { get; set; }
public virtual ICollection<Comment> Comments { get; set; }
}
}
Comment 类:
namespace CodeFirstSample
{
public partial class Comment
{
public int CommentId { get; set; }
public string UserName { get; set; }
public string Content { get; set; }
public int BlogId { get; set; }
public virtual Blog Blog { get; set; }
}
}
建立映射关系
Blog 的映射配置
using System.Data.Entity.ModelConfiguration;
namespace CodeFirstSample
{
public partial class BlogMap : EntityTypeConfiguration<Blog>
{
public BlogMap()
{
this.ToTable("Blog"); //表名
this.HasKey(x => x.BlogId); //设置主键
this.Property(x => x.Title).IsRequired().HasMaxLength(50); //设置字段属性,约束 not null, 最大长度50
this.Property(x => x.Content).HasColumnType("text"); //设置字段类型为 text
this.Property(x => x.CreateTime).IsRequired(); // 设置字段约束 not null
this.HasMany(x => x.Comments); // 设置导航字段, Blog: Comment --> one: many
}
}
}
Comment 的映射配置
using System.Data.Entity.ModelConfiguration;
namespace CodeFirstSample
{
public partial class CommentMap : EntityTypeConfiguration<Comment>
{
public CommentMap()
{
this.ToTable("Comment"); //表名
this.HasKey(x => x.CommentId); //设置主键
this.Property(x => x.UserName).IsRequired().HasMaxLength(30); //设置字段属性,约束 not null, 最大长度30
this.Property(x => x.Content).IsRequired().HasMaxLength(256); //设置字段属性,约束 not null, 最大长度256
this.Property(x => x.BlogId).IsRequired(); //设置字段属性,约束 not null
}
}
}
注册映射关系
using System;
using System.Linq;
using System.Data.Entity;
using System.Reflection;
using System.Data.Entity.ModelConfiguration;
namespace CodeFirstSample
{
public partial class CodeFirstContext : DbContext
{
public CodeFirstContext()
: base("CodeFirstContext")
{
}
///重写 OnModelCreating 方法, 注册配置关系
protected override void OnModelCreating(DbModelBuilder modelBuilder)
{
//获取程序集中所有的配置类
var typesToRegister = Assembly.GetExecutingAssembly().GetTypes()
.Where(type => !String.IsNullOrEmpty(type.Namespace))
.Where(type => type.BaseType != null
&& type.BaseType.IsGenericType
&& type.BaseType.GetGenericTypeDefinition() == typeof(EntityTypeConfiguration<>));
//遍历循环逐个添加到配置中
foreach (var type in typesToRegister)
{
//创建配置实例
dynamic configurationInstance = Activator.CreateInstance(type);
//添加配置
modelBuilder.Configurations.Add(configurationInstance);
}
base.OnModelCreating(modelBuilder);
}
///获取相关模型的数据集
///使用 new 关键字来隐藏父类的 Set<> 方法
public new IDbSet<TEntity> Set<TEntity>() where TEntity : class
{
return base.Set<TEntity>();
}
}
}
测试
using System;
namespace CodeFirstSample
{
class Program
{
static void Main(string[] args)
{
using (var db = new CodeFirstContext())
{
//获取 Blog 数据集
var blogs = db.Set<Blog>();
//获取 Comment 数据集
var comments = db.Set<Comment>();
var blog = new Blog
{
Title = "Entityframework",
Content = "xxxxx",
CreateTime = DateTime.Now
};
//添加 Blog
blog = blogs.Add(blog);
var comment = new Comment
{
UserName = "visitor 1",
Content = "xxxx",
BlogId = blog.BlogId,
Blog = blog
};
//添加 Comment
comments.Add(comment);
//保存更改
db.SaveChanges();
foreach (var entity in blogs)
{
Console.WriteLine(entity.Title);
}
foreach (var entity in comments)
{
Console.WriteLine(entity.UserName);
}
}
Console.ReadKey();
}
}
}
这里只是为后面的实例坐下铺垫, 各行代码作用注释中有, 源码上传好之后我会在评论中发布。