发布时间:2014-11-11 08:18:31来源:阅读(1071)
实体间的关系,简单来说无非就是一对一、一对多、多对多,根据方向性来说又分为双向和单向。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: }测试结果:
生成的关联表如下图所示:
关键字:
上一篇: Linq中Group和Sum的应用
下一篇: 分享一个ReSharper8.x的注册码
2130
1176
1935
1763
2046
1764
1175
1774
1808
1822
10241
6279
5820
5393
4890
4589
3804
3627
3627
3543