網站首頁 編程語言 正文
一、TPH
Table Per Hierarchy (默認,每個層次一個表)
每個層次結構共用一個表,類的每一個屬性都必須是可空的。
1、默認行為
只建立一個表,把基類和子類中的所有屬性都映射為表中的列。?
為基類和所有子類共建立一個表,基類和子類中的所有屬性都映射為表中的一個列。
默認在這個表中建立一個叫做Discriminator的列,類型是nvarchar,長度是128。在存儲基類或子類的時候,把類名作為Discriminator列的值。
2、Fluent API修改默認行為
Map方法中傳入的類型參數是子類的類名,Requires用于指定Discriminator列的名字,HasValue用于指定它的類型和每個子類對應的值。
modelBuilder.Entity<Course>()
.Map<Course>(m => m.Requires("Type").HasValue("Course"))
.Map<OnsiteCourse>(m => m.Requires("Type").HasValue("OnsiteCourse"));
二、TPT
Table Per Type(每個類各一個表)
1、默認行為
為基類和每個子類各建立一個表,每個與子類對應的表中只包含子類特有的屬性對應的列。?
子類的表中只包含子類特有的屬性,子表還會存儲一個將子表與基表聯接的外鍵。
2、Fluent API修改默認行為
我們可以使用Map方法強制讓Code First使用TPT方式,因為Code First默認使用的是TPH方式。
modelBuilder.Entity<Course>().ToTable("Course");
modelBuilder.Entity<OnsiteCourse>().ToTable("OnsiteCourse");
三、TPC
Table Per ConCrete Type(每個具體類型各一個表)
每個具體的派生類各一個表,沒有基表。不推薦使用。
1、默認行為
在子類對應的表中除了子類特有的屬性外還有基類的屬性對應的表。基類可以是abstract。
2、Fluent API修改默認行為
通過MapInheritedProperties方法就可以強制Code First使用TPC方式。
注意:因為屬于 TPC 繼承層次結構的表并不使用同一個主鍵, 關閉主鍵屬性的標識,避免為不同子表插入重復的實體鍵。
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");
});
四、實體拆分
允許一個實體類型的屬性分散在多個表中。?
實體拆分通過多次調用 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.兩個類之間的關系必須被映射為表之間的一對一關系。
modelBuilder.Entity<OfficeAssignment>().HasKey(t => t.InstructorID); //共用主鍵
modelBuilder.Entity<Instructor>() .HasRequired(t => t.OfficeAssignment).WithRequiredPrincipal(t => t.Instructor);//一對一關系
modelBuilder.Entity<Instructor>().ToTable("Instructor");
modelBuilder.Entity<OfficeAssignment>().ToTable("Instructor");
六、將類指定為復雜類型
1、指定方法:
DataAnnotations方式:
[ConlexType]
public Details details;
或FluentAPI:
modelBuilder.ComplexType<Details>();
注意:?
1.復雜類型類不能有主鍵。?
2.復雜類型只能包含.net基礎類型的屬性。?
3.使用復雜類型的類,只能包復雜類型的一個實例,不能使用復雜類型的集合。
2、配置復雜類型的屬性
(1)、可以對 ComplexTypeConfiguration 調用 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)、也可以使用點表示法訪問復雜類型的屬性。
modelBuilder.Entity<OnsiteCourse>().Property(t => t.Details.Location) .HasMaxLength(20);
七、DataBase初始化
1、調用Database.SetInitializer方法:
一般Global.ascx.cs,Main應用程序的入口等地方調用Database.SetInitializer方法:
- 只要Fluent API配置的數據庫映射發生變化或者domain中的model發生變化了,就把以前的數據庫刪除掉,根據新的配置重新建立數據庫。
Database.SetInitializer(new DropCreateDatabaseIfModelChanges<BreakAwayContext>());
- 只有在沒有數據庫的時候才會根據數據庫連接配置創建新的數據庫。這種配置主要用于production環境。
Database.SetInitializer(new CreateDatabaseIfNotExists<BreakAwayContext>());
- 不管數據庫映射或者model是否發生變化,每次都重新刪除并根據配置重建數據庫。
Database.SetInitializer(new DropCreateDatabaseAlways<BreakAwayContext>());
2、通過配置文件更靈活的指定數據庫初始化的方式:
<?xml version="1.0"?> <configuration> <appSettings> <add key="DatabaseInitializerForTypeOrderSystemContext" value="System.Data.Entity.DropCreateDatabaseIfModelChanges[[OrderSystemContext]], EntityFramework" /> </appSettings> </configuration>
3、自定義數據庫初始化類
通過自定的初始化類,還可以將一些基礎數據在創建數據庫之后插入到數據庫中去。
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());
原文鏈接:https://www.cnblogs.com/springsnow/p/13230102.html
相關推薦
- 2022-09-25 Spring核心IOC的核心類解析
- 2022-06-19 WPF項目在設計界面調用后臺代碼_實用技巧
- 2023-06-18 C#零基礎開發中最重要的概念總結_C#教程
- 2022-03-14 window環境編譯在linux環境運行的golang程序
- 2022-08-03 GoFrame?gmap遍歷hashmap?listmap?treemap使用技巧_Golang
- 2022-06-16 Python中的Super用法示例詳解_python
- 2022-01-28 Mybatis插件-責任鏈模式
- 2022-05-23 Python?圖形界面框架TkInter之在源碼中找pack方法_python
- 最近更新
-
- window11 系統安裝 yarn
- 超詳細win安裝深度學習環境2025年最新版(
- Linux 中運行的top命令 怎么退出?
- MySQL 中decimal 的用法? 存儲小
- get 、set 、toString 方法的使
- @Resource和 @Autowired注解
- Java基礎操作-- 運算符,流程控制 Flo
- 1. Int 和Integer 的區別,Jav
- spring @retryable不生效的一種
- Spring Security之認證信息的處理
- Spring Security之認證過濾器
- Spring Security概述快速入門
- Spring Security之配置體系
- 【SpringBoot】SpringCache
- Spring Security之基于方法配置權
- redisson分布式鎖中waittime的設
- maven:解決release錯誤:Artif
- restTemplate使用總結
- Spring Security之安全異常處理
- MybatisPlus優雅實現加密?
- Spring ioc容器與Bean的生命周期。
- 【探索SpringCloud】服務發現-Nac
- Spring Security之基于HttpR
- Redis 底層數據結構-簡單動態字符串(SD
- arthas操作spring被代理目標對象命令
- Spring中的單例模式應用詳解
- 聊聊消息隊列,發送消息的4種方式
- bootspring第三方資源配置管理
- GIT同步修改后的遠程分支