измнения в моделяз и котрактах хранилищ

This commit is contained in:
2025-03-25 18:05:09 +04:00
parent ed32c34921
commit eb4c1f037b
16 changed files with 93 additions and 52 deletions

View File

@@ -13,11 +13,11 @@ using System.Threading.Tasks;
namespace MagicCarpetDatabase.Implementations;
internal class ClientStorageContarct : IClientStorageContract
public class ClientStorageContract : IClientStorageContract
{
private readonly MagicCarpetDbContext _dbContext;
private readonly Mapper _mapper;
public ClientStorageContarct(MagicCarpetDbContext magicCarpetDbContext)
public ClientStorageContract(MagicCarpetDbContext magicCarpetDbContext)
{
_dbContext = magicCarpetDbContext;
var config = new MapperConfiguration(cfg =>

View File

@@ -11,7 +11,7 @@ using System.Threading.Tasks;
namespace MagicCarpetDatabase.Implementations;
internal class EmployeeStorageContract : IEmployeeStorageContract
public class EmployeeStorageContract : IEmployeeStorageContract
{
private readonly MagicCarpetDbContext _dbContext;
private readonly Mapper _mapper;
@@ -21,7 +21,10 @@ internal class EmployeeStorageContract : IEmployeeStorageContract
_dbContext = dbContext;
var config = new MapperConfiguration(cfg =>
{
cfg.AddMaps(typeof(MagicCarpetDbContext).Assembly);
cfg.CreateMap<Post, PostDataModel>()
.ForMember(x => x.Id, x => x.MapFrom(src => src.PostId));
cfg.CreateMap<Employee, EmployeeDataModel>();
cfg.CreateMap<EmployeeDataModel, Employee>();
});
_mapper = new Mapper(config);
}
@@ -46,7 +49,7 @@ internal class EmployeeStorageContract : IEmployeeStorageContract
{
query = query.Where(x => x.EmploymentDate >= fromEmploymentDate && x.EmploymentDate <= toEmploymentDate);
}
return [.. query.Select(x => _mapper.Map<EmployeeDataModel>(x))];
return [.. JoinPost(query).Select(x => _mapper.Map<EmployeeDataModel>(x))];
}
catch (Exception ex)
{
@@ -72,7 +75,7 @@ internal class EmployeeStorageContract : IEmployeeStorageContract
{
try
{
return _mapper.Map<EmployeeDataModel>(_dbContext.Employees.FirstOrDefault(x => x.FIO == fio));
return _mapper.Map<EmployeeDataModel>(AddPost(_dbContext.Employees.FirstOrDefault(x => x.FIO == fio && !x.IsDeleted)));
}
catch (Exception ex)
{
@@ -84,7 +87,7 @@ internal class EmployeeStorageContract : IEmployeeStorageContract
{
try
{
return _mapper.Map<EmployeeDataModel>(_dbContext.Employees.FirstOrDefault(x => x.Email == email));
return _mapper.Map<EmployeeDataModel>(AddPost(_dbContext.Employees.FirstOrDefault(x => x.Email == email && !x.IsDeleted)));
}
catch (Exception ex)
{
@@ -152,5 +155,12 @@ internal class EmployeeStorageContract : IEmployeeStorageContract
}
}
private Employee? GetEmployeeById(string id) => _dbContext.Employees.FirstOrDefault(x => x.Id == id && !x.IsDeleted);
private Employee? GetEmployeeById(string id) => _dbContext.Employees.FirstOrDefault(x => x.Id == id && !x.IsDeleted);
private IQueryable<Employee> JoinPost(IQueryable<Employee> query)
=> query.GroupJoin(_dbContext.Posts.Where(x => x.IsActual), x => x.PostId, y => y.PostId, (x, y) => new { Employee = x, Post = y })
.SelectMany(xy => xy.Post.DefaultIfEmpty(), (x, y) => x.Employee.AddPost(y));
private Employee? AddPost(Employee? employee)
=> employee?.AddPost(_dbContext.Posts.FirstOrDefault(x => x.PostId == employee.PostId && x.IsActual));
}

View File

@@ -13,7 +13,7 @@ using System.Threading.Tasks;
namespace MagicCarpetDatabase.Implementations;
internal class PostStorageContract : IPostStorageContract
public class PostStorageContract : IPostStorageContract
{
private readonly MagicCarpetDbContext _dbContext;
private readonly Mapper _mapper;
@@ -34,16 +34,11 @@ internal class PostStorageContract : IPostStorageContract
_mapper = new Mapper(config);
}
public List<PostDataModel> GetList(bool onlyActual = true)
public List<PostDataModel> GetList()
{
try
{
var query = _dbContext.Posts.AsQueryable();
if (onlyActual)
{
query = query.Where(x => x.IsActual);
}
return [.. query.Select(x => _mapper.Map<PostDataModel>(x))];
return [.. _dbContext.Posts.Select(x => _mapper.Map<PostDataModel>(x))];
}
catch (Exception ex)
{

View File

@@ -11,7 +11,7 @@ using System.Threading.Tasks;
namespace MagicCarpetDatabase.Implementations;
internal class SalaryStorageContract : ISalaryStorageContract
public class SalaryStorageContract : ISalaryStorageContract
{
private readonly MagicCarpetDbContext _dbContext;
private readonly Mapper _mapper;

View File

@@ -12,7 +12,7 @@ using System.Threading.Tasks;
namespace MagicCarpetDatabase.Implementations;
internal class SaleStorageContract : ISaleStorageContract
public class SaleStorageContract : ISaleStorageContract
{
private readonly MagicCarpetDbContext _dbContext;
private readonly Mapper _mapper;
@@ -22,12 +22,18 @@ internal class SaleStorageContract : ISaleStorageContract
_dbContext = dbContext;
var config = new MapperConfiguration(cfg =>
{
cfg.CreateMap<SaleTour, SaleTourDataModel>();
cfg.CreateMap<SaleTourDataModel, SaleTour>();
cfg.CreateMap<Sale, SaleDataModel>();
cfg.CreateMap<SaleDataModel, Sale>()
.ForMember(x => x.IsCancel, x => x.MapFrom(src => false))
.ForMember(x => x.SaleTours, x => x.MapFrom(src => src.Tours));
cfg.CreateMap<Client, ClientDataModel>();
cfg.CreateMap<Tour, TourDataModel>();
cfg.CreateMap<Employee, EmployeeDataModel>();
cfg.CreateMap<SaleTour, SaleTourDataModel>();
cfg.CreateMap<SaleTourDataModel, SaleTour>()
.ForMember(x => x.Tour, x => x.Ignore());
cfg.CreateMap<Sale, SaleDataModel>();
cfg.CreateMap<SaleDataModel, Sale>()
.ForMember(x => x.IsCancel, x => x.MapFrom(src => false))
.ForMember(x => x.SaleTours, x => x.MapFrom(src => src.Tours))
.ForMember(x => x.Employee, x => x.Ignore())
.ForMember(x => x.Client, x => x.Ignore());
});
_mapper = new Mapper(config);
}
@@ -36,7 +42,7 @@ internal class SaleStorageContract : ISaleStorageContract
{
try
{
var query = _dbContext.Sales.Include(x => x.SaleTours).AsQueryable();
var query = _dbContext.Sales.Include(x => x.Client).Include(x => x.Employee).Include(x => x.SaleTours)!.ThenInclude(x => x.Tour).AsQueryable();
if (startDate is not null && endDate is not null)
{
query = query.Where(x => x.SaleDate >= startDate && x.SaleDate < endDate);
@@ -113,5 +119,5 @@ internal class SaleStorageContract : ISaleStorageContract
}
}
private Sale? GetSaleById(string id) => _dbContext.Sales.FirstOrDefault(x => x.Id == id);
private Sale? GetSaleById(string id) => _dbContext.Sales.Include(x => x.Client).Include(x => x.Employee).Include(x => x.SaleTours)!.ThenInclude(x => x.Tour).FirstOrDefault(x => x.Id == id);
}

View File

@@ -13,7 +13,7 @@ using System.Threading.Tasks;
namespace MagicCarpetDatabase.Implementations;
internal class TourStorageContract : ITourStorageContract
public class TourStorageContract : ITourStorageContract
{
private readonly MagicCarpetDbContext _dbContext;
private readonly Mapper _mapper;
@@ -47,7 +47,7 @@ internal class TourStorageContract : ITourStorageContract
{
try
{
return [.. _dbContext.TourHistories.Where(x => x.TourId == tourId).OrderByDescending(x => x.ChangeDate).Select(x => _mapper.Map<TourHistoryDataModel>(x))];
return [.. _dbContext.TourHistories.Include(x => x.Tour).Where(x => x.TourId == tourId).OrderByDescending(x => x.ChangeDate).Select(x => _mapper.Map<TourHistoryDataModel>(x))];
}
catch (Exception ex)
{
@@ -110,20 +110,35 @@ internal class TourStorageContract : ITourStorageContract
{
try
{
var element = GetTourById(tourDataModel.Id) ?? throw new ElementNotFoundException(tourDataModel.Id);
_dbContext.Tours.Update(_mapper.Map(tourDataModel, element));
_dbContext.SaveChanges();
var transaction = _dbContext.Database.BeginTransaction();
try
{
var element = GetTourById(tourDataModel.Id) ?? throw new ElementNotFoundException(tourDataModel.Id);
if (element.Price != tourDataModel.Price)
{
_dbContext.TourHistories.Add(new TourHistory() { TourId = element.Id, OldPrice = element.Price });
_dbContext.SaveChanges();
}
_dbContext.Tours.Update(_mapper.Map(tourDataModel, element));
_dbContext.SaveChanges();
transaction.Commit();
}
catch
{
transaction.Rollback();
throw;
}
}
catch (ElementNotFoundException)
{
_dbContext.ChangeTracker.Clear();
throw;
}
catch (DbUpdateException ex) when (ex.InnerException is PostgresException { ConstraintName: "IX_Tours_TourName" })
catch (DbUpdateException ex) when (ex.InnerException is PostgresException { ConstraintName: "IX_Tours_TourName_IsDeleted" })
{
_dbContext.ChangeTracker.Clear();
throw new ElementExistsException("TourName", tourDataModel.TourName);
}
catch (Exception ex) when (ex is ElementDeletedException || ex is ElementNotFoundException)
{
_dbContext.ChangeTracker.Clear();
throw;
}
catch (Exception ex)
{
_dbContext.ChangeTracker.Clear();

View File

@@ -15,9 +15,6 @@
<ItemGroup>
<ProjectReference Include="..\MagicCarpetContracts\MagicCarpetContracts.csproj" />
</ItemGroup>
<ItemGroup>
<InternalsVisibleTo Include="MagicCarpetTests" />
<InternalsVisibleTo Include="DynamicProxyGenAssembly2" />
</ItemGroup>
</Project>

View File

@@ -9,7 +9,7 @@ using System.Threading.Tasks;
namespace MagicCarpetDatabase;
internal class MagicCarpetDbContext(IConfigurationDatabase configurationDatabase) : DbContext
public class MagicCarpetDbContext(IConfigurationDatabase configurationDatabase) : DbContext
{
private readonly IConfigurationDatabase? _configurationDatabase = configurationDatabase;
@@ -25,6 +25,11 @@ internal class MagicCarpetDbContext(IConfigurationDatabase configurationDatabase
modelBuilder.Entity<Client>().HasIndex(x => x.PhoneNumber).IsUnique();
modelBuilder.Entity<Sale>()
.HasOne(e => e.Client)
.WithMany(e => e.Sales)
.OnDelete(DeleteBehavior.SetNull);
modelBuilder.Entity<Tour>().HasIndex(x => x.TourName).IsUnique();
modelBuilder.Entity<Post>()

View File

@@ -10,7 +10,7 @@ using System.Threading.Tasks;
namespace MagicCarpetDatabase.Models;
[AutoMap(typeof(ClientDataModel), ReverseMap = true)]
internal class Client
public class Client
{
public required string Id { get; set; }

View File

@@ -10,7 +10,7 @@ using System.Threading.Tasks;
namespace MagicCarpetDatabase.Models;
[AutoMap(typeof(EmployeeDataModel), ReverseMap = true)]
internal class Employee
public class Employee
{
public required string Id { get; set; }
@@ -22,11 +22,18 @@ internal class Employee
public DateTime BirthDate { get; set; }
public DateTime EmploymentDate { get; set; }
public DateTime EmploymentDate { get; set; }
public bool IsDeleted { get; set; }
public bool IsDeleted { get; set; }
[NotMapped]
public Post? Post { get; set; }
[ForeignKey("EmployeeId")]
public List<Salary>? Salaries { get; set; }
[ForeignKey("EmployeeId")]
public List<Sale>? Sales { get; set; }
public Employee AddPost(Post? post)
{
Post = post;
return this;
}
}

View File

@@ -8,7 +8,7 @@ using System.Threading.Tasks;
namespace MagicCarpetDatabase.Models;
internal class Post
public class Post
{
public required string Id { get; set; } = Guid.NewGuid().ToString();
public required string PostId { get; set; }

View File

@@ -6,7 +6,7 @@ using System.Threading.Tasks;
namespace MagicCarpetDatabase.Models;
internal class Salary
public class Salary
{
public string Id { get; set; } = Guid.NewGuid().ToString();
public required string EmployeeId { get; set; }

View File

@@ -9,7 +9,7 @@ using System.Threading.Tasks;
namespace MagicCarpetDatabase.Models;
internal class Sale
public class Sale
{
public string Id { get; set; } = Guid.NewGuid().ToString();

View File

@@ -6,11 +6,17 @@ using System.Threading.Tasks;
namespace MagicCarpetDatabase.Models;
internal class SaleTour
public class SaleTour
{
public required string SaleId { get; set; }
public required string TourId { get; set; }
public int Count { get; set; }
public double Price { get; set; }
public Sale? Sale { get; set; }
public Tour? Tour { get; set; }
}

View File

@@ -9,7 +9,7 @@ using System.Threading.Tasks;
namespace MagicCarpetDatabase.Models;
internal class Tour
public class Tour
{
public required string Id { get; set; }
public required string TourName { get; set; }

View File

@@ -6,7 +6,7 @@ using System.Threading.Tasks;
namespace MagicCarpetDatabase.Models;
internal class TourHistory
public class TourHistory
{
public string Id { get; set; } = Guid.NewGuid().ToString();
public required string TourId { get; set; }