featute/ChangeLog #6

Merged
on.nemtina merged 25 commits from featute/ChangeLog into master 2024-12-09 17:44:48 +05:00
6 changed files with 109 additions and 67 deletions
Showing only changes of commit 2e567e7eba - Show all commits

View File

@ -2,13 +2,14 @@
using System.ComponentModel.DataAnnotations.Schema; using System.ComponentModel.DataAnnotations.Schema;
using System.ComponentModel.DataAnnotations; using System.ComponentModel.DataAnnotations;
using Microsoft.EntityFrameworkCore; using Microsoft.EntityFrameworkCore;
using Persistence.Models;
namespace Persistence.Database.Model; namespace Persistence.Database.Model;
/// <summary> /// <summary>
/// Часть записи, описывающая изменение /// Часть записи, описывающая изменение
/// </summary> /// </summary>
public class ChangeLog : IChangeLog public class ChangeLog : IChangeLog, IWithSectionPart
{ {
[Key, Comment("Ключ записи")] [Key, Comment("Ключ записи")]
public Guid Id { get; set; } public Guid Id { get; set; }
Review

Договаривались в моделях БД не указывать имя колонки, чтобы оно совпадало с именем свойства.
А чтобы модель визуально оставалась узнаваемой как модель решили указывать атрибут комментария..

Договаривались в моделях БД не указывать имя колонки, чтобы оно совпадало с именем свойства. А чтобы модель визуально оставалась узнаваемой как модель решили указывать атрибут комментария..

View File

@ -1,6 +1,4 @@
 
using System.ComponentModel.DataAnnotations.Schema;
namespace Persistence.Database.Model; namespace Persistence.Database.Model;
/// <summary> /// <summary>

View File

@ -14,4 +14,8 @@
</PackageReference> </PackageReference>
</ItemGroup> </ItemGroup>
<ItemGroup>
<ProjectReference Include="..\Persistence\Persistence.csproj" />
</ItemGroup>
</Project> </Project>

View File

@ -0,0 +1,76 @@
using Microsoft.EntityFrameworkCore;
using Persistence.Database.Model;
using Persistence.Models;
using Persistence.Models.Requests;
namespace Persistence.Repository;
/// <summary>
/// класс с набором методов, необходимых для фильтрации записей
/// </summary>
public static class QueryBuilders
{
public static void Apply<TEntity>(this IQueryable<TEntity> query, SectionPartRequest request)
where TEntity : class, IWithSectionPart
{
if (request.IdSection.HasValue)
{
query = query.Where(e => e.IdSection == request.IdSection);
}
if (request.DepthStart.HasValue)
{
query = query.Where(e => e.DepthStart >= request.DepthStart);
}
if (request.DepthEnd.HasValue)
{
query = query.Where(e => e.DepthEnd <= request.DepthEnd);
}
}
public static void Apply<TEntity>(this IQueryable<TEntity> query,DateTimeOffset momentUtc)
where TEntity : class, IChangeLog
{
momentUtc = momentUtc.ToUniversalTime();
query = query
.Where(e => e.Creation <= momentUtc)
.Where(e => e.Obsolete == null || e.Obsolete >= momentUtc);
}
public static async Task<PaginationContainer<TDto>> ApplyPagination<TEntity, TDto>(
this IQueryable<TEntity> query,
PaginationRequest request,
Func<TEntity, TDto> Convert,
CancellationToken token)
where TEntity : class, IWithSectionPart
where TDto : class
{
if (String.IsNullOrEmpty(request.SortSettings))
{
query = query
.OrderBy(e => e.IdSection)
.ThenBy(e => e.DepthStart)
.ThenBy(e => e.DepthEnd);
}
else
{
query = query.SortBy(request.SortSettings);
}
var entities = await query
.Skip(request.Skip)
.Take(request.Take)
.ToArrayAsync(token);
var result = new PaginationContainer<TDto>
{
Skip = request.Skip,
Take = request.Take,
Items = entities.Select(Convert),
Count = await query.CountAsync(token)
};
return result;
}
}

View File

@ -138,33 +138,18 @@ public class ChangeLogRepository : IChangeLogRepository
PaginationRequest paginationRequest, PaginationRequest paginationRequest,
CancellationToken token) CancellationToken token)
private IQueryable<ChangeLog> MakeReadQuery(Guid idDiscriminator, DateTimeOffset momentUtc){...}
private IQueryable<ChangeLog> ApplyFilter(IQueryable<ChangeLog> query,  SectionPartRequest request){...}

"Build" - намекает на наличие билдера, а его нет. (можно подумать чтобы его завести:))

``` private IQueryable<ChangeLog> MakeReadQuery(Guid idDiscriminator, DateTimeOffset momentUtc){...} private IQueryable<ChangeLog> ApplyFilter(IQueryable<ChangeLog> query, SectionPartRequest request){...} ``` "Build" - намекает на наличие билдера, а его нет. (можно подумать чтобы его завести:))
{ {
var query = BuildQuery(idDiscriminator, momentUtc, filterRequest); var query = CreateQuery(idDiscriminator);
//ApplyFilter(query, , filterRequest); query.Apply(momentUtc);
var result = await BuildPaginationContainer(query, paginationRequest, token); query.Apply(filterRequest);

Мы не доверяем пользователям и все равно приводим к UTC

Мы не доверяем пользователям и все равно приводим к UTC
var result = await query.ApplyPagination(paginationRequest, Convert, token);
return result; return result;
} }
private IQueryable<ChangeLog> BuildQuery(Guid idDiscriminator, DateTimeOffset momentUtc, SectionPartRequest request) private IQueryable<ChangeLog> CreateQuery(Guid idDiscriminator)
{ {
momentUtc = momentUtc.ToUniversalTime(); var query = db.Set<ChangeLog>().Where(e => e.IdDiscriminator == idDiscriminator);
var query = db.Set<ChangeLog>()
.Where(e => e.IdDiscriminator == idDiscriminator)
.Where(e => e.Creation <= momentUtc)
.Where(e => e.Obsolete == null || e.Obsolete >= momentUtc);
if (request.IdSection.HasValue)
{
query = query.Where(e => e.IdSection == request.IdSection);
}
if (request.DepthStart.HasValue)
{
query = query.Where(e => e.DepthStart >= request.DepthStart);
}
if (request.DepthEnd.HasValue)
{
query = query.Where(e => e.DepthEnd <= request.DepthEnd);
}
return query; return query;
} }
@ -173,8 +158,8 @@ public class ChangeLogRepository : IChangeLogRepository
{ {
var query = db.Set<ChangeLog>().Where(s => s.IdDiscriminator == idDiscriminator); var query = db.Set<ChangeLog>().Where(s => s.IdDiscriminator == idDiscriminator);
var min = new DateTimeOffset(dateBegin.Year, dateBegin.Month, dateBegin.Day, 0, 0, 0, TimeSpan.Zero); var min = new DateTimeOffset(dateBegin.ToUniversalTime().Date, TimeSpan.Zero);
var max = new DateTimeOffset(dateEnd.Year, dateEnd.Month, dateEnd.Day, 0, 0, 0, TimeSpan.Zero); var max = new DateTimeOffset(dateEnd.ToUniversalTime().Date, TimeSpan.Zero);
var createdQuery = query.Where(e => e.Creation >= min && e.Creation <= max); var createdQuery = query.Where(e => e.Creation >= min && e.Creation <= max);
var editedQuery = query.Where(e => e.Obsolete != null && e.Obsolete >= min && e.Obsolete <= max); var editedQuery = query.Where(e => e.Obsolete != null && e.Obsolete >= min && e.Obsolete <= max);
@ -189,39 +174,6 @@ public class ChangeLogRepository : IChangeLogRepository
private async Task<PaginationContainer<DataWithWellDepthAndSectionDto>> BuildPaginationContainer(IQueryable<ChangeLog> query, PaginationRequest request, CancellationToken token)
{
var result = new PaginationContainer<DataWithWellDepthAndSectionDto>
{
Skip = request.Skip,
Take = request.Take,
Items = Enumerable.Empty<DataWithWellDepthAndSectionDto>(),
Count = await query.CountAsync(token)
};
if (!String.IsNullOrEmpty(request.SortSettings))
{
query = query.SortBy(request.SortSettings);
}
else
{
query = query
.OrderBy(e => e.IdSection)
.ThenBy(e => e.DepthStart)
.ThenBy(e => e.DepthEnd);
}
var entities = await query
.Skip(result.Skip)
.Take(result.Take)
.ToArrayAsync(token);
var dtos = entities.Select(e => e.Adapt<DataWithWellDepthAndSectionDto>());
result.Items = dtos;
return result;
}
public async Task<IEnumerable<DateOnly>> GetDatesChange(Guid idDiscriminator, CancellationToken token) public async Task<IEnumerable<DateOnly>> GetDatesChange(Guid idDiscriminator, CancellationToken token)
{ {
var query = db.Set<ChangeLog>().Where(e => e.IdDiscriminator == idDiscriminator); var query = db.Set<ChangeLog>().Where(e => e.IdDiscriminator == idDiscriminator);
@ -276,7 +228,7 @@ public class ChangeLogRepository : IChangeLogRepository
var entities = await query.ToArrayAsync(token); var entities = await query.ToArrayAsync(token);
var dtos = entities.Select(e => e.Adapt<DataWithWellDepthAndSectionDto>()); var dtos = entities.Select(Convert);
return dtos; return dtos;
} }
@ -289,7 +241,7 @@ public class ChangeLogRepository : IChangeLogRepository
.Select(group => new .Select(group => new
{ {
Min = group.Min(e => e.Creation), Min = group.Min(e => e.Creation),
Max = group.Max(e => e.Creation), Max = group.Max(e => (e.Creation > e.Obsolete ? e.Creation : e.Obsolete!.Value)),
}); });

Не все базы так поймут. Лучше для новых сущностей их генерировать самостоятельно (в идеале по седьмой версии).

Не все базы так поймут. Лучше для новых сущностей их генерировать самостоятельно (в идеале по [седьмой версии](https://steven-giesel.com/blogPost/ea42a518-4d8b-4e08-8f73-e542bdd3b983)).
var values = await query.FirstOrDefaultAsync(token); var values = await query.FirstOrDefaultAsync(token);
@ -305,4 +257,6 @@ public class ChangeLogRepository : IChangeLogRepository
To = values.Max, To = values.Max,
}; };
} }
private DataWithWellDepthAndSectionDto Convert(ChangeLog entity) => entity.Adapt<DataWithWellDepthAndSectionDto>();
} }

View File

@ -0,0 +1,9 @@
namespace Persistence.Models;
public interface IWithSectionPart
{
public double DepthStart { get; set; }
public double DepthEnd { get; set; }
public Guid IdSection { get; set; }
}