zoukankan      html  css  js  c++  java
  • 7. EF Core 导航属性配置

    一、多导航属性配型

    在 Post 类中,可能需要跟踪是文章的创建者和最后编辑者,下面是 Post 类的两个新的导航属性。
    1、设置导航属性方式
    public class Post
    {
       public int PostId { get; set; }
       public string Title { get; set; }
       public string Content { get; set; }
       public User Author { get; set; }
       public User Contributor { get; set; }
    }
    
    public class User
    {
       public string UserId { get; set; }
       public string FirstName { get; set; }
       public string LastName { get; set; }
    
       [InverseProperty(nameof(Post.Author))] //设置反转导航属性
        public List<Post> AuthoredPosts { get; set; }
        [InverseProperty(nameof(Post.Contributor))] //设置反转导航属性
         public List<Post> ContributedToPosts { get; set; } 
    }

    在Post类设置反转导航属性也可以

    public class Post
    {
       public int PostId { get; set; }
       public string Title { get; set; }
       public string Content { get; set; }

    [InverseProperty(nameof(User.AuthoredPosts))]   
    public User Author { get; set; }
    [InverseProperty(nameof(User.ContributedToPosts))]   
    public User Contributor { get; set; } } public class User {   public string UserId { get; set; }   public string FirstName { get; set; }   public string LastName { get; set; }   public List<Post> AuthoredPosts { get; set; } public List<Post> ContributedToPosts { get; set; } }

     Post表会默认生成:“导航属性名Id” 的外键  AuthorId,ContributorId

    2.ForeignKeyAttribute方式设置
    public class Post
    {
        public int PostId { get; set; }
        public string Title { get; set; }
        public string Content { get; set; }
        public User Author { get; set; }
        public User Contributor { get; set; }
    }
    
    public class User
    {
        public string UserId { get; set; }
        public string FirstName { get; set; }
        public string LastName { get; set; }
    
        public User Author { get; set; }
        [ForeignKey("AuthorID")]
        public string ContributorID { get; set; }
        [ForeignKey("ContributorID")]
        public User Contributor { get; set; }
    }

    3.Fluent API方式

    modelBuilder.Entity<Post>().HasOne(p => p.Author).WithMany(u=>u.AuthoredPosts).HasForeignKey("AuthorId");
    modelBuilder.Entity<Post>().HasOne(p => p.Contributor).WithMany(u => u.ContributedToPosts);

    二、Fluent API显示设置外键

    1、显示设置外键

    referenceCollectionBuilder.HasForeignKey(p => p.BlogForeignKey);
    modelBuilder.Entity<Car>().HasKey(c => new { c.State, c.LicensePlate });  //复合主键设置
    referenceCollectionBuilder.HasFoHasForeignKey(s => new { s.CarState, s.CarLicensePlate }) //设置有复合主键表的外键,依赖主体要定义CarState,CarLicensePlate 这两个复合主键的属性字段
    referenceCollectionBuilder.HasForeignKey("BlogId");

     2、显式设置外键关联主体主键之外的键,通过 HasPrincipalKey 配置

    modelBuilder.Entity<Post>().HasOne(p => p.Blog).WithMany(b => b.Posts).HasForeignKey(p 
    => p.BlogUrl).HasPrincipalKey(b => b.Url); //Post表BlogUrl字段是外键,关联Blog表Url字段
    modelBuilder.Entity<Post>().HasOne(p => p.Blog).WithMany(b => b.Posts).HasForeignKey(p 
    => new { p.BlogUrl, p.BlogState }).HasPrincipalKey(b => new { b.Url, b.State });

    三、一对一关系:一对一关系两端都是引用导航属性,无法判断那个作为主体实体,推荐显式指定外键属性

    1、数据注解方式

    public class Blog
    {
     public int BlogId { get; set; }
     public string Url { get; set; }
     public BlogImage BlogImage { get; set; }
    }
    public class BlogImage
    {
       public int BlogImageId { get; set; }
       public byte[] Image { get; set; }
       public string Caption { get; set; }
      
    public int BlogId { get; set; } //显示指定外键属性,设置在Blog端也可以   public Blog Blog { get; set; } }

    2、Fluent API方式:使用 HasOne 和 WithOne 方法

    modelBuilder.Entity<Blog>().HasOne(p => p.BlogImage).WithOne(i => i.Blog).HasForeignKey<BlogImage>(b => b.BlogForeignKey);  //HasForeignKey<BlogImage>指定设置外键那一端

    四、多对多:关系型数据库中不支持多对多的映射,通过建立中间表连接,使用一对多的方式模拟多对多关系

    public class Post
    {
       public int PostId { get; set; }
       public string Title { get; set; }
       public string Content { get; set; }
       public List<PostTag> PostTags { get; set; }
    }
    public class Tag {   public string TagId { get; set; }   public List<PostTag> PostTags { get; set; } }  

    //中间表
    public class PostTag {   public int PostId { get; set; }   public Post Post { get; set; }   public string TagId { get; set; }   public Tag Tag { get; set; } } class MyContext : DbContext {   public DbSet<Post> Posts { get; set; }   public DbSet<Tag> Tags { get; set; }   protected override void OnModelCreating(ModelBuilder modelBuilder)   {     modelBuilder.Entity<PostTag>()     .HasKey(t => new { t.PostId, t.TagId }); //设置中间表主键
        modelBuilder.Entity
    <PostTag>()     .HasOne(pt => pt.Post)     .WithMany(p => p.PostTags)     .HasForeignKey(pt => pt.PostId);
        modelBuilder.Entity
    <PostTag>()     .HasOne(pt => pt.Tag)     .WithMany(t => t.PostTags)     .HasForeignKey(pt => pt.TagId);   } }

     五、自引用关系: 依赖关系和主体实体类型相同的关系

    1.模型定义

      public class PictureCategory 
      { [Key] [DatabaseGenerated(DatabaseGeneratedOption.Identity)]
    public int CategoryId { get; private set; } public string Name { get; set; } public int? ParentCategoryId { get; private set; }public virtual PictureCategory ParentCategory { get; set; } //没有virtual关键字,这会导致导航属性不能加载 public virtual List<PictureCategory> Subcategories { get; set; } }

    2.FluentAPI配置:在EFCore Context中重写方法OnModelCreating配置双向关联(ParentCategory 和 SubCategories)

            protected override void OnModelCreating(DbModelBuilder modelBuilder) {
                base.OnModelCreating(modelBuilder);
                modelBuilder.Entity<PictureCategory>()
                .WithMany(cat => cat.SubCategories)
                .HasOne(cat => cat.ParentCategory)
           .HasForeignKey(cat=>cat.ParentCategoryId);
            }
  • 相关阅读:
    IOS上传图片方向问题
    在线抠图的小工具
    Notion笔记工具免费开通教育许可
    多国正在遭遇新型勒索病毒Petya侵袭
    UC 网盘:我又回来了
    数字统计
    Hello,World!
    Unity开发笔记-Timeline利用Clip实现Rewind回放
    Unity开发笔记-Timeline利用Single实现Rewind回放
    Unity开发笔记-PSD自动导出UGUI工具开发要点记录(1)PSD树形结构解析
  • 原文地址:https://www.cnblogs.com/Adoni/p/12300357.html
Copyright © 2011-2022 走看看