.net core EF 关系(一) 一对多 映射配置

参考 一对多关系 - EF Core | Microsoft Learn

关系映射 最难得就是一对多 ,剩下得多对多 一对一看看就行

blog类是 一端 post 类多端

                                  映射关系
一端 和多端都有导航属性 多端有外键  builder.HasMany(x=>x.Posts).WithOne(x=>x.Blog).HasForeignKey(x=>x.BlogId).IsRequired();
一端和多端都有导航属性 多端有外键 ,多端外键可null 多端导航属性可null builder.HasMany(x=>x.Posts).WithOne(x=>x.Blog).HasForeignKey(x=>x.Id).IsRequired(false);
一端和多端都有导航属性,多端没有外键,必须存在关系 builder.HasMany(x => x.Posts).WithOne(x => x.Blog).HasForeignKey("BlogId").IsRequired();
一端和多端都有导航属性,多端没有外键,存在关系可null

//设置外键名称 BlogId

builder.HasMany(x => x.Posts).WithOne(x => x.Blog).HasForeignKey("BlogId").IsRequired(false)

 

//这种 外键自动生成 BlogId

 builder.HasMany(x=>x.Posts).WithOne(x=>x.Blog).IsRequired(false);

一端只有导航属性多端没有导航属性,多端只有外键 builder.HasMany(x => x.Posts).WithOne().HasForeignKey(x=>x.BlogId).IsRequired();
一端只有导航属性多端没有导航属性,多端只有外键,多端外键可null builder.HasMany(x => x.Posts).WithOne().HasForeignKey(x=>x.BlogId).IsRequired(false);
一端和多端都没有导航属性,多端只有外键 builder.HasMany<Post>().WithOne().HasForeignKey(x => x.BlogId).IsRequired();
备选键          

 

注意 如果一对多 两端都只有导航属性配置

可以 如下配置 那么会有一个问题 外键如何访问? 使用  EF.Property<int>(x, "BlogId")  访问

不明白可以查看  阴影和索引器属性 - EF Core | Microsoft Learn 这里详细讲解了 如何配置和访问

//设置外键名称 BlogId
builder.HasMany(x => x.Posts).WithOne(x => x.Blog).HasForeignKey("BlogId").IsRequired(false)

//这种 外键自动生成 BlogId
builder.HasMany(x=>x.Posts).WithOne(x=>x.Blog).IsRequired(false); 

 

下面配置的该情况 可以看到 一端 多端 都只有导航属性 没有配置外键

 /// <summary>
 /// 博客
 /// </summary>
 public class Blog
 {
     public Blog()
     {

     }

     public Blog(string url)
     {
         _url = url;
     }
     public int Id { get; set; }

     private IEnumerable<Post> _posts;

     /// <summary>
     /// 导航属性发布集合
     /// </summary>
     public IEnumerable<Post> Posts => _posts ??= new List<Post>();

     /// <summary>
     /// 私有字段
     /// </summary>
     private string _url;
     /// <summary>
     /// 属性
     /// </summary>
     public string Url => _url;

     /// <summary>
     /// 私有字段
     /// </summary>
     private string soltCode ="solt";

 }
 /// <summary>
 /// 发布
 /// </summary>
 public class Post
 {
     public int Id { get; set; }
     public string Name { get; set; }
     ///// <summary>
     ///// 外键 博客Id
     ///// </summary>
     //public int BlogId { get; set; }
     /// <summary>
     /// 导航属性Blog
     /// </summary>
     public Blog? Blog { get; set; }
 }

  

关系配置  需要单独配置 

//配置阴影属性 外键
builder.Property<int>("BlogId");
  public class BlogEntityTypeConfiguration : IEntityTypeConfiguration<Blog>
  {
      public void Configure(EntityTypeBuilder<Blog> builder)
      {
          builder.ToTable("T_Blogs");
          builder.HasKey(x => x.Id);
          //博客和发布时一对多  导航属性 Blog 不为null 外键博客BlogId 必须存在关系 IsRequired() 默认为true
          //builder.HasMany(x=>x.Posts).WithOne(x=>x.Blog).HasForeignKey(x=>x.BlogId).IsRequired();

          //博客和发布时一对多 导航属性 Blog 为null  外键为null 博客BlogId 必须存在关系 IsRequired(false)
          //builder.HasMany(x=>x.Posts).WithOne(x=>x.Blog).HasForeignKey(x=>x.Id).IsRequired(false);

          //博客和发布时一对多 只有导航属性 Blog 没有外键 的必须存在关系IsRequired()
          // builder.HasMany(x => x.Posts).WithOne(x => x.Blog).HasForeignKey("BlogId").IsRequired();

          //博客和发布时一对多 只有导航属性 Blog 没有外键 的必须存在关系IsRequired(false)
          // builder.HasMany(x => x.Posts).WithOne(x => x.Blog).HasForeignKey("BlogId").IsRequired(false);

          //博客和发布时一对多 Blog有导航属性 Post没有有导航属性 Blog 只有有外键 的必须存在关系IsRequired()
          // builder.HasMany(x => x.Posts).WithOne().HasForeignKey(x=>x.BlogId).IsRequired();

          //博客和发布时一对多 Blog没有有导航属性  只有有外键 的必须存在关系IsRequired()
           builder.HasMany(x=>x.Posts).WithOne(x=>x.Blog).IsRequired(false);
         
          //私有字段
          //builder.Property(x => x.Url).HasField("_url");
 
          builder.Property(x=>x.Url).HasField("_url").UsePropertyAccessMode(PropertyAccessMode.Field);

          builder.Property("soltCode").HasColumnName("SoltCode");


          var navigation =  builder.Metadata.FindNavigation(nameof(Blog.Posts));
          navigation.SetPropertyAccessMode(PropertyAccessMode.Field);
      }
  }

    public class PostEntityTypeConfiguration : IEntityTypeConfiguration<Post>
    {
        public void Configure(EntityTypeBuilder<Post> builder)
        {
            builder.ToTable("T_Post");
            builder.HasKey(x => x.Id);
            //配置阴影属性
            builder.Property<int>("BlogId");
        }
    }

 

访问使用 EF.Property<int>(x, "BlogId")  

例如

      /// <summary>
      /// 查询
      /// </summary>
      /// <param name="id"></param>
      /// <returns></returns>
      /// <exception cref="NotImplementedException"></exception>
      public async Task<Blog> FindByIdAsync(int id)
      {
          //通过阴影属性查询
          Blog blog = await _context.Blogs.Include(x =>
          x.Posts.Where(x => EF.Property<int>(x, "BlogId") == id)).AsNoTracking().FirstOrDefaultAsync(x => x.Id == id);
          return blog;
      }

  

=============================================================================================================================

下面是关系配置的各种情况 关系一对多 其实 就是 配置导航属性(如果没有外键,就在EntityTypeConfiguration 指定),如果配置了外键了 就指定外键 其实挺简单

实体类 都包含导航属性  并且多端含有外键 BlogId 

此关系按约定发现。 即:

  • Blog 作为关系中的主体实体被发现,Post 作为依赖实体被发现。
  • Post.BlogId 作为引用主体实体的 Blog.Id 主键的依赖实体的外键被发现。 由于 Post.BlogId 不可为空,所以发现这一关系是必需的。
  • Blog.Posts 作为集合导航被发现。
  • Post.Blog 作为引用导航被发现。
/// <summary>
/// 博客
/// </summary>
public class Blog
{
    public Blog()
    {
        Posts = new List<Post>();
    }
    public int Id { get; set; }
    /// <summary>
    /// 导航属性发布集合
    /// </summary>
    public IEnumerable<Post> Posts { get; set; }
}
/// <summary>
/// 发布
/// </summary>
public class Post
{
    public int Id { get; set; }
    /// <summary>
    /// 外键 博客Id
    /// </summary>
    public int BlogId { get; set; }
    /// <summary>
    /// 导航属性Blog
    /// </summary>
    public Blog Blog { get; set; }
}

实体类中  配置必须有关系

必需的关系可确保每个依赖实体都必须与某个主体实体相关联。 但是,主体实体可以在没有任何依赖实体的情况下始终存在。 也就是说,必需的关系并不表示始终存在至少一个依赖实体。 无论是在 EF 模型,还是在关系数据库中,都没有确保主体实体与特定数量的依赖实体相关联的标准方法。 如果需要,则必须在应用程序(业务)逻辑中实现它。

 

    public class BlogEntityTypeConfiguration : IEntityTypeConfiguration<Blog>
    {
        public void Configure(EntityTypeBuilder<Blog> builder)
        {
            builder.ToTable("T_Blogs");
            builder.HasKey(x=>x.Id);
            //博客和发布时一对多 外键博客BlogId 必须存在关系
            builder.HasMany(x=>x.Posts).WithOne(x=>x.Blog).HasForeignKey(x=>x.BlogId).IsRequired();
        }
    } 

 

生成的迁移文件 查看 关系 是 onDelete: ReferentialAction.Cascade 这是级联关系 删除blog 时候会连相关发布一起删除

using Microsoft.EntityFrameworkCore.Metadata;
using Microsoft.EntityFrameworkCore.Migrations;

#nullable disable

namespace WebApplication2.Migrations
{
    /// <inheritdoc />
    public partial class init : Migration
    {
        /// <inheritdoc />
        protected override void Up(MigrationBuilder migrationBuilder)
        {
            migrationBuilder.AlterDatabase()
                .Annotation("MySql:CharSet", "utf8mb4");

            migrationBuilder.CreateTable(
                name: "T_Blogs",
                columns: table => new
                {
                    Id = table.Column<int>(type: "int", nullable: false)
                        .Annotation("MySql:ValueGenerationStrategy", MySqlValueGenerationStrategy.IdentityColumn)
                },
                constraints: table =>
                {
                    table.PrimaryKey("PK_T_Blogs", x => x.Id);
                })
                .Annotation("MySql:CharSet", "utf8mb4");

            migrationBuilder.CreateTable(
                name: "Post",
                columns: table => new
                {
                    Id = table.Column<int>(type: "int", nullable: false)
                        .Annotation("MySql:ValueGenerationStrategy", MySqlValueGenerationStrategy.IdentityColumn),
                    BlogId = table.Column<int>(type: "int", nullable: false)
                },
                constraints: table =>
                {
                    table.PrimaryKey("PK_Post", x => x.Id);
                    table.ForeignKey(
                        name: "FK_Post_T_Blogs_BlogId",
                        column: x => x.BlogId,
                        principalTable: "T_Blogs",
                        principalColumn: "Id",
                        onDelete: ReferentialAction.Cascade);
                })
                .Annotation("MySql:CharSet", "utf8mb4");

            migrationBuilder.CreateIndex(
                name: "IX_Post_BlogId",
                table: "Post",
                column: "BlogId");
        }

        /// <inheritdoc />
        protected override void Down(MigrationBuilder migrationBuilder)
        {
            migrationBuilder.DropTable(
                name: "Post");

            migrationBuilder.DropTable(
                name: "T_Blogs");
        }
    }
}

 以下 是 mysql 表设计

 

上面例子是 外键不为null 下面例子是 外键为null 导航和外键 Blog? Blog   int? BlogId 都设置为null

/// <summary>
/// 博客
/// </summary>
public class Blog
{
    public Blog()
    {
        Posts = new List<Post>();
    }
    public int Id { get; set; }
    /// <summary>
    /// 导航属性发布集合
    /// </summary>
    public IEnumerable<Post> Posts { get; set; }
}
/// <summary>
/// 发布
/// </summary>
public class Post
{
    public int Id { get; set; }
    /// <summary>
    /// 外键 博客Id
    /// </summary>
    public int? BlogId { get; set; }
    /// <summary>
    /// 导航属性Blog
    /// </summary>
    public Blog? Blog { get; set; }
}

  

    public class BlogEntityTypeConfiguration : IEntityTypeConfiguration<Blog>
    {
        public void Configure(EntityTypeBuilder<Blog> builder)
        {
            builder.ToTable("T_Blogs");
            builder.HasKey(x=>x.Id);
            //博客和发布时一对多 外键博客BlogId 必须存在关系 IsRequired() 默认为true
            //builder.HasMany(x=>x.Posts).WithOne(x=>x.Blog).HasForeignKey(x=>x.BlogId).IsRequired();

            //博客和发布时一对多 外键为null 博客BlogId 必须存在关系 IsRequired(false)
            builder.HasMany(x=>x.Posts).WithOne(x=>x.Blog).HasForeignKey(x=>x.Id).IsRequired(false);
        }
    }

 

外键 关系可以看到 迁移文件 没了

  /// <inheritdoc />
  public partial class init1 : Migration
  {
      /// <inheritdoc />
      protected override void Up(MigrationBuilder migrationBuilder)
      {
          migrationBuilder.AlterDatabase()
              .Annotation("MySql:CharSet", "utf8mb4");

          migrationBuilder.CreateTable(
              name: "T_Blogs",
              columns: table => new
              {
                  Id = table.Column<int>(type: "int", nullable: false)
                      .Annotation("MySql:ValueGenerationStrategy", MySqlValueGenerationStrategy.IdentityColumn)
              },
              constraints: table =>
              {
                  table.PrimaryKey("PK_T_Blogs", x => x.Id);
              })
              .Annotation("MySql:CharSet", "utf8mb4");

          migrationBuilder.CreateTable(
              name: "Post",
              columns: table => new
              {
                  Id = table.Column<int>(type: "int", nullable: false),
                  BlogId = table.Column<int>(type: "int", nullable: true)
              },
              constraints: table =>
              {
                  table.PrimaryKey("PK_Post", x => x.Id);
                  table.ForeignKey(
                      name: "FK_Post_T_Blogs_Id",
                      column: x => x.Id,
                      principalTable: "T_Blogs",
                      principalColumn: "Id");
              })
              .Annotation("MySql:CharSet", "utf8mb4");
      }

      /// <inheritdoc />
      protected override void Down(MigrationBuilder migrationBuilder)
      {
          migrationBuilder.DropTable(
              name: "Post");

          migrationBuilder.DropTable(
              name: "T_Blogs");
      }
  }

  查看mysql 外键的状态改变了 也就是说删除 blog 相关的发布不会被删除

 只有导航属性 没有 外键id情况

    /// <summary>
    /// 博客
    /// </summary>
    public class Blog
    {
        public Blog()
        {
            Posts = new List<Post>();
        }
        public int Id { get; set; }
        /// <summary>
        /// 导航属性发布集合
        /// </summary>
        public IEnumerable<Post> Posts { get; set; }
    }
    /// <summary>
    /// 发布
    /// </summary>
    public class Post
    {
        public int Id { get; set; }
        ///// <summary>
        ///// 外键 博客Id
        ///// </summary>
        //public int? BlogId { get; set; }
        /// <summary>
        /// 导航属性Blog
        /// </summary>
        public Blog Blog { get; set; }
    }

  

public class BlogEntityTypeConfiguration : IEntityTypeConfiguration<Blog>
{
    public void Configure(EntityTypeBuilder<Blog> builder)
    {
        builder.ToTable("T_Blogs");
        builder.HasKey(x=>x.Id);
        //博客和发布时一对多  导航属性 Blog 不为null 外键博客BlogId 必须存在关系 IsRequired() 默认为true
        //builder.HasMany(x=>x.Posts).WithOne(x=>x.Blog).HasForeignKey(x=>x.BlogId).IsRequired();

        //博客和发布时一对多 导航属性 Blog 为null  外键为null 博客BlogId 必须存在关系 IsRequired(false)
        //builder.HasMany(x=>x.Posts).WithOne(x=>x.Blog).HasForeignKey(x=>x.Id).IsRequired(false);

        //博客和发布时一对多 只有导航属性 Blog 没有外键 的必须存在关系IsRequired()
        builder.HasMany(x => x.Posts).WithOne(x => x.Blog).HasForeignKey("BlogId").IsRequired();


    }
}

  

迁移文件中查看 配置的外键关系

 /// <inheritdoc />
 public partial class init1 : Migration
 {
     /// <inheritdoc />
     protected override void Up(MigrationBuilder migrationBuilder)
     {
         migrationBuilder.AlterDatabase()
             .Annotation("MySql:CharSet", "utf8mb4");

         migrationBuilder.CreateTable(
             name: "T_Blogs",
             columns: table => new
             {
                 Id = table.Column<int>(type: "int", nullable: false)
                     .Annotation("MySql:ValueGenerationStrategy", MySqlValueGenerationStrategy.IdentityColumn)
             },
             constraints: table =>
             {
                 table.PrimaryKey("PK_T_Blogs", x => x.Id);
             })
             .Annotation("MySql:CharSet", "utf8mb4");

         migrationBuilder.CreateTable(
             name: "Post",
             columns: table => new
             {
                 Id = table.Column<int>(type: "int", nullable: false)
                     .Annotation("MySql:ValueGenerationStrategy", MySqlValueGenerationStrategy.IdentityColumn),
                 BlogId = table.Column<int>(type: "int", nullable: false)
             },
             constraints: table =>
             {
                 table.PrimaryKey("PK_Post", x => x.Id);
                 table.ForeignKey(
                     name: "FK_Post_T_Blogs_BlogId",
                     column: x => x.BlogId,
                     principalTable: "T_Blogs",
                     principalColumn: "Id",
                     onDelete: ReferentialAction.Cascade);
             })
             .Annotation("MySql:CharSet", "utf8mb4");

         migrationBuilder.CreateIndex(
             name: "IX_Post_BlogId",
             table: "Post",
             column: "BlogId");
     }

     /// <inheritdoc />
     protected override void Down(MigrationBuilder migrationBuilder)
     {
         migrationBuilder.DropTable(
             name: "Post");

         migrationBuilder.DropTable(
             name: "T_Blogs");
     }
 }

  

  只有导航属性 没有 外键id情况 导航属性 可null

    /// <summary>
    /// 博客
    /// </summary>
    public class Blog
    {
        public Blog()
        {
            Posts = new List<Post>();
        }
        public int Id { get; set; }
        /// <summary>
        /// 导航属性发布集合
        /// </summary>
        public IEnumerable<Post> Posts { get; set; }
    }
    /// <summary>
    /// 发布
    /// </summary>
    public class Post
    {
        public int Id { get; set; }
        ///// <summary>
        ///// 外键 博客Id
        ///// </summary>
        //public int? BlogId { get; set; }
        /// <summary>
        /// 导航属性Blog
        /// </summary>
        public Blog? Blog { get; set; }
    }

  

   public class BlogEntityTypeConfiguration : IEntityTypeConfiguration<Blog>
   {
       public void Configure(EntityTypeBuilder<Blog> builder)
       {
           builder.ToTable("T_Blogs");
           builder.HasKey(x=>x.Id);
           //博客和发布时一对多  导航属性 Blog 不为null 外键博客BlogId 必须存在关系 IsRequired() 默认为true
           //builder.HasMany(x=>x.Posts).WithOne(x=>x.Blog).HasForeignKey(x=>x.BlogId).IsRequired();

           //博客和发布时一对多 导航属性 Blog 为null  外键为null 博客BlogId 必须存在关系 IsRequired(false)
           //builder.HasMany(x=>x.Posts).WithOne(x=>x.Blog).HasForeignKey(x=>x.Id).IsRequired(false);

           //博客和发布时一对多 只有导航属性 Blog 没有外键 的必须存在关系IsRequired()
           // builder.HasMany(x => x.Posts).WithOne(x => x.Blog).HasForeignKey("BlogId").IsRequired();

           //博客和发布时一对多 只有导航属性 Blog 没有外键 的必须存在关系IsRequired(false)
           builder.HasMany(x => x.Posts).WithOne(x => x.Blog).HasForeignKey("BlogId").IsRequired(false);

       }
   }

  

   /// <inheritdoc />
   public partial class init1 : Migration
   {
       /// <inheritdoc />
       protected override void Up(MigrationBuilder migrationBuilder)
       {
           migrationBuilder.AlterDatabase()
               .Annotation("MySql:CharSet", "utf8mb4");

           migrationBuilder.CreateTable(
               name: "T_Blogs",
               columns: table => new
               {
                   Id = table.Column<int>(type: "int", nullable: false)
                       .Annotation("MySql:ValueGenerationStrategy", MySqlValueGenerationStrategy.IdentityColumn)
               },
               constraints: table =>
               {
                   table.PrimaryKey("PK_T_Blogs", x => x.Id);
               })
               .Annotation("MySql:CharSet", "utf8mb4");

           migrationBuilder.CreateTable(
               name: "Post",
               columns: table => new
               {
                   Id = table.Column<int>(type: "int", nullable: false)
                       .Annotation("MySql:ValueGenerationStrategy", MySqlValueGenerationStrategy.IdentityColumn),
                   BlogId = table.Column<int>(type: "int", nullable: true)
               },
               constraints: table =>
               {
                   table.PrimaryKey("PK_Post", x => x.Id);
                   table.ForeignKey(
                       name: "FK_Post_T_Blogs_BlogId",
                       column: x => x.BlogId,
                       principalTable: "T_Blogs",
                       principalColumn: "Id");
               })
               .Annotation("MySql:CharSet", "utf8mb4");

           migrationBuilder.CreateIndex(
               name: "IX_Post_BlogId",
               table: "Post",
               column: "BlogId");
       }

       /// <inheritdoc />
       protected override void Down(MigrationBuilder migrationBuilder)
       {
           migrationBuilder.DropTable(
               name: "Post");

           migrationBuilder.DropTable(
               name: "T_Blogs");
       }
   }

  

 

没有导航属性 只有外键

{
    /// <summary>
    /// 博客
    /// </summary>
    public class Blog
    {
        public Blog()
        {
            Posts = new List<Post>();
        }
        public int Id { get; set; }
        /// <summary>
        /// 导航属性发布集合
        /// </summary>
        public IEnumerable<Post> Posts { get; set; }
    }
    /// <summary>
    /// 发布
    /// </summary>
    public class Post
    {
        public int Id { get; set; }
        ///// <summary>
        ///// 外键 博客Id
        ///// </summary>
        public int BlogId { get; set; }
        ///// <summary>
        ///// 导航属性Blog
        ///// </summary>
        // public Blog? Blog { get; set; }
    }

  

    public class BlogEntityTypeConfiguration : IEntityTypeConfiguration<Blog>
    {
        public void Configure(EntityTypeBuilder<Blog> builder)
        {
            builder.ToTable("T_Blogs");
            builder.HasKey(x=>x.Id);
            //博客和发布时一对多  导航属性 Blog 不为null 外键博客BlogId 必须存在关系 IsRequired() 默认为true
            //builder.HasMany(x=>x.Posts).WithOne(x=>x.Blog).HasForeignKey(x=>x.BlogId).IsRequired();

            //博客和发布时一对多 导航属性 Blog 为null  外键为null 博客BlogId 必须存在关系 IsRequired(false)
            //builder.HasMany(x=>x.Posts).WithOne(x=>x.Blog).HasForeignKey(x=>x.Id).IsRequired(false);

            //博客和发布时一对多 只有导航属性 Blog 没有外键 的必须存在关系IsRequired()
            // builder.HasMany(x => x.Posts).WithOne(x => x.Blog).HasForeignKey("BlogId").IsRequired();

            //博客和发布时一对多 只有导航属性 Blog 没有外键 的必须存在关系IsRequired(false)
            // builder.HasMany(x => x.Posts).WithOne(x => x.Blog).HasForeignKey("BlogId").IsRequired(false);

            //博客和发布时一对多 没有有导航属性 Blog 只有有外键 的必须存在关系IsRequired()
             builder.HasMany(x => x.Posts).WithOne().HasForeignKey(x=>x.BlogId).IsRequired();
        }
    }

  

    /// <inheritdoc />
    public partial class init1 : Migration
    {
        /// <inheritdoc />
        protected override void Up(MigrationBuilder migrationBuilder)
        {
            migrationBuilder.AlterDatabase()
                .Annotation("MySql:CharSet", "utf8mb4");

            migrationBuilder.CreateTable(
                name: "T_Blogs",
                columns: table => new
                {
                    Id = table.Column<int>(type: "int", nullable: false)
                        .Annotation("MySql:ValueGenerationStrategy", MySqlValueGenerationStrategy.IdentityColumn)
                },
                constraints: table =>
                {
                    table.PrimaryKey("PK_T_Blogs", x => x.Id);
                })
                .Annotation("MySql:CharSet", "utf8mb4");

            migrationBuilder.CreateTable(
                name: "Post",
                columns: table => new
                {
                    Id = table.Column<int>(type: "int", nullable: false)
                        .Annotation("MySql:ValueGenerationStrategy", MySqlValueGenerationStrategy.IdentityColumn),
                    BlogId = table.Column<int>(type: "int", nullable: false)
                },
                constraints: table =>
                {
                    table.PrimaryKey("PK_Post", x => x.Id);
                    table.ForeignKey(
                        name: "FK_Post_T_Blogs_BlogId",
                        column: x => x.BlogId,
                        principalTable: "T_Blogs",
                        principalColumn: "Id",
                        onDelete: ReferentialAction.Cascade);
                })
                .Annotation("MySql:CharSet", "utf8mb4");

            migrationBuilder.CreateIndex(
                name: "IX_Post_BlogId",
                table: "Post",
                column: "BlogId");
        }

        /// <inheritdoc />
        protected override void Down(MigrationBuilder migrationBuilder)
        {
            migrationBuilder.DropTable(
                name: "Post");

            migrationBuilder.DropTable(
                name: "T_Blogs");
        }
    }

  

 

没有 导航属性 只有外键

 /// <summary>
 /// 博客
 /// </summary>
 public class Blog
 {
     public Blog()
     {
        // Posts = new List<Post>();
     }
     public int Id { get; set; }
     ///// <summary>
     ///// 导航属性发布集合
     ///// </summary>
     //public IEnumerable<Post> Posts { get; set; }
 }
 /// <summary>
 /// 发布
 /// </summary>
 public class Post
 {
     public int Id { get; set; }
     ///// <summary>
     ///// 外键 博客Id
     ///// </summary>
     public int BlogId { get; set; }
     ///// <summary>
     ///// 导航属性Blog
     ///// </summary>
     // public Blog? Blog { get; set; }
 }

  

 public class BlogEntityTypeConfiguration : IEntityTypeConfiguration<Blog>
 {
     public void Configure(EntityTypeBuilder<Blog> builder)
     {
         builder.ToTable("T_Blogs");
         builder.HasKey(x => x.Id);
         //博客和发布时一对多  导航属性 Blog 不为null 外键博客BlogId 必须存在关系 IsRequired() 默认为true
         //builder.HasMany(x=>x.Posts).WithOne(x=>x.Blog).HasForeignKey(x=>x.BlogId).IsRequired();

         //博客和发布时一对多 导航属性 Blog 为null  外键为null 博客BlogId 必须存在关系 IsRequired(false)
         //builder.HasMany(x=>x.Posts).WithOne(x=>x.Blog).HasForeignKey(x=>x.Id).IsRequired(false);

         //博客和发布时一对多 只有导航属性 Blog 没有外键 的必须存在关系IsRequired()
         // builder.HasMany(x => x.Posts).WithOne(x => x.Blog).HasForeignKey("BlogId").IsRequired();

         //博客和发布时一对多 只有导航属性 Blog 没有外键 的必须存在关系IsRequired(false)
         // builder.HasMany(x => x.Posts).WithOne(x => x.Blog).HasForeignKey("BlogId").IsRequired(false);

         //博客和发布时一对多 Blog有导航属性 Post没有有导航属性 Blog 只有有外键 的必须存在关系IsRequired()
         // builder.HasMany(x => x.Posts).WithOne().HasForeignKey(x=>x.BlogId).IsRequired();

         //博客和发布时一对多 Blog没有有导航属性  只有有外键 的必须存在关系IsRequired()
         builder.HasMany<Post>().WithOne().HasForeignKey(x => x.BlogId).IsRequired();
     }
 }

  

 

/// <inheritdoc />
public partial class init1 : Migration
{
    /// <inheritdoc />
    protected override void Up(MigrationBuilder migrationBuilder)
    {
        migrationBuilder.AlterDatabase()
            .Annotation("MySql:CharSet", "utf8mb4");

        migrationBuilder.CreateTable(
            name: "T_Blogs",
            columns: table => new
            {
                Id = table.Column<int>(type: "int", nullable: false)
                    .Annotation("MySql:ValueGenerationStrategy", MySqlValueGenerationStrategy.IdentityColumn)
            },
            constraints: table =>
            {
                table.PrimaryKey("PK_T_Blogs", x => x.Id);
            })
            .Annotation("MySql:CharSet", "utf8mb4");

        migrationBuilder.CreateTable(
            name: "Post",
            columns: table => new
            {
                Id = table.Column<int>(type: "int", nullable: false)
                    .Annotation("MySql:ValueGenerationStrategy", MySqlValueGenerationStrategy.IdentityColumn),
                BlogId = table.Column<int>(type: "int", nullable: false)
            },
            constraints: table =>
            {
                table.PrimaryKey("PK_Post", x => x.Id);
                table.ForeignKey(
                    name: "FK_Post_T_Blogs_BlogId",
                    column: x => x.BlogId,
                    principalTable: "T_Blogs",
                    principalColumn: "Id",
                    onDelete: ReferentialAction.Cascade);
            })
            .Annotation("MySql:CharSet", "utf8mb4");

        migrationBuilder.CreateIndex(
            name: "IX_Post_BlogId",
            table: "Post",
            column: "BlogId");
    }

    /// <inheritdoc />
    protected override void Down(MigrationBuilder migrationBuilder)
    {
        migrationBuilder.DropTable(
            name: "Post");

        migrationBuilder.DropTable(
            name: "T_Blogs");
    }
}

  

 

 

在没有配置外键得情况下 可以使用  EF.Property<int>(x, "BlogId") == id) 进行查询

        /// <summary>
        /// 查询
        /// </summary>
        /// <param name="id"></param>
        /// <returns></returns>
        /// <exception cref="NotImplementedException"></exception>
        public async Task<Blog> FindByIdAsync(int id)
        {
            //通过阴影属性查询
            Blog blog = await _context.Blogs.Include(x =>
            x.Posts.Where(x => EF.Property<int>(x, "BlogId") == id)).AsNoTracking().FirstOrDefaultAsync(x => x.Id == id);
            return blog;
        }

  

 

posted on 2024-04-26 11:25  是水饺不是水饺  阅读(654)  评论(0)    收藏  举报

导航