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

1.1 拆分实体到多张表

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

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

图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 测试代码:

 using (var context = new EF6RecipesContext())
{
var product = new Product
{
SKU = ,
Description = "Expandable Hydration Pack",
Price = 19.97M,
ImageURL = "/pack147.jpg"
};
context.Products.Add(product);
product = new Product
{
SKU = ,
Description = "Rugged Ranger Duffel Bag",
Price = 39.97M,
ImageURL = "/pack178.jpg"
};
context.Products.Add(product);
product = new Product
{
SKU = ,
Description = "Range Field Pack",
Price = 98.97M,
ImageURL = "/noimage.jp"
};
context.Products.Add(product);
product = new Product
{
SKU = ,
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);
}
}

2.1 分拆一张表到多个实体

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

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

图6-2

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

 public class Photograph
{
[Key]
[DatabaseGenerated(DatabaseGeneratedOption.Identity)]
public int PhotoId { get; set; }
public string Title { get; set; }
public byte[] ThumbnailBits { get; set; }
[ForeignKey("PhotoId")]
public virtual PhotographFullImage PhotographFullImage { get; set; }
} public class PhotographFullImage
{
[Key]
public int PhotoId { get; set; }
public byte[] HighResolutionBits { get; set; }
[ForeignKey("PhotoId")]
public virtual Photograph Photograph { get; set; }
}

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

 public class EF6RecipesContext2:DbContext
{
public EF6RecipesContext2()
: base("name=EF6CodeFirstRecipesContext")
{
}
public DbSet<Photograph> Photographs { get; set; }
public DbSet<PhotographFullImage> PhotographFullImages { get; set; }
protected override void OnModelCreating(DbModelBuilder modelBuilder)
{
base.OnModelCreating(modelBuilder); modelBuilder.Entity<Photograph>()
.HasRequired(p => p.PhotographFullImage)
.WithRequiredPrincipal(p => p.Photograph); modelBuilder.Entity<Photograph>().ToTable("Photograph");
modelBuilder.Entity<PhotographFullImage>().ToTable("Photograph");
}
}

2.4 测试代码:

  byte[] thumbBits = new byte[];
byte[] fullBits = new byte[];
using (var context = new EF6RecipesContext2())
{
var photo = new Photograph
{
Title = "My Dog",
ThumbnailBits = thumbBits
};
var fullImage = new PhotographFullImage { HighResolutionBits = fullBits };
photo.PhotographFullImage = fullImage;
context.Photographs.Add(photo);
context.SaveChanges();
}
using (var context = new EF6RecipesContext2())
{
//context.Configuration.LazyLoadingEnabled = false;//1 如果关闭演示加载,则注释2必须写上
foreach (var photo in context.Photographs)
{
Console.WriteLine("Photo: {0}, ThumbnailSize {1} bytes",
photo.Title, photo.ThumbnailBits.Length); //显式加载存储完整图像的字段
//context.Entry(photo).Reference(p => p.PhotographFullImage).Load();//2 这里指定显示加载
Console.WriteLine("Full Image Size: {0} bytes",
photo.PhotographFullImage.HighResolutionBits.Length);
}
}

输出如下:

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

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

上一篇:Laravel框架中的数据库CURD操作、连贯操作、链式操作的用法


下一篇:C#中oracle数据库的连接方法