Initial .NET 8 Web API with EF Core Db-First for Catalogs
Set up multi-project solution with DbFirst API, Application, Domain, and Infrastructure layers. Implemented database-first EF Core for the Catalog entity, including domain, DTOs, repository, service, and controller. Configured AutoMapper, DI, Swagger, and project settings. Added .gitattributes and initial configuration files.
This commit is contained in:
56
DbFirst.Infrastructure/ApplicationDbContext.cs
Normal file
56
DbFirst.Infrastructure/ApplicationDbContext.cs
Normal file
@@ -0,0 +1,56 @@
|
||||
using DbFirst.Infrastructure.ScaffoldEntities;
|
||||
using Microsoft.EntityFrameworkCore;
|
||||
|
||||
namespace DbFirst.Infrastructure;
|
||||
|
||||
public partial class ApplicationDbContext : DbContext
|
||||
{
|
||||
public ApplicationDbContext(DbContextOptions<ApplicationDbContext> options)
|
||||
: base(options)
|
||||
{
|
||||
}
|
||||
|
||||
public virtual DbSet<TbmyCatalog> TbmyCatalogs { get; set; }
|
||||
|
||||
protected override void OnModelCreating(ModelBuilder modelBuilder)
|
||||
{
|
||||
modelBuilder.Entity<TbmyCatalog>(entity =>
|
||||
{
|
||||
entity.HasKey(e => e.Guid);
|
||||
|
||||
entity.ToTable("TBMY_CATALOG");
|
||||
|
||||
entity.HasIndex(e => e.CatTitle, "UQ_TBMY_CATALOG_TITLE").IsUnique();
|
||||
|
||||
entity.Property(e => e.Guid).HasColumnName("GUID");
|
||||
entity.Property(e => e.AddedWhen)
|
||||
.HasDefaultValueSql("(getdate())")
|
||||
.HasColumnType("datetime")
|
||||
.HasColumnName("ADDED_WHEN");
|
||||
entity.Property(e => e.AddedWho)
|
||||
.HasMaxLength(30)
|
||||
.IsUnicode(false)
|
||||
.HasDefaultValue("SYSTEM")
|
||||
.HasColumnName("ADDED_WHO");
|
||||
entity.Property(e => e.CatString)
|
||||
.HasMaxLength(900)
|
||||
.IsUnicode(false)
|
||||
.HasColumnName("CAT_STRING");
|
||||
entity.Property(e => e.CatTitle)
|
||||
.HasMaxLength(100)
|
||||
.IsUnicode(false)
|
||||
.HasColumnName("CAT_TITLE");
|
||||
entity.Property(e => e.ChangedWhen)
|
||||
.HasColumnType("datetime")
|
||||
.HasColumnName("CHANGED_WHEN");
|
||||
entity.Property(e => e.ChangedWho)
|
||||
.HasMaxLength(30)
|
||||
.IsUnicode(false)
|
||||
.HasColumnName("CHANGED_WHO");
|
||||
});
|
||||
|
||||
OnModelCreatingPartial(modelBuilder);
|
||||
}
|
||||
|
||||
partial void OnModelCreatingPartial(ModelBuilder modelBuilder);
|
||||
}
|
||||
23
DbFirst.Infrastructure/DbFirst.Infrastructure.csproj
Normal file
23
DbFirst.Infrastructure/DbFirst.Infrastructure.csproj
Normal file
@@ -0,0 +1,23 @@
|
||||
<Project Sdk="Microsoft.NET.Sdk">
|
||||
|
||||
<PropertyGroup>
|
||||
<TargetFramework>net8.0</TargetFramework>
|
||||
<ImplicitUsings>enable</ImplicitUsings>
|
||||
<Nullable>enable</Nullable>
|
||||
</PropertyGroup>
|
||||
|
||||
<ItemGroup>
|
||||
<PackageReference Include="AutoMapper" Version="12.0.1" />
|
||||
<PackageReference Include="Microsoft.EntityFrameworkCore" Version="8.0.22" />
|
||||
<PackageReference Include="Microsoft.EntityFrameworkCore.SqlServer" Version="8.0.22" />
|
||||
<PackageReference Include="Microsoft.EntityFrameworkCore.Tools" Version="8.0.22">
|
||||
<PrivateAssets>all</PrivateAssets>
|
||||
<IncludeAssets>runtime; build; native; contentfiles; analyzers; buildtransitive</IncludeAssets>
|
||||
</PackageReference>
|
||||
</ItemGroup>
|
||||
|
||||
<ItemGroup>
|
||||
<ProjectReference Include="..\DbFirst.Domain\DbFirst.Domain.csproj" />
|
||||
</ItemGroup>
|
||||
|
||||
</Project>
|
||||
@@ -0,0 +1,13 @@
|
||||
using AutoMapper;
|
||||
using DbFirst.Domain.DomainEntities;
|
||||
using DbFirst.Infrastructure.ScaffoldEntities;
|
||||
|
||||
namespace DbFirst.Infrastructure.Mappings;
|
||||
|
||||
public class CatalogInfrastructureProfile : Profile
|
||||
{
|
||||
public CatalogInfrastructureProfile()
|
||||
{
|
||||
CreateMap<TbmyCatalog, Catalog>().ReverseMap();
|
||||
}
|
||||
}
|
||||
66
DbFirst.Infrastructure/Repositories/CatalogRepository.cs
Normal file
66
DbFirst.Infrastructure/Repositories/CatalogRepository.cs
Normal file
@@ -0,0 +1,66 @@
|
||||
using AutoMapper;
|
||||
using DbFirst.Domain.DomainEntities;
|
||||
using DbFirst.Domain.Repositories;
|
||||
using DbFirst.Infrastructure.ScaffoldEntities;
|
||||
using Microsoft.EntityFrameworkCore;
|
||||
|
||||
namespace DbFirst.Infrastructure.Repositories;
|
||||
|
||||
public class CatalogRepository : ICatalogRepository
|
||||
{
|
||||
private readonly ApplicationDbContext _db;
|
||||
private readonly IMapper _mapper;
|
||||
|
||||
public CatalogRepository(ApplicationDbContext db, IMapper mapper)
|
||||
{
|
||||
_db = db;
|
||||
_mapper = mapper;
|
||||
}
|
||||
|
||||
public async Task<List<Catalog>> GetAllAsync(CancellationToken cancellationToken = default)
|
||||
{
|
||||
var entities = await _db.TbmyCatalogs.AsNoTracking().ToListAsync(cancellationToken);
|
||||
return _mapper.Map<List<Catalog>>(entities);
|
||||
}
|
||||
|
||||
public async Task<Catalog?> GetByIdAsync(int id, CancellationToken cancellationToken = default)
|
||||
{
|
||||
var entity = await _db.TbmyCatalogs.AsNoTracking().FirstOrDefaultAsync(x => x.Guid == id, cancellationToken);
|
||||
return entity == null ? null : _mapper.Map<Catalog>(entity);
|
||||
}
|
||||
|
||||
public async Task<Catalog> AddAsync(Catalog catalog, CancellationToken cancellationToken = default)
|
||||
{
|
||||
var entity = _mapper.Map<TbmyCatalog>(catalog);
|
||||
_db.TbmyCatalogs.Add(entity);
|
||||
await _db.SaveChangesAsync(cancellationToken);
|
||||
return _mapper.Map<Catalog>(entity);
|
||||
}
|
||||
|
||||
public async Task<bool> UpdateAsync(int id, Catalog catalog, CancellationToken cancellationToken = default)
|
||||
{
|
||||
var entity = await _db.TbmyCatalogs.FirstOrDefaultAsync(x => x.Guid == id, cancellationToken);
|
||||
if (entity == null)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
_mapper.Map(catalog, entity);
|
||||
entity.Guid = id;
|
||||
await _db.SaveChangesAsync(cancellationToken);
|
||||
return true;
|
||||
}
|
||||
|
||||
public async Task<bool> DeleteAsync(int id, CancellationToken cancellationToken = default)
|
||||
{
|
||||
var entity = await _db.TbmyCatalogs.FirstOrDefaultAsync(x => x.Guid == id, cancellationToken);
|
||||
if (entity == null)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
_db.TbmyCatalogs.Remove(entity);
|
||||
await _db.SaveChangesAsync(cancellationToken);
|
||||
return true;
|
||||
}
|
||||
}
|
||||
24
DbFirst.Infrastructure/ScaffoldEntities/TbmyCatalog.cs
Normal file
24
DbFirst.Infrastructure/ScaffoldEntities/TbmyCatalog.cs
Normal file
@@ -0,0 +1,24 @@
|
||||
namespace DbFirst.Infrastructure.ScaffoldEntities;
|
||||
|
||||
public partial class TbmyCatalog
|
||||
{
|
||||
public int Guid { get; set; }
|
||||
|
||||
public string CatTitle { get; set; } = null!;
|
||||
|
||||
public string CatString { get; set; } = null!;
|
||||
|
||||
public string AddedWho { get; set; } = null!;
|
||||
|
||||
public DateTime AddedWhen { get; set; }
|
||||
|
||||
public string? ChangedWho { get; set; }
|
||||
|
||||
public DateTime? ChangedWhen { get; set; }
|
||||
|
||||
// = null!; ist nur eine Null-Unterdrückung für Non‑Nullable-Referenztypen. Hintergrund: Die Spalten CatTitle, CatString, AddedWho
|
||||
// sind in der DB als NOT NULL definiert, also generiert der Scaffold string (ohne ?). Damit der Compiler bei aktivierter Nullable-Analyse
|
||||
// nicht warnt („non-nullable property is uninitialized“), wird ein Dummy-Init auf null! gesetzt. Das ! sagt dem Compiler „ich garantiere,
|
||||
// dass zur Laufzeit ein Wert gesetzt wird“. Bei string? ChangedWho/DateTime? ChangedWhen sind die Spalten nullable, daher kein null! nötig.
|
||||
// Bei Value Types wie int/DateTime braucht es ebenfalls kein Init, da sie Standardwerte haben.
|
||||
}
|
||||
Reference in New Issue
Block a user