EntityFramework 实体拆分和表拆分

简介:

两个概念:

  • 实体拆分:一个实体拆分成多个表,如 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; }
}
AI 代码解读

映射效果:

测试代码:

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();
}
AI 代码解读

测试结果为 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; }
}
AI 代码解读

映射效果:

测试代码:

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

测试结果为 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.



本文转自田园里的蟋蟀博客园博客,原文链接:http://www.cnblogs.com/xishuai/p/ef-entity-table-splitting.html,如需转载请自行联系原作者

目录
打赏
0
0
0
0
49
分享
相关文章
C#数据分表核心代码
C#数据分表核心代码
73 0
Mybatis关联关系映射与表对象之间的关系
Mybatis关联关系映射与表对象之间的关系
81 0
Mybatis关联关系映射与表对象之间的关系
关系模型知识点总结(2)—— 关系完整性约束&关系操作基础
关系模型应提供定义和检验这类完整性机制,以便用统一的系统方法处理他们,而不需要由应用程序承担
383 0
关系模型知识点总结(2)—— 关系完整性约束&关系操作基础
关系数据库设计中,用中间表好还是直接设定主外键关联好?
有人会对数据库有这样的疑问: 因为大多数的数据库教程上都是告诉你关系数据库如何去创建1:1、1:N和N:M的数据库关系,但我发现很多开源产品中,并没有直接使用关系数据库的关系查询、关系删除等功能,而是直接在代码中对多个表的查询结果进行组合。
2518 0
EntityFramework 实体拆分和表拆分
原文:EntityFramework 实体拆分和表拆分 之前有人问过 EF 如何进行实体拆分和表拆分?我记得当时认为不可能,理由忘记了,后来又有人发了一段配置截图,发现原来是可以的,不记录的东西容易忘掉,关于 EF 实体拆分和表拆分,下面是自己的一些整理。
1439 0
从分库分表后遗症,总结数据库表拆分策略
本文将主要从背景、分库分表带来的后遗症、分表策略以及一些注意事项等方面对数据库分表来进行小结。
3628 0
sqlsever 视图和事物以及索引的概念
视图: 相当于将一个表用一个视图来存储 create view vw_1 as select top 100 emp.
1097 0
AI助理

你好,我是AI助理

可以解答问题、推荐解决方案等