using Microsoft.EntityFrameworkCore; using Microsoft.SelfService.Portal.Core.API.Extensions.Dataannotations; using Microsoft.SelfService.Portal.Core.API.Models; using System.Reflection; namespace Microsoft.SelfService.Portal.Core.API.Context { public class DataContext : DbContext { public DataContext(DbContextOptions options) : base(options) { } public DbSet Events { get; set; } public DbSet Environments { get; set; } public DbSet EnvironmentDomains { get; set; } public DbSet Domains { get; set; } public DbSet VirtualMachines { get; set; } public DbSet Deployments { get; set; } public DbSet DeploymentGroups { get; set; } public DbSet Templates { get; set; } public DbSet TemplateCategories { get; set; } public DbSet Services { get; set; } public DbSet TemplateOptions { get; set; } public DbSet Options { get; set; } public DbSet OptionCategories { get; set; } public DbSet Jobs { get; set; } public DbSet Runbooks { get; set; } protected override void OnModelCreating(ModelBuilder modelBuilder) { base.OnModelCreating(modelBuilder); modelBuilder.Entity() .HasKey(ed => new { ed.EnvironmentId, ed.DomainId }); modelBuilder.Entity() .HasOne(ed => ed.Environment) .WithMany(e => e.EnvironmentDomains) .HasForeignKey(ed => ed.EnvironmentId); modelBuilder.Entity() .HasOne(ed => ed.Domain) .WithMany(d => d.EnvironmentDomains) .HasForeignKey(ed => ed.DomainId); modelBuilder.Entity() .HasKey(to => new { to.OptionId, to.TemplateId }); modelBuilder.Entity() .HasOne(to => to.Option) .WithMany(o => o.TemplateOptions) .HasForeignKey(to => to.OptionId); modelBuilder.Entity() .HasOne(to => to.Template) .WithMany(t => t.TemplateOptions) .HasForeignKey(to => to.TemplateId); modelBuilder.Entity() .HasOne(tc => tc.Service) .WithMany(s => s.TemplateCategories) .HasForeignKey(tc => tc.ServiceId); modelBuilder.Entity() .HasKey(d => new { d.VirtualMachineId, d.DeploymentGroupId }); modelBuilder.Entity() .HasOne(d => d.VirtualMachine) .WithMany(vm => vm.Deployments) .HasForeignKey(d => d.VirtualMachineId); modelBuilder.Entity() .HasOne(d => d.DeploymentGroup) .WithMany(dg => dg.Deployments) .HasForeignKey(d => d.DeploymentGroupId); modelBuilder.Entity() .HasOne(dg => dg.Template) .WithMany(t => t.DeploymentGroups) .HasForeignKey(dg => dg.TemplateId); modelBuilder.Entity() .HasKey(j => new { j.RunbookId, j.DeploymentId }); modelBuilder.Entity() .HasOne(j => j.Deployment) .WithMany(d => d.Jobs) .HasPrincipalKey(d => d.Id) .HasForeignKey(j => j.DeploymentId); modelBuilder.Entity() .HasOne(j => j.Runbook) .WithMany(r => r.Jobs) .HasPrincipalKey(r => r.Id) .HasForeignKey(j => j.RunbookId); modelBuilder.Entity() .HasOne(e => e.Runbook) .WithMany(r => r.Events) .HasPrincipalKey(e => e.Id) .HasForeignKey(r => r.RunbookId); OnModelCreatingAddDefaultSqlValues(modelBuilder); } private void OnModelCreatingAddDefaultSqlValues(ModelBuilder modelBuilder) { var assemblyName = "Microsoft.SelfService.Portal.Core.API"; var nameSpace = "Microsoft.SelfService.Portal.Core.API.Models"; var asm = Assembly.Load(assemblyName); List types = asm.GetTypes().Where(p => p.Namespace == nameSpace).ToList(); var dbSets = typeof(DataContext).GetProperties().Where(p => p.PropertyType.Name.ToLower().Contains("dbset")).ToList(); List dbSetTypes = new List(); foreach (PropertyInfo pi in dbSets) { dbSetTypes.Add(pi.PropertyType.GetGenericArguments()[0]); } foreach (Type t in types) { if (typeof(BaseModel).IsAssignableFrom(t) && t.Name != nameof(BaseModel) && dbSetTypes.Contains(t)) { var properties = t.GetProperties().ToList(); foreach (var p in properties) { var att = p.GetCustomAttribute(); if (att != null) { modelBuilder.Entity(t).Property(p.Name).HasDefaultValueSql(att.DefaultValueSql); } } } } } } }