学校网站建设栏目设置,网站模板内容页在哪,wordpress 在线留言插件,专注徐州网站开发通过类型继承#xff0c;我们可以更弹性地处理数据#xff0c;有3中相关的技巧#xff0c;即TPH#xff0c;TPT#xff0c;TPC。 Table Per Hierarchy#xff08;TPH#xff09;
当单个数据表存储不同数据类型时#xff0c;在数据模型的设计上#xff0c;可以使用Tab… 通过类型继承我们可以更弹性地处理数据有3中相关的技巧即TPHTPTTPC。 Table Per HierarchyTPH
当单个数据表存储不同数据类型时在数据模型的设计上可以使用Table Per HierarchyTPH每个层次结构一张表设计分割成数个不同的类型。在通过继承来建立彼此的关系。
新建一个空的控制台项目TPHDemo。添加如下几个实体类 public class Product{public int Id { get; set; }public string Name { get; set; }public int Price { get; set; }}public class Magazine:Product{public int Year { get; set; }public int Month { get; set; }public string ISSN { get; set; }public int MPages { get; set; }}public class Book:Product{public string Title { get; set; }public string ISBN { get; set; }public string Author { get; set; }public int Pages { get; set; }}
上下文类代码如下图所示 public class TPHModel : DbContext{public TPHModel(): base(nameTPHModel){}public virtual DbSetProduct Product { get; set; }}
运行项目生成数据库中的表结构如下图所示 这个数据表存储各种类型的商品我们可以将其中的数据字段分割成3部分以针对特定的数据进行存储。分别是一般性商品的共同数据、图书、杂志。结构如下图所示
商品数据表按类型分割的数据字段 字段名说明数据类型一般性商品的共同数据Id商品识别编号intName商品名称stringPrice价格int图书Title书名stringISBN图书ISBN编码stringAuthor作者stringPages页数int杂志Years杂志年份intMonth杂志月份intISSN杂志ISSN编码stringMPages杂志页数int
现在向Main函数中加入代码目的是向数据库中插入数据
static void Main(string[] args){using (TPHModel db new TPHModel()){Product book new Book{Name 图书,Price 12,Title EF进阶,ISBN 001,Author admin,Pages 1000};db.Product.Add(book);Product magazine new Magazine{Name 杂志,Price 10,Year 2019,Month 10,ISSN 0001,MPages 500};db.Product.Add(magazine);db.SaveChanges();}} 向数据库中插入的数据如下图所示 向数据库中取出插入的数据可编辑如下代码
static void Main(string[] args)
{using (TPHModel db new TPHModel()){var bs db.Product.OfTypeBook().Where(p p.Id 1);//筛选出Book类型if (bs.Any()){Book b bs.Single();Console.WriteLine(\n{0}--{1}\n\n 书名:{2}\n 价格{3}\n ISBN:{4}\n 页数{5}\n 作者:{6},b.Id,b.Name,b.Title,b.Price,b.ISBN,b.Pages,b.Author);Console.ReadKey();}else{Console.WriteLine(无此书编号);}}
}
运行效果如下图所示 Table Per TypeTPT
Table per TypeTPT每种类型一张表通过类型继承建立数据实体对应到关联数据表的外键与TPH不同的地方在于每一个数据类型对应到独立的数据表数据表彼此形成关联的外键就形成类型彼此间的继承关系。
新建一个空的控制台应用程序TPTDemo添加如下几个实体类 [Table(Product)]public class Product{public int Id { get; set; }public string Name { get; set; }public int Price { get; set; }}[Table(Book)]public class Book:Product{public string Title { get; set; }public string ISBN { get; set; }public string Author { get; set; }public int Pages { get; set; }}[Table(Magazine)]public class Magazine:Product{public int Year { get; set; }public int Month { get; set; }public string ISSN { get; set; }public int MPages { get; set; }}
上下文类代码如下图所示 public class TPTModel : DbContext{public TPTModel(): base(nameTPTModel){}public virtual DbSetProduct Product { get; set; }}
运行项目后数据库中新建的表表结构如如下图所示 修改Main函数中的代码目标是插入一些数据 static void Main(string[] args){using (TPTModel db new TPTModel()){Product book new Book{Name 图书,Title EF进阶,ISBN 001,Author admin,Pages 500,};db.Product.Add(book);Product magezine new Magazine{Name 杂志,Year 2019,Month 10,ISSN 00001,MPages 1000,};db.Product.Add(magezine);db.SaveChanges();Console.WriteLine(insert successd);}}
数据插入数据表后如下图所示 修改Main函数中代码目标是查询出表中的数据如下图所示
static void Main(string[] args)
{using (TPTModel db new TPTModel()){var Products db.Product;Console.WriteLine(\n图书列表\n);foreach (var book in Products.OfTypeBook()){Console.WriteLine({0} 页数:{1} ISBN:{2} 作者:{3},book.Title,book.Pages,book.ISBN,book.Author);}Console.WriteLine(\n杂志列表\n);foreach (var magazine in Products.OfTypeMagazine()){Console.WriteLine({0} 页数:{1} ISSN{2} 年份{3} 月份{4},magazine.Name,magazine.MPages,magazine.ISSN,magazine.Year,magazine.Month);}Console.Read(); }
}
运行结果如下图所示 Table Per Concrete ClassTPC
TPH通过几个类表示单个数据表并且由派生类属性对应特定的字段。如果想要派生类同时拥有基类的共同属性可以尝试TPC策略。
新建空的控制台应用程序 TPCDemo新增实体类如下图所示 public class Product{public int Id { get; set; }public string Name { get; set; }public int Price { get; set; }}public class Book:Product{public string Title { get; set; }public string ISBN { get; set; }public string Author { get; set; }public int Pages { get; set; }}public class Magazine:Product{public int Year { get; set; }public int Month { get; set; }public string ISSN { get; set; }public string MPages { get; set; }}
上下文类代码如下图所示
public class TPCModel : DbContext
{public TPCModel(): base(nameTPCModel){}protected override void OnModelCreating(DbModelBuilder modelBuilder){modelBuilder.EntityProduct().Property(c c.Id).HasDatabaseGeneratedOption(System.ComponentModel.DataAnnotations.Schema.DatabaseGeneratedOption.None);modelBuilder.EntityBook().Map(m {m.MapInheritedProperties();m.ToTable(Book);});modelBuilder.EntityMagazine().Map(m {m.MapInheritedProperties();m.ToTable(Magazine);});}public virtual DbSetProduct Product { get; set; }
}
运行项目在数据库中建的表结构如下图所示 修改Main函数中的方法目标为向数据表中插入一些数据代码如下图所示 static void Main(string[] args){using (TPCModel db new TPCModel()){Book book new Book{Id 1,Name 图书,Price 100,Title EF进阶,ISBN 001,Author admin,Pages 1000,};db.Product.Add(book);Magazine magazine new Magazine{Id 2,Name 杂志,Price 500,Year 2019,Month 10,ISSN 0001,MPages 500,};db.Product.Add(magazine);db.SaveChanges();Console.WriteLine(OK);}}
运行程序后数据表的中结果如下图所示 采用TPC策略与TPH有类似性但是在每一种类型的数据添加过程中都必须指定Id和Name等共享字段的值而且Product、Book、Magazine类对应的数据表中Id字段不能存在重复的值。
读取数据表中的字段代码如下图所示
static void Main(string[] args)
{using (TPCModel db new TPCModel()){var books db.Product.OfTypeBook();foreach (var book in books){Console.WriteLine(Name:{0},Price:{1}, Title:{2} ,ISBN:{3},Author:{4}, Pages:{5},book.Name,book.Price,book.Title,book.ISBN,book.Author,book.Pages);}Console.ReadKey();}
} 运行结果如下图所示 复杂类型
当一个实体类不具备Id之类的键值标识属性时在EF定义上是一种复杂类型。如果我们想要单个数据表的字段用不同类型的属性完成对应那么复杂类型就非常适合这种情况。
Product数据表只含Book类型的数据字段共同商品的数据Id商品识别编号intName商品名称stringPrice价格int图书类型的数据Title书名string ISBNISBN编号stringAuthor作者stringPages页数int新建空的控制台应用程序ComplexTypeDemo新增实体类如下图所示 public class Product{public int Id { get; set; }public string Name { get; set; }public int Price { get; set; }public Book Book { get; set; }}public class Book{public string Title { get; set; }public string ISBN { get; set; }public string Author { get; set; }public int Pages { get; set; }} 上下文类中的代码如下图所示 public class ComplexTypeModel : DbContext{public ComplexTypeModel(): base(nameComplexTypeModel){}public virtual DbSetProduct Product { get; set; }}
运行程序后建立的数据表如下图所示 生成的列名带有Book前缀这是默认的操作如果要将其对应到指定的数据字段比如没有Book前缀就需要数据注解进行注释如下图所示 public class Book{[Column(Title)]public string Title { get; set; }[Column(ISBN)]public string ISBN { get; set; }[Column(Author)]public string Author { get; set; }[Column(Pages)]public int Pages { get; set; }}
修改main函数代码 目标是往表里插入数据代码如下图所示 static void Main(string[] args){using (ComplexTypeModel db new ComplexTypeModel()) {var book new Book{Title 新的图书,ISBN 0001,Author admin,Pages 100,};var product new Product{Name 图书,Price 1000,Book book,};db.Product.Add(product);db.SaveChanges();Console.WriteLine(OK);}}
运行后插入数据后表中内容如下图所示 修改main函数中的代码执行查询操作
static void Main(string[] args)
{using (ComplexTypeModel db new ComplexTypeModel()) {foreach (Product product in db.Product){Console.WriteLine(\n\n 商品名称是{0},商品价格是{1},product.Name,product.Price);Console.WriteLine(\n书名是{0} ISBN编号是{1} 作者是{2} 页数是{3}, product.Book.Title, product.Book.ISBN, product.Book.Author, product.Book.Pages);}Console.ReadKey();}
}
运行效果如下图所示