前言

之前有学过EF一段时间那时EF才4.0似乎还不太稳定,而现在EF都已7.0版本,同时AspNet Identity都与此大有关联,看来是大势所趋于是开始学习EF,在学EF过程中也遇到一些小问题,特此录下,以备忘!

数据库和表基本创建

为了更好的循序渐进稍微概括下典型创建EF Code First过程(看之即懂,懂即略过)

第一步先定义两个类,如下:

public classStudent

{publicStudent()

{

}public int StudentID { get; set; }public string StudentName { get; set; }

}public classStandard

{publicStandard()

{

}public int StandardId { get; set; }public string StandardName { get; set; }

}

第二步:继承EF上下文DbContext

public classSchoolContext : DbContext

{

public SchoolContext():base("name=DBConnectionString"){

}public DbSet Students { get; set; }public DbSet Standards { get; set; }protected override voidOnModelCreating(DbModelBuilder modelBuilder)

{base.OnModelCreating(modelBuilder);

}

}

学生上下文中构造函数中的name去读取如下配置文件来命名数据库名称: DBByConnectionString

然后在控制台中通过EF上下文添加数据并保存,如下:

using (var ctx = newSchoolContext())

{

Student stud= new Student() { StudentName = "New Student"};

ctx.Students.Add(stud);

ctx.SaveChanges();

}

最终生成数据库以及表如下图:

上述创建数据库的过程只需注意:可以手动通过添加构造函数的name来命名数据库名称或者无需添加name那么生成的数据库名称是以上下文中的命名空间+上下文类来命名数据库名称。

数据库创建以及表一劳永逸配置

下面创建方法是看过园友hystar(EF教程)而写的,确实是好方法,就搬过来了,为什么说一劳永逸呢?不明白的话,可以去看看他的文章!首先添加两个类Student(学生类)和Course(课程类)。

public classStudent

{public int ID { get; set; }public string Name { get; set; }public int Age { get; set; }public virtual Course Course { get; set; }

}public classCourse

{public int StudentID { get; set; }public string Name { get; set; }public virtual Student Student { get; set; }

}

添加EFDbContext类并继承DbContext上下文,代码如下:

public classEntityDbContext : DbContext

{publicEntityDbContext()

:base("name=test2")

{ }///

///通过反射一次性将表进行映射///

///

protected override voidOnModelCreating(DbModelBuilder modelBuilder)

{var typesRegister =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 intypesRegister)

{

dynamic configurationInstance=Activator.CreateInstance(type);

modelBuilder.Configurations.Add(configurationInstance);

}

}

}

由于是手动命名数据库名称,当然得读取配置文件

上述配置要添加的数据库建立在VS2013自带的实例中!我们首先初始化数据库看看:

EntityDbContext ctx = newEntityDbContext();

结果运行就出现如下经典错误:

在与SQLServer建立连接时出现与网络相关的或特定与实例的错误.未找到或无法访问服务器.请验证实例名称是否正确并且SQL SERVER已配置允许远程链接provide:命名管道提供程序,error:40 -无法打开到SQL Server的连接)

那肯定是无法连接到 (localdb)\v11.0 ,于是当我在服务器打开添加连接中添加服务器名为 (localdb)\v11.0 时也是无法响应,连接不到!最终通过SqlLocalDB命令在Command Prompt(命令行)中输入

SqlLocalDB.exe start v11.0

启动该实例才算完事,主要原因是安装了SQL 2012默认启动的实例该SQL 2012而VS 2013中的实例被停止运行得手动启动,如果要查看其信息来查看是否已经启动,通过以下命令即可:

SqlLocalDB.exe info v11.0

VS2013中默认的实例应该是(localdb)\v11.0,如果在服务器中添加连接输入(localdb)\v11.0是错误的,你可以通过上述 SqlLocalDB.exe info v11.0 命令复制并添加如图的字符串即可

似乎只要第一次启动了,以后每次都会连接上,不会再出现如上问题!

上述中我们对于EF上下文不用每次都初始化数据库,在EF中初始化数据库有三种策略:

CreateDatabaseIfNotExists:该项也是默认初始化数据库的一项,要是数据库不存在就创建数据库。

DropCreateDatabaseIfModelChanges:只要数据模型发生了改变就重新创建数据库。

DropCreateDatabaseAlways:只要每次初始化上下文时就创建数据库。

鉴于此我们在EFDbContext中采用第二种策略。创建一个初始化类的策略 EFDbContextInit

///

///当对象实体对象发生改变时重生创建数据库///

public class EntityDbContextInit : DropCreateDatabaseIfModelChanges{protected override voidSeed(EntityDbContext context)

{base.Seed(context);

}

}

在EFDbContext静态构造函数中进行初始化此方法:

staticEntityDbContext()

{

Database.SetInitializer(newEntityDbContextInit());

}

自此EFDbContext构建完毕!下面就是模型映射了,我们假设学生和课程是1:1关系,则我们添加的两个实体映射如下:

StudentMap(学生类实体映射)

public class StudentMap : EntityTypeConfiguration{publicStudentMap()

{

ToTable("Student");

HasKey(d=>d.ID);//HasRequired(p => p.Course).WithRequiredDependent(i => i.Student);//HasRequired(p => p.Course).WithOptional(i => i.Student);

HasRequired(p=> p.Course).WithRequiredPrincipal(p =>p.Student);

HasOptional(p=> p.Course).WithRequired(p =>p.Student);

/*

对于上述映射关系不太理解的话可以去上述给出链接文章。我只说明怎么去很好的理解这两组的意思,第一组 WithRequiredDependent 和第二组

WithRequiredPrincipal 一个是Dependent是依赖的意思说明后面紧接着的Student是依赖对象,而前面的Course是主体,而Principal

首先的意思,说明后面紧接着的是Student是主体,而Course是依赖对象。很显然在这个关系中课程是依赖学生的。所以映射选第二组

*/

}

}

CourseMap(课程类映射)

public class CourseMap : EntityTypeConfiguration{publicCourseMap()

{

ToTable("Course");

HasKey(p=>p.StudentID);

}

}

接下来我们进行添加数据并保存通过如下代码:

EntityDbContext ctx = newEntityDbContext();var s = newStudent()

{

Name= "1",

Age= 12,

Course= new Course() { Name = "12"}

};

ctx.Set().Add(s);

ctx.SaveChanges();

数据添加和保存都已通过,接下来进行查询数据,查询数据有两种方式:

(1)直接通过EF中Set()方法获得数据集合

(2)通过EF中SqlQuery()方法通过sql语句查询

如要获得上述学生数据列表集合,可以通过如下操作:

EntityDbContext ctx = newEntityDbContext();var list = ctx.Set().ToList();

或者

SqlParameter[] parameter={ };var list = ctx.Database.SqlQuery("select * from student", parameter);

于是我监视下返回的list集合中的数据类型,如图

oh,shit!和我们实际的实体类型不符,通过EF产生的却是 DynamicProxies ,于是到Sytem.Data.Entity类下去看看是个什么类型,居然没找到,估计看这单词意思就是运行时产生的动态代理对象。那么,你觉得是不是没什么影响了???那影响可大了,请看下面操作:

var list = ctx.Set().ToList();var jsonString = JsonConvert.SerializeObject(list);

我尝试将其序列化看看结果,一运行,oh,no!错误如下:

这意思是检测到在Course里面有Student属性,而Student类里又有Course这就相当于自己引用自己,导致了循环引用就成了死循环。(这就是因为 DynamicProxies 导致的结果)所以当前要将其代理对象转换为我们的实体对象即可。

则通过Select()方法投影将其代码进行改造后如下:

var list = ctx.Set().Include(p => p.Course).ToList().Select(entity => new Student() { ID = entity.ID, Name = entity.Name, Age =entity.Age }).ToList();

或者var list = ctx.Set().Include("Course").ToList().Select(entity => new Student() { ID = entity.ID, Name = entity.Name, Age = entity.Age }).ToList();

对象转换成功,如下:

序列化成功结果如下:

【注意】你用EF获得数据集合后得 ToList() 因为此时集合对象为代理对象,否则进行转换将报错,代码如下:

var list = ctx.Set().Include(p => p.Course).Select(entity => new Student() { ID = entity.ID, Name = entity.Name, Age = entity.Age }).ToList();

报错如下:

上述转换也叫DTO(Data Transfer Objects)数据转换为对象,像这种情况在EF中很常见。下面给出老外的用两张图在两个常见的场景中来展现关于DTO的概念:

Getting Information: DAL=>BLL=>GUI

Insert Information: GUI=>BLL=>DAL

总结

(1)当安装了sql时则默认启动的是此实例,那么VS中的实例则会停止启动,需要通过SqlLocalDB命令进行启动。

(2)通过EF获得的数据集合对象为代理对象,需要先转换为实体对象才能进行序列化或者其他操作。

补充

在此感谢园友中华小鹰,经其提示用上述一劳永逸配置无法配置复杂类型!

modelBuilder.Configurations.AddFromAssembly(Assembly.GetExecutingAssembly());

通过上述代码既能配置实体类型也能配置复杂类型,用此方法更加精简!当然若你将复杂类型作为另一个类的导航属性时上述代码也是可以满足所需的!

mysql 表引擎 entity framework_EntityFramework之数据库以及表基本创建(一)相关推荐

  1. MySQL federated存储引擎--访问在远程数据库的表中的数据,而不是本地的表

    一.FEDERATED简介 federated就像他的名字所说"联盟",意思就是:把两个不同区域的数据库联系起来,以致可以访问在远程数据库的表中的数据,而不是本地的表. 二.安装F ...

  2. python获取数据库查询的元数据_Python数据库、MySQL存储引擎、使用分区表、更改表结构、获取数据库元数据...

    :1. 数据库基本操作 1.1 创建数据库 - CREATE DATABASE test; #创建数据库 - GRANT ALL ON test.* to user(s); #为指定用户(或所有用户) ...

  3. 修改mysql数据引擎的方法- 提高数据库性能

    前言:同学告我说,他为了能使得数据查询变得快一点,修改的数据引擎,故查询一下,总结一下. 登录mysql后,查看当前数据库支持的引擎和默认的数据库引擎,使用下面命令: mysql>show en ...

  4. Mysql学习宝典(六) -- 数据库锁表及阻塞的几大常见原因和解决办法

    问题说明 当多个用户并发地存取数据时,在数据库中就会产生多个事务同时存取同一数据的情况.若对并发操作不加控制就可能会读取和存储不正确的数据,破坏数据库的一致性.加锁是实现数据库并发控制的一个非常重要的 ...

  5. mysql 复制数据_MySQL快速复制数据库数据表的方法

    某些时候,例如为了搭建一个测试环境,或者克隆一个网站,需要复制一个已存在的mysql数据库.使用以下方法,可以非常简单地实现. 假设已经存在的数据库名字叫db1,想要复制一份,命名为newdb.步骤如 ...

  6. php判断mysql表的字段_tp6 获取数据库某个表的所有字段名称_php菜鸟技术天地-CSDN博客...

    $rs = Db::query("show tables"); PHP获取mysql数据表的字段名称和详细信息的一些列命令 SHOW DATABASES //列出 MySQL Se ...

  7. hive mysql hdfs关系_Hive中的数据库、表、数据与HDFS的对应关系

    1.hive数据库 我们在hive终端,查看数据库信息,可以看出hive有一个默认的数据库default,而且我们还知道hive数据库对应的是hdfs上面的一个目录,那么默认的数据库default到底 ...

  8. 达梦数据库和mysql索引引擎_达梦数据库如何建索引和使用

    一.建立索引的准则 1.1在表中插入数据后创建索引 一般情况下,在插入或装载了数据后,为表创建索引会更加有效率.如果在装载数据之前创建了一个或多个索引,那么在插入每行时DM数据库都必须更改和维护每个索 ...

  9. Mysql中 设置大小写敏感,Quartz数据库持久化表

    问题描述 生产环境中linux是区分大小写的,windows默认不区分,因为项目涉及到的数据库名含大写,所以进行设置 解决方案: 找到my.ini文件 这里推荐用Everything 直接搜就行 打开 ...

最新文章

  1. 轻量级人脸属性Slim-CNN
  2. 启动weblogic的错误:Could not obtain an exclusive lock to the embedded LDAP data files directory...
  3. Docker 安装MySQL以及外部访问
  4. mysql 窗口函数_MySQL数分:窗口函数
  5. 十种深度学习算法要点及代码解析
  6. matlab编程设计fir滤波器,用MATLAB设计FIR滤波器
  7. vim显示行号_使用 vim 不得不看的 2 个 tips
  8. 关于flink的时间处理不正确的现象复现原因分析
  9. 小代码编写神器:LINQPad 使用入门
  10. as(四级考试频度很大的几个用法)
  11. 嵌入式Linux下获取CPU温度方法
  12. 手机wifi显示已连接,却上不了网怎么办???
  13. 数据库常考题型(2)——求候选键(候选码)
  14. 解密MySQL 8.0 multi-valued indexes
  15. 女孩上中专学财经类号还是计算机好,女生学财经类专业好吗
  16. 专访陈勇: 敏捷开发现状及发展之路
  17. 第七天课程预览和发布
  18. argparse简化版图片教程
  19. kotlin 实战之面向对象特性全方位总结
  20. 基于ssm的医院病历管理系统SSM医院管理系统

热门文章

  1. 终止中台乱象 《2021年中国中台市场研究报告》隆重发布
  2. 云原生除了K8S、微服务,还有...?
  3. 如何在 Kubernetes 上配置 Jenkins?
  4. 行,Python终于跌神坛了!程序员:活该!你敢来评论吗...
  5. 终于!华为在欧盟注册新商标“Harmony”;亚马逊AWS宣布张文翊“新官上任”;甲骨文失去竞购100亿美元国防部云计算合同资格...
  6. Spring精华问答 | Spring Bean的自动装配是怎么回事?
  7. 小米回应有品特殊激励需放弃年终奖……外媒说,荷兰运营商KPN允许华为有限参与5G网络建设;传苹果挖角英特尔5G工程师...
  8. Cloud一分钟 |乐视系近亿元资产被查封;快手推出新社区产品,取名“蹦迪”;高通:已终止收购恩智浦的交易...
  9. MySQL的错误:No query specified
  10. 定时器new Timer().schedule()的使用