C
C#8mo ago
SWEETPONY

Is it worth to create configurations for dbcontext?

I have following dbcontext:
public sealed class ReadModelDbContext: DbContext
{
public ReadModelDbContext(DbContextOptions<ReadModelDbContext> options)
: base(options)
{
}
protected override void OnModelCreating(ModelBuilder modelBuilder)
{
modelBuilder.Entity<Qualification>().HasIndex(x => x.Identity);
modelBuilder.Entity<Qualification>().HasAlternateKey(x => x.Identity);
modelBuilder.Entity<Function>().HasIndex(x => x.Name);
modelBuilder.Entity<Resource>().HasIndex(x => x.Identity);
modelBuilder.Entity<Node>().HasIndex(x => x.Identity);
modelBuilder.Entity<Location>().HasIndex(x => x.Identity);
}

public DbSet<Qualification> Qualifications => Set<Qualification>();
public DbSet<Function> Functions => Set<Function>();
public DbSet<FunctionQualification> FunctionQualifications => Set<FunctionQualification>();
public DbSet<Resource> Resources => Set<Resource>();
public DbSet<Node> Nodes => Set<Node>();
public DbSet<Location> Locations => Set<Location>();
}
public sealed class ReadModelDbContext: DbContext
{
public ReadModelDbContext(DbContextOptions<ReadModelDbContext> options)
: base(options)
{
}
protected override void OnModelCreating(ModelBuilder modelBuilder)
{
modelBuilder.Entity<Qualification>().HasIndex(x => x.Identity);
modelBuilder.Entity<Qualification>().HasAlternateKey(x => x.Identity);
modelBuilder.Entity<Function>().HasIndex(x => x.Name);
modelBuilder.Entity<Resource>().HasIndex(x => x.Identity);
modelBuilder.Entity<Node>().HasIndex(x => x.Identity);
modelBuilder.Entity<Location>().HasIndex(x => x.Identity);
}

public DbSet<Qualification> Qualifications => Set<Qualification>();
public DbSet<Function> Functions => Set<Function>();
public DbSet<FunctionQualification> FunctionQualifications => Set<FunctionQualification>();
public DbSet<Resource> Resources => Set<Resource>();
public DbSet<Node> Nodes => Set<Node>();
public DbSet<Location> Locations => Set<Location>();
}
I think context doesn't look good that is why I decided to use configurations Example of configuration:
internal class ResourceConfiguration : IEntityTypeConfiguration<Resource>
{
public override void Configure(EntityTypeBuilder<Resource> builder)
{
base.Configure(builder);

builder.Property(p => p.Identity).IsRequired(true);
builder.Property(p => p.Type).IsRequired(true);
builder.Property(p => p.AdditionalData)
.HasColumnType("jsonb")
}
}
internal class ResourceConfiguration : IEntityTypeConfiguration<Resource>
{
public override void Configure(EntityTypeBuilder<Resource> builder)
{
base.Configure(builder);

builder.Property(p => p.Identity).IsRequired(true);
builder.Property(p => p.Type).IsRequired(true);
builder.Property(p => p.AdditionalData)
.HasColumnType("jsonb")
}
}
is it worth it? what is the best practice for such things?
4 Replies
Joschi
Joschi8mo ago
At some point I don't think that there's a way around it. Unless you want you DBContext class to get enormous.
SWEETPONY
SWEETPONY8mo ago
if I'll use configurations then where DbSet properties should be placed? dbcontext right now:
public sealed class ReadModelDbContext: DbContext
{
public ReadModelDbContext(DbContextOptions<ReadModelDbContext> options)
: base(options)
{
}

protected override void OnModelCreating(ModelBuilder modelBuilder)
{
modelBuilder.ApplyConfigurationsFromAssembly(Assembly.GetExecutingAssembly());
}

public DbSet<Qualification> Qualifications => Set<Qualification>();
public DbSet<Function> Functions => Set<Function>();
public DbSet<FunctionQualification> FunctionQualifications => Set<FunctionQualification>();
public DbSet<Resource> Resources => Set<Resource>();
public DbSet<Node> Nodes => Set<Node>();
public DbSet<Location> Locations => Set<Location>();
}
public sealed class ReadModelDbContext: DbContext
{
public ReadModelDbContext(DbContextOptions<ReadModelDbContext> options)
: base(options)
{
}

protected override void OnModelCreating(ModelBuilder modelBuilder)
{
modelBuilder.ApplyConfigurationsFromAssembly(Assembly.GetExecutingAssembly());
}

public DbSet<Qualification> Qualifications => Set<Qualification>();
public DbSet<Function> Functions => Set<Function>();
public DbSet<FunctionQualification> FunctionQualifications => Set<FunctionQualification>();
public DbSet<Resource> Resources => Set<Resource>();
public DbSet<Node> Nodes => Set<Node>();
public DbSet<Location> Locations => Set<Location>();
}
Joschi
Joschi8mo ago
I think those should stay on the DBcontext.
i like chatgpt
i like chatgpt8mo ago
If I were you, I would organize as follows. A single file Resource.cs in YourProject.Models.Resources folder structure.
namespace YourProject.Models.Resources
{
public sealed class Resource
{
public required Guid Id { get; init; }
public required string Name { get; set; } = default!; // or null!
}

public sealed class ResourceConfiguration : IEntityTypeConfiguration<Resource>
{
public void Configure(EntityTypeBuilder<Resource> builder)
{
/*
* Use only for special cases
builder
.Property(p => p.AdditionalData)
.HasColumnType("jsonb")
*/
}
}

}

namespace YourProject.Infrastructure.Commons
{
using YourProject.Models.Resources;

public sealed partial class ReadModelDbContext
{
public DbSet<Resource> Resources { get; private init; }
}
}
namespace YourProject.Models.Resources
{
public sealed class Resource
{
public required Guid Id { get; init; }
public required string Name { get; set; } = default!; // or null!
}

public sealed class ResourceConfiguration : IEntityTypeConfiguration<Resource>
{
public void Configure(EntityTypeBuilder<Resource> builder)
{
/*
* Use only for special cases
builder
.Property(p => p.AdditionalData)
.HasColumnType("jsonb")
*/
}
}

}

namespace YourProject.Infrastructure.Commons
{
using YourProject.Models.Resources;

public sealed partial class ReadModelDbContext
{
public DbSet<Resource> Resources { get; private init; }
}
}
As file scoped namespace cannot be combined with normal namespaces, we have 2 options: - if we want to use just a single file then use normal namespace as mention above. (prefer for the sake of simplicity) - if we want to separate the partial ReadModelDbContext from the remaining one, use either normal namespace or file-scoped namespace. Warning: partial classes cannot work as expected if they are in different namespaces. Because they are considered different types even though their names are identical. The main ReadModelDbContext.cs is saved usually in YourProject.Infrastructure.Commons folder structure.
namespace YourProject.Infrastructure.Commons;
public sealed partial class
ReadModelDbContext(DbContextOptions<ReadModelDbContext> options) :
DbContext(options)
{
protected override void OnModelCreating(ModelBuilder modelBuilder)
{
modelBuilder.ApplyConfigurationsFromAssembly(Assembly.GetExecutingAssembly());
}
}
namespace YourProject.Infrastructure.Commons;
public sealed partial class
ReadModelDbContext(DbContextOptions<ReadModelDbContext> options) :
DbContext(options)
{
protected override void OnModelCreating(ModelBuilder modelBuilder)
{
modelBuilder.ApplyConfigurationsFromAssembly(Assembly.GetExecutingAssembly());
}
}
Want results from more Discord servers?
Add your server