EF使用CodeFirst方式生成数据库技巧经验

前言

EF已经发布很久了,也有越来越多的人在使用EF。如果你已经能够非常熟练的使用EF的功能,那么就不需要看了。本文意在将自己使用EF的方式记录下来备忘,也是为了给刚刚入门的同学一些指导。看完此文,你应该就学会以CodeFirst的方式操作数据库了。

本文主要内容

  • CodeFirst生成数据库的流程
  • 初始化配置
  • 数据库实体构造技巧
  • 主外键设置
  • decimal精度修改

项目框架搭建

本文所使用的开发工具是vs2015(EF6.1.3)

第一步:新建一个空白项目

第二步:引用EntityFramework

 

DbContext的初始化配置

 DbContext作为操作数据库的网关,十分重要。我们需要对它进行一些类的初始化操作,例如:解决团队开发中,多人迁移数据库造成的修改覆盖问题。

代码如下:

using System;
using System.Collections.Generic;
using System.Data.Entity;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Data.Entity.ModelConfiguration.Conventions;
namespace EFDemo.Core.EF
{/// <summary>/// EF访问数据库的接口   /// </summary>public class MyDbContext : System.Data.Entity.DbContext{        public MyDbContext(): base("EFDemo"){//解决团队开发中,多人迁移数据库造成的修改覆盖问题。Database.SetInitializer<MyDbContext>(null);//base.Configuration.AutoDetectChangesEnabled = false;////关闭EF6.x 默认自动生成null判断语句//base.Configuration.UseDatabaseNullSemantics = true;           
        }    public MyDbContext(System.Data.Common.DbConnection oConnection): base(oConnection, true){this.Configuration.LazyLoadingEnabled = true;         }protected override void OnModelCreating(DbModelBuilder modelBuilder){//表名不用复数形式modelBuilder.Conventions.Remove<PluralizingTableNameConvention>();//移除一对多的级联删除约定,想要级联删除可以在 EntityTypeConfiguration<TEntity>的实现类中进行控制modelBuilder.Conventions.Remove<OneToManyCascadeDeleteConvention>();//多对多启用级联删除约定,不想级联删除可以在删除前判断关联的数据进行拦截modelBuilder.Conventions.Remove<ManyToManyCascadeDeleteConvention>();          base.OnModelCreating(modelBuilder);}//将实体对象写在这里,就可以生成对应的数据。 如下://public DbSet<Demo> Demo { get; set; }
}}

项目位置:

Migrations下Configuration类的初始化配置

 Configuration类的初始化配置十分重要,我们需要通过配置解决一系列迁移问题。例如:允许自动迁移,自动迁移默认情况下不扔掉列在我们的数据库中的表。如果我们不希望这样的行为,我们可以告诉迁移明确允许数据丢失的配置类的AutomaticMigrationDataLossAllowed属性设置为true。

代码如下:

namespace EFDemo.Core.Migrations
{using System;using System.Data.Entity;using System.Data.Entity.Migrations;using System.Linq;internal sealed class Configuration : DbMigrationsConfiguration<EFDemo.Core.EF.MyDbContext>{public Configuration(){//允许自动迁移//不然会报错Unable to update database to match the current model because there are pending changes and automatic migration is disabled. Either write the pending model changes to a code-based migration or enable automatic migration. Set DbMigrationsConfiguration.AutomaticMigrationsEnabled to true to enable automatic migration.You can use the Add-Migration command to write the pending model changes to a code-based migration.//允许自动迁移AutomaticMigrationsEnabled = true;//自动迁移默认情况下不扔掉列在我们的数据库中的表。如果我们不希望这样的行为,我们可以告诉迁移明确允许数据丢失的配置类的AutomaticMigrationDataLossAllowed属性设置为true。AutomaticMigrationDataLossAllowed = true;}protected override void Seed(EF.MyDbContext context){//  This method will be called after migrating to the latest version.//  You can use the DbSet<T>.AddOrUpdate() helper extension method //  to avoid creating duplicate seed data. E.g.////    context.People.AddOrUpdate(//      p => p.FullName,//      new Person { FullName = "Andrew Peters" },//      new Person { FullName = "Brice Lambson" },//      new Person { FullName = "Rowan Miller" }//    );//
        }}
}

项目位置:

数据库对应实体对象的定义

 CodeFirst模式需要我们先定义实体,然后通过实体生成数据。

通常我们设计数据库表时,每个表都有(ID,是否删除,备注,添加人,添加时间,修改人,修改时间)等字段。我们可以用基类处理

基类实体:

using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.ComponentModel.DataAnnotations;
using System.ComponentModel.DataAnnotations.Schema;
using System.Linq;
using System.Text;
using System.Threading.Tasks;namespace EFDemo.Core.Entity
{public class BaseEntity{}[Serializable]public class BaseEntity<TKey> : BaseEntity{public BaseEntity(){this.AddTime = DateTime.Now;}[Key][Display(Name = "编号")]public TKey ID { get; set; }[Display(Name = "排序")][Required(ErrorMessage = "{0}是必填项"), Range(0, int.MaxValue, ErrorMessage = "{0}的范围是{1}到{2}")][DefaultValue(0)]public int Sort { get; set; }[Display(Name = "备注")][MaxLength(256, ErrorMessage = "{0}最大长度{1}")]public string Remark { get; set; }[Display(Name = "是否删除")][Required]public bool Deleted { get; set; }public int AddUser { get; set; }[Display(Name = "添加时间")][DisplayFormat(ApplyFormatInEditMode = true, ConvertEmptyStringToNull = true, DataFormatString = "{0:yyyy-MM-dd HH mm}", HtmlEncode = false, NullDisplayText = "数据无效")]public DateTime AddTime { get; set; }public int ModUser { get; set; }[DisplayFormat(ApplyFormatInEditMode = true, ConvertEmptyStringToNull = true, DataFormatString = "{0:yyyy-MM-dd  HH mm}", HtmlEncode = false, NullDisplayText = "数据无效")]public DateTime? ModTime { get; set; }}}
View Code

省市区表:

using System;
using System.Collections.Generic;
using System.ComponentModel.DataAnnotations;
using System.ComponentModel.DataAnnotations.Schema;
using System.Linq;
using System.Text;
using System.Threading.Tasks;namespace EFDemo.Core.Entity
{/// <summary>/// 省市区/// </summary>public class Public_Area{        [Key]public Guid ID { get; set; }[Display(Name = "父亲ID")]public Guid ParentID { get; set; }[Display(Name = "名称")][MaxLength(32, ErrorMessage = "{0}最大长度{1}")]public String Name { get; set; }}
}
View Code

班级表:

using System;
using System.Collections.Generic;
using System.ComponentModel.DataAnnotations;
using System.ComponentModel.DataAnnotations.Schema;
using System.Linq;
using System.Text;
using System.Threading.Tasks;namespace EFDemo.Core.Entity
{/// <summary>/// 班级/// </summary>public class T_Classes : BaseEntity<int>{public T_Classes() {this.T_Student = new List<Entity.T_Student>();}[InverseProperty("T_Classes")]public virtual List<T_Student> T_Student { get; set; }[Display(Name = "班级名称")][Required(ErrorMessage = "{0}是必填项")][MaxLength(8, ErrorMessage = "{0}最大长度{1}")]public string Name { get; set; }[Display(Name = "人数")]public int Count { get; set; }[Display(Name = "班级经费")]public decimal Money { get; set; }}
}
View Code

 

学生表:

using System;
using System.Collections.Generic;
using System.ComponentModel.DataAnnotations;
using System.ComponentModel.DataAnnotations.Schema;
using System.Linq;
using System.Text;
using System.Threading.Tasks;namespace EFDemo.Core.Entity
{/// <summary>/// 学生/// </summary>public class T_Student : BaseEntity<int>{/// <summary>/// 外键/// </summary>[ForeignKey("ClassesID")]public virtual T_Classes T_Classes { get; set; }[Display(Name = "班级ID")]public int ClassesID { get; set; }[Display(Name = "姓名")][Required(ErrorMessage = "{0}是必填项")][MaxLength(8, ErrorMessage = "{0}最大长度{1}")]public string Name { get; set; }[Display(Name = "性别")]public bool Sex { get; set; }[Display(Name = "年龄")]public int Age { get; set; }[Display(Name = "电话")][Required(ErrorMessage = "{0}是必填项")][RegularExpression(@"^(13[0-9]|15[0-9]|18[0-9])\d{8}$", ErrorMessage = "不是手机号格式")][MaxLength(11, ErrorMessage = "{0}最大长度{1}")]public string Phone { get; set; }/// <summary>/// 省市县外键/// </summary>
[ForeignKey("ProvinceID")]public virtual Public_Area Public_Area_Province { get; set; }[Display(Name = "省ID")]public Guid ProvinceID { get; set; }[ForeignKey("CityID")]public virtual Public_Area Public_Area_City { get; set; }[Display(Name = "市ID")]public Guid CityID { get; set; }[ForeignKey("CountyID")]public virtual Public_Area Public_Area_County { get; set; }[Display(Name = "县ID")]public Guid CountyID { get; set; }}
}
View Code

 

班级表和学生表是一对多的关系,省市区表和学生表是一对多的关系,同时学生表中有多个省市区表的外键。

项目位置:

 

使用命令生成数据库

第一步:将实体对象加入到DbContext中,

如下:

//将实体对象写在这里,就可以生成对应的数据。 如下://public DbSet<Demo> Demo { get; set; }public DbSet<Public_Area> Public_Area { get; set; }public DbSet<T_Classes> T_Classes { get; set; }public DbSet<T_Student> T_Student { get; set; }

第二步:在EFDemo.Core项目下的App.config文件夹中添加生成数据库的配置项

 

 

配置文件代码如下:

name="EFDemo"中的EFDemo要和DbContex中的一致。 
<?xml version="1.0" encoding="utf-8"?>
<configuration><configSections><!-- For more information on Entity Framework configuration, visit http://go.microsoft.com/fwlink/?LinkID=237468 --><section name="entityFramework" type="System.Data.Entity.Internal.ConfigFile.EntityFrameworkSection, EntityFramework, Version=6.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089" requirePermission="false" /></configSections><connectionStrings><!--生成数据库的连接字符串--><add name="EFDemo" connectionString="Data Source=.;Initial Catalog=EFDemoDB;User ID=sa;Password=123456;MultipleActiveResultSets=True;Application Name=EntityFramework" providerName="System.Data.SqlClient" /></connectionStrings><entityFramework><defaultConnectionFactory type="System.Data.Entity.Infrastructure.LocalDbConnectionFactory, EntityFramework"><parameters><parameter value="mssqllocaldb" /></parameters></defaultConnectionFactory><providers><provider invariantName="System.Data.SqlClient" type="System.Data.Entity.SqlServer.SqlProviderServices, EntityFramework.SqlServer" /></providers></entityFramework>
</configuration>

 

第三步:执行更新命令

启动项目一定要选择EFDemo.Core

生成数据库如下:

主外键关系设置

 班级和学生一对多关系的设置:

一个表中的多个外键是另一个表中的主键的情况:学生表和省市县表

生成的数据库如下:

需要注意的是:这种情况,在Public_Area表中不能反向设置 public virtual List<T_Student> T_Student ,不然会报错。

 

decimal怎么保存四位小数  

 decimal默认保留两位小数,我们需要通过如下设置让其保留四位小数。

在DbContext中配置班级表中的Money字段让其保留四位小数:

 执行Update-Database命令:

结果如下:

 

 

  

使用EF操作数据库数据

第一步:

 让EFDemo.Web应用EFDemo.Core程序集。

第二步:

配置EFDemo.Web中的webconfig中的数据库连接字符串:

 <connectionStrings><!--操作数据库的连接字符串--><add name="EFDemo" connectionString="Data Source=.;Initial Catalog=EFDemoDB;User ID=sa;Password=123456;MultipleActiveResultSets=True;Application Name=EntityFramework" providerName="System.Data.SqlClient" /></connectionStrings>

第三步:

使用EF向数据库添加数据

    public ActionResult Index(){using (var db = new Core.EF.MyDbContext()){Public_Area area1 = new Public_Area(){ID = Guid.NewGuid(),Name = "河南",ParentID = Guid.NewGuid()};db.Public_Area.Add(area1);Public_Area area2 = new Public_Area(){ID = Guid.NewGuid(),Name = "郑州",ParentID = area1.ID};db.Public_Area.Add(area2);Public_Area area3 = new Public_Area(){ID = Guid.NewGuid(),Name = "新郑",ParentID = area2.ID};db.Public_Area.Add(area3);//添加测试数据T_Classes classes = new T_Classes(){Name = "高中三班",Money = 2000};db.T_Classes.Add(classes);T_Student student = new T_Student(){ClassesID = classes.ID,Name = "张三",Phone = "15236265820",Sex = true,ProvinceID = area1.ID,CityID = area2.ID,CountyID = area3.ID,};db.T_Student.Add(student);db.SaveChanges();}return View();}

第四步:

查看数据库数据

 

Demo完整代码下载

EFDemo.Core.7z

 

下一篇:EF查询之性能优化技巧

 

转载于:https://www.cnblogs.com/eggTwo/p/5959158.html

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

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

相关文章

对象过滤某个属性 循环 php_37道PHP面试题(附答案)

1、什么事面向对象&#xff1f;主要特征是什么&#xff1f;面向对象是程序的一种设计方式&#xff0c;它利于提高程序的重用性&#xff0c;使程序结构更加清晰。主要特征&#xff1a;封装、继承、多态。2、SESSION 与 COOKIE的区别是什么&#xff0c;请从协议&#xff0c;产生的…

oracle   SQL执行过程

1.sql执行过程1>解析&#xff08;判断对象是否存在&#xff0c;是否有权限查询&#xff0c;语义解析&#xff0c;检查缓存中是否有相同的SQL等等&#xff09;2>优化&#xff08;CBO确定优化模式&#xff0c;确定访问路径&#xff0c;联接顺序&#xff0c;过程中通过很多综…

vue-video-player修改src就会报错_4、修改入口点代码

在riscv上电时&#xff0c;会进行CPU自检&#xff0c;然后跳转到bootloader处执行。bootloader设置好kernel的运行环境后&#xff0c;从硬盘加载kernel到内存&#xff0c;最后再跳转到kernel入口地址。我们采用的bootloader为OpenSBI&#xff0c;被加载到0x80000000地址&#x…

社交应用动态九宫格图片的规则

这里主要以微信和QQ空间为作为研究对象&#xff0c;得到的结论如下。 QQ空间里的动态 iOS设备&#xff0c;以iPhone6为分界 iPhone6及以上分辨率的设备&#xff1a; 当宽且高同时 > 512px时&#xff0c;判断 宽/高的比例值&#xff1a;大于 2时&#xff0c;以高度为基准&…

splunk中 如何隐藏input_翻糖制作中,如何避免裂缝,如何隐藏裂缝,如何防粘?...

翻糖蛋糕 因精致的样子和栩栩如生的各种造型深得人们的喜爱&#xff0c;它不仅满足了人们对蛋糕口味及装饰日益多样化的需求&#xff0c;同时也在动手制作的过程中&#xff0c;享受到美食与生活的无穷乐趣。不过裂缝&#xff0c;不平整&#xff0c;干燥对翻糖作品来说无疑是噩梦…

wpf中groupbox有什么用_展示设计中的标摊是什么 用的什么材料

经常听从事展示设计的工作人员说起标摊&#xff0c;那什么是标摊呢&#xff1f;顾名思义&#xff0c;标摊就是通用标准的国际展会摊位的缩写。但是不少人看到干巴巴的词语还是不能理解。那么这篇文章从用途、材料等方面来详细介绍标摊究竟是什么。 标摊的主要材质是什么一般来说…

ActiveX: 如何用.inf和.ocx文件生成cab文件

ActiveX: 如何用.inf和.ocx文件生成cab文件 转载于:https://www.cnblogs.com/time-is-life/p/5977962.html

操作系统中的处理机调度调度_操作系统中的多处理器调度

操作系统中的处理机调度调度多处理器操作系统 (Multiprocessor Operating system) A multiprocessor system consists of several processors which share memory. In the multiprocessor, there is more than one processor in the system. The reason we use multiprocessor …

sed 替换_sed命令批量替换文件内容

“ 开发人员有时会大批量替换文件内容&#xff0c;sed命令是一个很好用的工具。”01—暴力替换方式近期有个临时任务,将系统中所有"帐"替换为"账",那"帐"和"账"有啥区别呢;1、账的部首是贝&#xff1b;帐的部首是巾。2、账是关于货币、…

android 模仿uc标签页,模仿UCweb菜单 - 白羽雕弓 - 博客园

UCWeb的菜单看起来不错&#xff0c;自己想模仿做一个&#xff0c;苦恼一直没有思路google了几天&#xff0c;终于找到一个帖子 http://www.eoeandroid.com/viewthread.php?tid28824按照上面提供的思路实现了1、保留menu按键作用2、用popupwindow作为菜单显示容器3、用GridVie…

android webview 监听js,Android webview与js的数据交互

项目要用到Webview和js交互&#xff0c;查了查以前的项目感觉还是有必要整理下的。简单描述下项目中用到的地方&#xff0c;比如说在web页需要用到登录的地方点击登录跳转到APP原生登录界面去登录&#xff0c;点击web页的拨打电话弹出原生dialog询问是否拨打&#xff0c;点击we…

android web通讯录,Android手机开发之通讯录

Android手机开发——通讯录实现增加、查询、修改、删除的功能&#xff0c;输入联系人信息&#xff0c;点击“添加”按钮&#xff0c;可以添加联系人信息到数据库&#xff1b;点击“查询”按钮&#xff0c;会发现添加的联系人信息显示在界面中&#xff1b;重新输入联系人电话&am…

有关UITableView--cell复用问题

近来用Tableview做了一个九宫格。过程中碰到了两个cell复用问题。 问题一&#xff1a; 在cell中为button添加addTarget点击事件时&#xff0c;出现后面的cell会重叠它前面cell的事件。代码如下&#xff1a; C代码 static NSString *CellWithIdentifier "DiscoverHomeTab…

JavaScript基础之Number对象和Math对象

2019独角兽企业重金招聘Python工程师标准>>> //Math对象//属性float Math.E; //返回自然对数的底数e&#xff0c;约2.718float Math.LN2; //返回2的自然对数&#xff0c;约0.693float Math.LN10; //返回10的自然对数&#xff0c;约2.302fl…

My linux

为什么80%的码农都做不了架构师&#xff1f;>>> 1.linux 命令方式修改机器名称 # hostname newHostName # vi /etc/sysconfig/network 修改或增加配置&#xff1a;hostnamenewHostName # vi /etc/hosts 修改对应的本地HOST映射 xx.xxx.xxx.xxx newHostName 2.Redha…

狂神说es笔记_人教版七上英语Unit5电子课本音频+课堂笔记+课后同步习题

1人教 七上英语Unit5单词七年级英语上册Unit 5单词默写1做&#xff1b;干(助动词)__________2做&#xff0c;干(助动词第三人称单数形式)__________3有__________4网球__________5球__________6乒乓球______7球棒&#xff1b;球拍__________8(英式)足球____________________9排…

先进技术android,React Native实战(JavaScript开发iOS和Android应用)/计算机科学先进技术译丛...

导语内容提要本书作者Nader Dabit是AWS Mobile开发人员、React Native Training创始人和React Native Radio播客主持人。本书旨在帮助iOS、Android和Web开发人员学习使用React Native框架&#xff0c;构建高质量的iOS和Android应用程序。书中介绍了React Native入门基础知识&am…

开发类似vs的黑色风格_传闻:2020年《使命召唤》将是《黑色行动》重启作品

据可信度较高的消息源透露&#xff0c;2020 年的《使命召唤》将是《黑色行动》的重启作。而据之前的报道&#xff0c;《黑色行动》开发商 Treyarch 正在开发今年的《使命召唤》&#xff0c; Sledgehammer Games 和 Raven Software 负责辅助工作。该项目代号为“宙斯”&#xff…

微信小程序 开发 微信开发者工具 快捷键

微信小程序已经跑起来了.快捷键设置找了好久没找到,完全凭感觉.图贴出来.大家看看. 我现在用的是0.10.101100的版本,后续版本更新快捷键也应该不会有什么变化. 现在貌似不能修改.如果有同学找到修改的方法,麻烦告诉我.谢谢. 微信小程序代码编辑快捷键 常用快捷键 格式调整 Ctrl…

android9有深色模式吗,深色模式还是黑色模式?微信把所有人都搞懵了

原标题&#xff1a;深色模式还是黑色模式&#xff1f;微信把所有人都搞懵了前一阵子&#xff0c;微信正式加入了对“深色模式”的支持&#xff0c;这也是除了Windows Phone 版本以外微信第一次从系统层面支持深色模式。虽然这次更新离WWDC上的演示已经过去了9个月&#xff0c;但…