<output id="qn6qe"></output>

    1. <output id="qn6qe"><tt id="qn6qe"></tt></output>
    2. <strike id="qn6qe"></strike>

      亚洲 日本 欧洲 欧美 视频,日韩中文字幕有码av,一本一道av中文字幕无码,国产线播放免费人成视频播放,人妻少妇偷人无码视频,日夜啪啪一区二区三区,国产尤物精品自在拍视频首页,久热这里只有精品12

      Entity Framework多對多關(guān)系實(shí)踐(many-to-many)

        Entity Framework中有三種關(guān)系,一對一(one-to-one),一對多(one-to-many),多對多(many-to-many),前兩種就不說了,園子里這方面的文章很多(dudu的:Entity Framework 實(shí)踐系列,楊延成的:EF框架step by step郝冠軍的:Entity Framework系列文章),看過之后簡單的使用基本沒什么問題,這里要說的是第三種:多對多(many-to-many)。

        這里單獨(dú)把多對多關(guān)系拿出來說,不是因?yàn)樯鲜鱿盗形恼轮袥]有,只不過需求不同,我的需求用上述系列文章中的方法實(shí)現(xiàn)不了。這里先用一個例子說一下我的需求吧:我要用EF處理 question(QID,Title)與tag(TID,TagName)之間的關(guān)系,這是一個多對多關(guān)系(一個問題有多個標(biāo)簽,一個標(biāo)簽有多個問題),因此在數(shù)據(jù)庫中除了question與tag表外應(yīng)該還有他們的關(guān)系表question_tag表,問題就出在question_tag表上。

        如果我的question_tag表僅僅只有兩個字段QID與TID,那么用上面系列文章中提到的方法就可以實(shí)現(xiàn),關(guān)鍵代碼如下:

       1     [Table("Question")]
      2 public class Question
      3 {
      4 [Key]
      5 [DatabaseGenerated(DatabaseGeneratedOption.Identity)]
      6 public int QID { get; set; }
      7 public string Title { get; set; }
      8 public virtual ICollection<Tag> Tags { get; set; }
      9 }
      10
      11 [Table("Tag")]
      12 public class Tag
      13 {
      14 [Key]
      15 [DatabaseGenerated(DatabaseGeneratedOption.Identity)]
      16 public int TID { get; set; }
      17 public string TagName { get; set; }
      18 public virtual ICollection<Question> Questions { get; set; }
      19 }
      20
      21 public class BlogDbContext : DbContext
      22 {
      23 protected override void OnModelCreating(DbModelBuilder modelBuilder)
      24 {
      25 modelBuilder.Entity<Question>()
      26 .HasMany(q => q.Tags)
      27 .WithMany(t => t.Questions)
      28 .Map
      29 (
      30 m =>
      31 {
      32 m.MapLeftKey("QID");
      33 m.MapRightKey("TID");
      34 m.ToTable("Question_Tag");
      35 }
      36 );
      37 base.OnModelCreating(modelBuilder);
      38 }
      39 public IDbSet<Question> Questions { get; set; }
      40 public IDbSet<Tag> Tags { get; set; }
      41 }

        現(xiàn)在的問題是我的question_tag表為了業(yè)務(wù)需求不僅僅只有這兩個字段(這個需求應(yīng)該很常見,本例中增加一個時間字段DateAdded作為示例),因此用上面的方案就不行了。那么要怎么處理呢,找了好多資料都不行,沒辦法只好自己動手,豐衣足食。

        首先想到的是,既然question_tag表中還有其它字段,那么這個實(shí)體肯定要表現(xiàn)出來。然后想到的是,按原來的方法question跟tag是直接產(chǎn)生聯(lián)系的,EF根據(jù)question和tag的定義可以判斷出是多對多關(guān)系,但現(xiàn)在加了一個關(guān)系實(shí)體question_tag,question跟question_tag的關(guān)系是一對多,tag跟question_tag的關(guān)系也是一對多,因此可以通過question_tag來聯(lián)接question跟tag(數(shù)據(jù)庫中這個表的存在本來就是這個意思),也就是說question跟tag不直接產(chǎn)生聯(lián)系。有了上面的想法,經(jīng)過多次嘗試后,我把實(shí)體間的關(guān)系修改為如下形式:

       1     [Table("Question")]
      2 public class Question
      3 {
      4 [Key]
      5 [DatabaseGenerated(DatabaseGeneratedOption.Identity)]
      6 public int QID { get; set; }
      7 public string Title { get; set; }
      8 public virtual ICollection<QuestionTag> QuestionTags { get; set; }
      9 }
      10
      11 [Table("Tag")]
      12 public class Tag
      13 {
      14 [Key]
      15 [DatabaseGenerated(DatabaseGeneratedOption.Identity)]
      16 public int TID { get;set;}
      17 public string TagName { get; set; }
      18 public virtual ICollection<QuestionTag> QuestionTags { get; set; }
      19 }
      20
      21 [Table("QuestionTag")]
      22 public class QuestionTag
      23 {
      24 [Key]
      25 [Column(Order=0)]
      26 [ForeignKey("Question")]
      27 public int QID { get; set; }
      28
      29 [Key]
      30 [Column(Order = 1)]
      31 [ForeignKey("Tag")]
      32 public int TID { get; set; }
      33
      34 public DateTime DateAdded { get; set; }
      35
      36 public virtual Question Question { get; set; }
      37
      38 public virtual Tag Tag { get; set; }
      39 }

        有了上面的定義后,DbContext的定義就很簡單了,不需要重寫OnModelCreating:

      1     public class BlogDbContext : DbContext
      2 {
      3 public IDbSet<Question> Questions { get; set; }
      4 public IDbSet<Tag> Tags { get; set; }
      5 public IDbSet<QuestionTag> QuestionTags { get; set; }
      6 }

      好了,下面開始寫測試代碼,就是增刪改查操作:

       

        1     public class EFTest
      2 {
      3 public void Insert()
      4 {
      5 using (var db = new BlogDbContext())
      6 {
      7 //添加一個question,兩個tag
      8 var question = new Question() { Title = "abc" };
      9 var tagA = new Tag() { TagName = "a" };
      10 var tagB = new Tag() { TagName = "b" };
      11 var qes = db.Questions.Add(question);
      12 var tA = db.Tags.Add(tagA);
      13 var tB = db.Tags.Add(tagB);
      14 db.SaveChanges();
      15
      16 //添加question_tag
      17 var questiontaga = new QuestionTag() { QID = qes.QID, TID = tA.TID, DateAdded = DateTime.Now };
      18 var questiontagb = new QuestionTag() { QID = qes.QID, TID = tB.TID, DateAdded = DateTime.Now };
      19 var qtA = db.QuestionTags.Add(questiontaga);
      20 var qtB = db.QuestionTags.Add(questiontagb);
      21 db.SaveChanges();
      22 Console.WriteLine("Insert Success");
      23
      24 //顯示數(shù)據(jù)
      25 Show();
      26 }
      27 }
      28
      29 public void Delete()
      30 {
      31 using (var db = new BlogDbContext())
      32 {
      33 var qes = db.Questions.SingleOrDefault(q => q.QID == 1);
      34 if (qes != null)
      35 {
      36 db.Questions.Remove(qes);
      37 db.SaveChanges();
      38 Console.WriteLine("Delete Success");
      39
      40 Show();
      41 }
      42 }
      43 }
      44
      45 public void Update()
      46 {
      47 using (var db = new BlogDbContext())
      48 {
      49 var qes = db.Questions.SingleOrDefault(q => q.QID == 2);
      50 if (qes != null)
      51 {
      52 qes.Title = "update abc";
      53 db.SaveChanges();
      54 Console.WriteLine("Update Success");
      55
      56 Show();
      57 }
      58 }
      59 }
      60
      61 public void Select()
      62 {
      63 using (var db = new BlogDbContext())
      64 {
      65 var qes = db.Questions.SingleOrDefault(q => q.QID == 2);
      66 if (qes != null)
      67 {
      68 Console.WriteLine("Select Question:");
      69 Console.Write("QID:"+qes.QID + "\tTitle:" + qes.Title+"\tTag:");
      70 qes.QuestionTags.ForEach(t => Console.Write(t.Tag.TagName+"\t"));
      71 }
      72 Console.WriteLine("\nSelect Success");
      73 }
      74 }
      75
      76 public void Show()
      77 {
      78 using (var db = new BlogDbContext())
      79 {
      80 //顯示question
      81 var qes = db.Questions;
      82 if (qes != null)
      83 {
      84 Console.WriteLine("Question:");
      85 qes.ForEach(q =>
      86 {
      87 Console.Write("QID:"+q.QID+"\tTitle:"+q.Title+"\tTag:");
      88 q.QuestionTags.ForEach(t =>
      89 {
      90 Console.Write(t.Tag.TagName+"\t");
      91 });
      92 Console.WriteLine();
      93 });
      94 }
      95
      96 //顯示tag
      97 var tag = db.Tags;
      98 if (tag != null)
      99 {
      100 Console.WriteLine("Tag:");
      101 tag.ForEach(t =>
      102 {
      103 Console.Write("TID:" + t.TID + "\tTagName:" + t.TagName + "\tQuestion:");
      104 t.QuestionTags.ForEach(q =>
      105 {
      106 Console.Write(q.Question.Title + "\t");
      107 });
      108 Console.WriteLine();
      109 });
      110 }
      111
      112 Console.WriteLine();
      113 }
      114 }
      115 }

        很幸運(yùn)地通過了,運(yùn)行后數(shù)據(jù)庫中生成的表如下:

       

        要注意的是這里QID和TID不僅僅是PK,也是FK。

        程序的輸出如下:

        可以看到程序能很好地滿足我的需求。在上面的刪除代碼中刪除了QID為1的question后,數(shù)據(jù)庫中question_tag表中的數(shù)據(jù)如下:

        我們可以看到,question_tag表中QID為1的數(shù)據(jù)也同時刪除了,正是我們需要的結(jié)果。

      最后做個小結(jié)吧:

        一直以來都是看的多,寫的少,從老鳥那里吸收的多,貢獻(xiàn)的少,總怕自己寫的不好,以后爭取慢慢改變這種狀況,把自己學(xué)到的知識總結(jié)出來,爭取能給新手一些幫助吧。

        希望這篇文章對大家有所幫助,當(dāng)然了,限于水平歡迎大家拍磚,提出更好的解決方案。

      posted @ 2011-11-03 12:11  artwl  閱讀(12026)  評論(28)    收藏  舉報

      個人簡介

      var ME = {
      	"name": "土豆/Artwl",
      	"job": "coding",
      	"languages": [
      		"JS", "HTML",
                      "CSS", "jQuery"
      		"MVC",".NET",
      		"設(shè)計模式"
      	],
      	"hobby": [
      		"閱讀", "旅游",
      		"音樂", "電影"
      	]
      }
      
      TOP
      主站蜘蛛池模板: 天天干天天日| 国产mv在线天堂mv免费观看| 激情久久av一区二区三区| 欧美成人精品三级网站视频| 国产乱码日产乱码精品精| 潮喷失禁大喷水无码| 国产一区二区三区在线观看免费 | 奶头好大揉着好爽视频| 另类 专区 欧美 制服| 无码熟妇人妻av在线电影| 偷拍精品一区二区三区| 人妻系列中文字幕精品| 白丝乳交内射一二三区| 大地资源中文第三页| 国内熟妇与亚洲洲熟妇妇| 国产精品自拍中文字幕| 澄江县| 亚洲av第一区二区三区| 99久久精品费精品国产一区二 | 国产亚洲999精品AA片在线爽 | 亚洲精品久久麻豆蜜桃| 亚洲AV无码一二区三区在线播放| 国产黄色一区二区三区四区| gogogo高清在线播放免费| 欧美性猛交xxxx乱大交丰满| 亚洲激情在线一区二区三区| 成人影片一区免费观看| 婷婷综合亚洲| 人人妻人人狠人人爽天天综合网| 欧洲一区二区中文字幕| 国产性色的免费视频网站| 久久久久蜜桃精品成人片公司 | 色秀网在线观看视频免费| 国产在线播放专区av| 67194熟妇在线观看线路| 成在人线av无码免费看网站直播| 9丨精品国产高清自在线看| 午夜激情小视频一区二区| 日韩精品国产精品十八禁| 久久国产精品福利一区二区三区| 亚洲熟少妇一区二区三区|