Initial code commit.
This commit is contained in:
@@ -0,0 +1,88 @@
|
||||
using Microsoft.AspNetCore.Identity;
|
||||
using Microsoft.EntityFrameworkCore;
|
||||
using Sufi.Demo.PeopleDirectory.Application.Contracts.Services;
|
||||
using Sufi.Demo.PeopleDirectory.Domain.Common;
|
||||
using Sufi.Demo.PeopleDirectory.Domain.Entities.Misc;
|
||||
using Sufi.Demo.PeopleDirectory.Persistence.Models.Identity;
|
||||
|
||||
namespace Sufi.Demo.PeopleDirectory.Persistence.Contexts
|
||||
{
|
||||
public class ApplicationDbContext(
|
||||
DbContextOptions<ApplicationDbContext> options,
|
||||
ICurrentUserService currentUserService
|
||||
) : AuditableContext(options)
|
||||
{
|
||||
public virtual DbSet<Contact> Contacts { get; set; } = null!;
|
||||
public virtual DbSet<ServerInfo> ServerInfos { get; set; } = null!;
|
||||
|
||||
public override Task<int> SaveChangesAsync(string? userId = null, CancellationToken cancellationToken = default)
|
||||
{
|
||||
PopulateAuditRecords();
|
||||
|
||||
return base.SaveChangesAsync(userId, cancellationToken);
|
||||
}
|
||||
|
||||
public override async Task<int> SaveChangesAsync(CancellationToken cancellationToken = default)
|
||||
{
|
||||
PopulateAuditRecords();
|
||||
|
||||
if (currentUserService.UserId == null)
|
||||
{
|
||||
return await base.SaveChangesAsync(cancellationToken);
|
||||
}
|
||||
|
||||
return await base.SaveChangesAsync(currentUserService.UserId, cancellationToken);
|
||||
}
|
||||
|
||||
protected override void OnModelCreating(ModelBuilder builder)
|
||||
{
|
||||
foreach (var property in builder.Model.GetEntityTypes()
|
||||
.SelectMany(t => t.GetProperties())
|
||||
.Where(p => p.ClrType == typeof(decimal) || p.ClrType == typeof(decimal?)))
|
||||
{
|
||||
property.SetColumnType("decimal(18,2)");
|
||||
}
|
||||
|
||||
foreach (var property in builder.Model.GetEntityTypes()
|
||||
.SelectMany(t => t.GetProperties())
|
||||
.Where(p => p.Name is "LastModifiedBy" or "CreatedBy"))
|
||||
{
|
||||
property.SetColumnType("character varying(100)");
|
||||
}
|
||||
|
||||
base.OnModelCreating(builder);
|
||||
|
||||
var assembly = typeof(ApplicationDbContext).Assembly;
|
||||
builder.ApplyConfigurationsFromAssembly(assembly);
|
||||
|
||||
builder.Entity<IdentityUserRole<string>>(entity => entity.ToTable("UserRoles", "Identity"));
|
||||
|
||||
builder.Entity<IdentityUserClaim<string>>(entity => entity.ToTable("UserClaims", "Identity"));
|
||||
|
||||
builder.Entity<IdentityUserLogin<string>>(entity => entity.ToTable("UserLogins", "Identity"));
|
||||
|
||||
builder.Entity<AppRoleClaim>(entity => entity.ToTable("RoleClaims", "Identity"));
|
||||
|
||||
builder.Entity<IdentityUserToken<string>>(entity => entity.ToTable("UserTokens", "Identity"));
|
||||
}
|
||||
|
||||
private void PopulateAuditRecords()
|
||||
{
|
||||
foreach (var entry in ChangeTracker.Entries<IAuditableEntity>().ToList())
|
||||
{
|
||||
switch (entry.State)
|
||||
{
|
||||
case EntityState.Added:
|
||||
entry.Entity.CreatedOn = DateTime.UtcNow;
|
||||
entry.Entity.CreatedBy = currentUserService.UserId;
|
||||
break;
|
||||
|
||||
case EntityState.Modified:
|
||||
entry.Entity.LastModifiedOn = DateTime.UtcNow;
|
||||
entry.Entity.LastModifiedBy = currentUserService.UserId;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,117 @@
|
||||
using Microsoft.AspNetCore.Identity;
|
||||
using Microsoft.AspNetCore.Identity.EntityFrameworkCore;
|
||||
using Microsoft.EntityFrameworkCore;
|
||||
using Microsoft.EntityFrameworkCore.ChangeTracking;
|
||||
using Sufi.Demo.PeopleDirectory.Application.Enums;
|
||||
using Sufi.Demo.PeopleDirectory.Persistence.Models.Audit;
|
||||
using Sufi.Demo.PeopleDirectory.Persistence.Models.Identity;
|
||||
|
||||
namespace Sufi.Demo.PeopleDirectory.Persistence.Contexts
|
||||
{
|
||||
public abstract class AuditableContext(
|
||||
DbContextOptions options
|
||||
) : IdentityDbContext<AppUser, AppRole, string, IdentityUserClaim<string>, IdentityUserRole<string>,
|
||||
IdentityUserLogin<string>, AppRoleClaim, IdentityUserToken<string>>(options)
|
||||
{
|
||||
public DbSet<Audit> AuditTrails { get; set; } = null!;
|
||||
|
||||
protected override void OnModelCreating(ModelBuilder builder)
|
||||
{
|
||||
base.OnModelCreating(builder);
|
||||
|
||||
builder.Entity<Audit>().ToTable("AuditTrails", "Audit");
|
||||
}
|
||||
|
||||
public virtual async Task<int> SaveChangesAsync(string? userId = null, CancellationToken cancellationToken = new())
|
||||
{
|
||||
var auditEntries = OnBeforeSaveChanges(userId);
|
||||
var result = await base.SaveChangesAsync(cancellationToken);
|
||||
await OnAfterSaveChanges(auditEntries, cancellationToken);
|
||||
return result;
|
||||
}
|
||||
|
||||
private List<AuditEntry> OnBeforeSaveChanges(string? userId)
|
||||
{
|
||||
ChangeTracker.DetectChanges();
|
||||
var auditEntries = new List<AuditEntry>();
|
||||
foreach (var entry in ChangeTracker.Entries())
|
||||
{
|
||||
if (entry.Entity is Audit || entry.State == EntityState.Detached || entry.State == EntityState.Unchanged)
|
||||
continue;
|
||||
|
||||
var auditEntry = new AuditEntry(entry)
|
||||
{
|
||||
TableName = entry.Entity.GetType().Name,
|
||||
UserId = userId
|
||||
};
|
||||
auditEntries.Add(auditEntry);
|
||||
foreach (var property in entry.Properties)
|
||||
{
|
||||
if (property.IsTemporary)
|
||||
{
|
||||
auditEntry.TemporaryProperties.Add(property);
|
||||
continue;
|
||||
}
|
||||
|
||||
string propertyName = property.Metadata.Name;
|
||||
if (property.Metadata.IsPrimaryKey())
|
||||
{
|
||||
auditEntry.KeyValues[propertyName] = property.CurrentValue;
|
||||
continue;
|
||||
}
|
||||
|
||||
switch (entry.State)
|
||||
{
|
||||
case EntityState.Added:
|
||||
auditEntry.AuditType = AuditType.Create;
|
||||
auditEntry.NewValues[propertyName] = property.CurrentValue;
|
||||
break;
|
||||
|
||||
case EntityState.Deleted:
|
||||
auditEntry.AuditType = AuditType.Delete;
|
||||
auditEntry.OldValues[propertyName] = property.OriginalValue;
|
||||
break;
|
||||
|
||||
case EntityState.Modified:
|
||||
if (property.IsModified && property.OriginalValue?.Equals(property.CurrentValue) == false)
|
||||
{
|
||||
auditEntry.ChangedColumns.Add(propertyName);
|
||||
auditEntry.AuditType = AuditType.Update;
|
||||
auditEntry.OldValues[propertyName] = property.OriginalValue;
|
||||
auditEntry.NewValues[propertyName] = property.CurrentValue;
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
foreach (var auditEntry in auditEntries.Where(_ => !_.HasTemporaryProperties))
|
||||
{
|
||||
AuditTrails.Add(auditEntry.ToAudit());
|
||||
}
|
||||
return [.. auditEntries.Where(_ => _.HasTemporaryProperties)];
|
||||
}
|
||||
|
||||
private Task OnAfterSaveChanges(List<AuditEntry> auditEntries, CancellationToken cancellationToken = new())
|
||||
{
|
||||
if (auditEntries == null || auditEntries.Count == 0)
|
||||
return Task.CompletedTask;
|
||||
|
||||
foreach (var auditEntry in auditEntries)
|
||||
{
|
||||
foreach (var prop in auditEntry.TemporaryProperties)
|
||||
{
|
||||
if (prop.Metadata.IsPrimaryKey())
|
||||
{
|
||||
auditEntry.KeyValues[prop.Metadata.Name] = prop.CurrentValue;
|
||||
}
|
||||
else
|
||||
{
|
||||
auditEntry.NewValues[prop.Metadata.Name] = prop.CurrentValue;
|
||||
}
|
||||
}
|
||||
AuditTrails.Add(auditEntry.ToAudit());
|
||||
}
|
||||
return SaveChangesAsync(cancellationToken);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,14 @@
|
||||
using Microsoft.EntityFrameworkCore;
|
||||
using Microsoft.EntityFrameworkCore.Metadata.Builders;
|
||||
using Sufi.Demo.PeopleDirectory.Persistence.Models.Identity;
|
||||
|
||||
namespace Sufi.Demo.PeopleDirectory.Persistence.Contexts.EntityMaps
|
||||
{
|
||||
public class AppRoleMap : IEntityTypeConfiguration<AppRole>
|
||||
{
|
||||
public void Configure(EntityTypeBuilder<AppRole> builder)
|
||||
{
|
||||
builder.ToTable("Roles", "Identity");
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,16 @@
|
||||
using Microsoft.EntityFrameworkCore;
|
||||
using Microsoft.EntityFrameworkCore.Metadata.Builders;
|
||||
using Sufi.Demo.PeopleDirectory.Persistence.Models.Identity;
|
||||
|
||||
namespace Sufi.Demo.PeopleDirectory.Persistence.Contexts.EntityMaps
|
||||
{
|
||||
public class AppUserMap : IEntityTypeConfiguration<AppUser>
|
||||
{
|
||||
public void Configure(EntityTypeBuilder<AppUser> builder)
|
||||
{
|
||||
builder.ToTable("Users", "Identity");
|
||||
|
||||
builder.Property(e => e.Id).ValueGeneratedOnAdd();
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,39 @@
|
||||
using Microsoft.AspNetCore.Identity;
|
||||
using Microsoft.EntityFrameworkCore;
|
||||
using Microsoft.Extensions.Configuration;
|
||||
using Microsoft.Extensions.DependencyInjection;
|
||||
using Sufi.Demo.PeopleDirectory.Application.Contracts.Repositories;
|
||||
using Sufi.Demo.PeopleDirectory.Persistence.Contexts;
|
||||
using Sufi.Demo.PeopleDirectory.Persistence.Models.Identity;
|
||||
using Sufi.Demo.PeopleDirectory.Persistence.Repositories;
|
||||
|
||||
namespace Sufi.Demo.PeopleDirectory.Persistence.Extensions
|
||||
{
|
||||
public static class ServiceCollectionExtensions
|
||||
{
|
||||
public static IServiceCollection AddPersistenceServices(this IServiceCollection services, IConfiguration configuration)
|
||||
{
|
||||
services.AddDbContext<ApplicationDbContext>(options => options.UseNpgsql(configuration.GetConnectionString("DefaultConnectionString")!));
|
||||
|
||||
services
|
||||
.AddIdentityCore<AppUser>(options =>
|
||||
{
|
||||
options.Password.RequiredLength = 6;
|
||||
options.Password.RequireDigit = false;
|
||||
options.Password.RequireLowercase = false;
|
||||
options.Password.RequireNonAlphanumeric = false;
|
||||
options.Password.RequireUppercase = false;
|
||||
options.User.RequireUniqueEmail = true;
|
||||
})
|
||||
.AddRoles<AppRole>()
|
||||
.AddEntityFrameworkStores<ApplicationDbContext>()
|
||||
.AddDefaultTokenProviders();
|
||||
|
||||
services
|
||||
.AddTransient(typeof(IAsyncRepository<,>), typeof(AsyncRepository<,>))
|
||||
.AddTransient(typeof(IUnitOfWork<>), typeof(UnitOfWork<>));
|
||||
|
||||
return services;
|
||||
}
|
||||
}
|
||||
}
|
||||
457
Sufi.Demo.PeopleDirectory.Persistence/Migrations/20250527161934_InitialSchema.Designer.cs
generated
Normal file
457
Sufi.Demo.PeopleDirectory.Persistence/Migrations/20250527161934_InitialSchema.Designer.cs
generated
Normal file
@@ -0,0 +1,457 @@
|
||||
// <auto-generated />
|
||||
using System;
|
||||
using Microsoft.EntityFrameworkCore;
|
||||
using Microsoft.EntityFrameworkCore.Infrastructure;
|
||||
using Microsoft.EntityFrameworkCore.Migrations;
|
||||
using Microsoft.EntityFrameworkCore.Storage.ValueConversion;
|
||||
using Npgsql.EntityFrameworkCore.PostgreSQL.Metadata;
|
||||
using Sufi.Demo.PeopleDirectory.Persistence.Contexts;
|
||||
|
||||
#nullable disable
|
||||
|
||||
namespace Sufi.Demo.PeopleDirectory.Persistence.Migrations
|
||||
{
|
||||
[DbContext(typeof(ApplicationDbContext))]
|
||||
[Migration("20250527161934_InitialSchema")]
|
||||
partial class InitialSchema
|
||||
{
|
||||
/// <inheritdoc />
|
||||
protected override void BuildTargetModel(ModelBuilder modelBuilder)
|
||||
{
|
||||
#pragma warning disable 612, 618
|
||||
modelBuilder
|
||||
.HasAnnotation("ProductVersion", "8.0.11")
|
||||
.HasAnnotation("Relational:MaxIdentifierLength", 63);
|
||||
|
||||
NpgsqlModelBuilderExtensions.UseIdentityByDefaultColumns(modelBuilder);
|
||||
|
||||
modelBuilder.Entity("Microsoft.AspNetCore.Identity.IdentityUserClaim<string>", b =>
|
||||
{
|
||||
b.Property<int>("Id")
|
||||
.ValueGeneratedOnAdd()
|
||||
.HasColumnType("integer");
|
||||
|
||||
NpgsqlPropertyBuilderExtensions.UseIdentityByDefaultColumn(b.Property<int>("Id"));
|
||||
|
||||
b.Property<string>("ClaimType")
|
||||
.HasColumnType("text");
|
||||
|
||||
b.Property<string>("ClaimValue")
|
||||
.HasColumnType("text");
|
||||
|
||||
b.Property<string>("UserId")
|
||||
.IsRequired()
|
||||
.HasColumnType("text");
|
||||
|
||||
b.HasKey("Id");
|
||||
|
||||
b.HasIndex("UserId");
|
||||
|
||||
b.ToTable("UserClaims", "Identity");
|
||||
});
|
||||
|
||||
modelBuilder.Entity("Microsoft.AspNetCore.Identity.IdentityUserLogin<string>", b =>
|
||||
{
|
||||
b.Property<string>("LoginProvider")
|
||||
.HasColumnType("text");
|
||||
|
||||
b.Property<string>("ProviderKey")
|
||||
.HasColumnType("text");
|
||||
|
||||
b.Property<string>("ProviderDisplayName")
|
||||
.HasColumnType("text");
|
||||
|
||||
b.Property<string>("UserId")
|
||||
.IsRequired()
|
||||
.HasColumnType("text");
|
||||
|
||||
b.HasKey("LoginProvider", "ProviderKey");
|
||||
|
||||
b.HasIndex("UserId");
|
||||
|
||||
b.ToTable("UserLogins", "Identity");
|
||||
});
|
||||
|
||||
modelBuilder.Entity("Microsoft.AspNetCore.Identity.IdentityUserRole<string>", b =>
|
||||
{
|
||||
b.Property<string>("UserId")
|
||||
.HasColumnType("text");
|
||||
|
||||
b.Property<string>("RoleId")
|
||||
.HasColumnType("text");
|
||||
|
||||
b.HasKey("UserId", "RoleId");
|
||||
|
||||
b.HasIndex("RoleId");
|
||||
|
||||
b.ToTable("UserRoles", "Identity");
|
||||
});
|
||||
|
||||
modelBuilder.Entity("Microsoft.AspNetCore.Identity.IdentityUserToken<string>", b =>
|
||||
{
|
||||
b.Property<string>("UserId")
|
||||
.HasColumnType("text");
|
||||
|
||||
b.Property<string>("LoginProvider")
|
||||
.HasColumnType("text");
|
||||
|
||||
b.Property<string>("Name")
|
||||
.HasColumnType("text");
|
||||
|
||||
b.Property<string>("Value")
|
||||
.HasColumnType("text");
|
||||
|
||||
b.HasKey("UserId", "LoginProvider", "Name");
|
||||
|
||||
b.ToTable("UserTokens", "Identity");
|
||||
});
|
||||
|
||||
modelBuilder.Entity("Sufi.Demo.PeopleDirectory.Domain.Entities.Misc.Contact", b =>
|
||||
{
|
||||
b.Property<int>("Id")
|
||||
.ValueGeneratedOnAdd()
|
||||
.HasColumnType("integer");
|
||||
|
||||
NpgsqlPropertyBuilderExtensions.UseIdentityByDefaultColumn(b.Property<int>("Id"));
|
||||
|
||||
b.Property<string>("CreatedBy")
|
||||
.HasColumnType("character varying(100)");
|
||||
|
||||
b.Property<DateTime>("CreatedOn")
|
||||
.HasColumnType("timestamp with time zone");
|
||||
|
||||
b.Property<string>("Email")
|
||||
.IsRequired()
|
||||
.HasColumnType("character varying(100)");
|
||||
|
||||
b.Property<string>("Hobby")
|
||||
.IsRequired()
|
||||
.HasColumnType("character varying(255)");
|
||||
|
||||
b.Property<string>("LastModifiedBy")
|
||||
.HasColumnType("character varying(100)");
|
||||
|
||||
b.Property<DateTime?>("LastModifiedOn")
|
||||
.HasColumnType("timestamp with time zone");
|
||||
|
||||
b.Property<string>("Phone")
|
||||
.IsRequired()
|
||||
.HasColumnType("character varying(20)");
|
||||
|
||||
b.Property<string>("SkillSets")
|
||||
.IsRequired()
|
||||
.HasColumnType("character varying(255)");
|
||||
|
||||
b.Property<string>("UserName")
|
||||
.IsRequired()
|
||||
.HasColumnType("character varying(50)");
|
||||
|
||||
b.HasKey("Id");
|
||||
|
||||
b.ToTable("Contacts");
|
||||
});
|
||||
|
||||
modelBuilder.Entity("Sufi.Demo.PeopleDirectory.Domain.Entities.Misc.ServerInfo", b =>
|
||||
{
|
||||
b.Property<string>("Id")
|
||||
.HasColumnType("text");
|
||||
|
||||
b.Property<string>("CreatedBy")
|
||||
.HasColumnType("character varying(100)");
|
||||
|
||||
b.Property<DateTime>("CreatedOn")
|
||||
.HasColumnType("timestamp with time zone");
|
||||
|
||||
b.Property<string>("LastModifiedBy")
|
||||
.HasColumnType("character varying(100)");
|
||||
|
||||
b.Property<DateTime?>("LastModifiedOn")
|
||||
.HasColumnType("timestamp with time zone");
|
||||
|
||||
b.Property<string>("Value")
|
||||
.IsRequired()
|
||||
.HasColumnType("character varying(255)");
|
||||
|
||||
b.HasKey("Id");
|
||||
|
||||
b.ToTable("ServerInfos");
|
||||
});
|
||||
|
||||
modelBuilder.Entity("Sufi.Demo.PeopleDirectory.Infrastructure.Models.Audit.Audit", b =>
|
||||
{
|
||||
b.Property<int>("Id")
|
||||
.ValueGeneratedOnAdd()
|
||||
.HasColumnType("integer");
|
||||
|
||||
NpgsqlPropertyBuilderExtensions.UseIdentityByDefaultColumn(b.Property<int>("Id"));
|
||||
|
||||
b.Property<string>("AffectedColumns")
|
||||
.HasColumnType("character varying(100)");
|
||||
|
||||
b.Property<DateTime>("DateTime")
|
||||
.HasColumnType("timestamp with time zone");
|
||||
|
||||
b.Property<string>("NewValues")
|
||||
.HasColumnType("character varying(255)");
|
||||
|
||||
b.Property<string>("OldValues")
|
||||
.HasColumnType("character varying(255)");
|
||||
|
||||
b.Property<string>("PrimaryKey")
|
||||
.IsRequired()
|
||||
.HasColumnType("character varying(100)");
|
||||
|
||||
b.Property<string>("TableName")
|
||||
.IsRequired()
|
||||
.HasColumnType("character varying(50)");
|
||||
|
||||
b.Property<string>("Type")
|
||||
.IsRequired()
|
||||
.HasColumnType("character varying(20)");
|
||||
|
||||
b.Property<string>("UserId")
|
||||
.HasColumnType("character varying(100)");
|
||||
|
||||
b.HasKey("Id");
|
||||
|
||||
b.ToTable("AuditTrails", "Audit");
|
||||
});
|
||||
|
||||
modelBuilder.Entity("Sufi.Demo.PeopleDirectory.Infrastructure.Models.Identity.AppRole", b =>
|
||||
{
|
||||
b.Property<string>("Id")
|
||||
.HasColumnType("text");
|
||||
|
||||
b.Property<string>("ConcurrencyStamp")
|
||||
.IsConcurrencyToken()
|
||||
.HasColumnType("text");
|
||||
|
||||
b.Property<string>("CreatedBy")
|
||||
.HasColumnType("character varying(100)");
|
||||
|
||||
b.Property<DateTime>("CreatedOn")
|
||||
.HasColumnType("timestamp with time zone");
|
||||
|
||||
b.Property<string>("Description")
|
||||
.HasColumnType("character varying(100)");
|
||||
|
||||
b.Property<string>("LastModifiedBy")
|
||||
.HasColumnType("character varying(100)");
|
||||
|
||||
b.Property<DateTime?>("LastModifiedOn")
|
||||
.HasColumnType("timestamp with time zone");
|
||||
|
||||
b.Property<string>("Name")
|
||||
.HasMaxLength(256)
|
||||
.HasColumnType("character varying(256)");
|
||||
|
||||
b.Property<string>("NormalizedName")
|
||||
.HasMaxLength(256)
|
||||
.HasColumnType("character varying(256)");
|
||||
|
||||
b.HasKey("Id");
|
||||
|
||||
b.HasIndex("NormalizedName")
|
||||
.IsUnique()
|
||||
.HasDatabaseName("RoleNameIndex");
|
||||
|
||||
b.ToTable("Roles", "Identity");
|
||||
});
|
||||
|
||||
modelBuilder.Entity("Sufi.Demo.PeopleDirectory.Infrastructure.Models.Identity.AppRoleClaim", b =>
|
||||
{
|
||||
b.Property<int>("Id")
|
||||
.ValueGeneratedOnAdd()
|
||||
.HasColumnType("integer");
|
||||
|
||||
NpgsqlPropertyBuilderExtensions.UseIdentityByDefaultColumn(b.Property<int>("Id"));
|
||||
|
||||
b.Property<string>("AppRoleId")
|
||||
.HasColumnType("text");
|
||||
|
||||
b.Property<string>("ClaimType")
|
||||
.HasColumnType("text");
|
||||
|
||||
b.Property<string>("ClaimValue")
|
||||
.HasColumnType("text");
|
||||
|
||||
b.Property<string>("CreatedBy")
|
||||
.HasColumnType("character varying(100)");
|
||||
|
||||
b.Property<DateTime>("CreatedOn")
|
||||
.HasColumnType("timestamp with time zone");
|
||||
|
||||
b.Property<string>("Description")
|
||||
.HasColumnType("character varying(100)");
|
||||
|
||||
b.Property<string>("Group")
|
||||
.HasColumnType("character varying(100)");
|
||||
|
||||
b.Property<string>("LastModifiedBy")
|
||||
.HasColumnType("character varying(100)");
|
||||
|
||||
b.Property<DateTime?>("LastModifiedOn")
|
||||
.HasColumnType("timestamp with time zone");
|
||||
|
||||
b.Property<string>("RoleId")
|
||||
.IsRequired()
|
||||
.HasColumnType("text");
|
||||
|
||||
b.HasKey("Id");
|
||||
|
||||
b.HasIndex("AppRoleId");
|
||||
|
||||
b.HasIndex("RoleId");
|
||||
|
||||
b.ToTable("RoleClaims", "Identity");
|
||||
});
|
||||
|
||||
modelBuilder.Entity("Sufi.Demo.PeopleDirectory.Infrastructure.Models.Identity.AppUser", b =>
|
||||
{
|
||||
b.Property<string>("Id")
|
||||
.ValueGeneratedOnAdd()
|
||||
.HasColumnType("text");
|
||||
|
||||
b.Property<int>("AccessFailedCount")
|
||||
.HasColumnType("integer");
|
||||
|
||||
b.Property<string>("ConcurrencyStamp")
|
||||
.IsConcurrencyToken()
|
||||
.HasColumnType("text");
|
||||
|
||||
b.Property<string>("CreatedBy")
|
||||
.HasColumnType("character varying(100)");
|
||||
|
||||
b.Property<DateTime>("CreatedOn")
|
||||
.HasColumnType("timestamp with time zone");
|
||||
|
||||
b.Property<DateTime?>("DeletedOn")
|
||||
.HasColumnType("timestamp with time zone");
|
||||
|
||||
b.Property<string>("Email")
|
||||
.HasMaxLength(256)
|
||||
.HasColumnType("character varying(256)");
|
||||
|
||||
b.Property<bool>("EmailConfirmed")
|
||||
.HasColumnType("boolean");
|
||||
|
||||
b.Property<bool>("IsActive")
|
||||
.HasColumnType("boolean");
|
||||
|
||||
b.Property<bool>("IsDeleted")
|
||||
.HasColumnType("boolean");
|
||||
|
||||
b.Property<string>("LastModifiedBy")
|
||||
.HasColumnType("character varying(100)");
|
||||
|
||||
b.Property<DateTime?>("LastModifiedOn")
|
||||
.HasColumnType("timestamp with time zone");
|
||||
|
||||
b.Property<bool>("LockoutEnabled")
|
||||
.HasColumnType("boolean");
|
||||
|
||||
b.Property<DateTimeOffset?>("LockoutEnd")
|
||||
.HasColumnType("timestamp with time zone");
|
||||
|
||||
b.Property<string>("NormalizedEmail")
|
||||
.HasMaxLength(256)
|
||||
.HasColumnType("character varying(256)");
|
||||
|
||||
b.Property<string>("NormalizedUserName")
|
||||
.HasMaxLength(256)
|
||||
.HasColumnType("character varying(256)");
|
||||
|
||||
b.Property<string>("PasswordHash")
|
||||
.HasColumnType("text");
|
||||
|
||||
b.Property<string>("PhoneNumber")
|
||||
.HasColumnType("text");
|
||||
|
||||
b.Property<bool>("PhoneNumberConfirmed")
|
||||
.HasColumnType("boolean");
|
||||
|
||||
b.Property<string>("SecurityStamp")
|
||||
.HasColumnType("text");
|
||||
|
||||
b.Property<bool>("TwoFactorEnabled")
|
||||
.HasColumnType("boolean");
|
||||
|
||||
b.Property<string>("UserName")
|
||||
.HasMaxLength(256)
|
||||
.HasColumnType("character varying(256)");
|
||||
|
||||
b.HasKey("Id");
|
||||
|
||||
b.HasIndex("NormalizedEmail")
|
||||
.HasDatabaseName("EmailIndex");
|
||||
|
||||
b.HasIndex("NormalizedUserName")
|
||||
.IsUnique()
|
||||
.HasDatabaseName("UserNameIndex");
|
||||
|
||||
b.ToTable("Users", "Identity");
|
||||
});
|
||||
|
||||
modelBuilder.Entity("Microsoft.AspNetCore.Identity.IdentityUserClaim<string>", b =>
|
||||
{
|
||||
b.HasOne("Sufi.Demo.PeopleDirectory.Infrastructure.Models.Identity.AppUser", null)
|
||||
.WithMany()
|
||||
.HasForeignKey("UserId")
|
||||
.OnDelete(DeleteBehavior.Cascade)
|
||||
.IsRequired();
|
||||
});
|
||||
|
||||
modelBuilder.Entity("Microsoft.AspNetCore.Identity.IdentityUserLogin<string>", b =>
|
||||
{
|
||||
b.HasOne("Sufi.Demo.PeopleDirectory.Infrastructure.Models.Identity.AppUser", null)
|
||||
.WithMany()
|
||||
.HasForeignKey("UserId")
|
||||
.OnDelete(DeleteBehavior.Cascade)
|
||||
.IsRequired();
|
||||
});
|
||||
|
||||
modelBuilder.Entity("Microsoft.AspNetCore.Identity.IdentityUserRole<string>", b =>
|
||||
{
|
||||
b.HasOne("Sufi.Demo.PeopleDirectory.Infrastructure.Models.Identity.AppRole", null)
|
||||
.WithMany()
|
||||
.HasForeignKey("RoleId")
|
||||
.OnDelete(DeleteBehavior.Cascade)
|
||||
.IsRequired();
|
||||
|
||||
b.HasOne("Sufi.Demo.PeopleDirectory.Infrastructure.Models.Identity.AppUser", null)
|
||||
.WithMany()
|
||||
.HasForeignKey("UserId")
|
||||
.OnDelete(DeleteBehavior.Cascade)
|
||||
.IsRequired();
|
||||
});
|
||||
|
||||
modelBuilder.Entity("Microsoft.AspNetCore.Identity.IdentityUserToken<string>", b =>
|
||||
{
|
||||
b.HasOne("Sufi.Demo.PeopleDirectory.Infrastructure.Models.Identity.AppUser", null)
|
||||
.WithMany()
|
||||
.HasForeignKey("UserId")
|
||||
.OnDelete(DeleteBehavior.Cascade)
|
||||
.IsRequired();
|
||||
});
|
||||
|
||||
modelBuilder.Entity("Sufi.Demo.PeopleDirectory.Infrastructure.Models.Identity.AppRoleClaim", b =>
|
||||
{
|
||||
b.HasOne("Sufi.Demo.PeopleDirectory.Infrastructure.Models.Identity.AppRole", null)
|
||||
.WithMany("RoleClaims")
|
||||
.HasForeignKey("AppRoleId");
|
||||
|
||||
b.HasOne("Sufi.Demo.PeopleDirectory.Infrastructure.Models.Identity.AppRole", null)
|
||||
.WithMany()
|
||||
.HasForeignKey("RoleId")
|
||||
.OnDelete(DeleteBehavior.Cascade)
|
||||
.IsRequired();
|
||||
});
|
||||
|
||||
modelBuilder.Entity("Sufi.Demo.PeopleDirectory.Infrastructure.Models.Identity.AppRole", b =>
|
||||
{
|
||||
b.Navigation("RoleClaims");
|
||||
});
|
||||
#pragma warning restore 612, 618
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,355 @@
|
||||
using System;
|
||||
using Microsoft.EntityFrameworkCore.Migrations;
|
||||
using Npgsql.EntityFrameworkCore.PostgreSQL.Metadata;
|
||||
|
||||
#nullable disable
|
||||
|
||||
namespace Sufi.Demo.PeopleDirectory.Persistence.Migrations
|
||||
{
|
||||
/// <inheritdoc />
|
||||
public partial class InitialSchema : Migration
|
||||
{
|
||||
/// <inheritdoc />
|
||||
protected override void Up(MigrationBuilder migrationBuilder)
|
||||
{
|
||||
migrationBuilder.EnsureSchema(
|
||||
name: "Audit");
|
||||
|
||||
migrationBuilder.EnsureSchema(
|
||||
name: "Identity");
|
||||
|
||||
migrationBuilder.CreateTable(
|
||||
name: "AuditTrails",
|
||||
schema: "Audit",
|
||||
columns: table => new
|
||||
{
|
||||
Id = table.Column<int>(type: "integer", nullable: false)
|
||||
.Annotation("Npgsql:ValueGenerationStrategy", NpgsqlValueGenerationStrategy.IdentityByDefaultColumn),
|
||||
UserId = table.Column<string>(type: "character varying(100)", nullable: true),
|
||||
Type = table.Column<string>(type: "character varying(20)", nullable: false),
|
||||
TableName = table.Column<string>(type: "character varying(50)", nullable: false),
|
||||
DateTime = table.Column<DateTime>(type: "timestamp with time zone", nullable: false),
|
||||
OldValues = table.Column<string>(type: "character varying(255)", nullable: true),
|
||||
NewValues = table.Column<string>(type: "character varying(255)", nullable: true),
|
||||
AffectedColumns = table.Column<string>(type: "character varying(100)", nullable: true),
|
||||
PrimaryKey = table.Column<string>(type: "character varying(100)", nullable: false)
|
||||
},
|
||||
constraints: table =>
|
||||
{
|
||||
table.PrimaryKey("PK_AuditTrails", x => x.Id);
|
||||
});
|
||||
|
||||
migrationBuilder.CreateTable(
|
||||
name: "Contacts",
|
||||
columns: table => new
|
||||
{
|
||||
Id = table.Column<int>(type: "integer", nullable: false)
|
||||
.Annotation("Npgsql:ValueGenerationStrategy", NpgsqlValueGenerationStrategy.IdentityByDefaultColumn),
|
||||
UserName = table.Column<string>(type: "character varying(50)", nullable: false),
|
||||
Phone = table.Column<string>(type: "character varying(20)", nullable: false),
|
||||
Email = table.Column<string>(type: "character varying(100)", nullable: false),
|
||||
SkillSets = table.Column<string>(type: "character varying(255)", nullable: false),
|
||||
Hobby = table.Column<string>(type: "character varying(255)", nullable: false),
|
||||
CreatedBy = table.Column<string>(type: "character varying(100)", nullable: true),
|
||||
CreatedOn = table.Column<DateTime>(type: "timestamp with time zone", nullable: false),
|
||||
LastModifiedBy = table.Column<string>(type: "character varying(100)", nullable: true),
|
||||
LastModifiedOn = table.Column<DateTime>(type: "timestamp with time zone", nullable: true)
|
||||
},
|
||||
constraints: table =>
|
||||
{
|
||||
table.PrimaryKey("PK_Contacts", x => x.Id);
|
||||
});
|
||||
|
||||
migrationBuilder.CreateTable(
|
||||
name: "Roles",
|
||||
schema: "Identity",
|
||||
columns: table => new
|
||||
{
|
||||
Id = table.Column<string>(type: "text", nullable: false),
|
||||
Description = table.Column<string>(type: "character varying(100)", nullable: true),
|
||||
CreatedBy = table.Column<string>(type: "character varying(100)", nullable: true),
|
||||
CreatedOn = table.Column<DateTime>(type: "timestamp with time zone", nullable: false),
|
||||
LastModifiedBy = table.Column<string>(type: "character varying(100)", nullable: true),
|
||||
LastModifiedOn = table.Column<DateTime>(type: "timestamp with time zone", nullable: true),
|
||||
Name = table.Column<string>(type: "character varying(256)", maxLength: 256, nullable: true),
|
||||
NormalizedName = table.Column<string>(type: "character varying(256)", maxLength: 256, nullable: true),
|
||||
ConcurrencyStamp = table.Column<string>(type: "text", nullable: true)
|
||||
},
|
||||
constraints: table =>
|
||||
{
|
||||
table.PrimaryKey("PK_Roles", x => x.Id);
|
||||
});
|
||||
|
||||
migrationBuilder.CreateTable(
|
||||
name: "ServerInfos",
|
||||
columns: table => new
|
||||
{
|
||||
Id = table.Column<string>(type: "text", nullable: false),
|
||||
Value = table.Column<string>(type: "character varying(255)", nullable: false),
|
||||
CreatedBy = table.Column<string>(type: "character varying(100)", nullable: true),
|
||||
CreatedOn = table.Column<DateTime>(type: "timestamp with time zone", nullable: false),
|
||||
LastModifiedBy = table.Column<string>(type: "character varying(100)", nullable: true),
|
||||
LastModifiedOn = table.Column<DateTime>(type: "timestamp with time zone", nullable: true)
|
||||
},
|
||||
constraints: table =>
|
||||
{
|
||||
table.PrimaryKey("PK_ServerInfos", x => x.Id);
|
||||
});
|
||||
|
||||
migrationBuilder.CreateTable(
|
||||
name: "Users",
|
||||
schema: "Identity",
|
||||
columns: table => new
|
||||
{
|
||||
Id = table.Column<string>(type: "text", nullable: false),
|
||||
IsActive = table.Column<bool>(type: "boolean", nullable: false),
|
||||
IsDeleted = table.Column<bool>(type: "boolean", nullable: false),
|
||||
DeletedOn = table.Column<DateTime>(type: "timestamp with time zone", nullable: true),
|
||||
CreatedBy = table.Column<string>(type: "character varying(100)", nullable: true),
|
||||
CreatedOn = table.Column<DateTime>(type: "timestamp with time zone", nullable: false),
|
||||
LastModifiedBy = table.Column<string>(type: "character varying(100)", nullable: true),
|
||||
LastModifiedOn = table.Column<DateTime>(type: "timestamp with time zone", nullable: true),
|
||||
UserName = table.Column<string>(type: "character varying(256)", maxLength: 256, nullable: true),
|
||||
NormalizedUserName = table.Column<string>(type: "character varying(256)", maxLength: 256, nullable: true),
|
||||
Email = table.Column<string>(type: "character varying(256)", maxLength: 256, nullable: true),
|
||||
NormalizedEmail = table.Column<string>(type: "character varying(256)", maxLength: 256, nullable: true),
|
||||
EmailConfirmed = table.Column<bool>(type: "boolean", nullable: false),
|
||||
PasswordHash = table.Column<string>(type: "text", nullable: true),
|
||||
SecurityStamp = table.Column<string>(type: "text", nullable: true),
|
||||
ConcurrencyStamp = table.Column<string>(type: "text", nullable: true),
|
||||
PhoneNumber = table.Column<string>(type: "text", nullable: true),
|
||||
PhoneNumberConfirmed = table.Column<bool>(type: "boolean", nullable: false),
|
||||
TwoFactorEnabled = table.Column<bool>(type: "boolean", nullable: false),
|
||||
LockoutEnd = table.Column<DateTimeOffset>(type: "timestamp with time zone", nullable: true),
|
||||
LockoutEnabled = table.Column<bool>(type: "boolean", nullable: false),
|
||||
AccessFailedCount = table.Column<int>(type: "integer", nullable: false)
|
||||
},
|
||||
constraints: table =>
|
||||
{
|
||||
table.PrimaryKey("PK_Users", x => x.Id);
|
||||
});
|
||||
|
||||
migrationBuilder.CreateTable(
|
||||
name: "RoleClaims",
|
||||
schema: "Identity",
|
||||
columns: table => new
|
||||
{
|
||||
Id = table.Column<int>(type: "integer", nullable: false)
|
||||
.Annotation("Npgsql:ValueGenerationStrategy", NpgsqlValueGenerationStrategy.IdentityByDefaultColumn),
|
||||
Description = table.Column<string>(type: "character varying(100)", nullable: true),
|
||||
Group = table.Column<string>(type: "character varying(100)", nullable: true),
|
||||
CreatedBy = table.Column<string>(type: "character varying(100)", nullable: true),
|
||||
CreatedOn = table.Column<DateTime>(type: "timestamp with time zone", nullable: false),
|
||||
LastModifiedBy = table.Column<string>(type: "character varying(100)", nullable: true),
|
||||
LastModifiedOn = table.Column<DateTime>(type: "timestamp with time zone", nullable: true),
|
||||
AppRoleId = table.Column<string>(type: "text", nullable: true),
|
||||
RoleId = table.Column<string>(type: "text", nullable: false),
|
||||
ClaimType = table.Column<string>(type: "text", nullable: true),
|
||||
ClaimValue = table.Column<string>(type: "text", nullable: true)
|
||||
},
|
||||
constraints: table =>
|
||||
{
|
||||
table.PrimaryKey("PK_RoleClaims", x => x.Id);
|
||||
table.ForeignKey(
|
||||
name: "FK_RoleClaims_Roles_AppRoleId",
|
||||
column: x => x.AppRoleId,
|
||||
principalSchema: "Identity",
|
||||
principalTable: "Roles",
|
||||
principalColumn: "Id");
|
||||
table.ForeignKey(
|
||||
name: "FK_RoleClaims_Roles_RoleId",
|
||||
column: x => x.RoleId,
|
||||
principalSchema: "Identity",
|
||||
principalTable: "Roles",
|
||||
principalColumn: "Id",
|
||||
onDelete: ReferentialAction.Cascade);
|
||||
});
|
||||
|
||||
migrationBuilder.CreateTable(
|
||||
name: "UserClaims",
|
||||
schema: "Identity",
|
||||
columns: table => new
|
||||
{
|
||||
Id = table.Column<int>(type: "integer", nullable: false)
|
||||
.Annotation("Npgsql:ValueGenerationStrategy", NpgsqlValueGenerationStrategy.IdentityByDefaultColumn),
|
||||
UserId = table.Column<string>(type: "text", nullable: false),
|
||||
ClaimType = table.Column<string>(type: "text", nullable: true),
|
||||
ClaimValue = table.Column<string>(type: "text", nullable: true)
|
||||
},
|
||||
constraints: table =>
|
||||
{
|
||||
table.PrimaryKey("PK_UserClaims", x => x.Id);
|
||||
table.ForeignKey(
|
||||
name: "FK_UserClaims_Users_UserId",
|
||||
column: x => x.UserId,
|
||||
principalSchema: "Identity",
|
||||
principalTable: "Users",
|
||||
principalColumn: "Id",
|
||||
onDelete: ReferentialAction.Cascade);
|
||||
});
|
||||
|
||||
migrationBuilder.CreateTable(
|
||||
name: "UserLogins",
|
||||
schema: "Identity",
|
||||
columns: table => new
|
||||
{
|
||||
LoginProvider = table.Column<string>(type: "text", nullable: false),
|
||||
ProviderKey = table.Column<string>(type: "text", nullable: false),
|
||||
ProviderDisplayName = table.Column<string>(type: "text", nullable: true),
|
||||
UserId = table.Column<string>(type: "text", nullable: false)
|
||||
},
|
||||
constraints: table =>
|
||||
{
|
||||
table.PrimaryKey("PK_UserLogins", x => new { x.LoginProvider, x.ProviderKey });
|
||||
table.ForeignKey(
|
||||
name: "FK_UserLogins_Users_UserId",
|
||||
column: x => x.UserId,
|
||||
principalSchema: "Identity",
|
||||
principalTable: "Users",
|
||||
principalColumn: "Id",
|
||||
onDelete: ReferentialAction.Cascade);
|
||||
});
|
||||
|
||||
migrationBuilder.CreateTable(
|
||||
name: "UserRoles",
|
||||
schema: "Identity",
|
||||
columns: table => new
|
||||
{
|
||||
UserId = table.Column<string>(type: "text", nullable: false),
|
||||
RoleId = table.Column<string>(type: "text", nullable: false)
|
||||
},
|
||||
constraints: table =>
|
||||
{
|
||||
table.PrimaryKey("PK_UserRoles", x => new { x.UserId, x.RoleId });
|
||||
table.ForeignKey(
|
||||
name: "FK_UserRoles_Roles_RoleId",
|
||||
column: x => x.RoleId,
|
||||
principalSchema: "Identity",
|
||||
principalTable: "Roles",
|
||||
principalColumn: "Id",
|
||||
onDelete: ReferentialAction.Cascade);
|
||||
table.ForeignKey(
|
||||
name: "FK_UserRoles_Users_UserId",
|
||||
column: x => x.UserId,
|
||||
principalSchema: "Identity",
|
||||
principalTable: "Users",
|
||||
principalColumn: "Id",
|
||||
onDelete: ReferentialAction.Cascade);
|
||||
});
|
||||
|
||||
migrationBuilder.CreateTable(
|
||||
name: "UserTokens",
|
||||
schema: "Identity",
|
||||
columns: table => new
|
||||
{
|
||||
UserId = table.Column<string>(type: "text", nullable: false),
|
||||
LoginProvider = table.Column<string>(type: "text", nullable: false),
|
||||
Name = table.Column<string>(type: "text", nullable: false),
|
||||
Value = table.Column<string>(type: "text", nullable: true)
|
||||
},
|
||||
constraints: table =>
|
||||
{
|
||||
table.PrimaryKey("PK_UserTokens", x => new { x.UserId, x.LoginProvider, x.Name });
|
||||
table.ForeignKey(
|
||||
name: "FK_UserTokens_Users_UserId",
|
||||
column: x => x.UserId,
|
||||
principalSchema: "Identity",
|
||||
principalTable: "Users",
|
||||
principalColumn: "Id",
|
||||
onDelete: ReferentialAction.Cascade);
|
||||
});
|
||||
|
||||
migrationBuilder.CreateIndex(
|
||||
name: "IX_RoleClaims_AppRoleId",
|
||||
schema: "Identity",
|
||||
table: "RoleClaims",
|
||||
column: "AppRoleId");
|
||||
|
||||
migrationBuilder.CreateIndex(
|
||||
name: "IX_RoleClaims_RoleId",
|
||||
schema: "Identity",
|
||||
table: "RoleClaims",
|
||||
column: "RoleId");
|
||||
|
||||
migrationBuilder.CreateIndex(
|
||||
name: "RoleNameIndex",
|
||||
schema: "Identity",
|
||||
table: "Roles",
|
||||
column: "NormalizedName",
|
||||
unique: true);
|
||||
|
||||
migrationBuilder.CreateIndex(
|
||||
name: "IX_UserClaims_UserId",
|
||||
schema: "Identity",
|
||||
table: "UserClaims",
|
||||
column: "UserId");
|
||||
|
||||
migrationBuilder.CreateIndex(
|
||||
name: "IX_UserLogins_UserId",
|
||||
schema: "Identity",
|
||||
table: "UserLogins",
|
||||
column: "UserId");
|
||||
|
||||
migrationBuilder.CreateIndex(
|
||||
name: "IX_UserRoles_RoleId",
|
||||
schema: "Identity",
|
||||
table: "UserRoles",
|
||||
column: "RoleId");
|
||||
|
||||
migrationBuilder.CreateIndex(
|
||||
name: "EmailIndex",
|
||||
schema: "Identity",
|
||||
table: "Users",
|
||||
column: "NormalizedEmail");
|
||||
|
||||
migrationBuilder.CreateIndex(
|
||||
name: "UserNameIndex",
|
||||
schema: "Identity",
|
||||
table: "Users",
|
||||
column: "NormalizedUserName",
|
||||
unique: true);
|
||||
}
|
||||
|
||||
/// <inheritdoc />
|
||||
protected override void Down(MigrationBuilder migrationBuilder)
|
||||
{
|
||||
migrationBuilder.DropTable(
|
||||
name: "AuditTrails",
|
||||
schema: "Audit");
|
||||
|
||||
migrationBuilder.DropTable(
|
||||
name: "Contacts");
|
||||
|
||||
migrationBuilder.DropTable(
|
||||
name: "RoleClaims",
|
||||
schema: "Identity");
|
||||
|
||||
migrationBuilder.DropTable(
|
||||
name: "ServerInfos");
|
||||
|
||||
migrationBuilder.DropTable(
|
||||
name: "UserClaims",
|
||||
schema: "Identity");
|
||||
|
||||
migrationBuilder.DropTable(
|
||||
name: "UserLogins",
|
||||
schema: "Identity");
|
||||
|
||||
migrationBuilder.DropTable(
|
||||
name: "UserRoles",
|
||||
schema: "Identity");
|
||||
|
||||
migrationBuilder.DropTable(
|
||||
name: "UserTokens",
|
||||
schema: "Identity");
|
||||
|
||||
migrationBuilder.DropTable(
|
||||
name: "Roles",
|
||||
schema: "Identity");
|
||||
|
||||
migrationBuilder.DropTable(
|
||||
name: "Users",
|
||||
schema: "Identity");
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,454 @@
|
||||
// <auto-generated />
|
||||
using System;
|
||||
using Microsoft.EntityFrameworkCore;
|
||||
using Microsoft.EntityFrameworkCore.Infrastructure;
|
||||
using Microsoft.EntityFrameworkCore.Storage.ValueConversion;
|
||||
using Npgsql.EntityFrameworkCore.PostgreSQL.Metadata;
|
||||
using Sufi.Demo.PeopleDirectory.Persistence.Contexts;
|
||||
|
||||
#nullable disable
|
||||
|
||||
namespace Sufi.Demo.PeopleDirectory.Persistence.Migrations
|
||||
{
|
||||
[DbContext(typeof(ApplicationDbContext))]
|
||||
partial class ApplicationDbContextModelSnapshot : ModelSnapshot
|
||||
{
|
||||
protected override void BuildModel(ModelBuilder modelBuilder)
|
||||
{
|
||||
#pragma warning disable 612, 618
|
||||
modelBuilder
|
||||
.HasAnnotation("ProductVersion", "8.0.11")
|
||||
.HasAnnotation("Relational:MaxIdentifierLength", 63);
|
||||
|
||||
NpgsqlModelBuilderExtensions.UseIdentityByDefaultColumns(modelBuilder);
|
||||
|
||||
modelBuilder.Entity("Microsoft.AspNetCore.Identity.IdentityUserClaim<string>", b =>
|
||||
{
|
||||
b.Property<int>("Id")
|
||||
.ValueGeneratedOnAdd()
|
||||
.HasColumnType("integer");
|
||||
|
||||
NpgsqlPropertyBuilderExtensions.UseIdentityByDefaultColumn(b.Property<int>("Id"));
|
||||
|
||||
b.Property<string>("ClaimType")
|
||||
.HasColumnType("text");
|
||||
|
||||
b.Property<string>("ClaimValue")
|
||||
.HasColumnType("text");
|
||||
|
||||
b.Property<string>("UserId")
|
||||
.IsRequired()
|
||||
.HasColumnType("text");
|
||||
|
||||
b.HasKey("Id");
|
||||
|
||||
b.HasIndex("UserId");
|
||||
|
||||
b.ToTable("UserClaims", "Identity");
|
||||
});
|
||||
|
||||
modelBuilder.Entity("Microsoft.AspNetCore.Identity.IdentityUserLogin<string>", b =>
|
||||
{
|
||||
b.Property<string>("LoginProvider")
|
||||
.HasColumnType("text");
|
||||
|
||||
b.Property<string>("ProviderKey")
|
||||
.HasColumnType("text");
|
||||
|
||||
b.Property<string>("ProviderDisplayName")
|
||||
.HasColumnType("text");
|
||||
|
||||
b.Property<string>("UserId")
|
||||
.IsRequired()
|
||||
.HasColumnType("text");
|
||||
|
||||
b.HasKey("LoginProvider", "ProviderKey");
|
||||
|
||||
b.HasIndex("UserId");
|
||||
|
||||
b.ToTable("UserLogins", "Identity");
|
||||
});
|
||||
|
||||
modelBuilder.Entity("Microsoft.AspNetCore.Identity.IdentityUserRole<string>", b =>
|
||||
{
|
||||
b.Property<string>("UserId")
|
||||
.HasColumnType("text");
|
||||
|
||||
b.Property<string>("RoleId")
|
||||
.HasColumnType("text");
|
||||
|
||||
b.HasKey("UserId", "RoleId");
|
||||
|
||||
b.HasIndex("RoleId");
|
||||
|
||||
b.ToTable("UserRoles", "Identity");
|
||||
});
|
||||
|
||||
modelBuilder.Entity("Microsoft.AspNetCore.Identity.IdentityUserToken<string>", b =>
|
||||
{
|
||||
b.Property<string>("UserId")
|
||||
.HasColumnType("text");
|
||||
|
||||
b.Property<string>("LoginProvider")
|
||||
.HasColumnType("text");
|
||||
|
||||
b.Property<string>("Name")
|
||||
.HasColumnType("text");
|
||||
|
||||
b.Property<string>("Value")
|
||||
.HasColumnType("text");
|
||||
|
||||
b.HasKey("UserId", "LoginProvider", "Name");
|
||||
|
||||
b.ToTable("UserTokens", "Identity");
|
||||
});
|
||||
|
||||
modelBuilder.Entity("Sufi.Demo.PeopleDirectory.Domain.Entities.Misc.Contact", b =>
|
||||
{
|
||||
b.Property<int>("Id")
|
||||
.ValueGeneratedOnAdd()
|
||||
.HasColumnType("integer");
|
||||
|
||||
NpgsqlPropertyBuilderExtensions.UseIdentityByDefaultColumn(b.Property<int>("Id"));
|
||||
|
||||
b.Property<string>("CreatedBy")
|
||||
.HasColumnType("character varying(100)");
|
||||
|
||||
b.Property<DateTime>("CreatedOn")
|
||||
.HasColumnType("timestamp with time zone");
|
||||
|
||||
b.Property<string>("Email")
|
||||
.IsRequired()
|
||||
.HasColumnType("character varying(100)");
|
||||
|
||||
b.Property<string>("Hobby")
|
||||
.IsRequired()
|
||||
.HasColumnType("character varying(255)");
|
||||
|
||||
b.Property<string>("LastModifiedBy")
|
||||
.HasColumnType("character varying(100)");
|
||||
|
||||
b.Property<DateTime?>("LastModifiedOn")
|
||||
.HasColumnType("timestamp with time zone");
|
||||
|
||||
b.Property<string>("Phone")
|
||||
.IsRequired()
|
||||
.HasColumnType("character varying(20)");
|
||||
|
||||
b.Property<string>("SkillSets")
|
||||
.IsRequired()
|
||||
.HasColumnType("character varying(255)");
|
||||
|
||||
b.Property<string>("UserName")
|
||||
.IsRequired()
|
||||
.HasColumnType("character varying(50)");
|
||||
|
||||
b.HasKey("Id");
|
||||
|
||||
b.ToTable("Contacts");
|
||||
});
|
||||
|
||||
modelBuilder.Entity("Sufi.Demo.PeopleDirectory.Domain.Entities.Misc.ServerInfo", b =>
|
||||
{
|
||||
b.Property<string>("Id")
|
||||
.HasColumnType("text");
|
||||
|
||||
b.Property<string>("CreatedBy")
|
||||
.HasColumnType("character varying(100)");
|
||||
|
||||
b.Property<DateTime>("CreatedOn")
|
||||
.HasColumnType("timestamp with time zone");
|
||||
|
||||
b.Property<string>("LastModifiedBy")
|
||||
.HasColumnType("character varying(100)");
|
||||
|
||||
b.Property<DateTime?>("LastModifiedOn")
|
||||
.HasColumnType("timestamp with time zone");
|
||||
|
||||
b.Property<string>("Value")
|
||||
.IsRequired()
|
||||
.HasColumnType("character varying(255)");
|
||||
|
||||
b.HasKey("Id");
|
||||
|
||||
b.ToTable("ServerInfos");
|
||||
});
|
||||
|
||||
modelBuilder.Entity("Sufi.Demo.PeopleDirectory.Infrastructure.Models.Audit.Audit", b =>
|
||||
{
|
||||
b.Property<int>("Id")
|
||||
.ValueGeneratedOnAdd()
|
||||
.HasColumnType("integer");
|
||||
|
||||
NpgsqlPropertyBuilderExtensions.UseIdentityByDefaultColumn(b.Property<int>("Id"));
|
||||
|
||||
b.Property<string>("AffectedColumns")
|
||||
.HasColumnType("character varying(100)");
|
||||
|
||||
b.Property<DateTime>("DateTime")
|
||||
.HasColumnType("timestamp with time zone");
|
||||
|
||||
b.Property<string>("NewValues")
|
||||
.HasColumnType("character varying(255)");
|
||||
|
||||
b.Property<string>("OldValues")
|
||||
.HasColumnType("character varying(255)");
|
||||
|
||||
b.Property<string>("PrimaryKey")
|
||||
.IsRequired()
|
||||
.HasColumnType("character varying(100)");
|
||||
|
||||
b.Property<string>("TableName")
|
||||
.IsRequired()
|
||||
.HasColumnType("character varying(50)");
|
||||
|
||||
b.Property<string>("Type")
|
||||
.IsRequired()
|
||||
.HasColumnType("character varying(20)");
|
||||
|
||||
b.Property<string>("UserId")
|
||||
.HasColumnType("character varying(100)");
|
||||
|
||||
b.HasKey("Id");
|
||||
|
||||
b.ToTable("AuditTrails", "Audit");
|
||||
});
|
||||
|
||||
modelBuilder.Entity("Sufi.Demo.PeopleDirectory.Infrastructure.Models.Identity.AppRole", b =>
|
||||
{
|
||||
b.Property<string>("Id")
|
||||
.HasColumnType("text");
|
||||
|
||||
b.Property<string>("ConcurrencyStamp")
|
||||
.IsConcurrencyToken()
|
||||
.HasColumnType("text");
|
||||
|
||||
b.Property<string>("CreatedBy")
|
||||
.HasColumnType("character varying(100)");
|
||||
|
||||
b.Property<DateTime>("CreatedOn")
|
||||
.HasColumnType("timestamp with time zone");
|
||||
|
||||
b.Property<string>("Description")
|
||||
.HasColumnType("character varying(100)");
|
||||
|
||||
b.Property<string>("LastModifiedBy")
|
||||
.HasColumnType("character varying(100)");
|
||||
|
||||
b.Property<DateTime?>("LastModifiedOn")
|
||||
.HasColumnType("timestamp with time zone");
|
||||
|
||||
b.Property<string>("Name")
|
||||
.HasMaxLength(256)
|
||||
.HasColumnType("character varying(256)");
|
||||
|
||||
b.Property<string>("NormalizedName")
|
||||
.HasMaxLength(256)
|
||||
.HasColumnType("character varying(256)");
|
||||
|
||||
b.HasKey("Id");
|
||||
|
||||
b.HasIndex("NormalizedName")
|
||||
.IsUnique()
|
||||
.HasDatabaseName("RoleNameIndex");
|
||||
|
||||
b.ToTable("Roles", "Identity");
|
||||
});
|
||||
|
||||
modelBuilder.Entity("Sufi.Demo.PeopleDirectory.Infrastructure.Models.Identity.AppRoleClaim", b =>
|
||||
{
|
||||
b.Property<int>("Id")
|
||||
.ValueGeneratedOnAdd()
|
||||
.HasColumnType("integer");
|
||||
|
||||
NpgsqlPropertyBuilderExtensions.UseIdentityByDefaultColumn(b.Property<int>("Id"));
|
||||
|
||||
b.Property<string>("AppRoleId")
|
||||
.HasColumnType("text");
|
||||
|
||||
b.Property<string>("ClaimType")
|
||||
.HasColumnType("text");
|
||||
|
||||
b.Property<string>("ClaimValue")
|
||||
.HasColumnType("text");
|
||||
|
||||
b.Property<string>("CreatedBy")
|
||||
.HasColumnType("character varying(100)");
|
||||
|
||||
b.Property<DateTime>("CreatedOn")
|
||||
.HasColumnType("timestamp with time zone");
|
||||
|
||||
b.Property<string>("Description")
|
||||
.HasColumnType("character varying(100)");
|
||||
|
||||
b.Property<string>("Group")
|
||||
.HasColumnType("character varying(100)");
|
||||
|
||||
b.Property<string>("LastModifiedBy")
|
||||
.HasColumnType("character varying(100)");
|
||||
|
||||
b.Property<DateTime?>("LastModifiedOn")
|
||||
.HasColumnType("timestamp with time zone");
|
||||
|
||||
b.Property<string>("RoleId")
|
||||
.IsRequired()
|
||||
.HasColumnType("text");
|
||||
|
||||
b.HasKey("Id");
|
||||
|
||||
b.HasIndex("AppRoleId");
|
||||
|
||||
b.HasIndex("RoleId");
|
||||
|
||||
b.ToTable("RoleClaims", "Identity");
|
||||
});
|
||||
|
||||
modelBuilder.Entity("Sufi.Demo.PeopleDirectory.Infrastructure.Models.Identity.AppUser", b =>
|
||||
{
|
||||
b.Property<string>("Id")
|
||||
.ValueGeneratedOnAdd()
|
||||
.HasColumnType("text");
|
||||
|
||||
b.Property<int>("AccessFailedCount")
|
||||
.HasColumnType("integer");
|
||||
|
||||
b.Property<string>("ConcurrencyStamp")
|
||||
.IsConcurrencyToken()
|
||||
.HasColumnType("text");
|
||||
|
||||
b.Property<string>("CreatedBy")
|
||||
.HasColumnType("character varying(100)");
|
||||
|
||||
b.Property<DateTime>("CreatedOn")
|
||||
.HasColumnType("timestamp with time zone");
|
||||
|
||||
b.Property<DateTime?>("DeletedOn")
|
||||
.HasColumnType("timestamp with time zone");
|
||||
|
||||
b.Property<string>("Email")
|
||||
.HasMaxLength(256)
|
||||
.HasColumnType("character varying(256)");
|
||||
|
||||
b.Property<bool>("EmailConfirmed")
|
||||
.HasColumnType("boolean");
|
||||
|
||||
b.Property<bool>("IsActive")
|
||||
.HasColumnType("boolean");
|
||||
|
||||
b.Property<bool>("IsDeleted")
|
||||
.HasColumnType("boolean");
|
||||
|
||||
b.Property<string>("LastModifiedBy")
|
||||
.HasColumnType("character varying(100)");
|
||||
|
||||
b.Property<DateTime?>("LastModifiedOn")
|
||||
.HasColumnType("timestamp with time zone");
|
||||
|
||||
b.Property<bool>("LockoutEnabled")
|
||||
.HasColumnType("boolean");
|
||||
|
||||
b.Property<DateTimeOffset?>("LockoutEnd")
|
||||
.HasColumnType("timestamp with time zone");
|
||||
|
||||
b.Property<string>("NormalizedEmail")
|
||||
.HasMaxLength(256)
|
||||
.HasColumnType("character varying(256)");
|
||||
|
||||
b.Property<string>("NormalizedUserName")
|
||||
.HasMaxLength(256)
|
||||
.HasColumnType("character varying(256)");
|
||||
|
||||
b.Property<string>("PasswordHash")
|
||||
.HasColumnType("text");
|
||||
|
||||
b.Property<string>("PhoneNumber")
|
||||
.HasColumnType("text");
|
||||
|
||||
b.Property<bool>("PhoneNumberConfirmed")
|
||||
.HasColumnType("boolean");
|
||||
|
||||
b.Property<string>("SecurityStamp")
|
||||
.HasColumnType("text");
|
||||
|
||||
b.Property<bool>("TwoFactorEnabled")
|
||||
.HasColumnType("boolean");
|
||||
|
||||
b.Property<string>("UserName")
|
||||
.HasMaxLength(256)
|
||||
.HasColumnType("character varying(256)");
|
||||
|
||||
b.HasKey("Id");
|
||||
|
||||
b.HasIndex("NormalizedEmail")
|
||||
.HasDatabaseName("EmailIndex");
|
||||
|
||||
b.HasIndex("NormalizedUserName")
|
||||
.IsUnique()
|
||||
.HasDatabaseName("UserNameIndex");
|
||||
|
||||
b.ToTable("Users", "Identity");
|
||||
});
|
||||
|
||||
modelBuilder.Entity("Microsoft.AspNetCore.Identity.IdentityUserClaim<string>", b =>
|
||||
{
|
||||
b.HasOne("Sufi.Demo.PeopleDirectory.Infrastructure.Models.Identity.AppUser", null)
|
||||
.WithMany()
|
||||
.HasForeignKey("UserId")
|
||||
.OnDelete(DeleteBehavior.Cascade)
|
||||
.IsRequired();
|
||||
});
|
||||
|
||||
modelBuilder.Entity("Microsoft.AspNetCore.Identity.IdentityUserLogin<string>", b =>
|
||||
{
|
||||
b.HasOne("Sufi.Demo.PeopleDirectory.Infrastructure.Models.Identity.AppUser", null)
|
||||
.WithMany()
|
||||
.HasForeignKey("UserId")
|
||||
.OnDelete(DeleteBehavior.Cascade)
|
||||
.IsRequired();
|
||||
});
|
||||
|
||||
modelBuilder.Entity("Microsoft.AspNetCore.Identity.IdentityUserRole<string>", b =>
|
||||
{
|
||||
b.HasOne("Sufi.Demo.PeopleDirectory.Infrastructure.Models.Identity.AppRole", null)
|
||||
.WithMany()
|
||||
.HasForeignKey("RoleId")
|
||||
.OnDelete(DeleteBehavior.Cascade)
|
||||
.IsRequired();
|
||||
|
||||
b.HasOne("Sufi.Demo.PeopleDirectory.Infrastructure.Models.Identity.AppUser", null)
|
||||
.WithMany()
|
||||
.HasForeignKey("UserId")
|
||||
.OnDelete(DeleteBehavior.Cascade)
|
||||
.IsRequired();
|
||||
});
|
||||
|
||||
modelBuilder.Entity("Microsoft.AspNetCore.Identity.IdentityUserToken<string>", b =>
|
||||
{
|
||||
b.HasOne("Sufi.Demo.PeopleDirectory.Infrastructure.Models.Identity.AppUser", null)
|
||||
.WithMany()
|
||||
.HasForeignKey("UserId")
|
||||
.OnDelete(DeleteBehavior.Cascade)
|
||||
.IsRequired();
|
||||
});
|
||||
|
||||
modelBuilder.Entity("Sufi.Demo.PeopleDirectory.Infrastructure.Models.Identity.AppRoleClaim", b =>
|
||||
{
|
||||
b.HasOne("Sufi.Demo.PeopleDirectory.Infrastructure.Models.Identity.AppRole", null)
|
||||
.WithMany("RoleClaims")
|
||||
.HasForeignKey("AppRoleId");
|
||||
|
||||
b.HasOne("Sufi.Demo.PeopleDirectory.Infrastructure.Models.Identity.AppRole", null)
|
||||
.WithMany()
|
||||
.HasForeignKey("RoleId")
|
||||
.OnDelete(DeleteBehavior.Cascade)
|
||||
.IsRequired();
|
||||
});
|
||||
|
||||
modelBuilder.Entity("Sufi.Demo.PeopleDirectory.Infrastructure.Models.Identity.AppRole", b =>
|
||||
{
|
||||
b.Navigation("RoleClaims");
|
||||
});
|
||||
#pragma warning restore 612, 618
|
||||
}
|
||||
}
|
||||
}
|
||||
25
Sufi.Demo.PeopleDirectory.Persistence/Models/Audit/Audit.cs
Normal file
25
Sufi.Demo.PeopleDirectory.Persistence/Models/Audit/Audit.cs
Normal file
@@ -0,0 +1,25 @@
|
||||
using Sufi.Demo.PeopleDirectory.Domain.Common;
|
||||
using System.ComponentModel.DataAnnotations.Schema;
|
||||
|
||||
namespace Sufi.Demo.PeopleDirectory.Persistence.Models.Audit
|
||||
{
|
||||
public class Audit : IEntity<int>
|
||||
{
|
||||
public int Id { get; set; }
|
||||
[Column(TypeName = "character varying(100)")]
|
||||
public string? UserId { get; set; }
|
||||
[Column(TypeName = "character varying(20)")]
|
||||
public string Type { get; set; } = null!;
|
||||
[Column(TypeName = "character varying(50)")]
|
||||
public string TableName { get; set; } = null!;
|
||||
public DateTime DateTime { get; set; }
|
||||
[Column(TypeName = "character varying(255)")]
|
||||
public string? OldValues { get; set; }
|
||||
[Column(TypeName = "character varying(255)")]
|
||||
public string? NewValues { get; set; }
|
||||
[Column(TypeName = "character varying(100)")]
|
||||
public string? AffectedColumns { get; set; }
|
||||
[Column(TypeName = "character varying(100)")]
|
||||
public string PrimaryKey { get; set; } = null!;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,36 @@
|
||||
using Microsoft.EntityFrameworkCore.ChangeTracking;
|
||||
using Sufi.Demo.PeopleDirectory.Application.Enums;
|
||||
using System.Text.Json;
|
||||
|
||||
namespace Sufi.Demo.PeopleDirectory.Persistence.Models.Audit
|
||||
{
|
||||
public class AuditEntry(EntityEntry entry)
|
||||
{
|
||||
public EntityEntry Entry { get; } = entry;
|
||||
public string? UserId { get; set; }
|
||||
public string TableName { get; set; } = null!;
|
||||
public Dictionary<string, object?> KeyValues { get; } = new();
|
||||
public Dictionary<string, object?> OldValues { get; } = new();
|
||||
public Dictionary<string, object?> NewValues { get; } = new();
|
||||
public List<PropertyEntry> TemporaryProperties { get; } = new();
|
||||
public AuditType AuditType { get; set; }
|
||||
public List<string> ChangedColumns { get; } = new();
|
||||
public bool HasTemporaryProperties => TemporaryProperties.Any();
|
||||
|
||||
public Audit ToAudit()
|
||||
{
|
||||
var audit = new Audit
|
||||
{
|
||||
UserId = UserId,
|
||||
Type = AuditType.ToString(),
|
||||
TableName = TableName,
|
||||
DateTime = DateTime.UtcNow,
|
||||
PrimaryKey = JsonSerializer.Serialize(KeyValues),
|
||||
OldValues = OldValues.Count == 0 ? null : JsonSerializer.Serialize(OldValues),
|
||||
NewValues = NewValues.Count == 0 ? null : JsonSerializer.Serialize(NewValues),
|
||||
AffectedColumns = ChangedColumns.Count == 0 ? null : JsonSerializer.Serialize(ChangedColumns)
|
||||
};
|
||||
return audit;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,28 @@
|
||||
using Microsoft.AspNetCore.Identity;
|
||||
using Sufi.Demo.PeopleDirectory.Domain.Common;
|
||||
using System.ComponentModel.DataAnnotations.Schema;
|
||||
|
||||
namespace Sufi.Demo.PeopleDirectory.Persistence.Models.Identity
|
||||
{
|
||||
public class AppRole : IdentityRole, IAuditableEntity<string>
|
||||
{
|
||||
[Column(TypeName = "character varying(100)")]
|
||||
public string? Description { get; set; }
|
||||
public string? CreatedBy { get; set; }
|
||||
public DateTime CreatedOn { get; set; }
|
||||
public string? LastModifiedBy { get; set; }
|
||||
public DateTime? LastModifiedOn { get; set; }
|
||||
public virtual ICollection<AppRoleClaim> RoleClaims { get; set; }
|
||||
|
||||
public AppRole() : base()
|
||||
{
|
||||
RoleClaims = new HashSet<AppRoleClaim>();
|
||||
}
|
||||
|
||||
public AppRole(string roleName, string? description = null) : base(roleName)
|
||||
{
|
||||
RoleClaims = new HashSet<AppRoleClaim>();
|
||||
Description = description;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,26 @@
|
||||
using Microsoft.AspNetCore.Identity;
|
||||
using Sufi.Demo.PeopleDirectory.Domain.Common;
|
||||
using System.ComponentModel.DataAnnotations.Schema;
|
||||
|
||||
namespace Sufi.Demo.PeopleDirectory.Persistence.Models.Identity
|
||||
{
|
||||
public class AppRoleClaim : IdentityRoleClaim<string>, IAuditableEntity<int>
|
||||
{
|
||||
[Column(TypeName = "character varying(100)")]
|
||||
public string? Description { get; set; }
|
||||
[Column(TypeName = "character varying(100)")]
|
||||
public string? Group { get; set; }
|
||||
public string? CreatedBy { get; set; }
|
||||
public DateTime CreatedOn { get; set; }
|
||||
public string? LastModifiedBy { get; set; }
|
||||
public DateTime? LastModifiedOn { get; set; }
|
||||
|
||||
public AppRoleClaim() : base() { }
|
||||
|
||||
public AppRoleClaim(string? description = null, string? group = null) : base()
|
||||
{
|
||||
Description = description;
|
||||
Group = group;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,17 @@
|
||||
using Microsoft.AspNetCore.Identity;
|
||||
using Sufi.Demo.PeopleDirectory.Domain.Common;
|
||||
using System.ComponentModel.DataAnnotations.Schema;
|
||||
|
||||
namespace Sufi.Demo.PeopleDirectory.Persistence.Models.Identity
|
||||
{
|
||||
public class AppUser : IdentityUser<string>, IAuditableEntity<string>
|
||||
{
|
||||
public bool IsActive { get; set; }
|
||||
public bool IsDeleted { get; set; }
|
||||
public DateTime? DeletedOn { get; set; }
|
||||
public string? CreatedBy { get; set; }
|
||||
public DateTime CreatedOn { get; set; }
|
||||
public string? LastModifiedBy { get; set; }
|
||||
public DateTime? LastModifiedOn { get; set; }
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,70 @@
|
||||
using Microsoft.EntityFrameworkCore;
|
||||
using Sufi.Demo.PeopleDirectory.Application.Contracts.Repositories;
|
||||
using Sufi.Demo.PeopleDirectory.Domain.Common;
|
||||
using Sufi.Demo.PeopleDirectory.Persistence.Contexts;
|
||||
|
||||
namespace Sufi.Demo.PeopleDirectory.Persistence.Repositories
|
||||
{
|
||||
public class AsyncRepository<T, TId>(
|
||||
ApplicationDbContext dbContext
|
||||
) : IAsyncRepository<T, TId> where T : AuditableEntity<TId>
|
||||
{
|
||||
public IQueryable<T> Entities => dbContext.Set<T>();
|
||||
|
||||
public async Task<T> AddAsync(T entity)
|
||||
{
|
||||
await dbContext.Set<T>().AddAsync(entity);
|
||||
return entity;
|
||||
}
|
||||
|
||||
public async Task<int> CountAsync() => await dbContext.Set<T>().CountAsync();
|
||||
|
||||
public Task DeleteAsync(T entity)
|
||||
{
|
||||
dbContext.Set<T>().Remove(entity);
|
||||
return Task.CompletedTask;
|
||||
}
|
||||
|
||||
public async Task<int> DeleteByIdAsync(TId id)
|
||||
{
|
||||
var rowsAffected = await dbContext.Set<T>()
|
||||
.Where(e => e.Id != null && e.Id.Equals(id))
|
||||
.ExecuteDeleteAsync();
|
||||
|
||||
return rowsAffected;
|
||||
}
|
||||
|
||||
public async Task<List<T>> GetAllAsync()
|
||||
{
|
||||
return await dbContext
|
||||
.Set<T>()
|
||||
.ToListAsync();
|
||||
}
|
||||
|
||||
public async Task<T?> GetByIdAsync(TId id)
|
||||
{
|
||||
return await dbContext.Set<T>().FindAsync(id);
|
||||
}
|
||||
|
||||
public async Task<List<T>> GetPagedResponseAsync(int pageNumber, int pageSize)
|
||||
{
|
||||
return await dbContext
|
||||
.Set<T>()
|
||||
.Skip((pageNumber - 1) * pageSize)
|
||||
.Take(pageSize)
|
||||
.AsNoTracking()
|
||||
.ToListAsync();
|
||||
}
|
||||
|
||||
public Task UpdateAsync(T entity)
|
||||
{
|
||||
T? exist = dbContext.Set<T>().Find(entity.Id);
|
||||
if (exist != null)
|
||||
{
|
||||
dbContext.Entry<T>(exist).CurrentValues.SetValues(entity);
|
||||
}
|
||||
|
||||
return Task.CompletedTask;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,71 @@
|
||||
using Sufi.Demo.PeopleDirectory.Application.Contracts.Repositories;
|
||||
using Sufi.Demo.PeopleDirectory.Domain.Common;
|
||||
using Sufi.Demo.PeopleDirectory.Persistence.Contexts;
|
||||
using System.Collections;
|
||||
|
||||
namespace Sufi.Demo.PeopleDirectory.Persistence.Repositories
|
||||
{
|
||||
public class UnitOfWork<TId>(
|
||||
ApplicationDbContext dbContext
|
||||
) : IUnitOfWork<TId>
|
||||
{
|
||||
private bool disposed;
|
||||
private Hashtable? _repositories;
|
||||
|
||||
public IAsyncRepository<TEntity, TId> Repository<TEntity>() where TEntity : AuditableEntity<TId>
|
||||
{
|
||||
_repositories ??= [];
|
||||
|
||||
var type = typeof(TEntity).Name;
|
||||
|
||||
if (!_repositories.ContainsKey(type))
|
||||
{
|
||||
var repositoryType = typeof(AsyncRepository<,>);
|
||||
|
||||
var repositoryInstance = Activator.CreateInstance(repositoryType.MakeGenericType(typeof(TEntity), typeof(TId)), dbContext);
|
||||
|
||||
_repositories.Add(type, repositoryInstance);
|
||||
}
|
||||
|
||||
return (IAsyncRepository<TEntity, TId>)_repositories[type]!;
|
||||
}
|
||||
|
||||
public async Task<int> Commit(CancellationToken cancellationToken)
|
||||
{
|
||||
return await dbContext.SaveChangesAsync(cancellationToken);
|
||||
}
|
||||
|
||||
public async Task<int> CommitAndRemoveCache(CancellationToken cancellationToken, params string[] cacheKeys)
|
||||
{
|
||||
var result = await dbContext.SaveChangesAsync(cancellationToken);
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
public Task Rollback()
|
||||
{
|
||||
dbContext.ChangeTracker.Entries().ToList().ForEach(x => x.Reload());
|
||||
return Task.CompletedTask;
|
||||
}
|
||||
|
||||
public void Dispose()
|
||||
{
|
||||
Dispose(true);
|
||||
GC.SuppressFinalize(this);
|
||||
}
|
||||
|
||||
protected virtual void Dispose(bool disposing)
|
||||
{
|
||||
if (!disposed)
|
||||
{
|
||||
if (disposing)
|
||||
{
|
||||
//dispose managed resources
|
||||
dbContext.Dispose();
|
||||
}
|
||||
}
|
||||
//dispose unmanaged resources
|
||||
disposed = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,20 @@
|
||||
<Project Sdk="Microsoft.NET.Sdk">
|
||||
|
||||
<PropertyGroup>
|
||||
<TargetFramework>net8.0</TargetFramework>
|
||||
<ImplicitUsings>enable</ImplicitUsings>
|
||||
<Nullable>enable</Nullable>
|
||||
</PropertyGroup>
|
||||
|
||||
<ItemGroup>
|
||||
<PackageReference Include="Microsoft.AspNetCore.Identity" Version="2.3.1" />
|
||||
<PackageReference Include="Microsoft.AspNetCore.Identity.EntityFrameworkCore" Version="8.0.21" />
|
||||
<PackageReference Include="Npgsql.EntityFrameworkCore.PostgreSQL" Version="9.0.4" />
|
||||
</ItemGroup>
|
||||
|
||||
<ItemGroup>
|
||||
<ProjectReference Include="..\Sufi.Demo.PeopleDirectory.Application\Sufi.Demo.PeopleDirectory.Application.csproj" />
|
||||
<ProjectReference Include="..\Sufi.Demo.PeopleDirectory.Domain\Sufi.Demo.PeopleDirectory.Domain.csproj" />
|
||||
</ItemGroup>
|
||||
|
||||
</Project>
|
||||
Reference in New Issue
Block a user