Welcome to OStack Knowledge Sharing Community for programmer and developer-Open, Learning and Share
Welcome To Ask or Share your Answers For Others

Categories

0 votes
195 views
in Technique[技术] by (71.8m points)

c# - EF Core 5, How to define multiple "one-many" relationships?

I'm creating a freelance task management app. Here is the logic. These are the 3 POCOs involved

User (LoggedIn User)

  1. A user can create any number of clients
  2. A user can create any number of projects
  3. A user is created, updated by another user

Client (Freelance Client)

  1. A client can have any number of projects
  2. A client is created, updated by a user

Project

  1. A project should have only one client
  2. A project is created, updated by a user

These are my Entities. I'm using Code-First approach and uses SQLServer. I removed many properties for posting here

User Entity

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; }        
}

Client Entity

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; }
}

Project Entity

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; }       
}

I'm now facing so many issues with ForginKeys and mappings. What is wrong with the entity mappings here? I can't insert 2 rows in clients table with same CreatedById, EF is constraining it with unique values.

This is my fluent mappings

    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);
    }

How can I implement this requirement?

question from:https://stackoverflow.com/questions/65951571/ef-core-5-how-to-define-multiple-one-many-relationships

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome To Ask or Share your Answers For Others

1 Answer

0 votes
by (71.8m points)

This was a relationship issue with my entities. I made my properties look like

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; }

And added fluent mapping

        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);
        }

Adding One-Many relationship resolved my issue. Thanks to @David


与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome to OStack Knowledge Sharing Community for programmer and developer-Open, Learning and Share
Click Here to Ask a Question

...