Fluent API 配置实体和数据库之间的映射关系

1. 配置主键

protected override void OnModelCreating(ModelBuilder modelBuilder)
{
    modelBuilder.Entity<Blog>()
        .HasKey(b => b.BlogId); // 配置Blog实体的主键为BlogId
}

 

2. 配置属性和列

protected override void OnModelCreating(ModelBuilder modelBuilder)
{
    modelBuilder.Entity<Blog>()
        .Property(b => b.Url)
        .HasColumnName("BlogUrl") // 配置Url属性映射到数据库中的BlogUrl列
        .HasMaxLength(200) // 设置列的最大长度为200
        .IsRequired(); // 设置该列在数据库中不允许为空
}

 

3. 配置一对多关系

protected override void OnModelCreating(ModelBuilder modelBuilder)
{
    modelBuilder.Entity<Blog>()
        .HasMany(b => b.Posts) // 配置Blog有一个Posts集合属性
        .WithOne(p => p.Blog) // 配置Post有一个Blog导航属性
        .HasForeignKey(p => p.BlogId); // 配置外键为Post实体的BlogId属性
}

 

4. 配置多对多关系(通过联接实体)

protected override void OnModelCreating(ModelBuilder modelBuilder)
{
    modelBuilder.Entity<Student>()
        .HasMany(s => s.Courses)
        .WithMany(c => c.Students)
        .UsingEntity<Enrollment>(
            j => j
                .HasOne(e => e.Student)
                .WithMany(s => s.Enrollments)
                .HasForeignKey(e => e.StudentId),
            j => j
                .HasOne(e => e.Course)
                .WithMany(c => c.Enrollments)
                .HasForeignKey(e => e.CourseId),
            j =>
            {
                j.ToTable("StudentCourse"); // 设置联接表的名称
            });
}

 

public class Enrollment
{
    public int StudentId { get; set; }
    public Student Student { get; set; }

    public int CourseId { get; set; }
    public Course Course { get; set; }

    // 可以添加其他属性,比如成绩等
}

 

5. 配置索引

protected override void OnModelCreating(ModelBuilder modelBuilder)
{
    modelBuilder.Entity<Blog>()
        .HasIndex(b => b.Url) // 为Url属性创建索引
        .IsUnique(); // 设置索引为唯一
}

 

6. 配置复合主键和索引

protected override void OnModelCreating(ModelBuilder modelBuilder)
{
    modelBuilder.Entity<SomeEntity>()
        .HasKey(e => new { e.Key1, e.Key2 }); // 配置复合主键

    modelBuilder.Entity<SomeEntity>()
        .HasIndex(e => new { e.Key1, e.Key2 }) // 配置复合索引
        .IsUnique(); // 设置索引为唯一
}

 

7. 配置数据注解与Fluent API混合使用

你可以同时使用数据注解(Data Annotations)和Fluent API来配置实体。Fluent API提供了更多的灵活性和更精细的控制,而数据注解则提供了更简洁的配置方式。例如:

[Table("Blogs")] // 使用数据注解配置表名
public class Blog
{
    public int BlogId { get; set; }
    public string Url { get; set; }
    // ... 其他属性 ...
}
protected override void OnModelCreating(ModelBuilder modelBuilder)
{
    modelBuilder.Entity<Blog>()
        .Property(b => b.Url)
        .HasMaxLength(200); // 使用Fluent API配置Url属性的最大长度
    // ... 其他配置 ...
}

 

在实际开发中,你可以根据项目的具体需求和团队偏好选择使用数据注解还是Fluent API,或者两者混合使用。通常,对于简单的配置可以使用数据注解,而对于需要更精细控制的场景则使用Fluent API。

 

对于您提供的模型,如果您想使用 Fluent API 来配置 PrivilegeGroup 和 Privilege 之间的关系,您可以这样做:

using Microsoft.EntityFrameworkCore;
using Microsoft.EntityFrameworkCore.Metadata.Builders;
using System.Collections.Generic;

namespace Model
{
    public class PrivilegeGroup
    {
        public int Id { get; set; }
        public string GroupName { get; set; }
        public virtual List<Privilege> Privileges { get; set; }
    }

    public class Privilege
    {
        public int Id { get; set; }
        public int PrivilegeGroupId { get; set; }
        public string PrivilegeName { get; set; }
        public virtual PrivilegeGroup PrivilegeGroup { get; set; }
    }

    public class YourDbContext : DbContext
    {
        public DbSet<PrivilegeGroup> PrivilegeGroups { get; set; }
        public DbSet<Privilege> Privileges { get; set; }

        protected override void OnModelCreating(ModelBuilder modelBuilder)
        {
            // 配置 PrivilegeGroup 实体
            modelBuilder.Entity<PrivilegeGroup>(ConfigurePrivilegeGroup);

            // 配置 Privilege 实体
            modelBuilder.Entity<Privilege>(ConfigurePrivilege);
        }

        private void ConfigurePrivilegeGroup(EntityTypeBuilder<PrivilegeGroup> builder)
        {
            // 配置主键
            builder.HasKey(pg => pg.Id);

            // 配置 GroupName 为唯一索引
            builder.HasIndex(pg => pg.GroupName).IsUnique();

            // 配置与 Privilege 之间的关系(一对多)
            builder.HasMany(pg => pg.Privileges)
                   .WithOne(p => p.PrivilegeGroup)
                   .HasForeignKey(p => p.PrivilegeGroupId);
        }

        private void ConfigurePrivilege(EntityTypeBuilder<Privilege> builder)
        {
            // 配置主键
            builder.HasKey(p => p.Id);

            // 配置外键
            builder.HasOne(p => p.PrivilegeGroup)
                   .WithMany(pg => pg.Privileges)
                   .HasForeignKey(p => p.PrivilegeGroupId);
        }
    }
}

 

在这个例子中,PrivilegeGroup 和 Privilege 之间的关系被配置为一对多关系。Privilege 实体包含一个名为 PrivilegeGroupId 的外键属性,该属性引用 PrivilegeGroup 实体的 Id 属性。

ConfigurePrivilegeGroup 和 ConfigurePrivilege 方法分别用于配置 PrivilegeGroup 和 Privilege 实体的映射关系。在 ConfigurePrivilegeGroup 方法中,我们使用 HasIndex 方法来配置 GroupName 为唯一索引,并使用 HasMany 和 WithOne 方法来配置一对多关系。在 ConfigurePrivilege 方法中,我们使用 HasOne 和 WithMany 方法来配置多对一关系,并指定外键属性。

通过这种方式,您可以完全通过 Fluent API 来配置实体和数据库之间的映射关系,而不是依赖数据注解。这提供了更多的灵活性和控制力,特别是在处理复杂的模型和数据库结构时。

posted @ 2024-05-20 15:13  剑小秀  阅读(36)  评论(0编辑  收藏  举报