1. 程式人生 > >Linq to Sql學習總結6

Linq to Sql學習總結6

單表繼承

繼承實體定義:

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