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

两个概念:

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

1. 实体拆分

配置代码:

public class BloggingContext : DbContext
{
public BloggingContext()
: base("name=ef_split_dbcontext")
{
} public DbSet<Blog> Blogs { get; set; } protected override void OnModelCreating(DbModelBuilder modelBuilder)
{
modelBuilder.Entity<Blog>()
.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; }
}

映射效果:

测试代码:

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<Post> Posts { get; set; }
public DbSet<PostDetail> PostDetails { get; set; } protected override void OnModelCreating(DbModelBuilder modelBuilder)
{
modelBuilder.Entity<Post>()
.HasKey(t => t.PostId); modelBuilder.Entity<PostDetail>()
.HasKey(t => t.PostId); modelBuilder.Entity<PostDetail>()
.HasRequired(t => t.Post)
.WithRequiredPrincipal(t => t.PostDetail); modelBuilder.Entity<Post>().ToTable("Posts");
modelBuilder.Entity<PostDetail>().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; }
}

映射效果:

测试代码:

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.

参考:使用 Fluent API 配置/映射属性和类型

EntityFramework 实体拆分和表拆分的更多相关文章

  1. EntityFramework 实体拆分与表拆分

    摘录自https://msdn.microsoft.com/zh-cn/data/jj591617 * 将实体类型的 CLR 属性映射到数据库中的多个表(实体拆分) 实体拆分允许一个实体类型的属性分散 ...

  2. mysql单个表拆分成多个表

    一.横向拆分 create table 新表的名称 select * from 被拆分的表 order by id limit int1,int2 int1为其实位置,int2为几条 注意:这样拆分后 ...

  3. 《Entity Framework 6 Recipes》中文翻译系列 (7) -----第二章 实体数据建模基础之拆分实体到多表以及拆分表到多实体

    2-6 拆分实体到多表 问题 你有两张或是更多的表,他们共享一样的主键,你想将他们映射到一个单独的实体. 解决方案 让我们用图2-15所示的两张表来演示这种情况. 图 2-15,两张表,Prodeuc ...

  4. Entity Framework表拆分

    一.概念 表拆分:一个表拆分成多个实体,例如Photograph表,可以拆分为Photograph和PhotographFullImage两张表. Photograph实体结构: using Syst ...

  5. 【mysql的设计与优化专题(4)】表的垂直拆分和水平拆分

    垂直拆分 垂直拆分是指数据表列的拆分,把一张列比较多的表拆分为多张表 通常我们按以下原则进行垂直拆分: 把不常用的字段单独放在一张表; 把text,blob等大字段拆分出来放在附表中; 经常组合查询的 ...

  6. mycat表拆分操作教程

    1,迁移数据 举例说明,比如一个博客数据库数据表如下: 这里水平拆分,垂直拆分,只是做个简单的实验,真正的线上业务要根据情况,数据进行拆分. ? 1 2 3 4 5 6 7 8 9 10 11 12 ...

  7. WPS 2019 多个sheet表拆分成独立的excel文件

    参考: https://www.cnblogs.com/hackxiyu/p/8945975.html 场景:将多个sheet表拆分成独立的excel文件 一.安装VB工具: 默认情况下:wps -- ...

  8. 表的垂直拆分和水平拆分-zz

    https://www.kancloud.cn/thinkphp/mysql-design-optimalize/39326 http://www.cnblogs.com/nixi8/tag/mysq ...

  9. mysql关于数据库表的水平拆分和垂直拆分

    最初知道水平垂直分表的时候是刚参加工作不久的时候,知道了这个概念,但是公司用户量和数据量始终没上来,所以也没用到过,知道有一天到了一家新公司后,这些才被应用到实际开发中,这里我就大概说说关于水平和垂直 ...

随机推荐

  1. Python 字符串操作(string替换、删除、截取、复制、连接、比较、查找、包含、大小写转换、分割等)

    去空格及特殊符号 s.strip().lstrip().rstrip(',') 复制字符串 #strcpy(sStr1,sStr2) sStr1 = 'strcpy' sStr2 = sStr1 sS ...

  2. 控制 Android 程序使用的内存

    如何控制应用程序使用的内存? 1. 记得关闭启动的服务 当服务中的任务完成后,要记得停止该服务.可以考虑使用 IntentService,因为 IntentService 在完成任务后会自动停止. 2 ...

  3. jquery mobile 问问多多

    jquery mobile  问题多多,兼容性太差.android4.1下完全崩溃.以后再也不用jquery mobile了

  4. 奇怪的UnexpectedRollbackException异常

    今天在使用一个原来常用的功能的时候,突然发现在某些场景下会报异常,内容如下: 通过断点调试发现一路都很顺畅,就是在从controller层返回前段的时候会报该异常,没办法,只能通过排除法定位问题,后来 ...

  5. Unity3D 与android交互流程步骤

    1.Android端代码可以在Eclipse中开发(AndroidStudio没有试,应该也可以) 2.Unity3D端代码要在Unity中开发 3.Android和Unity3D端,两边都需要加入一 ...

  6. 基于Picture Library创建的图片文档库中的上传多个文件功能(upload multiple files)报错怎么解决?

    复现过程 首先,我创建了一个基于Picture Library的图片文档库,名字是 Pic Lib 创建完毕后,我点击它的Upload 下拉菜单,点击Upload Picture按钮 在弹出的对话框中 ...

  7. DevExpress GridControl使用方法

    一.如何解决单击记录整行选中的问题 View->OptionsBehavior->EditorShowMode 设置为:Click 二.如何新增一条记录 (1).gridView.AddN ...

  8. MySQL 分区介绍总结

    200 ? "200px" : this.width)!important;} --> 介绍 分区是指根据一定的规则将一个大表分解成多个更小的部分,这里的规则一般就是利用分区 ...

  9. ASP.NET MVC 5 - 给电影表和模型添加新字段

    在本节中,您将使用Entity Framework Code First来实现模型类上的操作.从而使得这些操作和变更,可以应用到数据库中. 默认情况下,就像您在之前的教程中所作的那样,使用 Entit ...

  10. 学习RBAC 用户·角色·权限·表