Table per Type Inheritance (TPT)建模
1.假设你有两张表与一张公共的表密切相关,如图7-1所示,Businiss表与eCommerce表、Retail表有1:0...1关系。最关键的是,eCommerce表和Retail表中有关于Business表中代表业务的额外的信息。
图7-1
2. 右键你的项目,新建三个实体类,其中eCommerce、Retail继承自Businiss。如下代码:
1 [Table("Business", Schema = "example7")] 2 public class Business 3 { 4 [Key] 5 [DatabaseGenerated(DatabaseGeneratedOption.Identity)] 6 public int BusinessId { get; protected set; } 7 public string Name { get; set; } 8 public string LicenseNumber { get; set; } 9 }
1 [Table("eCommerce", Schema = "example7")] 2 public class eCommerce : Business 3 { 4 public string URL { get; set; } 5 }
1 [Table("Retail", Schema = "example7")] 2 public class Retail : Business 3 { 4 public string Address { get; set; } 5 public string City { get; set; } 6 public string State { get; set; } 7 public string ZIPCode { get; set; } 8 }
3.创建一个继承自DbContext的上下文对象EF6RecipesContext;
1 public class EF6RecipesContext : DbContext 2 { 3 public DbSet<Business> Businesses { get; set; } 4 public EF6RecipesContext() 5 : base("name=EF6CodeFirstRecipesContext") 6 { 7 } 8 protected override void OnModelCreating(DbModelBuilder modelBuilder) 9 { 10 11 } 12 }
4.测试代码:
1 using (var context = new EF6RecipesContext()) 2 { 3 var business = new Business 4 { 5 Name = "Corner Dry Cleaning", 6 LicenseNumber = "100x1" 7 }; 8 context.Businesses.Add(business); 9 var retail = new Retail 10 { 11 Name = "Shop and Save", 12 LicenseNumber = "200C", 13 Address = "101 Main", 14 City = "Anytown", 15 State = "TX", 16 ZIPCode = "76106" 17 }; 18 context.Businesses.Add(retail); 19 var web = new eCommerce 20 { 21 Name = "BuyNow.com", 22 LicenseNumber = "300AB", 23 URL = "www.buynow.com" 24 }; 25 context.Businesses.Add(web); 26 context.SaveChanges(); 27 } 28 29 using (var context = new EF6RecipesContext()) 30 { 31 Console.WriteLine(" --- All Businesses ---"); 32 foreach (var b in context.Businesses) 33 { 34 Console.WriteLine("{0} (#{1}).{2}", b.Name, b.LicenseNumber,b.BusinessId); 35 } 36 37 Console.WriteLine(" --- Retail Businesses ---"); 38 foreach (var r in context.Businesses.OfType<Retail>()) 39 { 40 Console.WriteLine("{0} (#{1}).{2}", r.Name, r.LicenseNumber,r.BusinessId); 41 Console.WriteLine("{0}", r.Address); 42 Console.WriteLine("{0}, {1} {2}", r.City, r.State, r.ZIPCode); 43 } 44 45 Console.WriteLine(" --- eCommerce Businesses ---"); 46 foreach (var e in context.Businesses.OfType<eCommerce>()) 47 { 48 Console.WriteLine("{0} (#{1}).{2}", e.Name, e.LicenseNumber,e.BusinessId); 49 Console.WriteLine("Online address is: {0}", e.URL); 50 } 51 }
输出:
5. TPT是实体框架支持三个继承映射中的一个,另外两个分别是Table per Hierarchy(TPH),和Table per Concrete Type(TPC),将在本章后面部分讨论。
TPT继承映射提供了数据库方面的灵活性,作为开发人员,我们可以很容易在模型中为新加的表添加派生类型。但是,每个派生类型都会涉及一个额外的join连接,这会降低系统的性能。 在真实的应用中,我们已经看到当派生类型很多时,使用TPT继承映射所带来的性能问题。
Table per hierarchy(TPH)继承映射。它将整个继承类型存储在一张单独的表中,他解决了TPT中的join连接问题,并带来了好的性能。但牺牲了数据库的灵活性。
Table per concrete(TPC)继承映射,它被实体框架于运行时所支持,但不被设计器支持。