博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
EntityFramework 实体拆分和表拆分
阅读量:6119 次
发布时间:2019-06-21

本文共 3532 字,大约阅读时间需要 11 分钟。

之前有人问过 EF 如何进行实体拆分和表拆分?我记得当时认为不可能,理由忘记了,后来又有人发了一段配置截图,发现原来是可以的,不记录的东西容易忘掉,关于 EF 实体拆分和表拆分,下面是自己的一些整理。

两个概念:

  • 实体拆分:一个实体拆分成多个表,如 Blog 实体,可以拆分成 Blogs 和 BlogDetails 两个表。
  • 表拆分:一个表拆分成多个实体,如 Posts 表,可以拆分成 Post 和 PostDetail 两个实体。

1. 实体拆分

配置代码:

public class BloggingContext : DbContext{    public BloggingContext()        : base("name=ef_split_dbcontext")    {    }    public DbSet
Blogs { get; set; } protected override void OnModelCreating(DbModelBuilder modelBuilder) { modelBuilder.Entity
() .Map(m => { m.Properties(t => new { t.Id, t.Title, t.Url }); m.ToTable("Blogs"); }) .Map(m => { m.Properties(t => new { t.Id, t.Remark }); m.ToTable("BlogDetails"); }); base.OnModelCreating(modelBuilder); }}public class Blog{ [Key] public int Id { get; set; } public string Title { get; set; } public string Url { get; set; } public string Remark { get; set; }}

映射效果:

031743322078744.png

测试代码:

using (var context=new BloggingContext()){    context.Blogs.Add(new Blog { Remark = "", Title = "EntityFramework 实体拆分和表拆分", Url = "http://www.cnblogs.com/xishuai/p/ef-entity-table-splitting.html" });    context.SaveChanges();}

测试结果为 Blogs 和 BlogDetails 表中,分别产生一条数据,即使 Remark 的值为空。

2. 表拆分

配置代码:

public class BloggingContext : DbContext{    public BloggingContext()        : base("name=ef_split_dbcontext")    {    }    public DbSet
Posts { get; set; } public DbSet
PostDetails { get; set; } protected override void OnModelCreating(DbModelBuilder modelBuilder) { modelBuilder.Entity
() .HasKey(t => t.PostId); modelBuilder.Entity
() .HasKey(t => t.PostId); modelBuilder.Entity
() .HasRequired(t => t.Post) .WithRequiredPrincipal(t => t.PostDetail); modelBuilder.Entity
().ToTable("Posts"); modelBuilder.Entity
().ToTable("Posts"); base.OnModelCreating(modelBuilder); }}public class Post{ public int PostId { get; set; } public string Title { get; set; } public string Content { get; set; } public virtual PostDetail PostDetail { get; set; }}public class PostDetail{ public int PostId { get; set; } public string Remark { get; set; } public virtual Post Post { get; set; }}

映射效果:

031747255353827.png

测试代码:

using (var context=new BloggingContext()){    context.Posts.Add(new Post { Title="EntityFramework 实体拆分和表拆分"});    context.PostDetails.Add(new PostDetail {  Remark=""});    context.SaveChanges();}

测试结果为 Posts 表中产生一条数据,注意映射配置中的这段代码:modelBuilder.Entity<PostDetail>().HasRequired(t => t.Post).WithRequiredPrincipal(t => t.PostDetail);,我们一般在外键配置的时候会用到 HasRequired,Required 表示的意思是必须,还有一种写法是:modelBuilder.Entity<PostDetail>().HasOptional(t => t.Post).WithOptionalPrincipal(t => t.PostDetail);,关键词 Optional,但映射会抱下面错误:The entity types 'Post' and 'PostDetail' cannot share table 'Posts' because they are not in the same type hierarchy or do not have a valid one to one foreign key relationship with matching primary keys between them.

其实我的想法是,在上面测试代码中,用了两个 Add(而不是一个 Add,然后用 PostDetail 属性赋值),那会不会在 Posts 表中产生两条数据,但显然没有,因为我们在映射配置的时候,使用的是 Required,可以理解为“强制合并为一个表”,不论你怎么添加数据,都会只添加一条数据,另外,需要注意的是,在上面表拆分示例中,主实体是 Post,所以,如果只有 context.PostDetails.Add(new PostDetail { Remark=""});,会抱下面错误:Invalid data encountered. A required relationship is missing. Examine StateEntries to determine the source of the constraint violation.

参考:

你可能感兴趣的文章
HDU 2818 (矢量并查集)
查看>>
【转】php字符串加密解密
查看>>
22. linux 常用命令
查看>>
ASP.Net 使用GridView模板删除一行的用法
查看>>
(十六)字段表集合
查看>>
JPGraph
查看>>
实验二 Java面向对象程序设计
查看>>
------__________________________9余数定理-__________ 1163______________
查看>>
webapp返回上一页 处理
查看>>
新安装的WAMP中phpmyadmin的密码问题
查看>>
20172303 2017-2018-2 《程序设计与数据结构》第5周学习总结
查看>>
eclipse中将一个项目作为library导入另一个项目中
查看>>
Go语言学习(五)----- 数组
查看>>
Android源码学习之观察者模式应用
查看>>
Content Provider的权限
查看>>
416. Partition Equal Subset Sum
查看>>
centos7.0 64位系统安装 nginx
查看>>
数据库运维平台~自动化上线审核需求
查看>>
注解开发
查看>>
如何用 Robotframework 来编写优秀的测试用例
查看>>