EntityFramework进阶——Entity Splitting和Table Splitting
Entity Splitting——把單個實體拆分成多個表。Table Splitting——把單個表拆分成多個實體
Entity Splitting?
下面通過例子來說明:
假設存在如下實體類:
public class Employee{public int EmployeeId { get; set; }public string Name { get; set; }public string PhoneNumber { get; set; }public string DetailAddress { get; set; }public DateTime CreatedTime { get; set; }public DateTime ModifiedTime { get; set; }}在同一個Employee實體類的前提下,我們需要將DetailAddress,PhoneNumber字段放在一張表, 其余字段放在另一張表,就可以使用如下Fluent API代碼進行配置:
public class EmployeeMap:EntityTypeConfiguration<Employee>{public EmployeeMap(){Map(map =>{map.Properties(p => new{p.EmployeeId,p.Name,p.CreatedTime,p.ModifiedTime});map.ToTable("Employees");}).Map(map => {map.Properties(p => new {p.PhoneNumber,p.DetailAddress});map.ToTable("EmployeeDetails"); });}}上下文類的代碼如下圖所示:
public class SplittingModel : DbContext{public SplittingModel(): base("name=SplittingModel"){}protected override void OnModelCreating(DbModelBuilder modelBuilder){modelBuilder.Configurations.Add(new EmployeeMap());}public virtual DbSet<Employee> Employee { get; set; }}運行程序后,數據庫建表結構如下圖所示:
? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ???
?
當對實體類Employee進行插入數據操作時,EF會生成Employee 和 EmployeeDetail兩個表的插入語句,代碼?和 截圖如下所示:
static void Main(string[] args) {using (SplittingModel db = new SplittingModel()){db.Database.Log = Console.WriteLine;Employee employee = new Employee{CreatedTime = DateTime.Now,ModifiedTime = DateTime.Now,Name = "Jack",PhoneNumber = "1129373834",DetailAddress = "USA"};db.Employee.Add(employee);db.SaveChanges();Console.ReadKey();} }? ? ? ??
?
對實體Employee進行查詢操作時,也會同時關聯兩個表,代碼 和 截圖如下圖所示:
using (SplittingModel db = new SplittingModel()) {db.Database.Log = Console.WriteLine;var e = db.Employee.First();Console.ReadKey(); }?
?
?
?Table Splitting
表拆分使我們能將多個實體映射到一個數據庫表單,與實體拆分正好相反。我們可以將模型中的兩個或者多個實體映射到同一個物理數據庫表中。
例子如下,比如將兩個實體類Employee和EmployeePhoto合并成一個數據表,實體類如下圖所示:
public class Employee{public int EmployeeId { get; set; }public string Name { get; set; }public string PhoneNumber { get; set; }public string DetailAddress { get; set; }public DateTime CreatedTime { get; set; }public DateTime ModifiedTime { get; set; }//導航屬性public virtual EmployeePhoto Photo { get; set; }} public class EmployeePhoto{public int Id { get; set; }public byte[] Photo { get; set; }public Employee Employee { get; set; }}Fluent API代碼如下圖所示:
public class EmployeeMap:EntityTypeConfiguration<Employee>{public EmployeeMap(){ToTable("Employees");HasKey(p => p.EmployeeId);HasRequired(e => e.Photo).WithRequiredPrincipal(p => p.Employee);}} public class EmployeePhotoMap:EntityTypeConfiguration<EmployeePhoto>{public EmployeePhotoMap(){ToTable("Employees");HasKey(p => p.Id);}}上下文類代碼如下圖所示:
public class TableSplittingModel : DbContext{public TableSplittingModel(): base("name=TableSplittingModel"){}protected override void OnModelCreating(DbModelBuilder modelBuilder){modelBuilder.Configurations.Add(new EmployeeMap());modelBuilder.Configurations.Add(new EmployeePhotoMap());}public virtual DbSet<Employee> Employee { get; set; }public virtual DbSet<EmployeePhoto> EmployeePhoto { get; set; }}生成的數據庫表結果如下圖所示:
? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ??
?
向數據庫中插入數據,代碼如下圖所示:
static void Main(string[] args){using (TableSplittingModel db = new TableSplittingModel()){Employee employee = new Employee{Name = "admin",PhoneNumber = "1000",DetailAddress = "USA",CreatedTime = DateTime.Now,ModifiedTime = DateTime.Now,Photo = new EmployeePhoto {} };db.Employee.Add(employee);db.SaveChanges();Console.WriteLine("OK");}}當查詢實體Employee實體時,將只返回Employee實體列而不會返回EmployeePhoto列作為Employee實體一部分:
using (TableSplittingModel db = new TableSplittingModel()){var employee = db.Employee.ToList();}當查詢Employee實體且延遲加載EmployeePhoto實體時,才會返回EmployeePhoto列:
using (TableSplittingModel db = new TableSplittingModel()){var employee = db.Employee.Include("Photo").toList();}?
?
?
?
?
?
?
?
?
總結
以上是生活随笔為你收集整理的EntityFramework进阶——Entity Splitting和Table Splitting的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: JQuery Datatables e
- 下一篇: 火柴 UVa11375