Linq to Sql學習總結6
阿新 • • 發佈:2018-11-20
單表繼承
繼承實體定義:
//linq to sql支援實體單表繼承,即某一實體類(具有對映關係的類)可以派生多個子類,子類不用再通過特性對映基類的關係資料 //子類對基類實體進行分類,通過特性InheritanceMapping對基類實體分類 //基類實體以某一成員屬性作為分類依據(IsDiscriminator) //應用場景:對於論壇來說,帖子有兩種,一種是主題貼,一種是回覆帖。 [Table(Name = "Topics")] [InheritanceMapping(Code = 0, Type = typeof(NewTopic), IsDefault = true)] [InheritanceMapping(Code = 1, Type = typeof(Reply))] public class Topic { [Column(Name = "TopicID", DbType = "int identity", IsPrimaryKey = true, IsDbGenerated = true, CanBeNull = false)] public int TopicID { get; set; } [Column(Name = "TopicTitle", DbType = "varchar(50)", CanBeNull = false)] public string TopicTitle { get; set; } [Column(Name = "TopicType", DbType = "tinyint", CanBeNull = false, IsDiscriminator = true)] public int TopicType { get; set; } [Column(Name = "TopicContent", DbType = "varchar(max)", CanBeNull = false)] public string TopicContent { get; set; } } public class NewTopic : Topic { public NewTopic() { base.TopicType = 0; } } public class Reply : Topic { public Reply() { base.TopicType = 1; } [Column(Name = "ParentTopic", DbType = "int", CanBeNull = false)] public int ParentTopic { get; set; } }
派生實體的使用:
//查詢基類實體 var topic = from t in bbs.Topics select t; foreach (Topic t in topic) { if (t is NewTopic) { //將基類實體轉換為派生類實體 NewTopic newTopic = t as NewTopic; Response.Write("標題:" + newTopic.TopicTitle + " 型別:" + newTopic.TopicType + "<br/>"); } else if (t is Reply) { Reply reply = t as Reply; Response.Write("標題:" + reply.TopicTitle + " 型別:" + reply.TopicType + " 隸屬主題:" + reply.ParentTopic + "<br/>"); } } //直接查詢派生類實體 IEnumerable q1 = (from t in bbs.Topics.OfType<NewTopic>() select t).ToList(); IEnumerable q2 = (from t in bbs.Topics.OfType<Reply>() select t).ToList(); //對派生類實體進行增刪改 NewTopic nt = new NewTopic() { TopicTitle = "還是新主題", TopicContent = "還是新主題" }; Reply rpl = new Reply() { TopicTitle = "還是新回覆", TopicContent = "還是新回覆", ParentTopic = 4 }; bbs.Topics.InsertOnSubmit(nt); bbs.Topics.InsertOnSubmit(rpl); bbs.SubmitChanges(); Reply rp = bbs.Topics.OfType<Reply>().Single(r => r.TopicID == 8); bbs.Topics.DeleteOnSubmit(rp); bbs.SubmitChanges();
實體關係定義
通過定義實體之間的關係,可以不用在對應的關係資料表之間建立外來鍵關係
具有關係的實體定義:
[Table(Name = "Categories")] public class BoardCategory { [Column(Name = "CategoryID", DbType = "int identity", IsPrimaryKey = true, IsDbGenerated = true, CanBeNull = false)] public int CategoryID { get; set; } [Column(Name = "CategoryName", DbType = "varchar(50)", CanBeNull = false)] public string CategoryName { get; set; } //定義一個私有儲存欄位儲存屬性的值,EntitySet表示需要關聯的實體集合 private EntitySet<Board> _boards; //OtherKey指定要關聯的(需要延遲載入的)的實體類的成員,通過該成員與指定實體類關聯 [Association(OtherKey = "BoardCategory", Storage = "_boards")] public EntitySet<Board> Boards { set { this._boards.Assign(value); } get { return this._boards; } } public BoardCategory() { this.Boards = new EntitySet<Board>(); } } [Table(Name = "Boards")] public class Board { [Column(Name = "BoardID", DbType = "int identity", IsPrimaryKey = true, IsDbGenerated = true, CanBeNull = false)] public int BoardID { get; set; } [Column(Name = "BoardName", DbType = "varchar(50)", CanBeNull = false)] public string BoardName { get; set; } [Column(Name = "BoardCategory", DbType = "int", CanBeNull = false)] public int BoardCategory { get; set; } //EntityRef表示關聯當前實體類的實體引用 private EntityRef<BoardCategory> _Category; //TisKey指定當前實體類的一個成員,用於延遲載入關聯當前實體類的實體 [Association(ThisKey = "BoardCategory", Storage = "_Category")] public BoardCategory Category { get { return this._Category.Entity; } set { this._Category.Entity = value; value.Boards.Add(this); } } }
關係實體類的應用:
var query1 = from b in bbs.Boards where b.Category.CategoryID == 1 select b; var query2 = from c in bbs.Categories where c.Boards.Count() > 2 select c; //在新增分類的時候,如果這個分類下還有新的版塊,那麼提交新增分類的時候版塊也會新增 BoardCategory dbcat = new BoardCategory() { CategoryName = "Database" }; Board oracle = new Board() { BoardName = "Oracle", Category = dbcat }; bbs.Categories.InsertOnSubmit(dbcat); bbs.SubmitChanges();
關係實體結合DataLoadOptions使用,查詢句法生成的sql會得到優化,從而提高查詢效能:
DataLoadOptions options = new DataLoadOptions(); options.LoadWith<BoardCategory>(c => c.Boards); bbs.LoadOptions = options; Response.Write("-------------查詢版塊大於2個的分類-------------<br/>"); var query2 = from c in bbs.Categories where c.Boards.Count > 2 select c; foreach (BoardCategory c in query2) { Response.Write(c.CategoryID + " " + c.CategoryName + " " + c.Boards.Count + "<br/>"); }