EF Core对象关系映射多种方法

Posted 二二姐

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了EF Core对象关系映射多种方法相关的知识,希望对你有一定的参考价值。

如果要看本篇文章请先查看《netcore mvc efcore 简单框架搭建+增删改查》文章,才能衔接这篇文章。

映射数据库这里我举例三种方法

一:方法一

就是文章netcore mvc efcore 简单框架搭建+增删改查上下文中使用的  DbSet<实体> 表名 get; set; ,因为微软约定大于配置,所以实体中每个属性映射到数据库中的类型会自动匹配到

 public DbSet<User> User  get; set; 

上下文例子中插入这句可以映射数据库,这种是最简单最直观的,但是这种映射方法的使用只能让表中的字段是默认的类型和大小,这个问题在方法二中可以解决。

二:方法二

上下文中插入这个方法,可以设置属性大小也可以改表属性类型

 protected override void OnModelCreating(ModelBuilder modelBuilder)
        
            base.OnModelCreating(modelBuilder);
           
            var user = modelBuilder.Entity<User>();
            user.HasKey(e => e.Id);
            user.Property(e => e.Name).HasMaxLength(50);
           
        

但是将所有的实体都放在上下文类中映射,如果表太多,看着会很乱。这个问题在方法三种可以解决。

三:方法三和方法二差不多,可以设置属性大小也可以改表属性类型,上下文中插入该方法,这个方法又有两种形式,一种是指定用户模型映射,另一种是指定程序集映射。

 protected override void OnModelCreating(ModelBuilder modelBuilder)
        
            base.OnModelCreating(modelBuilder);
modelBuilder.ApplyConfiguration(new UserEntityTypeConfiguration());//指定用户模型映射 //modelBuilder.ApplyConfigurationsFromAssembly(this.GetType().Assembly);//指定程序集映射

再创建一个类,这个类的作用其实和方法二中的作用一样,只不过把上下文中方法OnModelCreating() 映射的实体分别写在不同的类中,这样一个实体对应一个映射类,代码也不会显得那么乱了。

public class UserEntityTypeConfiguration : IEntityTypeConfiguration<User>
    

        public void Configure(EntityTypeBuilder<User> builder)
        
            builder.ToTable("user");
            builder.HasKey(x => x.Id);
            builder.Property(x => x.Name).HasMaxLength(50).IsRequired();
            builder.Property(x => x.Phone).HasMaxLength(250);
            builder.Property(x => x.Age);
            builder.Property(x => x.Like).HasMaxLength(100);
        
    

该文章到此结束!

 

EF Core多对多关系表命名[重复]

【中文标题】EF Core多对多关系表命名[重复]【英文标题】:EF Core Many-to-Many Relation Table Naming [duplicate] 【发布时间】:2021-10-26 11:03:54 【问题描述】:

EF Core 是否提供命名映射到数据库表的多对多关系的方法?

在代码优先模式中,我有以下 2 个实体:

[Table("Prefix.Users")]
public class User

    public int ID  get; set; 
    public IEnumerable<Role> Roles  get; set; 



[Table("Prefix.Roles")]
public class Role

    public int ID  get; set; 
    public IEnumerable<User> Users  get; set; 

我在这里跳过了详细的实体结构。 User & Role 中的 ID 属性是键(数据库生成的身份)

UserRole 实体共享一个 many-to-many relationship

EF Core 在数据库中生成第三个表,表名UsersRoles

有没有一种方法可以为第三个表名添加前缀,使其变为Prefix.UsersRoles,而无需手动添加映射UserRole 的第三个实体UserRoles 并为其指定所需的名称Prefix

【问题讨论】:

除标注为重复的帖子外,与当前文档基本相同Join entity type configuration 【参考方案1】:

使用 fluent API 而不是使用数据注释

你的模型类应该是这样的。

 public class User
 
    public int Id  get; set; 
    public string Username  get; set; 
    public string Email  get; set; 
    public string FirstName  get; set; 
    public string LastName  get; set; 
    public string Password  get; set; 

     public virtual ICollection<UserRole> UserRoles  get; set; 


public class Role

    public int Id  get; set; 
    public string Name  get; set; 
    public string Description  get; set; 

    public virtual ICollection<UserRole> UserRoles  get; set; 


public class UserRole

    public int UserId  get; set; 
    public int RoleId  get; set; 

    public virtual User User  get; set; 
    public virtual Role Role  get; set; 


你的 fluent api 配置类是这样的

public class UserConfiguration : IEntityTypeConfiguration<User>

    public void Configure(EntityTypeBuilder<User> builder)
    
        builder.ToTable("User");

        builder.HasKey(x => x.Id);
    

public class RoleConfiguration : IEntityTypeConfiguration<Role>

    public void Configure(EntityTypeBuilder<Role> builder)
    
        builder.ToTable("Role");

        builder.HasKey(x => x.Id);
    


public class UserRoleConfiguration : IEntityTypeConfiguration<UserRole>

    public void Configure(EntityTypeBuilder<UserRole> builder)
    
        builder.ToTable("UserRole");

        builder.HasKey(x => new  x.UserId, x.RoleId );

        builder
            .HasOne<Role>(s => s.Role)
            .WithMany(r => r.UserRoles)
            .HasForeignKey(s => s.RoleId).OnDelete(DeleteBehavior.Restrict);

        builder
            .HasOne<User>(s => s.User)
            .WithMany(r => r.UserRoles)
            .HasForeignKey(s => s.UserId).OnDelete(DeleteBehavior.Restrict);

    

你的 DbContext 类应该是这样的

public class MyDbContext : DbContext

    public EEGDbContext()
    
    

    protected override void OnConfiguring(DbContextOptionsBuilder optionsBuilder)
    
        if (!optionsBuilder.IsConfigured)
        
            optionsBuilder.UseSqlServer(@"Server=xxxx;Database=DB;User Id=sa;Password=xxxxx;");
        
    

    protected override void OnModelCreating(ModelBuilder modelBuilder)
    
        modelBuilder.ApplyConfiguration(new UserConfiguration());
        modelBuilder.ApplyConfiguration(new RoleConfiguration());
        modelBuilder.ApplyConfiguration(new UserRoleConfiguration());

        base.OnModelCreating(modelBuilder);
    

    public DbSet<User> Users  get; set; 
    public DbSet<Role> Roles  get; set; 
    public DbSet<UserRole> UserRoles  get; set; 


【讨论】:

感谢@Erandika 的精心回复。我有点希望如果可以跳过第三个实体UserRole 创建,并且 EF Core 会像现在这样处理它(我当前的设置),我们仍然可以选择一个 自定义表名.

以上是关于EF Core对象关系映射多种方法的主要内容,如果未能解决你的问题,请参考以下文章

C# 数据操作系列 - 6 EF Core 配置映射关系

EF Core 慢速批量插入(~80k 行)

带有 EF Core 的 ASP.NET Core - DTO 集合映射

EF Core 在映射到 Select 中的对象时查询 SQL 中的所有列

EF CORE中复杂类型的映射

EF CORE中复杂类型的映射