首页 > 代码库 > entityframework学习笔记--006-表拆分与实体拆分

entityframework学习笔记--006-表拆分与实体拆分

1.1 拆分实体到多张表

假设你有如下表,如图6-1。Product表用于存储商品的字符类信息,ProductWebInfo用于存储商品的图片,两张表通过SKU关联。现在你想把两张表的信息整合到一个实体类。

技术分享

图6-1

1.2 使用code first 新建如下的poco实体:

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; }
    }

1.3 创建一个继承自DbContext的数据访问类“EF6RecipesContext”

public class EF6RecipesContext : DbContext
    {
        public DbSet<Product> Products { get; set; }
        public EF6RecipesContext()
            : base("name=EF6CodeFirstRecipesContext")
        {
        }
        protected override void OnModelCreating(DbModelBuilder modelBuilder)
        {
            base.OnModelCreating(modelBuilder);
            modelBuilder.Entity<Product>()
            .Map(m => {
                m.Properties(p => new { p.SKU, p.Description, p.Price });
                m.ToTable("Product");
            })
            .Map(m => {
                m.Properties(p => new { p.SKU, p.ImageURL });
                m.ToTable("ProductWebInfo");
            });
        }
    }

1.4 测试代码:

技术分享
 1 using (var context = new EF6RecipesContext())
 2             {
 3                 var product = new Product
 4                 {
 5                     SKU = 147,
 6                     Description = "Expandable Hydration Pack",
 7                     Price = 19.97M,
 8                     ImageURL = "/pack147.jpg"
 9                 };
10                 context.Products.Add(product);
11                 product = new Product
12                 {
13                     SKU = 178,
14                     Description = "Rugged Ranger Duffel Bag",
15                     Price = 39.97M,
16                     ImageURL = "/pack178.jpg"
17                 };
18                 context.Products.Add(product);
19                 product = new Product
20                 {
21                     SKU = 186,
22                     Description = "Range Field Pack",
23                     Price = 98.97M,
24                     ImageURL = "/noimage.jp"
25                 };
26                 context.Products.Add(product);
27                 product = new Product
28                 {
29                     SKU = 202,
30                     Description = "Small Deployment Back Pack",
31                     Price = 29.97M,
32                     ImageURL = "/pack202.jpg"
33                 };
34                 context.Products.Add(product);
35                 context.SaveChanges();
36             }
37             using (var context = new EF6RecipesContext())
38             {
39                 foreach (var p in context.Products)
40                 {
41                     Console.WriteLine("{0} {1} {2} {3}", p.SKU, p.Description,
42                     p.Price.ToString("C"), p.ImageURL);
43                 }
44             }
View Code

2.1 分拆一张表到多个实体

你有这样的一张数据库表如图6-2,里面包含经常使用的字符,一些不常用的大字段。为了性能,需要避免每个查询都去加载这些字段。你需要将这张表分拆成两个或是更多的实体。

技术分享

图6-2

2.2 把上面的表分拆成两个poco实体。

 1 public class Photograph
 2     {
 3         [Key]
 4         [DatabaseGenerated(DatabaseGeneratedOption.Identity)]
 5         public int PhotoId { get; set; }
 6         public string Title { get; set; }
 7         public byte[] ThumbnailBits { get; set; }
 8         [ForeignKey("PhotoId")]
 9         public virtual PhotographFullImage PhotographFullImage { get; set; }
10     }
11 
12 public class PhotographFullImage
13     {
14         [Key]
15         public int PhotoId { get; set; }
16         public byte[] HighResolutionBits { get; set; }
17         [ForeignKey("PhotoId")]
18         public virtual Photograph Photograph { get; set; }
19     }

2.3 创建ef数据访问类,并注册表拆分规则。

 1 public class EF6RecipesContext2:DbContext
 2     {
 3         public EF6RecipesContext2()
 4             : base("name=EF6CodeFirstRecipesContext")
 5         {
 6         }
 7         public DbSet<Photograph> Photographs { get; set; }
 8         public DbSet<PhotographFullImage> PhotographFullImages { get; set; }
 9         protected override void OnModelCreating(DbModelBuilder modelBuilder)
10         {
11             base.OnModelCreating(modelBuilder);
12 
13             modelBuilder.Entity<Photograph>()
14             .HasRequired(p => p.PhotographFullImage)
15             .WithRequiredPrincipal(p => p.Photograph);
16 
17             modelBuilder.Entity<Photograph>().ToTable("Photograph");
18             modelBuilder.Entity<PhotographFullImage>().ToTable("Photograph");
19         }
20     }

2.4 测试代码:

 1  byte[] thumbBits = new byte[100];
 2             byte[] fullBits = new byte[2000];
 3             using (var context = new EF6RecipesContext2())
 4             {
 5                 var photo = new Photograph
 6                 {
 7                     Title = "My Dog",
 8                     ThumbnailBits = thumbBits
 9                 };
10                 var fullImage = new PhotographFullImage { HighResolutionBits = fullBits };
11                 photo.PhotographFullImage = fullImage;
12                 context.Photographs.Add(photo);
13                 context.SaveChanges();
14             }
15             using (var context = new EF6RecipesContext2())
16             {
17                 //context.Configuration.LazyLoadingEnabled = false;//1 如果关闭演示加载,则注释2必须写上
18                 foreach (var photo in context.Photographs)
19                 {
20                     Console.WriteLine("Photo: {0}, ThumbnailSize {1} bytes",
21                         photo.Title, photo.ThumbnailBits.Length);
22 
23                     //显式加载存储完整图像的字段
24                     //context.Entry(photo).Reference(p => p.PhotographFullImage).Load();//2 这里指定显示加载
25                     Console.WriteLine("Full Image Size: {0} bytes",
26                         photo.PhotographFullImage.HighResolutionBits.Length);
27                 }
28             }

输出如下:

Photo: My Dog, Thumbnail Size: 100 bytes
Full Image Size: 2000 bytes

2.5 ef的默认规则是开发延迟加载的,所以在我们获取“Photograph”的时候,其对应的“PhotographFullImage”是不会加载进来的,只有使用到“PhotographFullImage”的属性的时候才会加载进来。

entityframework学习笔记--006-表拆分与实体拆分