您好,登錄后才能下訂單哦!
這篇“Entity Framework如何映射TPH、TPT、TPC與繼承類”文章的知識點大部分人都不太理解,所以小編給大家總結(jié)了以下內(nèi)容,內(nèi)容詳細,步驟清晰,具有一定的借鑒價值,希望大家閱讀完這篇文章能有所收獲,下面我們一起來看看這篇“Entity Framework如何映射TPH、TPT、TPC與繼承類”文章吧。
Table Per Hierarchy (默認,每個層次一個表)
每個層次結(jié)構(gòu)共用一個表,類的每一個屬性都必須是可空的。
只建立一個表,把基類和子類中的所有屬性都映射為表中的列。
為基類和所有子類共建立一個表,基類和子類中的所有屬性都映射為表中的一個列。
默認在這個表中建立一個叫做Discriminator的列,類型是nvarchar,長度是128。在存儲基類或子類的時候,把類名作為Discriminator列的值。
Map方法中傳入的類型參數(shù)是子類的類名,Requires用于指定Discriminator列的名字,HasValue用于指定它的類型和每個子類對應(yīng)的值。
modelBuilder.Entity<Course>() .Map<Course>(m => m.Requires("Type").HasValue("Course")) .Map<OnsiteCourse>(m => m.Requires("Type").HasValue("OnsiteCourse"));
Table Per Type(每個類各一個表)
為基類和每個子類各建立一個表,每個與子類對應(yīng)的表中只包含子類特有的屬性對應(yīng)的列。
子類的表中只包含子類特有的屬性,子表還會存儲一個將子表與基表聯(lián)接的外鍵。
我們可以使用Map方法強制讓Code First使用TPT方式,因為Code First默認使用的是TPH方式。
modelBuilder.Entity<Course>().ToTable("Course"); modelBuilder.Entity<OnsiteCourse>().ToTable("OnsiteCourse");
Table Per ConCrete Type(每個具體類型各一個表)
每個具體的派生類各一個表,沒有基表。不推薦使用。
在子類對應(yīng)的表中除了子類特有的屬性外還有基類的屬性對應(yīng)的表?;惪梢允莂bstract。
通過MapInheritedProperties方法就可以強制Code First使用TPC方式。
注意:因為屬于 TPC 繼承層次結(jié)構(gòu)的表并不使用同一個主鍵, 關(guān)閉主鍵屬性的標識,避免為不同子表插入重復(fù)的實體鍵。
modelBuilder.Entity<Course>() .Property(c => c.CourseID) .HasDatabaseGeneratedOption(DatabaseGeneratedOption.None); modelBuilder.Entity<OnsiteCourse>().Map(m => { m.MapInheritedProperties(); m.ToTable("OnsiteCourse"); }); modelBuilder.Entity<OnlineCourse>().Map(m => { m.MapInheritedProperties(); m.ToTable("OnlineCourse"); });
允許一個實體類型的屬性分散在多個表中。
實體拆分通過多次調(diào)用 Map 方法將一部分屬性映射到特定表。
在以下示例中,Department 實體拆分到兩個表中:Department 和 DepartmentDetails。
modelBuilder.Entity<Department>() .Map(m => { m.Properties(t => new { t.DepartmentID, t.Name }); m.ToTable("Department"); }). Map(m => { m.Properties(t => new { t.DepartmentID, t.Administrator, t.StartDate, t.Budget }); m.ToTable("DepartmentDetails"); });
兩個實體類型映射到同一個表。
1.兩個類必須共享同一個主鍵。
2.兩個類之間的關(guān)系必須被映射為表之間的一對一關(guān)系。
modelBuilder.Entity<OfficeAssignment>().HasKey(t => t.InstructorID); //共用主鍵 modelBuilder.Entity<Instructor>() .HasRequired(t => t.OfficeAssignment).WithRequiredPrincipal(t => t.Instructor);//一對一關(guān)系 modelBuilder.Entity<Instructor>().ToTable("Instructor"); modelBuilder.Entity<OfficeAssignment>().ToTable("Instructor");
DataAnnotations方式:
[ConlexType] public Details details;
或FluentAPI:
modelBuilder.ComplexType<Details>();
注意:
1.復(fù)雜類型類不能有主鍵。
2.復(fù)雜類型只能包含.net基礎(chǔ)類型的屬性。
3.使用復(fù)雜類型的類,只能包復(fù)雜類型的一個實例,不能使用復(fù)雜類型的集合。
(1)、可以對 ComplexTypeConfiguration 調(diào)用 Property。
modelBuilder.ComplexType<Details>() .Property(t => t.Location).HasMaxLength(20);
或
public class AddressComplexTypeConfiguration:ComplexTypeConfiguration<Address> { public AddressComplexTypeConfiguration() { Property(a => a.Country).HasColumnName("Country").HasMaxLength(100); Property(a => a.ZipCode).HasColumnName("ZipCode").HasMaxLength(6); } }
(2)、也可以使用點表示法訪問復(fù)雜類型的屬性。
modelBuilder.Entity<OnsiteCourse>().Property(t => t.Details.Location) .HasMaxLength(20);
一般Global.ascx.cs,Main應(yīng)用程序的入口等地方調(diào)用Database.SetInitializer方法:
只要Fluent API配置的數(shù)據(jù)庫映射發(fā)生變化或者domain中的model發(fā)生變化了,就把以前的數(shù)據(jù)庫刪除掉,根據(jù)新的配置重新建立數(shù)據(jù)庫。
Database.SetInitializer(new DropCreateDatabaseIfModelChanges<BreakAwayContext>());
只有在沒有數(shù)據(jù)庫的時候才會根據(jù)數(shù)據(jù)庫連接配置創(chuàng)建新的數(shù)據(jù)庫。這種配置主要用于production環(huán)境。
Database.SetInitializer(new CreateDatabaseIfNotExists<BreakAwayContext>());
不管數(shù)據(jù)庫映射或者model是否發(fā)生變化,每次都重新刪除并根據(jù)配置重建數(shù)據(jù)庫。
Database.SetInitializer(new DropCreateDatabaseAlways<BreakAwayContext>());
<?xml version="1.0"?> <configuration> <appSettings> <add key="DatabaseInitializerForTypeOrderSystemContext" value="System.Data.Entity.DropCreateDatabaseIfModelChanges[[OrderSystemContext]], EntityFramework" /> </appSettings> </configuration>
通過自定的初始化類,還可以將一些基礎(chǔ)數(shù)據(jù)在創(chuàng)建數(shù)據(jù)庫之后插入到數(shù)據(jù)庫中去。
public class DropCreateOrderDatabaseWithSeedValueAlways : DropCreateDatabaseAlways<OrderSystemContext> { protected override void Seed(OrderSystemContext context) { context.ProductCatalogs.Add(new ProductCatalog { CatalogName = "DELL E6400", Manufactory = "DELL", ListPrice = 5600, NetPrice = 4300 }); context.ProductCatalogs.Add(new ProductCatalog { CatalogName = "DELL E6420", Manufactory = "DELL", ListPrice = 7000, NetPrice = 5400 }); } } Database.SetInitializer(new DropCreateOrderDatabaseWithSeedValueAlways());
以上就是關(guān)于“Entity Framework如何映射TPH、TPT、TPC與繼承類”這篇文章的內(nèi)容,相信大家都有了一定的了解,希望小編分享的內(nèi)容對大家有幫助,若想了解更多相關(guān)的知識內(nèi)容,請關(guān)注億速云行業(yè)資訊頻道。
免責(zé)聲明:本站發(fā)布的內(nèi)容(圖片、視頻和文字)以原創(chuàng)、轉(zhuǎn)載和分享為主,文章觀點不代表本網(wǎng)站立場,如果涉及侵權(quán)請聯(lián)系站長郵箱:is@yisu.com進行舉報,并提供相關(guān)證據(jù),一經(jīng)查實,將立刻刪除涉嫌侵權(quán)內(nèi)容。