问题:
有2个或更多的表共享相同的主键,现在需要使用单个实体映射这些表。
解决方案:
数据库图表:
使用代码优先的方式建模。
1、添加ADO.NET实体数据模型,命名模型为EF6CodeFirstRecipesContext,选择空代码优先模型。
2、将生成的EF6CodeFirstRecipesContext类修改为EF6RecipesContext类。
3、修改app.config中的连接字符串参数。
4、添加POCO实体类Product。代码如下:
using System.ComponentModel.DataAnnotations; using System.ComponentModel.DataAnnotations.Schema; public class Product { [Key] [DatabaseGenerated(DatabaseGeneratedOption.None)] public int SKU { get; set; } public string Description { get; set; } public decimal Price { get; set; } public string ImageURL { get; set; } }
5、在EF6RecipesContext类中添加如下属性:
public DbSet<Product> Products { get; set; }
6、在重写的OnModelCreating方法中添加如下代码:
modelBuilder.Entity<Product>() .Map(m => { m.Properties(p => new { p.SKU, p.Description, p.Price }); m.ToTable("Product", "Chapter2"); }) .Map(m => { m.Properties(p => new { p.SKU, p.ImageURL }); m.ToTable("ProductWebInfo", "Chapter2"); });
具体过程可参见上一节内容。如果需要直接使用上一节内容,目前我们还没有使用Migration指令,则需要手动将_Migration表删除。
原理:
从另外的表中获取当前表每一行的额外的信息这种情况在旧系统中很常见。特别是当数据库扩展时,没有人喜欢在一些核心表中添加额外的列。这时候就可以通过另外的表来嫁接额外的信息。
通过整合2个或多个表为单个实体类,更通俗的讲,将单个实体类拆分成2个或多个表,这个过程通常称为垂直拆分(vertical splitting)。
垂直拆分的弊端是,每次我们需要获取实体类的实例时,都需要使用join连接用于从其他表中获取信息。
using (var context = new EF6RecipesContext()) { var product = new Product { SKU = 147, Description = "Expandable Hydration Pack", Price = 19.97M, ImageURL = "/pack147.jpg" }; context.Products.Add(product); product = new Product { SKU = 178, Description = "Rugged Ranger Duffel Bag", Price = 39.97M, ImageURL = "/pack178.jpg" }; context.Products.Add(product); product = new Product { SKU = 186, Description = "Range Field Pack", Price = 98.97M, ImageURL = "/noimage.jpg" }; context.Products.Add(product); product = new Product { SKU = 202, Description = "Small Deployment Back Pack", Price = 29.97M, ImageURL = "/pack202.jpg" }; context.Products.Add(product); context.SaveChanges(); } using (var context = new EF6RecipesContext()) { foreach (var p in context.Products) { Console.WriteLine("{0} {1} {2} {3}", p.SKU, p.Description, p.Price.ToString("C"), p.ImageURL); } }
执行结果如下: