1数据库初始化策略选择

三种初始化策略:

1)CreateDatabaseIfNotExists:默认的策略。如果数据库不存在,那么就创建数据库。但是如果数据库已存在,而且实体发生了变化,就会出现异常。

2)DropCreateDatabaseIfModelChanges:模型改变时,原来的数据库会被删除,自动重新创建一个新的数据库。

3)DropCreateDatabaseAlways:每次运行都会删除原来的数据库,然后重新生成数据库。

4)Null:在Codefirst模式下,当实体结构改变时,运行程序不会自动生成表,改变实体结构与改变表结构互不影响,

前三种策略无法应对的问题是:分别改变实体模型和数据库表结构。即,当使用CreateDatabaseIfNotExists策略时,修改实体模型会抛异常(The model backing the <Database> context has changed since the database was created

);若使用DropCreateDatabaseIfModelChanges模式,那么每次运行都会重新生成数据库,这导致历史数据丢失,然而提前备份数据这种策略比较麻烦,尤其是系统上线以后。

解决办法:

采用第四种初始化策略,初次使用codefirst方式创建好数据库以后,不使用任何数据库初始化策略,即给Database.SetInitializer传null。

[DbConfigurationType(typeof(MySqlEFConfiguration))]
public class HY_WebApiContext : DbContext
{
  public HY_WebApiContext(): base("name=HY_WebApiContext")
  {
    Database.SetInitializer<HY_WebApiContext>(null);
  }
  ......
}

2实体关系与依赖默认规则创建的表关系

Codefirst模式下,实体与表之间的映射,随实体关系的不同而不同。

1)实体之间为一对一关系

实体

     public class EntityOne
{
public int Id { get; set; }
public string FieldEntityOne { get; set; }
public EntityTwo EntityTwo { get; set; }
} public class EntityTwo
{
public int Id { get; set; }
public string FieldEntityTwo { get; set; }
}

表结构

entityones,其中EntityTwo_Id为外键。

EntityTwo

2)实体间的一对多关系

实体

     public class EntityOne
{
public int Id { get; set; }
public string FieldEntityOne { get; set; }
public List<EntityTwo> EntityTwos { get; set; }
} public class EntityTwo
{
public int Id { get; set; }
public string FieldEntityTwo { get; set; }
}

表结构

entityones

entitytwoes,其中EntityOne_Id是外键

3)实体间的多对多关系

实体

     public class EntityOne
{
public int Id { get; set; }
public string FieldEntityOne { get; set; }
public List<EntityTwo> EntityTwos { get; set; } } public class EntityTwo
{
public int Id { get; set; }
public string FieldEntityTwo { get; set; }
       public List<EntityOne> EntityOnes { get; set; }
}

表结构

Codefirst模式下,两个实体间的多对多关系,映射为三张表,其中一张表表示实体间的联系。

entityones

entitytwoes

entitytwoentityones,其中EntityTwo_Id和EntityOne_Id是外键,这两个外键构成了改表的复合主键。

4)实体包含类型相同的两个或多个名称不同的导航属性

实体

public class EntityOne
{
public int Id { get; set; }
public string FieldEntityOne { get; set; }
public EntityTwo EntityTwos { get; set; }
public EntityTwo EntityTwosOther { get; set; }
} public class EntityTwo
{
public int Id { get; set; }
public string FieldEntityTwo { get; set; }
}

Entityones,其中EntityTwos_Id、EntityTwosOther_Id是外键。

entitytwoes

3为关系创建实体:

一个用户可以订阅多种出版物,一种出版物可被多个用户订阅,实体建模如下:

public class Publication
{
  public int Id { get; set; }
  public virtual ICollection<User> Users { get; set; }
  ......
} public class User
{
  public int Id { get; set; }
  public virtual ICollection<Publication> Publications { get; set; }
  ......
}

EF框架对上述多对多关系的默认处理方式为生成三张表:publications,user,publicationusers

其中publicationusers为关系表,表的属性只包括两个表的主键。

问题1:publications表的数据会大量重复:假设用户A订阅了电子学报,publications表里会有一条关于电子学报的记录,当用户B也订阅电子学报的时候,又会将这条数据插入publications表,如此等等。

解决方案

每次向publications表插入记录时,先在表中查找待插入的刊物是否存在,如果存在就不插入,只更新publicationusers表。

问题2:虽然使用上面的方法可以解决这个问题,但用户何时订阅了一种刊物,这类信息没有被记录下来。

解决方案:

添加一个实体,表达publications,user这两个实体之间的关系,实体如下:

public class Publication
{
  public int Id { get; set; }
  ......
}
public class User
{
  public int Id { get; set; }
  ......
} public class PublicationUser
{
public int Id { get; set; }
/// <summary>
/// 出版物
/// </summary>
public Publication Publication { get; set; }
/// <summary>
/// 所属用户
/// </summary>
public User User { get; set; }
/// <summary>
/// 记录插入时间
/// </summary>
public DateTime InsertTime { get; set; }
/// <summary>
/// 记录修改时间
/// </summary>
public DateTime UpdateTime { get; set; }
}

经上述处理后,EF仍然生成三张表publications,user,publicationusers,与之前不同的是publicationusers表中多了Id ,InsertTime ,UpdateTime 这三个字段,同时去掉了publications,user其中的导航属性,这样的设计满足需求,且无冗余。那么经过这样的修改后,每一个PublicationUser实例对应了表中的一条记录。

Entity Framework——建模建库的更多相关文章

  1. 查询大数据表的效率对比:Linq to SQL、Entity Framework、企业库存储过程、ADO.Net

    最近因为要开发大数据量网站,特作比较. Linq to SQL 查询 记录数:399997Linq to SQL 查询 Milliseconds:1910视图查询 记录数:399997视图查询 Mil ...

  2. Entity Framework的扩展库

    https://github.com/jcachat/EntityFramework.DynamicFilters Provides global & scoped filters for E ...

  3. Programming Entity Framework CodeFirst--数据库约定和配置

    这一章主要主要讲的是我们的模型如何映射到数据库,而不影响模型,以及不同的映射场景. 一.表名和列名 1.指定表名 [Table("PersonPhotos")] public cl ...

  4. ADO.NET-EF:ADO.NET Entity Framework 百科

    ylbtech-ADO.NET-EF:ADO.NET Entity Framework 百科 ADO.NET Entity Framework 是微软以 ADO.NET 为基础所发展出来的对象关系对应 ...

  5. 8天掌握EF的Code First开发之Entity Framework介绍

    返回<8天掌握EF的Code First开发>总目录 本篇目录 Entity Framework概要 什么是ORM Entity Framework简史 Entity Framework具 ...

  6. 转载 8天掌握EF的Code First开发之Entity Framework介绍

    转载原地址:  http://www.cnblogs.com/farb/p/IntroductionToEF.html Entity Framework概要 Entity Framework是微软的O ...

  7. Entity Framework开发介绍

    一.Entity Framework概要 Entity Framework是微软的Object Relational Mapper(对象关系映射),也就是我们平常说的ORM,它可以让应用程序开发者将关 ...

  8. 《Entity Framework 6 Recipes》中文翻译系列 (37) ------ 第六章 继承与建模高级应用之独立关联与外键关联

    翻译的初衷以及为什么选择<Entity Framework 6 Recipes>来学习,请看本系列开篇 6-13  在基类中应用条件 问题 你想从一个已存在的模型中的实体派生一个新的实体, ...

  9. Entity Framework扩展库

    这个Entity Framework扩展完全支持EF 5.0/6.0,项目地址 https://github.com/loresoft/EntityFramework.Extended,这个库支持批量 ...

随机推荐

  1. UVa816,Ordering Tasks,WA

    #include <iostream> #include <cstdio> #include <string> #include <cstring> # ...

  2. formData 无需form异步上传多个图片

    上周帮其它公司套一下一个web端微信投票系统的后台接口,遇到了一个图片以及视频上传报名的小问题,网上实现方式有很多但都不是ui上面的效果,于是自己动手改造了一个.先来看看效果图 流程很简单,就是点击每 ...

  3. Windows下MongoDB常用命令

    以下命令中的启动与暂停服务命令需要使用管理员身份运行cmd.exe,其他命令需要先cd到Mongodb安装目录的bin目录. 1.启动服务:net start [Mongodb服务名].示例: net ...

  4. JAVA基础知识总结:四

    一.方法 1.什么是方法? 对于功能相同的代码段,为了简化代码,会把功能相同的代码抽取出来,方便多次使用,Java中,我们使用[方法],也被称为函数 2.函数的声明 语法: 访问权限修饰符 其他修饰符 ...

  5. jstl 处理字符串

    1.引入 <%@ taglib uri="http://java.sun.com/jsp/jstl/functions" prefix="fn"%> ...

  6. Yii2之组件的注册与创建

    今天本来打算研究一下yii2.0的AR模型的实现原理,然而,计划赶不上变化,突然就想先研究一下yii2.0的数据库组件创建的过程.通过对yii源码的学习,了解了yii组件注册与创建的过程,并发现原来y ...

  7. 聊聊Java中的反射(一)

    本文为作者原创,转载请注明出处(http://www.cnblogs.com/mar-q/)by 负赑屃 反射reflection主要为了动态操作Java代码,它的主要功能体现在Java提供的refl ...

  8. 读书笔记-你不知道的JS上-混入与原型

    继承 mixin混合继承 function mixin(obj1, obj2) { for (var key in obj2) { //重复不复制 if (!(key in obj1)) { obj1 ...

  9. win7旗舰版安装IIS

    1.在控制面板中:程序->打开或关闭Windows功能 2.在弹出的对话窗中,在“Internet服务信息”中作如下勾选(打钩的为全选) 点击确定后安装. 3.安装成功后回到控制面板->系 ...

  10. linq 在查询表达式中处理 null 值

    此示例显示如何在源集合中处理可能的 null 值. IEnumerable<T> 等对象集合可包含值为 null 的元素. 如果源集合为 null 或包含值为 null 的元素,并且查询不 ...