日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當(dāng)前位置: 首頁 > 编程资源 > 编程问答 >内容正文

编程问答

EntityFramework进阶——继承

發(fā)布時間:2025/3/11 编程问答 26 豆豆
生活随笔 收集整理的這篇文章主要介紹了 EntityFramework进阶——继承 小編覺得挺不錯的,現(xiàn)在分享給大家,幫大家做個參考.

通過類型繼承,我們可以更彈性地處理數(shù)據(jù),有3中相關(guān)的技巧,即TPHTPTTPC

?

Table Per Hierarchy(TPH)

當(dāng)單個數(shù)據(jù)表存儲不同數(shù)據(jù)類型時,在數(shù)據(jù)模型的設(shè)計上,可以使用Table Per Hierarchy(TPH,每個層次結(jié)構(gòu)一張表)設(shè)計分割成數(shù)個不同的類型。在通過繼承來建立彼此的關(guān)系。

新建一個空的控制臺項目: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("name=TPHModel"){}public virtual DbSet<Product> Product { get; set; }}

運行項目生成數(shù)據(jù)庫中的表結(jié)構(gòu)如下圖所示:

? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ??

這個數(shù)據(jù)表存儲各種類型的商品,我們可以將其中的數(shù)據(jù)字段分割成3部分,以針對特定的數(shù)據(jù)進行存儲。分別是一般性商品的共同數(shù)據(jù)、圖書、雜志。結(jié)構(gòu)如下圖所示:

商品數(shù)據(jù)表按類型分割的數(shù)據(jù)字段
?字段名說明數(shù)據(jù)類型
一般性商品的共同數(shù)據(jù)Id商品識別編號int
Name商品名稱string
Price價格int
圖書Title書名string
ISBN圖書ISBN編碼string
Author作者string
Pages頁數(shù)int
雜志Years雜志年份int
Month雜志月份int
ISSN雜志ISSN編碼string
MPages雜志頁數(shù)int

現(xiàn)在向Main函數(shù)中加入代碼,目的是向數(shù)據(jù)庫中插入數(shù)據(jù):

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

?向數(shù)據(jù)庫中插入的數(shù)據(jù)如下圖所示:

? ? ? ? ? ? ? ??

向數(shù)據(jù)庫中取出插入的數(shù)據(jù),可編輯如下代碼:

static void Main(string[] args) {using (TPHModel db = new TPHModel()){var bs = db.Product.OfType<Book>().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 頁數(shù):{5}\n 作者:{6}",b.Id,b.Name,b.Title,b.Price,b.ISBN,b.Pages,b.Author);Console.ReadKey();}else{Console.WriteLine("無此書編號");}} }

運行效果如下圖所示:

? ? ? ? ? ? ? ? ? ? ??

?


?Table Per Type(TPT)

Table per Type(TPT,每種類型一張表)通過類型繼承建立數(shù)據(jù)實體對應(yīng)到關(guān)聯(lián)數(shù)據(jù)表的外鍵,與TPH不同的地方在于,每一個數(shù)據(jù)類型對應(yīng)到獨立的數(shù)據(jù)表,數(shù)據(jù)表彼此形成關(guān)聯(lián)的外鍵就形成類型彼此間的繼承關(guān)系。

新建一個空的控制臺應(yīng)用程序: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("name=TPTModel"){}public virtual DbSet<Product> Product { get; set; }}

運行項目后,數(shù)據(jù)庫中新建的表表結(jié)構(gòu)如如下圖所示:

? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ??

?

修改Main函數(shù)中的代碼,目標(biāo)是插入一些數(shù)據(jù):?

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

數(shù)據(jù)插入數(shù)據(jù)表后,如下圖所示:

? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ??

?

修改Main函數(shù)中代碼,目標(biāo)是查詢出表中的數(shù)據(jù),如下圖所示:

static void Main(string[] args) {using (TPTModel db = new TPTModel()){var Products = db.Product;Console.WriteLine("\n圖書列表:\n");foreach (var book in Products.OfType<Book>()){Console.WriteLine("{0} 頁數(shù):{1} ISBN:{2} 作者:{3}",book.Title,book.Pages,book.ISBN,book.Author);}Console.WriteLine("\n雜志列表:\n");foreach (var magazine in Products.OfType<Magazine>()){Console.WriteLine("{0} 頁數(shù):{1} ISSN:{2} 年份:{3} 月份:{4}",magazine.Name,magazine.MPages,magazine.ISSN,magazine.Year,magazine.Month);}Console.Read(); } }

運行結(jié)果如下圖所示:

? ? ? ? ? ? ? ? ? ??


Table Per Concrete Class(TPC)?

TPH通過幾個類表示單個數(shù)據(jù)表,并且由派生類屬性對應(yīng)特定的字段。如果想要派生類同時擁有基類的共同屬性,可以嘗試TPC策略。

新建空的控制臺應(yīng)用程序 :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("name=TPCModel"){}protected override void OnModelCreating(DbModelBuilder modelBuilder){modelBuilder.Entity<Product>().Property(c => c.Id).HasDatabaseGeneratedOption(System.ComponentModel.DataAnnotations.Schema.DatabaseGeneratedOption.None);modelBuilder.Entity<Book>().Map(m => {m.MapInheritedProperties();m.ToTable("Book");});modelBuilder.Entity<Magazine>().Map(m => {m.MapInheritedProperties();m.ToTable("Magazine");});}public virtual DbSet<Product> Product { get; set; } }

運行項目,在數(shù)據(jù)庫中建的表結(jié)構(gòu)如下圖所示:

? ? ? ? ? ? ? ? ???

?

修改Main函數(shù)中的方法,目標(biāo)為向數(shù)據(jù)表中插入一些數(shù)據(jù),代碼如下圖所示:

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

運行程序后數(shù)據(jù)表的中結(jié)果如下圖所示:

? ? ? ? ? ? ? ? ? ? ? ? ???

采用TPC策略與TPH有類似性,但是在每一種類型的數(shù)據(jù)添加過程中都必須指定Id和Name等共享字段的值,而且Product、Book、Magazine類對應(yīng)的數(shù)據(jù)表中,Id字段不能存在重復(fù)的值。?

讀取數(shù)據(jù)表中的字段代碼如下圖所示:

static void Main(string[] args) {using (TPCModel db = new TPCModel()){var books = db.Product.OfType<Book>();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();} }

?運行結(jié)果如下圖所示:

? ? ? ? ? ? ??


復(fù)雜類型

當(dāng)一個實體類不具備Id之類的鍵值標(biāo)識屬性時,在EF定義上是一種復(fù)雜類型。如果我們想要單個數(shù)據(jù)表的字段用不同類型的屬性完成對應(yīng),那么復(fù)雜類型就非常適合這種情況。

Product數(shù)據(jù)表只含Book類型的數(shù)據(jù)字段
共同商品的數(shù)據(jù)Id商品識別編號int
Name商品名稱string
Price價格int
圖書類型的數(shù)據(jù)Title書名string?
ISBNISBN編號string
Author作者string
Pages頁數(shù)int

?

新建空的控制臺應(yīng)用程序: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("name=ComplexTypeModel"){}public virtual DbSet<Product> Product { get; set; }}

運行程序后,建立的數(shù)據(jù)表如下圖所示:

? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ??

生成的列名帶有Book前綴這是默認(rèn)的操作,如果要將其對應(yīng)到指定的數(shù)據(jù)字段,比如沒有Book前綴,就需要數(shù)據(jù)注解進行注釋,如下圖所示:

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函數(shù)代碼,?目標(biāo)是往表里插入數(shù)據(jù),代碼如下圖所示:

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

運行后插入數(shù)據(jù)后,表中內(nèi)容如下圖所示:

? ? ? ? ? ? ? ? ? ? ? ? ? ? ??

?

修改main函數(shù)中的代碼,執(zhí)行查詢操作:

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} 頁數(shù)是:{3}", product.Book.Title, product.Book.ISBN, product.Book.Author, product.Book.Pages);}Console.ReadKey();} }

運行效果如下圖所示:

? ? ? ? ? ? ? ???

?

?

總結(jié)

以上是生活随笔為你收集整理的EntityFramework进阶——继承的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網(wǎng)站內(nèi)容還不錯,歡迎將生活随笔推薦給好友。