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

前言

之前有学过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();

}

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

017d734b044104f042d1bee2bb09bb10.png

上述创建数据库的过程只需注意:可以手动通过添加构造函数的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 命令复制并添加如图的字符串即可

f6ca463cdad596b93bcf715bd6bc5e3b.png

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

上述中我们对于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集合中的数据类型,如图

597da0b925024a699cd39be32e77dc5f.png

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

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

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

9ef9f3a22e5328c20736561913af9ab9.png

这意思是检测到在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();

对象转换成功,如下:

755f4312fe163daf9cf7b2ea31afd36d.png

序列化成功结果如下:

221f689b20e0c8f5032c13c57dc5beb9.png

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

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

报错如下:

3bd2aeed9c559b1e440c7381254e2d7b.png

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

Getting Information: DAL=>BLL=>GUI

48513af99f60ddd49de02ffbba9ffd99.png

Insert Information: GUI=>BLL=>DAL

e455b773509849196fce0609cd6436ad.png

总结

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

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

补充

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

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

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

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/528567.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

mysql+linux+无法启动服务无法启动不了_Linux实例中MySQL服务常见的无法启动或启动异常处理...

概述本文介绍了在Linux实例中&#xff0c;MySQL常见的无法启动或启动异常处理方法。详细描述常见问题处理描述&#xff0c;目录如下。提示&#xff1a;MySQL错误日志通常记录在/alidata/log/mysql/error.log文件下。MySQL配置文件my.cnf权限问题导致无法启动&#xff0c;错误提…

python3缺少pip_Ubuntu中找不到pip3命令的解决方法

Ubuntu中找不到pip3命令的解决方法Ubuntu 有 python2 和 python3。今天使用 Ubuntu 中的 python3 时&#xff0c;想要安装第三方库却发现 pip 指向的是 python2 。因为记得 Ubuntu 系统默认将 python3 的 pip 命令改成了 pip3&#xff0c;于是执行 pip3 -V &#xff0c;报命令不…

linux mysql revoke_Linux环境下MySQL基础命令(4)----数据库的用户授权

MySQL数据库的root用户拥有对所有库&#xff0c;表的全部权限&#xff0c;频繁的使用root用户会给数据库带来很大的风险&#xff0c;因此应建立一些低权限用户&#xff0c;只负责一部分库、表的管理维护操作&#xff0c;甚至可以对增、删、改、查各个操作进一步细化限制&#x…

java gc机制新区域旧屋_Java 内存回收机制——GC机制-Go语言中文社区

一、Java GC 概念说明Java GC(Garbage Collection&#xff0c;垃圾收集&#xff0c;垃圾回收)机制&#xff0c;是Java与C/C的主要区别之一&#xff0c;作为Java开发者&#xff0c;一般不需要专门编写内存回收和垃圾清理代码&#xff0c;对内存泄露和溢出的问题&#xff0c;也不…

java反射 虚拟机优化_面试官问我:Java反射是什么?我回答竟然不上来......

每天凌晨00点00分,第一时间与你相约每日英文We all have moments of desperation. But if we can face them head on, that’s when we find out just how strong we really are.我们都有绝望的时候&#xff0c;只有在勇敢面对时&#xff0c;我们才知道我们有多坚强。每日掏心话…

c java 开发效率高_Java 的开发效率究竟比 C++ 高在哪里?

如果选择C&#xff0c;那C 的难度与JAVA 比&#xff0c;那应该不在一个层次。因为 C 作者及委员会想给你带来足够的抽象能力&#xff0c;让你可以抽象这个世界&#xff1b;给你足够的自由与控制硬件的能力&#xff0c;及零开销的高性能。简单点说&#xff0c;C程序员如同神一般…

java矩阵类_151-矩阵类

[java]代码库import java.util.Scanner;import java.util.Arrays;public class Main {public static void main(String[] args) {Scanner scan new Scanner(System.in);int r scan.nextInt();int c scan.nextInt();System.out.println("row:"r" column:"…

刻画小狗状态java_JAVA面向接口编程

JAVA面向接口编程小狗在不同环境条件下可能呈现不同的状态&#xff0c;小狗通过调用 cry()方法体现自己的当前的状 态。要求用接口封装小狗的状态。具体要求如下。• 编写一个接口 DogState&#xff0c;该接口有一个名字为 void showState()的方法。• 编写 Dog 类&#xff0c;…

php 图片合成,PHP中多张图片合成一张图片例子

今天分享一段PHP中多张图片合成一张图片的代码实现&#xff0c;我们可以在图片合成&#xff0c;水印&#xff0c;九宫格等需求下使用到类似这样的图片合成效果,下面一起来看看例子吧。今天分享一段PHP中多张图片合成一张图片的代码实现&#xff0c;我们可以在图片合成&#xff…

php的cms是什么意思,phpcms是什么

phpcms是一款具备文章、下载、图片、分类信息、影视、商城、采集、财务等众多功能的强大、易用、可扩展的优秀网站管理软件&#xff1b;该软件采用模块化开发&#xff0c;支持多种分类方式&#xff0c;使其可方便实现个性化网站的设计、开发与维护。phpcms是一款具备文章、下载…

边缘检测滤波matlab,卷积滤波器与边缘检测

频率&#xff1a;对于声音&#xff0c;频率实际上是指声波振荡的速度高低频率高频图像是强度变化很大的图像。并且亮度级别从一个像素到下一个像素快速变化。低频图像可以是亮度相对均匀或变化非常慢的图像。这是一个例子中最容易看到的。大多数图像都有高频和低频成分。在上图…

php 读取 stl 文件,科学网—[转载]【源码】读取ASCII STL文件的STLReader - 刘春静的博文...

读取包含顶点和面的ASCII STL文件&#xff0c;并将其构造为矩阵“顶点”、“颜色”和“面”。之后&#xff0c;使用各小模块在Matlab上建立模型。Read ASCII STL file which contains vertexes and faces and structure it to matrixes "vertexes", "colors&quo…

dsm php,docker dsm是什么?

docker dsm是什么&#xff1f;docker dsm是&#xff1a;从DSM6.0开始如果装了docker的话可以看到下面的图&#xff1a;上图可以看到创建了一个新的DSM&#xff0c;名字为DDSM1&#xff0c;经试验功能和正式DSM一模一样。同时白裙一样可以QuickConnect。然后用Putty登录上去&…

php 5.6 文档,文件存储 | 进阶系列 | Laravel 5.6 中文文档

文件存储由 学院君 创建于3年前, 最后更新于 1年前版本号 #231608 views3 likes0 collects简介Laravel 基于 Frank de Jonge 开发的 PHP 包 Flysystem 提供了强大的文件系统抽象层。Laravel 集成 Flysystem 以便使用不同驱动简化对文件系统的操作&#xff0c;这些驱动包括本地文…

阐述oracle的体系结构,Oracle数据库逻辑体系结构详解

以前对Oracle数据库的了解大多数是集中在mysql&#xff0c;最近工作里面一直使用的是Oracle&#xff0c;虽然说在互联网行业mysql大行其道&#xff0c;但是一些传统行业或者是金融领域还是更加倾向于使用oracle&#xff0c;sqlserver这种大型数据库。为此还是有必要深入了解以下…

linux解锁文件.user.ini,Linux下解决网页服务器权限和.user.ini无法删除的问题

解决网页服务器权限问题在linux环境下搭建Nginx/apache网页服务器&#xff0c;在尝试访问页面时都会遇到这个问题&#xff0c;提示没有写入权限&#xff0c;或者必须访问网页服务器权限。这源自于linux对于权限的限制比较严格。所以网上无数的解决方法&#xff0c;无外乎一个提…

linux内核 lts长期演进,Linux Kernel 4.19 和 5.4 生命周期延长至 6 年

近日&#xff0c;Linux 内核开发及维护者 Greg Kroah-Hartman 宣布将 Linux 内核 4.19 和 5.4 版本的生命周期终止(EOL)支持从两年延长到六年&#xff0c;分别延长至 2024 和 2025 年。在这期间&#xff0c;它们能够继续向后移植 bug 并获得一些重要的安全修复程序。Linux 内核…

linux如何运行qt源码,Linux/Ubuntu下编译Qt4.8.2源码

本人所用的系统为Ubuntu 14&#xff0c;所下载的QT源码版本为4.8.2。以下是编译QT源码的基本步骤&#xff1a;2&#xff0e;解压代码输入指令&#xff1a; tar zxvf qt-everywhere-opensource-src-4.8.2.tar.gz&#xff0c;解压出QT源代码。3&#xff0e;执行./config生成makef…

linux启动过程中内核拷贝,轻松识破linux内核启动过程中的“”套路“”

内核启动流程相关的内容让很多热爱linux的小伙伴既爱又恨&#xff0c;因为这是了解linux系统基本构造的良好过程同时由于其本身复杂且底层&#xff0c;脑子中的脉络不是很清晰&#xff0c;本文就总结了一些优秀博文&#xff0c;以自己的理解来解构一下。本文的环境是CentOS 6.8…

linux wifi ip,Linux环境下使用WIFI模块:使用DHCP工具动态获得IP地址

使用DHCP工具动态获得IP地址实验版本及下载地址DHCP&#xff1a;dhcp-4.4.1.tar.gz链接: [https://www.isc.org/downloads/]编译安装DHCP配置编译选项解压完成后进入DHCP根文件目录&#xff0c;输入配置指令./configure --hostarm-linux ac_cv_file__dev_randomyes --with-rand…