您的位置:首页 > 其它

【配置关系】—Entity Framework实例详解-超详细

2016-07-18 00:00 375 查看
摘要: 【配置关系】—Entity Framework实例详解-超详细

【配置关系】—Entity Framework实例详解

实体间的关系,简单来说无非就是一对一、一对多、多对多,根据方向性来说又分为双向和单向。Code First在实体关系上有以下约定:

1. 两个实体,如果一个实体包含一个引用属性,另一个实体包含一个集合属性,Code First默认约定它们为一对多关系。
2. 两个实体,如果只有一个实体包含一个导航属性或一个集合属性,Code First也默认约定它们是一对多关系。
3. 两个实体分别包含一个集合属性,Code First默认约定它们为多对多关系。
4. 两个实体分别包含一个引用属性,Code First默认约定它们为一对一关系。
5. 在一对一关系情况下,需要提供给Code First额外的信息,以确定它们的主从关系。
6. 在实体中定义一个外键属性,Code First使用属性是否为空来确定关系是必须还是可选。

一、一对一

在Code First中,一对一关系总是需要配置,因为两个实体都包含有一个引用属性,无法确定它们的主从关系。

配置一对一关系常用的方法:

HasRequired ,HasOptional ,WithOptional ,WithRequiredPrincipal,WithRequiredDependent

下面是用到的类:

1:      public class Person

2:      {

3:          public int PersonId { get; set; }

4:          public int SocialSecurityNumber { get; set; }

5:          public string FirstName { get; set; }

6:          public string LastName { get; set; }

7:          public byte[] RowVersion { get; set; }

8:          public PersonPhoto Photo { get; set; }

9:      }

10:

11:      public class PersonPhoto

12:      {

13:          public int PersonId { get; set; }

14:          public byte[] Photo { get; set; }

15:          public string Caption { get; set; }

16:          public Person PhotoOf { get; set; }

17:      }

因为Photo是具体人的,所以PersonPhoto使用PersonId作为主键。

下面是一对一关系配置的几种情况:

1.PersonPhoto必须属于一个Person,但是Person不一定有PersonPhoto,这种关系是1:0..1,此种情况下Person是一定存在的,所以它是主从关系主的一方。

1:  HasRequired(t => t.PhotoOf).WithOptional(t => t.Photo);



1:  HasOptional(t => t.Photo).WithRequired(t => t.PhotoOf);

2.PersonPhoto必须属于一个Person,Person也必须有PersonPhoto,这种关系式1:1,此种情况下,两个都一定存在,要确定主从关系,需要使用WithRequiredPrincipal或WithRequiredDependent。

1:  HasRequired(t => t.PhotoOf).WithRequiredDependent(t => t.Photo);



1:  HasRequired(t => t.Photo).WithRequiredPrincipal(t => t.PhotoOf);

上述两种情况都是真实存在的,不真实存在的就不说了。

下面配置一对一关系贴出Demo:

1: public class Person

2: {

3:     public int PersonId { get; set; }

4:     public int SocialSecurityNumber { get; set; }

5:     public string FirstName { get; set; }

6:     public string LastName { get; set; }

7:     public byte[] RowVersion { get; set; }

8:     public PersonPhoto Photo { get; set; }

9: }

10:

11: public class PersonPhoto

12: {

13:     public int PersonId { get; set; }

14:     public byte[] Photo { get; set; }

15:     public string Caption { get; set; }

16:     public Person PhotoOf { get; set; }

17: }

18:

19: //配置Person

20: public class PersonConfiguration : EntityTypeConfiguration<Person>

21: {

22:     public PersonConfiguration()

23:     {

24:         //主键

25:         HasKey(t => t.PersonId);

26:         //并发检查

27:         Property(t => t.SocialSecurityNumber).HasDatabaseGeneratedOption(DatabaseGeneratedOption.None).IsConcurrencyToken();

28:         //长度50 不为空

29:         Property(t => t.FirstName).IsRequired().HasMaxLength(50);

30:         //长度50 不为空

31:         Property(t => t.LastName).IsRequired().HasMaxLength(50);

32:         //并发检查

33:         Property(t => t.RowVersion).IsRowVersion();

34:         //HasRequired(t => t.Photo).WithRequiredPrincipal(t => t.PhotoOf);

35:         //HasOptional(t => t.Photo).WithRequired(t => t.PhotoOf);

36:     }

37: }

38:

39: //配置PersonPhoto

40: public class PersonPhotoConfiguration : EntityTypeConfiguration<PersonPhoto>

41: {

42:     public PersonPhotoConfiguration()

43:     {

44:         //主键

45:         HasKey(t => t.PersonId);

46:         //长度50

47:         Property(t => t.Caption).HasMaxLength(50);

48:         //必须从属于Person

49:         HasRequired(t => t.PhotoOf).WithRequiredDependent(t => t.Photo);

50:     }

51: }

52:

53: public class BreakAwayContext : DbContext

54: {

55:     public DbSet<Person> People { get; set; }

56:     public DbSet<PersonPhoto> Photos { get; set; }

57:

58:     protected override void OnModelCreating(DbModelBuilder modelBuilder)

59:     {

60:         modelBuilder.Configurations.Add(new PersonConfiguration());

61:         modelBuilder.Configurations.Add(new PersonPhotoConfiguration());

62:         base.OnModelCreating(modelBuilder);

63:     }

64: }

65:

66: public class Initializer : DropCreateDatabaseAlways<BreakAwayContext>

67: {

68:     public Initializer()

69:     {

70:     }

71:

72:     //创建数据库时 Seed数据

73:     protected override void Seed(BreakAwayContext context)

74:     {

75:         context.People.Add(new Person()

76:         {

77:             FirstName = "E",

78:             LastName = "F",

79:             SocialSecurityNumber = 123456,

80:             Photo = new PersonPhoto()

81:             {

82:                 Caption = "这是照片",

83:                 Photo = new byte[] { }

84:             }

85:         });

86:         context.SaveChanges();

87:     }

88: }

测试程序

1: [TestClass]

2: public class UnitTest1

3: {

4:     [TestMethod]

5:     public void ShouldReturnAPersonWithPhoto()

6:     {

7:         //Arrange

8:         var init = new Initializer();

9:         Person person;

10:      using (var context = new BreakAwayContext())

11:         {

12:             init.InitializeDatabase(context);

13:             //Act

14:             person = context.People.Include(t => t.Photo).FirstOrDefault();

15:         }

16:         //Assert

17:         Assert.IsNotNull(person);

18:        Assert.IsNotNull(person.Photo);

19:     }

20: }

测试结果:





二、一对多

下面是用到的类:

1:      public class Blog

2:      {

3:          public Blog()

4:          {

5:              Posts = new List<Post>();

6:          }

7:

8:          public int Id { get; set; }

9:          public DateTime Creationdate { get; set; }

10:       public string ShortDescription { get; set; }

11:          public string Title { get; set; }

12:          public List<Post> Posts { get; set; }

13:      }

14:

15:      public class Post

16:      {

17:          public int Id { get; set; }

18:         public string Title { get; set; }

19:          public string Content { get; set; }

20:          public DateTime PostedDate { get; set; }

21:

22:          public Nullable<int> BlogId { get; set; }

23:          public virtual Blog Blog { get; set; }

24:

25:          public int PrimaryAuthorId { get; set; }

26:          public virtual Author PrimaryAuthor { get; set; }

27:          public Nullable<int> SecondaryAuthorId { get; set; }

28:          public virtual Author SecondaryAuthor { get; set; }

29:      }

30:

31:      public class Author

32:      {

33:          public int Id { get; set; }

34:          public string Name { get; set; }

35:          public string Email { get; set; }

36:          //个人简历

37:          public string Bio { get; set; }

38:  

39:          public List<Post> PrimaryAuthorFor { get; set; }

40:          public List<Post> SecondaryAuthorFor { get; set; }

41:      }

配置一对多关系常用的方法有:

HasOptional ,HasRequired ,HasMany

Has方法后面往往跟着With方法

WithOptional ,WithRequired ,WithMany

下面配置一对多的几种情况:

1.Post一定归属于一个Blog,这种关系是1:n。

1:  HasMany(x => x.Posts).WithRequired(x =>x.Blog)



1:  HasRequired(x => x.Blog).WithMany(x => x.Posts)

2.Post可以单独存在,不用归属于Blog,这种关系是0..1:n。

1:  HasMany(x => x.Posts).WithOptional(x => x.Blog)



1:  HasOptional(x => x.Blog).WithMany(x => x.Posts)

设置外键

外键的默认约定:

[Target Type Key Name], [Target Type Name] + [Target Type Key Name], or [Navigation
Property Name] + [Target Type Key Name]

本例中,匹配的是[Target Type Name] + [Target Type Key Name],目标类型是Blog,目标类型主键是Id,加起来就是BlogId。下面使用Fluent API显示设置外键:

1:  HasMany(x => x.Posts).WithOptional(x => x.Blog).HasForeignKey(x => x.BlogId)

设置级联删除

1:  HasMany(x => x.Posts).WithOptional(x => x.Blog).HasForeignKey(x => x.BlogId).WillCascadeOnDelete();

反转属性

在Post实体中,有两个属性:PrimaryAuthor和SecondaryAuthor,第一作者和第二作者。在Author中有两个集合属性,Code First默认不能确定哪个集合属性和Post中的导航属性相匹配。使用Fluent API配置反转属性,如下:

1:  HasRequired(t => t.PrimaryAuthor).WithMany(t => t.PrimaryAuthorFor);

2:  HasOptional(t => t.SecondaryAuthor).WithMany(t => t.SecondaryAuthorFor);

下面是配置一对多关系的Demo:

1: public class Blog

2: {

3:     public Blog()

4:     {

5:         Posts = new List<Post>();

6:     }

7:

8:     public int Id { get; set; }

9:     public DateTime Creationdate { get; set; }

10:  public string ShortDescription { get; set; }

11:     public string Title { get; set; }

12:     public List<Post> Posts { get; set; }

13: }

14:

15: public class Post

16: {

17:     public int Id { get; set; }

18:    public string Title { get; set; }

19:     public string Content { get; set; }

20:     public DateTime PostedDate { get; set; }

21:

22:     //Post可以不归属到Blog独立存在,注意这里的外键属性要设置为可空的

23:     public Nullable<int> BlogId { get; set; }

24:  public virtual Blog Blog { get; set; }

25:

26:     public int PrimaryAuthorId { get; set; }

27:     public virtual Author PrimaryAuthor { get; set; }

28:     public Nullable<int> SecondaryAuthorId { get; set; }

29:     public virtual Author SecondaryAuthor { get; set; }

30: }

31:

32: public class Author

33: {

34:     public int Id { get; set; }

35:     public string Name { get; set; }

36:     public string Email { get; set; }

37:     //个人简历

38:    public string Bio { get; set; }

39:

40:     public List<Post> PrimaryAuthorFor { get; set; }

41:     public List<Post> SecondaryAuthorFor { get; set; }

42: }

43:

44: public class BlogConfiguratioin : EntityTypeConfiguration<Blog>

45: {

46:     public BlogConfiguratioin()

47:     {

48:         ToTable("Blogs");

49:         HasKey(t => t.Id);

50:         Property(t => t.Id).HasDatabaseGeneratedOption(DatabaseGeneratedOption.Identity);

51:         Property(t => t.Title).IsRequired().HasMaxLength(250);

52:        Property(t => t.Creationdate).HasColumnName("CreationDate").IsRequired();

53:         Property(t => t.ShortDescription).HasColumnType("Text").IsMaxLength().IsOptional().HasColumnName("Description");

54:         //配置Blog和Post的一对多关系,Blog对Post是可选的,外键BlogId,并设置为级联删除

55:         HasMany(t => t.Posts).WithOptional(t => t.Blog).HasForeignKey(t => t.BlogId).WillCascadeOnDelete();

56:     }

57:}

58:

59: public class PostConfiguration : EntityTypeConfiguration<Post>

60: {

61:     public PostConfiguration()

62:     {

63:         ToTable("Posts");

64:         HasKey(t => t.Id);

65:        Property(t => t.Id).HasColumnName("PostId").HasDatabaseGeneratedOption(DatabaseGeneratedOption.Identity);

66:         Property(t => t.Content).HasColumnName("Body").IsMaxLength();

67:         Property(t => t.PostedDate).HasColumnName("PostedDate");

68:         Property(t => t.Title).HasColumnName("Title").IsMaxLength();

69:         //配置反转属性,集合属性PrimaryAuthorFor匹配PrimaryAuthor

70:         HasRequired(t => t.PrimaryAuthor).WithMany(t => t.PrimaryAuthorFor);

71:        //配置反转属性,集合属性SecondaryAuthorFor匹配SecondaryAuthor

72:         HasOptional(t => t.SecondaryAuthor).WithMany(t => t.SecondaryAuthorFor);

73:     }

74: }

75:

76: public class AuthorConfiguration : EntityTypeConfiguration<Author>

77: {

78:     public AuthorConfiguration()

79:     {

80:         ToTable("Authors");

81:         HasKey(t => t.Id).Property(t => t.Id).HasColumnName("AuthorId").HasDatabaseGeneratedOption(DatabaseGeneratedOption.Identity);

82:         Property(t => t.Name).IsRequired().HasMaxLength(50);

83:         Property(t => t.Email).IsRequired().HasMaxLength(50);

84:         Property(t => t.Bio).HasMaxLength(1000);

85:     }

86: }

87:

88: public class BreakAwayContext : DbContext

89: {

90:     public DbSet<Blog> Blogs { get; set; }

91:     public DbSet<Post> Posts { get; set; }

92:     public DbSet<Author> Authors { get; set; }

93:

94:     protected override void OnModelCreating(DbModelBuilder modelBuilder)

95:     {

96:         modelBuilder.Configurations.Add(new BlogConfiguratioin());

97:         modelBuilder.Configurations.Add(new PostConfiguration());

98:         modelBuilder.Configurations.Add(new AuthorConfiguration());

99:         base.OnModelCreating(modelBuilder);

100:     }

101: }

102:

103: public class Initializer : DropCreateDatabaseAlways<BreakAwayContext>

104: {

105:     public Initializer()

106:     {

107:     }

108:

109:     protected override void Seed(BreakAwayContext context)

110:     {

111:         var primaryAuthor = new Author()

112:         {

113:             Name = "张三",

114:             Email = "zhangsan@126.com",

115:             Bio = "张三的简历"

116:         };

117:         var secondaryAuthor = new Author()

118:         {

119:             Name = "李四",

120:             Email = "lisi@126.com",

121:             Bio = "李四的简历"

122:         };

123:         var blog = new Blog()

124:         {

125:             Title = "EF",

126:             ShortDescription = "关于EF的博客",

127:             Creationdate = DateTime.Now

128:         };

129:         blog.Posts.Add(new Post()

130:         {

131:             Title = "配置关系",

132:             PostedDate = DateTime.Now,

133:             Content = "这是Post的内容",

134:             PrimaryAuthor = primaryAuthor,

135:             SecondaryAuthor = secondaryAuthor

136:         });

137:         context.Blogs.Add(blog);

138:         context.SaveChanges();

139:     }

140: }

测试程序:

1: [TestClass]

2: public class OneToManyTest

3: {

4:     [TestMethod]

5:     public void ShouldReturnBlogWithPosts()

6:     {

7:      //Arrage

8:         Database.SetInitializer(new Initializer());

9:         var context = new BreakAwayContext();

10:      //Act

11:         var blog = context.Blogs.Include(t => t.Posts).FirstOrDefault();

12:         //Assert

13:         Assert.IsNotNull(blog);

14:      Assert.IsNotNull(blog.Posts);

15:         Assert.IsNotNull(blog.Posts.FirstOrDefault().PrimaryAuthor);

16:     }

17: }

测试结果:





三、多对多

下面是配置多对多关系用到的类,跟一对多差不多,只不过Post和Author的关系变成多对多的了。

1:      public class Post

2:      {

3:          public int Id { get; set; }

4:          public string Title { get; set; }

5:          public string Content { get; set; }

6:          public DateTime PostedDate { get; set; }

7:

8:          public virtual List<Author> Authors { get; set; }

9:      }

10:

11:      public class Author

12:      {

13:          public int Id { get; set; }

14:       public string Name { get; set; }

15:          public string Email { get; set; }

16:          //个人简历

17:          public string Bio { get; set; }

18:  

19:          public virtual List<Post> Posts { get; set; }

20:      }

一篇文章有多个作者,一个作者著有多篇文章。

配置多对多关系使用HasMany和WithMany方法,可以使用Map配置生成关联表的名字。

下面是配置多对多关系的Demo:

1: public class Post

2: {

3:     public Post()

4:     {

5:         Authors = new List<Author>();

6:     }

7:

8:     public int Id { get; set; }

9:     public string Title { get; set; }

10:  public string Content { get; set; }

11:     public DateTime PostedDate { get; set; }

12:

13:     public virtual List<Author> Authors { get; set; }

14:}

15:

16: public class Author

17: {

18:    public Author()

19:     {

20:         Posts = new List<Post>();

21:  }

22:

23:     public int Id { get; set; }

24:  public string Name { get; set; }

25:    public string Email { get; set; }

26:     //个人简历

27:     public string Bio { get; set; }

28:

29:     public virtual List<Post> Posts { get; set; }

30: }

31:

32: public class PostConfiguration : EntityTypeConfiguration<Post>

33: {

34:     public PostConfiguration()

35:     {

36:         ToTable("Posts");

37:         HasKey(t => t.Id);

38:        Property(t => t.Id).HasColumnName("PostId").HasDatabaseGeneratedOption(DatabaseGeneratedOption.Identity);

39:        Property(t => t.Content).HasColumnName("Body").IsMaxLength();

40:         Property(t => t.PostedDate).HasColumnName("PostedDate");

41:         Property(t => t.Title).HasColumnName("Title").IsMaxLength();

42:         //配置多对多关系 ToTable 配置生成的关联表名字 MapLeftKey默认表示调用HasMany的实体的主键

43:        //本例中如果不使用MapLeftKey默认生成Post_Id

44:         HasMany(t => t.Authors).WithMany(t => t.Posts).Map(m =>

45:             {

46:                 m.ToTable("PostAuthor");

47:                 m.MapLeftKey("PostId");

48:                 m.MapRightKey("AuthorId");

49:             });

50:     }

51: }

52:

53: public class AuthorConfiguration : EntityTypeConfiguration<Author>

54: {

55:     public AuthorConfiguration()

56:     {

57:        ToTable("Authors");

58:        HasKey(t => t.Id);

59:         Property(t => t.Id).HasColumnName("AuthorId").HasDatabaseGeneratedOption(DatabaseGeneratedOption.Identity);

60:         Property(t => t.Bio).HasColumnType("Text").IsMaxLength();

61:         Property(t => t.Email).HasMaxLength(100).IsRequired();

62:         Property(t => t.Name).HasMaxLength(100).IsRequired();

63:     }

64: }

65:

66: public class TestContext : DbContext

67: {

68:     public DbSet<Post> Posts { get; set; }

69:     public DbSet<Author> Authors { get; set; }

70:

71:    protected override void OnModelCreating(DbModelBuilder modelBuilder)

72:     {

73:         modelBuilder.Configurations.Add(new PostConfiguration());

74:         modelBuilder.Configurations.Add(new AuthorConfiguration());

75:        base.OnModelCreating(modelBuilder);

76:     }

77: }

78:

79: public class Initializer : DropCreateDatabaseAlways<TestContext>

80: {

81:     protected override void Seed(TestContext context)

82:     {

83:         var post = new Post()

84:         {

85:             Title = "Post1",

86:             Content = "Content1",

87:            PostedDate = DateTime.Now

88:         };

89:         var author = new Author()

90:         {

91:             Name = "张三",

92:             Email = "zhangsan@126.com",

93:            Bio = "张三的简历"

94:         };

95:         var author1 = new Author()

96:         {

97:             Name = "李四",

98:             Email = "lisi@126.com",

99:             Bio = "李四的简历"

100:         };

101:         var author2 = new Author()

102:        {

103:             Name = "王五",

104:             Email = "wangwu@126.com",

105:             Bio = "王五的简历"

106:         };

107:         post.Authors.Add(author);

108:        post.Authors.Add(author1);

109:         context.Posts.Add(post);

110:         post = new Post()

111:         {

112:             Title = "Post2",

113:             Content = "Content2",

114:             PostedDate = DateTime.Now

115:         };

116:         post.Authors.Add(author);

117:         post.Authors.Add(author2);

118:         context.Posts.Add(post);

119:         context.SaveChanges();

120:     }

121: }

测试程序:

1: [TestClass]

2: public class ManyToManyTest

3: {

4:     [TestMethod]

5:     public void ShouldReturnPostWithAuthors()

6:     {

7:      //Arrage

8:         var init = new Initializer();

9:         var context = new ManyToMany.TestContext();

10:      init.InitializeDatabase(context);

11:         //Act

12:        var post = context.Posts.Include(t => t.Authors).FirstOrDefault();

13:         //Assert

14:      Assert.IsNotNull(post);

15:        Assert.AreEqual(2, post.Authors.Count);

16:         Assert.AreEqual("李四", post.Authors[1].Name);

17:     }

18:}

测试结果:





现在关联表中只有两个字段,如下图所示:





如果再加个字段,比如DateAdd,这就需要给关联表定义一个实体。

1:      public class PostAuthor

2:      {

3:          public int PostId { get; set; }

4:          public int AuthorId { get; set; }

5:

6:          public Post Post { get; set; }

7:       public Author Author { get; set; }

8:

9:          public DateTime DateAdd { get; set; }

10:   }

另外需要在Post和Author实体中加入一个集合属性:

1:          public virtual List<PostAuthor> PostAuthors { get; set; }

另外还需要配置PostAuthor实体,具体代码如下面的Demo所示:

1: public class Post

2: {

3:     public Post()

4:     {

5:      PostAuthors = new List<PostAuthor>();

6:     }

7:

8:     public int Id { get; set; }

9:     public string Title { get; set; }

10:  public string Content { get; set; }

11:     public DateTime PostedDate { get; set; }

12:

13:     //public virtual List<Author> Authors { get; set; }

14:  public virtual List<PostAuthor> PostAuthors { get; set; }

15:}

16:

17: public class Author

18:{

19:     public Author()

20:     {

21:      PostAuthors = new List<PostAuthor>();

22:    }

23:

24:  public int Id { get; set; }

25:    public string Name { get; set; }

26:     public string Email { get; set; }

27:     //个人简历

28:    public string Bio { get; set; }

29:

30:  //public virtual List<Post> Posts { get; set; }

31:    public virtual List<PostAuthor> PostAuthors { get; set; }

32: }

33:

34: //关联表的实体

35: public class PostAuthor

36: {

37:     public int PostId { get; set; }

38:    public int AuthorId { get; set; }

39:

40:     public Post Post { get; set; }

41:     public Author Author { get; set; }

42:

43:    public DateTime? DateAdd { get; set; }

44: }

45:

46: public class PostConfiguration : EntityTypeConfiguration<Post>

47: {

48:     public PostConfiguration()

49:     {

50:         ToTable("Posts");

51:         HasKey(t => t.Id);

52:        Property(t => t.Id).HasColumnName("PostId").HasDatabaseGeneratedOption(DatabaseGeneratedOption.Identity);

53:         Property(t => t.Content).HasColumnName("Body").IsMaxLength();

54:         Property(t => t.PostedDate).HasColumnName("PostedDate");

55:         Property(t => t.Title).HasColumnName("Title").IsMaxLength();

56:     }

57:}

58:

59: public class AuthorConfiguration : EntityTypeConfiguration<Author>

60: {

61:     public AuthorConfiguration()

62:     {

63:         ToTable("Authors");

64:         HasKey(t => t.Id);

65:        Property(t => t.Id).HasColumnName("AuthorId").HasDatabaseGeneratedOption(DatabaseGeneratedOption.Identity);

66:         Property(t => t.Bio).HasColumnType("Text").IsMaxLength();

67:         Property(t => t.Email).HasMaxLength(100).IsRequired();

68:         Property(t => t.Name).HasMaxLength(100).IsRequired();

69:     }

70:}

71:

72: //配置关联表实体

73: public class PostAuthorConfiguration : EntityTypeConfiguration<PostAuthor>

74: {

75:    public PostAuthorConfiguration()

76:     {

77:         ToTable("PostAuthors");

78:        //配置组合主键

79:         HasKey(t => new { t.PostId, t.AuthorId });

80:         Property(t => t.PostId).HasColumnOrder(0);

81:         Property(t => t.AuthorId).HasColumnOrder(1);

82:         //这里是配置一对多关系

83:         HasRequired(t => t.Post).WithMany(t => t.PostAuthors).HasForeignKey(t => t.PostId);

84:         HasRequired(t => t.Author).WithMany(t => t.PostAuthors).HasForeignKey(t => t.AuthorId);

85:     }

86: }

87:

88: public class TestContext : DbContext

89: {

90:     public DbSet<Post> Posts { get; set; }

91:     public DbSet<Author> Authors { get; set; }

92:     public DbSet<PostAuthor> PostAuthors { get; set; }

93:

94:     protected override void OnModelCreating(DbModelBuilder modelBuilder)

95:     {

96:         modelBuilder.Configurations.Add(new PostConfiguration());

97:         modelBuilder.Configurations.Add(new AuthorConfiguration());

98:         modelBuilder.Configurations.Add(new PostAuthorConfiguration());

99:         base.OnModelCreating(modelBuilder);

100:     }

101: }

102:

103: public class Initializer : DropCreateDatabaseAlways<TestContext>

104: {

105:     protected override void Seed(TestContext context)

106:     {

107:         var post = new Post()

108:        {

109:             Title = "Post1",

110:             Content = "Content1",

111:             PostedDate = DateTime.Now

112:         };

113:         post = context.Posts.Add(post);

114:         var author = new Author()

115:         {

116:             Name = "张三",

117:             Email = "zhangsan@126.com",

118:             Bio = "张三的简历"

119:         };

120:         var author1 = new Author()

121:         {

122:             Name = "李四",

123:             Email = "lisi@126.com",

124:             Bio = "李四的简历"

125:         };

126:         author = context.Authors.Add(author);

127:         author1 = context.Authors.Add(author1);

128:         context.SaveChanges();

129:         PostAuthor pa1 = new PostAuthor()

130:         {

131:             PostId = post.Id,

132:             AuthorId = author.Id,

133:             DateAdd = DateTime.Now

134:         };

135:         PostAuthor pa2 = new PostAuthor()

136:         {

137:             PostId = post.Id,

138:             AuthorId = author1.Id,

139:             DateAdd = DateTime.Now

140:         };

141:         context.PostAuthors.Add(pa1);

142:         context.PostAuthors.Add(pa2);

143:         context.SaveChanges();

144:     }

145: }

测试程序:

1: [TestMethod]

2: public void ShouldReturnAuthorsWithDateAdd()

3: {

4:     //Arrage

5:  var init = new Initializer();

6:     var context = new ManyToMany.TestContext();

7:  init.InitializeDatabase(context);

8:  //Act

9:     var post = context.Posts.Include(t => t.PostAuthors).FirstOrDefault();

10:  //Assert

11:     Assert.IsNotNull(post);

12:    Assert.AreEqual(2, post.PostAuthors.Count);

13:     Assert.IsNotNull(post.PostAuthors[0].DateAdd);

14:}

测试结果:





生成的关联表如下图所示:





四、结束语

点击查看《Entity Framework实例详解》系列的其他文章。

如果遇到问题,可以访问Entity Framework社区,网址是www.ef-community.comwww.ef-community.cn
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: