日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當(dāng)前位置: 首頁 > 运维知识 > 数据库 >内容正文

数据库

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

發(fā)布時間:2024/9/27 数据库 35 豆豆
生活随笔 收集整理的這篇文章主要介紹了 mysql 表引擎 entity framework_EntityFramework之数据库以及表基本创建(一) 小編覺得挺不錯的,現(xiàn)在分享給大家,幫大家做個參考.

前言

之前有學(xué)過EF一段時間那時EF才4.0似乎還不太穩(wěn)定,而現(xiàn)在EF都已7.0版本,同時AspNet Identity都與此大有關(guān)聯(lián),看來是大勢所趨于是開始學(xué)習(xí)EF,在學(xué)EF過程中也遇到一些小問題,特此錄下,以備忘!

數(shù)據(jù)庫和表基本創(chuàng)建

為了更好的循序漸進(jìn)稍微概括下典型創(chuàng)建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);

}

}

學(xué)生上下文中構(gòu)造函數(shù)中的name去讀取如下配置文件來命名數(shù)據(jù)庫名稱:?DBByConnectionString

然后在控制臺中通過EF上下文添加數(shù)據(jù)并保存,如下:

using (var ctx = newSchoolContext())

{

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

ctx.Students.Add(stud);

ctx.SaveChanges();

}

最終生成數(shù)據(jù)庫以及表如下圖:

上述創(chuàng)建數(shù)據(jù)庫的過程只需注意:可以手動通過添加構(gòu)造函數(shù)的name來命名數(shù)據(jù)庫名稱或者無需添加name那么生成的數(shù)據(jù)庫名稱是以上下文中的命名空間+上下文類來命名數(shù)據(jù)庫名稱。

數(shù)據(jù)庫創(chuàng)建以及表一勞永逸配置

下面創(chuàng)建方法是看過園友hystar(EF教程)而寫的,確實(shí)是好方法,就搬過來了,為什么說一勞永逸呢?不明白的話,可以去看看他的文章!首先添加兩個類Student(學(xué)生類)和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")

{ }///

///通過反射一次性將表進(jìn)行映射///

///

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);

}

}

}

由于是手動命名數(shù)據(jù)庫名稱,當(dāng)然得讀取配置文件

上述配置要添加的數(shù)據(jù)庫建立在VS2013自帶的實(shí)例中!我們首先初始化數(shù)據(jù)庫看看:

EntityDbContext ctx = newEntityDbContext();

結(jié)果運(yùn)行就出現(xiàn)如下經(jīng)典錯誤:

在與SQLServer建立連接時出現(xiàn)與網(wǎng)絡(luò)相關(guān)的或特定與實(shí)例的錯誤.未找到或無法訪問服務(wù)器.請驗(yàn)證實(shí)例名稱是否正確并且SQL SERVER已配置允許遠(yuǎn)程鏈接provide:命名管道提供程序,error:40 -無法打開到SQL Server的連接)

那肯定是無法連接到?(localdb)\v11.0?,于是當(dāng)我在服務(wù)器打開添加連接中添加服務(wù)器名為?(localdb)\v11.0?時也是無法響應(yīng),連接不到!最終通過SqlLocalDB命令在Command Prompt(命令行)中輸入

SqlLocalDB.exe start v11.0

啟動該實(shí)例才算完事,主要原因是安裝了SQL 2012默認(rèn)啟動的實(shí)例該SQL 2012而VS 2013中的實(shí)例被停止運(yùn)行得手動啟動,如果要查看其信息來查看是否已經(jīng)啟動,通過以下命令即可:

SqlLocalDB.exe info v11.0

VS2013中默認(rèn)的實(shí)例應(yīng)該是(localdb)\v11.0,如果在服務(wù)器中添加連接輸入(localdb)\v11.0是錯誤的,你可以通過上述?SqlLocalDB.exe info v11.0?命令復(fù)制并添加如圖的字符串即可

似乎只要第一次啟動了,以后每次都會連接上,不會再出現(xiàn)如上問題!

上述中我們對于EF上下文不用每次都初始化數(shù)據(jù)庫,在EF中初始化數(shù)據(jù)庫有三種策略:

CreateDatabaseIfNotExists:該項也是默認(rèn)初始化數(shù)據(jù)庫的一項,要是數(shù)據(jù)庫不存在就創(chuàng)建數(shù)據(jù)庫。

DropCreateDatabaseIfModelChanges:只要數(shù)據(jù)模型發(fā)生了改變就重新創(chuàng)建數(shù)據(jù)庫。

DropCreateDatabaseAlways:只要每次初始化上下文時就創(chuàng)建數(shù)據(jù)庫。

鑒于此我們在EFDbContext中采用第二種策略。創(chuàng)建一個初始化類的策略?EFDbContextInit

///

///當(dāng)對象實(shí)體對象發(fā)生改變時重生創(chuàng)建數(shù)據(jù)庫///

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

{base.Seed(context);

}

}

在EFDbContext靜態(tài)構(gòu)造函數(shù)中進(jìn)行初始化此方法:

staticEntityDbContext()

{

Database.SetInitializer(newEntityDbContextInit());

}

自此EFDbContext構(gòu)建完畢!下面就是模型映射了,我們假設(shè)學(xué)生和課程是1:1關(guān)系,則我們添加的兩個實(shí)體映射如下:

StudentMap(學(xué)生類實(shí)體映射)

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);

/*

對于上述映射關(guān)系不太理解的話可以去上述給出鏈接文章。我只說明怎么去很好的理解這兩組的意思,第一組?WithRequiredDependent?和第二組

WithRequiredPrincipal?一個是Dependent是依賴的意思說明后面緊接著的Student是依賴對象,而前面的Course是主體,而Principal

首先的意思,說明后面緊接著的是Student是主體,而Course是依賴對象。很顯然在這個關(guān)系中課程是依賴學(xué)生的。所以映射選第二組

*/

}

}

CourseMap(課程類映射)

public class CourseMap : EntityTypeConfiguration{publicCourseMap()

{

ToTable("Course");

HasKey(p=>p.StudentID);

}

}

接下來我們進(jìn)行添加數(shù)據(jù)并保存通過如下代碼:

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

{

Name= "1",

Age= 12,

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

};

ctx.Set().Add(s);

ctx.SaveChanges();

數(shù)據(jù)添加和保存都已通過,接下來進(jìn)行查詢數(shù)據(jù),查詢數(shù)據(jù)有兩種方式:

(1)直接通過EF中Set()方法獲得數(shù)據(jù)集合

(2)通過EF中SqlQuery()方法通過sql語句查詢

如要獲得上述學(xué)生數(shù)據(jù)列表集合,可以通過如下操作:

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

或者

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

于是我監(jiān)視下返回的list集合中的數(shù)據(jù)類型,如圖

oh,shit!和我們實(shí)際的實(shí)體類型不符,通過EF產(chǎn)生的卻是?DynamicProxies?,于是到Sytem.Data.Entity類下去看看是個什么類型,居然沒找到,估計看這單詞意思就是運(yùn)行時產(chǎn)生的動態(tài)代理對象。那么,你覺得是不是沒什么影響了???那影響可大了,請看下面操作:

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

我嘗試將其序列化看看結(jié)果,一運(yùn)行,oh,no!錯誤如下:

這意思是檢測到在Course里面有Student屬性,而Student類里又有Course這就相當(dāng)于自己引用自己,導(dǎo)致了循環(huán)引用就成了死循環(huán)。(這就是因?yàn)?DynamicProxies?導(dǎo)致的結(jié)果)所以當(dāng)前要將其代理對象轉(zhuǎn)換為我們的實(shí)體對象即可。

則通過Select()方法投影將其代碼進(jìn)行改造后如下:

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();

對象轉(zhuǎn)換成功,如下:

序列化成功結(jié)果如下:

【注意】你用EF獲得數(shù)據(jù)集合后得?ToList()?因?yàn)榇藭r集合對象為代理對象,否則進(jìn)行轉(zhuǎn)換將報錯,代碼如下:

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

報錯如下:

上述轉(zhuǎn)換也叫DTO(Data Transfer Objects)數(shù)據(jù)轉(zhuǎn)換為對象,像這種情況在EF中很常見。下面給出老外的用兩張圖在兩個常見的場景中來展現(xiàn)關(guān)于DTO的概念:

Getting Information: DAL=>BLL=>GUI

Insert Information: GUI=>BLL=>DAL

總結(jié)

(1)當(dāng)安裝了sql時則默認(rèn)啟動的是此實(shí)例,那么VS中的實(shí)例則會停止啟動,需要通過SqlLocalDB命令進(jìn)行啟動。

(2)通過EF獲得的數(shù)據(jù)集合對象為代理對象,需要先轉(zhuǎn)換為實(shí)體對象才能進(jìn)行序列化或者其他操作。

補(bǔ)充

在此感謝園友中華小鷹,經(jīng)其提示用上述一勞永逸配置無法配置復(fù)雜類型!

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

通過上述代碼既能配置實(shí)體類型也能配置復(fù)雜類型,用此方法更加精簡!當(dāng)然若你將復(fù)雜類型作為另一個類的導(dǎo)航屬性時上述代碼也是可以滿足所需的!

總結(jié)

以上是生活随笔為你收集整理的mysql 表引擎 entity framework_EntityFramework之数据库以及表基本创建(一)的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網(wǎng)站內(nèi)容還不錯,歡迎將生活随笔推薦給好友。