asp.net-coreef-fluent-api

ASP.NET Core : Fluent Api relationships configuration


There are a lot of examples how to use Fluent API in the internet, but mostly shows how configure one relationship between two models. In my case I need 3 relationships between 2 models. How to configure relationships between models below with Fluent API?

public class Company
{
    public int Id { get; set; }

    public string Name { get; set; }

    public int FinanceEstimateId { get; set; }
    public Estimate FinanceEstimate { get; set; }

    public int EnvironmentEstimateId { get; set; }
    public Estimate EnvironmentEstimate { get; set; }

    public int SelfEstimateId { get; set; }
    public Estimate SelfEstimate { get; set; }
}

public class Estimate
{
    public int Id { get; set; }
    public string Name { get; set; } // like: bad, good, excellent
    public float Value { get; set; } // like: 1,2,3
}

Solution

  • Maybe this points you in the right direction.

    I would go for 2 configurations like:

    public class CompanyConfiguration : IEntityTypeConfiguration<Company>
    {
        public void Configure(EntityTypeBuilder<Company> builder)
        {
            builder.ToTable("Companies");
    
            builder
                .HasOne(x => x.EnvironmentEstimate)
                .WithMany()
                .HasForeignKey(x => x.EnvironmentEstimateId)
                .OnDelete(DeleteBehavior.NoAction);
    
            builder
                .HasOne(x => x.FinanceEstimate)
                .WithMany()
                .HasForeignKey(x => x.FinanceEstimateId)
                .OnDelete(DeleteBehavior.NoAction);
    
            builder
                .HasOne(x => x.SelfEstimate)
                .WithMany()
                .HasForeignKey(x => x.SelfEstimateId)
                .OnDelete(DeleteBehavior.NoAction);
        }
    }
    
    public class EstimateConfiguration : IEntityTypeConfiguration<Estimate>
    {
        public void Configure(EntityTypeBuilder<Estimate> builder)
        {
            builder.ToTable("Estimates");
        }
    }
    

    You need a DbContext:

    public class MyDbContext : DbContext
    {
        public DbSet<Company> Companies { get; set; } = null!;
    
        protected override void OnConfiguring(DbContextOptionsBuilder optionsBuilder)
        {
            optionsBuilder.UseSqlServer(@"CONNECTIONSTRING");
        }
    
        protected override void OnModelCreating(ModelBuilder modelBuilder)
        {
            base.OnModelCreating(modelBuilder);
            // applies the configuration (those IEntityTypeConfiguration<T> things)
            modelBuilder.ApplyConfigurationsFromAssembly(typeof(MyDbContext).Assembly);
        }
    }
    

    I created a console application that demonstrates the usage

    using var ctx = new MyDbContext();
    await ctx.Database.EnsureDeletedAsync();
    await ctx.Database.EnsureCreatedAsync();
    
    var company1 = new Company
    {
        Name = "Name1",
        EnvironmentEstimate = new Estimate { Name = "EnvironmentEstimate1", Value = 1 },
        FinanceEstimate = new Estimate { Name = "FinanceEstimate1", Value = 2 },
        SelfEstimate = new Estimate { Name = "SelfEstimate1", Value = 3 }
    };
    
    var company2 = new Company
    {
        Name = "Name2",
        EnvironmentEstimate = new Estimate { Name = "EnvironmentEstimate2", Value = 4 },
        FinanceEstimate = new Estimate { Name = "FinanceEstimate2", Value = 5 },
        SelfEstimate = new Estimate { Name = "SelfEstimate2", Value = 6 }
    };
    
    await ctx.Companies.AddAsync(company1);
    await ctx.Companies.AddAsync(company2);
    await ctx.SaveChangesAsync();
    
    var result = await ctx.Companies.ToListAsync();
    
    Console.WriteLine("Done");