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.pswp.cn/news/542404.shtml
繁體地址,請注明出處:http://hk.pswp.cn/news/542404.shtml
英文地址,請注明出處:http://en.pswp.cn/news/542404.shtml

如若內容造成侵權/違法違規/事實不符,請聯系多彩編程網進行投訴反饋email:809451989@qq.com,一經查實,立即刪除!

相關文章

java jar包示例_Java包getImplementationVersion()方法和示例

java jar包示例包類的getImplementationVersion()方法 (Package Class getImplementationVersion() method) getImplementationVersion() method is available in java.lang package. getImplementationVersion()方法在java.lang包中可用。 getImplementationVersion() method …

c語言中字母的定義,c語言字符串定義與初始化 - 且聽風吟

字符串的兩種定義方式char數組char sa[] “hello world”;char指針char *sp “hello world”;這兩種方式都產生了一個”hello world”的字符串常量,字符串常量存儲在靜態存儲區中&#xff0c;靜態存儲區中的內容在程序運行的整個過程中都存在&#xff0c;而且只存儲一份。數組…

python計算兩字符串中的位置_python – 計算兩個字符串之間距離的算法

是否有任何字符串距離算法沒有考慮到單詞的順序&#xff1f;以下算法未提供所需結果(在該示例中,所需結果應為1)&#xff1a;import jarojaro.jaro_winkler_metric(uMichael Jordan,uJordan Michael)>>>0.47import LevenshteinLevenshtein.ratio(Michael Jordan,Jorda…

php unset函數_PHP | 使用unset()函數從數組中刪除元素

php unset函數Given an array and we have to remove an element from the array. 給定一個數組&#xff0c;我們必須從數組中刪除一個元素。 unset()函數 (unset() function) To remove an element from an array, we can use a PHP library unset() function, it accepts th…

vi顯示行號

vi顯示行號 :set nu 帶行號查看&#xff0c;并不改變文件內容:set nonu 取消帶行號查看在每個用戶的主目錄下,都有一個 vi 的配置文件".vimrc"或".exrc"用戶可以編輯它,使這些設置在每次啟動 vi 時,都有效.例如,加入如下設置行:set nu 顯示行號…

對象過濾某個屬性 循環 php_37道PHP面試題(附答案)

1、什么事面向對象&#xff1f;主要特征是什么&#xff1f;面向對象是程序的一種設計方式&#xff0c;它利于提高程序的重用性&#xff0c;使程序結構更加清晰。主要特征&#xff1a;封裝、繼承、多態。2、SESSION 與 COOKIE的區別是什么&#xff0c;請從協議&#xff0c;產生的…

項響琴C語言書籍在線瀏覽,電子琴 c語言程序

實用#include unsigned char code table[]{0x3f,0x06,0x5b,0x4f,0x66,0x6d,0x7d,0x07,0x7f,0x6f,0x77,0x7c,0x39,0x5e,0x79,0x71};unsigned char temp;unsigned char key;unsigned char i,j;unsigned char STH0;unsigned char STL0;unsigned int code tab[]{64021,64103,64260,…

Java File類boolean createNewFile()方法(帶示例)

文件類布爾型createNewFile() (File Class boolean createNewFile()) This method is available in package java.io.File.createNewFile(). 軟件包java.io.File.createNewFile()中提供了此方法。 This method is used to create a new file by using createNewFile() method a…

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…

數碼管超聲波c語言黑51,51單片機開發板-超聲波測距-數碼管顯示

《51單片機開發板-超聲波測距-數碼管顯示》由會員分享&#xff0c;可在線閱讀&#xff0c;更多相關《51單片機開發板-超聲波測距-數碼管顯示(16頁珍藏版)》請在人人文庫網上搜索。1、計算機技術系項目工作報告課程名稱單片機開發板設計與制作實訓班級學號姓名項目名稱超聲波測距…

java 方法 示例_Java ArrayDeque帶有示例的removeFirstOccurrence()方法

java 方法 示例ArrayDeque類removeFirstOccurrence()方法 (ArrayDeque Class removeFirstOccurrence() method) removeFirstOccurrence() method is available in java.lang package. removeFirstOccurrence()方法在java.lang包中可用。 removeFirstOccurrence() method is use…

社交應用動態九宮格圖片的規則

這里主要以微信和QQ空間為作為研究對象&#xff0c;得到的結論如下。 QQ空間里的動態 iOS設備&#xff0c;以iPhone6為分界 iPhone6及以上分辨率的設備&#xff1a; 當寬且高同時 > 512px時&#xff0c;判斷 寬/高的比例值&#xff1a;大于 2時&#xff0c;以高度為基準&…

c語言實現鏈表結構6,用c語言實現的鏈表結構--數據結構實驗

該樓層疑似違規已被系統折疊 隱藏此樓查看此樓#include"stdio.h"//使用new指針來將臨時變量重新初始化#include"stdio.h"typedef int ElemType;typedef struct LNode{ElemType data;struct LNode *next;}LNode,*LinkList;void InitList(LinkList &L)//…

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

翻糖蛋糕 因精致的樣子和栩栩如生的各種造型深得人們的喜愛&#xff0c;它不僅滿足了人們對蛋糕口味及裝飾日益多樣化的需求&#xff0c;同時也在動手制作的過程中&#xff0c;享受到美食與生活的無窮樂趣。不過裂縫&#xff0c;不平整&#xff0c;干燥對翻糖作品來說無疑是噩夢…

Java DataInputStream readUnsignedByte()方法(帶示例)

DataInputStream類readUnsignedByte()方法 (DataInputStream Class readUnsignedByte() method) readUnsignedByte() method is available in java.io package. readUnsignedByte()方法在java.io包中可用。 readUnsignedByte() method is used to read 1 byte (i.e. 8 bit) of …

wpf中groupbox有什么用_展示設計中的標攤是什么 用的什么材料

經常聽從事展示設計的工作人員說起標攤&#xff0c;那什么是標攤呢&#xff1f;顧名思義&#xff0c;標攤就是通用標準的國際展會攤位的縮寫。但是不少人看到干巴巴的詞語還是不能理解。那么這篇文章從用途、材料等方面來詳細介紹標攤究竟是什么。 標攤的主要材質是什么一般來說…

Java BigInteger類| nextProbablePrime()方法與示例

BigInteger類nextProbablePrime()方法 (BigInteger Class nextProbablePrime() method) nextProbablePrime() method is available in java.math package. nextProbablePrime()方法在java.math包中可用。 nextProbablePrime() method is used to get the next probable prime n…

SQL 行轉列的兩種做法

if object_id(tb)is not null drop table tbGocreate table tb(姓名 varchar(10),課程 varchar(10),分數 int)insert into tb values(張三,語文,74)insert into tb values(張三,數學,83)insert into tb values(張三,物理,93)insert into tb values(李四,語文,74)insert into tb…

android一個工程的xml怎么引用另外一個工程的xml,如何在Android中使用XML引用庫中另一個包的字符串?...

Androiddocumentation告訴我,我可以使用“包名”訪問另一個包中的字符串,無論這意味著什么&#xff1a;[:]/所以在我的清單中,我想訪問一個字符串,我已將其放在一個單獨的庫項目中,在com.globalmentor.android包中 – 畢竟我的R類就是這樣&#xff1a;android:label"com.g…