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


    转:http://www.58os.com/Article/HTML/CNTopic-561.html

    实体间的关系,简单来说无非就是一对一、一对多、多对多,根据方向性来说又分为双向和单向。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: }

    测试结果:

    QQ截图20121110174644

    二、一对多

    下面是用到的类:

       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: }

    测试结果:

    QQ截图20121110235536

    三、多对多

    下面是配置多对多关系用到的类,跟一对多差不多,只不过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: }

    测试结果:

    QQ截图20121112201038

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

    QQ截图20121112202337

    如果再加个字段,比如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: }

    测试结果:

    QQ截图20121112211304

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

    QQ截图20121112211859

    四、结束语

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

    如果遇到问题,可以加群:276721846  进行讨论。

    另外欢迎大家访问Entity Framework社区,网址是www.ef-community.comwww.ef-community.cn

    var isLogined = false; var cb_blogId = 90375; var cb_entryId = 2767089; var cb_blogApp = currentBlogApp; var cb_blogUserGuid = "90331348-10a5-de11-ba8f-001cf0cd104b"; var cb_entryCreatedDate = '2012/11/12 21:53:00'; var enableGoogleAd = true; var googletag = googletag || {}; googletag.cmd = googletag.cmd || [];

    原文地址:http://www.cnblogs.com/nianming/archive/2012/11/12/2767089.html
  • 相关阅读:
    js动态生成表格
    My97DatePicker显示时间控件的使用方法
    理解Action,Service和Dao功能(转)
    Myeclipseforspring 10破解
    MySQL常用命令(参考资料,部分改动)
    Struts2---Result(传统Web应用程序与Ajax应用程序的异同)
    正则表达式笔记
    day5.字符串内置函数
    day5.数据类型简介
    day4.变量+程序交互
  • 原文地址:https://www.cnblogs.com/jackljf/p/3589273.html
Copyright © 2020-2023  润新知