首页 > 解决方案 > EF Core 5,如何定义多个“一对多”关系?

问题描述

我正在创建一个自由任务管理应用程序。这是逻辑。这些是涉及的 3 个 POCO

用户(登录用户)

  1. 一个用户可以创建任意数量的客户端
  2. 用户可以创建任意数量的项目
  3. 一个用户由另一个用户创建,更新

客户(自由客户)

  1. 一个客户可以有任意数量的项目
  2. 客户端由用户创建、更新

项目

  1. 一个项目应该只有一个客户
  2. 项目由用户创建、更新

这些是我的实体。我正在使用 Code-First 方法并使用 SQLServer。我删除了许多要在此处发布的属性

用户实体

public class User
{
    [DatabaseGenerated(DatabaseGeneratedOption.Identity)]
    [Key]
    public int Id { get; set; }
    public string FirstName { get; set; }
    public string LastName { get; set; }        

    public DateTime? CreatedOn { get; set; }
    public DateTime? UpdatedOn { get; set; }
    public virtual User CreatedBy { get; set; }
    public virtual User UpdatedBy { get; set; }

    [ForeignKey("UserId")]
    public int? CreatedById { get; set; }
    [ForeignKey("UserId")]
    public int? UpdatedById { get; set; }

    public virtual ICollection<Project> Projects { get; set; }
    public virtual ICollection<Client> Clients { get; set; }        
}

客户实体

public class Client
{
    [DatabaseGenerated(DatabaseGeneratedOption.Identity)]
    [Key]
    public int Id { get; set; }
    public string Company { get; set; }
    public string Email { get; set; }
    public string Phone { get; set; }
    public string Address { get; set; }        

    public DateTime? CreatedOn { get; set; }
    public DateTime? UpdatedOn { get; set; }
    public virtual User CreatedBy { get; set; }
    public virtual User UpdatedBy { get; set; }

    [ForeignKey("UserId")]
    public int? CreatedById { get; set; }
    [ForeignKey("UserId")]
    public int? UpdatedById { get; set; }

    public ICollection<Project> Projects { get; set; }
}

项目实体

public class Project
{
    [DatabaseGenerated(DatabaseGeneratedOption.Identity)]
    [Key]
    public int Id { get; set; }
    public string Name { get; set; }
    public string Description { get; set; }
    public string ProjectLogo { get; set; }        

    public DateTime? CreatedOn { get; set; }
    public DateTime? UpdatedOn { get; set; }
    public virtual User CreatedBy { get; set; }
    public virtual User UpdatedBy { get; set; }

    [ForeignKey("UserId")]
    public int? CreatedById { get; set; }
    [ForeignKey("UserId")]
    public int? UpdatedById { get; set; }

    public virtual Client Client { get; set; }       
}

我现在面临着 ForginKeys 和映射的许多问题。这里的实体映射有什么问题?我无法在具有相同 CreatedById 的客户表中插入 2 行,EF 用唯一值限制它。

这是我的流利映射

    protected override void OnModelCreating(ModelBuilder modelBuilder)
    {
        base.OnModelCreating(modelBuilder);
        //User
        modelBuilder.Entity<User>().HasOne(a => a.CreatedBy).WithOne().OnDelete(DeleteBehavior.NoAction);
        modelBuilder.Entity<User>().HasOne(a => a.UpdatedBy).WithOne().OnDelete(DeleteBehavior.NoAction);
        //Project
        modelBuilder.Entity<Project>().HasOne(a => a.CreatedBy).WithOne().OnDelete(DeleteBehavior.NoAction);
        modelBuilder.Entity<Project>().HasOne(a => a.UpdatedBy).WithOne().OnDelete(DeleteBehavior.NoAction);
        //Client
        modelBuilder.Entity<Client>().HasOne(a => a.CreatedBy).WithOne().OnDelete(DeleteBehavior.NoAction);
        modelBuilder.Entity<Client>().HasOne(a => a.UpdatedBy).WithOne().OnDelete(DeleteBehavior.NoAction);
    }

我该如何实现这个要求?

标签: c#sql-serverentity-frameworkef-core-5.0

解决方案


这是与我的实体的关系问题。我让我的属性看起来像

public DateTime? CreatedOn { get; set; }
public DateTime? UpdatedOn { get; set; }
public virtual User CreatedBy { get; set; }
public virtual User UpdatedBy { get; set; }
public int? CreatedById { get; set; }
public int? UpdatedById { get; set; }

并添加了流畅的映射

        protected override void OnModelCreating(ModelBuilder modelBuilder)
        {
            base.OnModelCreating(modelBuilder);
            //User
            modelBuilder.Entity<User>().HasOne(a => a.CreatedBy).WithMany().OnDelete(DeleteBehavior.SetNull);
            modelBuilder.Entity<User>().HasOne(a => a.UpdatedBy).WithMany().OnDelete(DeleteBehavior.SetNull);
            //Project
            modelBuilder.Entity<Project>().HasOne(a => a.CreatedBy).WithMany().OnDelete(DeleteBehavior.SetNull);
            modelBuilder.Entity<Project>().HasOne(a => a.UpdatedBy).WithMany().OnDelete(DeleteBehavior.SetNull);
            //Client
            modelBuilder.Entity<Client>().HasOne(a => a.CreatedBy).WithMany().OnDelete(DeleteBehavior.SetNull);
            modelBuilder.Entity<Client>().HasOne(a => a.UpdatedBy).WithMany().OnDelete(DeleteBehavior.SetNull);
        }

添加一对多关系解决了我的问题。感谢@大卫


推荐阅读