Добавить таблицу для учета комментариев и действий пользователя для вывода статистики по ChangeLog #30
@ -9,7 +9,7 @@ using DD.Persistence.Models.Common;
|
||||
namespace DD.Persistence.API.Controllers;
|
||||
|
||||
[ApiController]
|
||||
[Authorize]
|
||||
//[Authorize]
|
||||
[Route("api/[controller]")]
|
||||
public class ChangeLogController : ControllerBase, IChangeLogApi
|
||||
{
|
||||
@ -25,10 +25,13 @@ public class ChangeLogController : ControllerBase, IChangeLogApi
|
||||
public async Task<IActionResult> Add(
|
||||
|
||||
[FromRoute] Guid idDiscriminator,
|
||||
[FromBody] ChangeLogValuesDto dto,
|
||||
ng.frolov
commented
Было бы здорова дать методам контроллеров текстовое описание для сваггера. Было бы здорова дать методам контроллеров текстовое описание для сваггера.
|
||||
string comment,
|
||||
CancellationToken token)
|
||||
{
|
||||
var userId = User.GetUserId<Guid>();
|
||||
var result = await repository.AddRange(userId, idDiscriminator, [dto], token);
|
||||
//var userId = User.GetUserId<Guid>();
|
||||
var userId = Guid.NewGuid();
|
||||
var changeLogCommit = new ChangeLogCommitDto(userId, comment, [dto]);
|
||||
ng.frolov
commented
Скорее всего этот метод лишний. Скорее всего этот метод лишний.
|
||||
var result = await repository.AddRange(idDiscriminator, changeLogCommit, token);
|
||||
|
||||
return CreatedAtAction(nameof(Add), result);
|
||||
}
|
||||
@ -38,10 +41,13 @@ public class ChangeLogController : ControllerBase, IChangeLogApi
|
||||
public async Task<IActionResult> AddRange(
|
||||
[FromRoute] Guid idDiscriminator,
|
||||
[FromBody] IEnumerable<ChangeLogValuesDto> dtos,
|
||||
string comment,
|
||||
CancellationToken token)
|
||||
{
|
||||
var userId = User.GetUserId<Guid>();
|
||||
var result = await repository.AddRange(userId, idDiscriminator, dtos, token);
|
||||
//var userId = User.GetUserId<Guid>();
|
||||
var userId = Guid.NewGuid();
|
||||
var changeLogCommit = new ChangeLogCommitDto(userId, comment, dtos);
|
||||
var result = await repository.AddRange(idDiscriminator, changeLogCommit, token);
|
||||
|
||||
return CreatedAtAction(nameof(AddRange), result);
|
||||
}
|
||||
@ -71,10 +77,13 @@ public class ChangeLogController : ControllerBase, IChangeLogApi
|
||||
public async Task<IActionResult> ClearAndAddRange(
|
||||
[FromRoute] Guid idDiscriminator,
|
||||
[FromBody] IEnumerable<ChangeLogValuesDto> dtos,
|
||||
string comment,
|
||||
CancellationToken token)
|
||||
{
|
||||
var userId = User.GetUserId<Guid>();
|
||||
var result = await repository.ClearAndAddRange(userId, idDiscriminator, dtos, token);
|
||||
//var userId = User.GetUserId<Guid>();
|
||||
var userId = Guid.NewGuid();
|
||||
var changeLogCommit = new ChangeLogCommitDto(userId, comment, dtos);
|
||||
var result = await repository.ClearAndAddRange(idDiscriminator, changeLogCommit, token);
|
||||
return Ok(result);
|
||||
}
|
||||
|
||||
@ -82,10 +91,13 @@ public class ChangeLogController : ControllerBase, IChangeLogApi
|
||||
[ProducesResponseType(typeof(int), (int)HttpStatusCode.OK)]
|
||||
public async Task<IActionResult> Update(
|
||||
ChangeLogValuesDto dto,
|
||||
string comment,
|
||||
CancellationToken token)
|
||||
{
|
||||
var userId = User.GetUserId<Guid>();
|
||||
var result = await repository.UpdateRange(userId, [dto], token);
|
||||
//var userId = User.GetUserId<Guid>();
|
||||
var userId = Guid.NewGuid();
|
||||
var changeLogCommit = new ChangeLogCommitDto(userId, comment, [dto]);
|
||||
var result = await repository.UpdateRange(changeLogCommit, token);
|
||||
|
||||
return Ok(result);
|
||||
}
|
||||
@ -94,10 +106,13 @@ public class ChangeLogController : ControllerBase, IChangeLogApi
|
||||
[ProducesResponseType(typeof(int), (int)HttpStatusCode.OK)]
|
||||
public async Task<IActionResult> UpdateRange(
|
||||
IEnumerable<ChangeLogValuesDto> dtos,
|
||||
string comment,
|
||||
CancellationToken token)
|
||||
{
|
||||
var userId = User.GetUserId<Guid>();
|
||||
var result = await repository.UpdateRange(userId, dtos, token);
|
||||
//var userId = User.GetUserId<Guid>();
|
||||
var userId = Guid.NewGuid();
|
||||
var changeLogCommit = new ChangeLogCommitDto(userId, comment, dtos);
|
||||
var result = await repository.UpdateRange(changeLogCommit, token);
|
||||
|
||||
return Ok(result);
|
||||
}
|
||||
|
@ -13,7 +13,7 @@ using Npgsql.EntityFrameworkCore.PostgreSQL.Metadata;
|
||||
namespace DD.Persistence.Database.Postgres.Migrations
|
||||
{
|
||||
[DbContext(typeof(PersistencePostgresContext))]
|
||||
[Migration("20250205114037_Init")]
|
||||
[Migration("20250211124554_Init")]
|
||||
partial class Init
|
||||
{
|
||||
/// <inheritdoc />
|
||||
@ -41,14 +41,14 @@ namespace DD.Persistence.Database.Postgres.Migrations
|
||||
.HasColumnType("uuid")
|
||||
.HasComment("Автор изменения");
|
||||
|
||||
b.Property<Guid>("IdCommit")
|
||||
.HasColumnType("uuid")
|
||||
.HasComment("Id коммита");
|
||||
|
||||
b.Property<Guid>("IdDiscriminator")
|
||||
.HasColumnType("uuid")
|
||||
.HasComment("Дискриминатор таблицы");
|
||||
|
||||
b.Property<Guid?>("IdEditor")
|
||||
.HasColumnType("uuid")
|
||||
.HasComment("Редактор");
|
||||
|
||||
b.Property<Guid?>("IdNext")
|
||||
.HasColumnType("uuid")
|
||||
.HasComment("Id заменяющей записи");
|
||||
@ -64,9 +64,36 @@ namespace DD.Persistence.Database.Postgres.Migrations
|
||||
|
||||
b.HasKey("Id");
|
||||
|
||||
b.HasIndex("IdCommit");
|
||||
|
||||
b.ToTable("change_log");
|
||||
});
|
||||
|
||||
modelBuilder.Entity("DD.Persistence.Database.Entity.ChangeLogCommit", b =>
|
||||
{
|
||||
b.Property<Guid>("Id")
|
||||
.ValueGeneratedOnAdd()
|
||||
.HasColumnType("uuid")
|
||||
.HasComment("Id коммита");
|
||||
|
||||
b.Property<string>("Comment")
|
||||
.IsRequired()
|
||||
.HasColumnType("text")
|
||||
.HasComment("Комментарий к коммиту");
|
||||
|
||||
b.Property<DateTimeOffset>("Creation")
|
||||
.HasColumnType("timestamp with time zone")
|
||||
.HasComment("Дата создания коммита");
|
||||
|
||||
b.Property<Guid>("IdCommitAuthor")
|
||||
.HasColumnType("uuid")
|
||||
.HasComment("Пользователь, создавший коммит");
|
||||
|
||||
b.HasKey("Id");
|
||||
|
||||
b.ToTable("change_log_commit");
|
||||
});
|
||||
|
||||
modelBuilder.Entity("DD.Persistence.Database.Entity.DataSourceSystem", b =>
|
||||
{
|
||||
b.Property<Guid>("SystemId")
|
||||
@ -214,6 +241,17 @@ namespace DD.Persistence.Database.Postgres.Migrations
|
||||
b.ToTable("timestamped_values");
|
||||
});
|
||||
|
||||
modelBuilder.Entity("DD.Persistence.Database.Entity.ChangeLog", b =>
|
||||
{
|
||||
b.HasOne("DD.Persistence.Database.Entity.ChangeLogCommit", "Commit")
|
||||
.WithMany("ChangeLogItems")
|
||||
.HasForeignKey("IdCommit")
|
||||
.OnDelete(DeleteBehavior.Cascade)
|
||||
.IsRequired();
|
||||
|
||||
b.Navigation("Commit");
|
||||
});
|
||||
|
||||
modelBuilder.Entity("DD.Persistence.Database.Entity.TechMessage", b =>
|
||||
{
|
||||
b.HasOne("DD.Persistence.Database.Entity.DataSourceSystem", "System")
|
||||
@ -224,6 +262,11 @@ namespace DD.Persistence.Database.Postgres.Migrations
|
||||
|
||||
b.Navigation("System");
|
||||
});
|
||||
|
||||
modelBuilder.Entity("DD.Persistence.Database.Entity.ChangeLogCommit", b =>
|
||||
{
|
||||
b.Navigation("ChangeLogItems");
|
||||
});
|
||||
#pragma warning restore 612, 618
|
||||
}
|
||||
}
|
@ -13,21 +13,17 @@ namespace DD.Persistence.Database.Postgres.Migrations
|
||||
protected override void Up(MigrationBuilder migrationBuilder)
|
||||
{
|
||||
migrationBuilder.CreateTable(
|
||||
name: "change_log",
|
||||
name: "change_log_commit",
|
||||
columns: table => new
|
||||
{
|
||||
Id = table.Column<Guid>(type: "uuid", nullable: false, comment: "Ключ записи"),
|
||||
IdDiscriminator = table.Column<Guid>(type: "uuid", nullable: false, comment: "Дискриминатор таблицы"),
|
||||
IdAuthor = table.Column<Guid>(type: "uuid", nullable: false, comment: "Автор изменения"),
|
||||
IdEditor = table.Column<Guid>(type: "uuid", nullable: true, comment: "Редактор"),
|
||||
Creation = table.Column<DateTimeOffset>(type: "timestamp with time zone", nullable: false, comment: "Дата создания записи"),
|
||||
Obsolete = table.Column<DateTimeOffset>(type: "timestamp with time zone", nullable: true, comment: "Дата устаревания (например при удалении)"),
|
||||
IdNext = table.Column<Guid>(type: "uuid", nullable: true, comment: "Id заменяющей записи"),
|
||||
Value = table.Column<string>(type: "jsonb", nullable: false, comment: "Значение")
|
||||
Id = table.Column<Guid>(type: "uuid", nullable: false, comment: "Id коммита"),
|
||||
IdCommitAuthor = table.Column<Guid>(type: "uuid", nullable: false, comment: "Пользователь, создавший коммит"),
|
||||
Creation = table.Column<DateTimeOffset>(type: "timestamp with time zone", nullable: false, comment: "Дата создания коммита"),
|
||||
Comment = table.Column<string>(type: "text", nullable: false, comment: "Комментарий к коммиту")
|
||||
},
|
||||
constraints: table =>
|
||||
{
|
||||
table.PrimaryKey("PK_change_log", x => x.Id);
|
||||
table.PrimaryKey("PK_change_log_commit", x => x.Id);
|
||||
});
|
||||
|
||||
migrationBuilder.CreateTable(
|
||||
@ -98,6 +94,30 @@ namespace DD.Persistence.Database.Postgres.Migrations
|
||||
table.PrimaryKey("PK_timestamped_values", x => new { x.DiscriminatorId, x.Timestamp });
|
||||
});
|
||||
|
||||
migrationBuilder.CreateTable(
|
||||
name: "change_log",
|
||||
columns: table => new
|
||||
{
|
||||
Id = table.Column<Guid>(type: "uuid", nullable: false, comment: "Ключ записи"),
|
||||
IdDiscriminator = table.Column<Guid>(type: "uuid", nullable: false, comment: "Дискриминатор таблицы"),
|
||||
IdAuthor = table.Column<Guid>(type: "uuid", nullable: false, comment: "Автор изменения"),
|
||||
Creation = table.Column<DateTimeOffset>(type: "timestamp with time zone", nullable: false, comment: "Дата создания записи"),
|
||||
Obsolete = table.Column<DateTimeOffset>(type: "timestamp with time zone", nullable: true, comment: "Дата устаревания (например при удалении)"),
|
||||
IdNext = table.Column<Guid>(type: "uuid", nullable: true, comment: "Id заменяющей записи"),
|
||||
Value = table.Column<string>(type: "jsonb", nullable: false, comment: "Значение"),
|
||||
IdCommit = table.Column<Guid>(type: "uuid", nullable: false, comment: "Id коммита")
|
||||
},
|
||||
constraints: table =>
|
||||
{
|
||||
table.PrimaryKey("PK_change_log", x => x.Id);
|
||||
table.ForeignKey(
|
||||
name: "FK_change_log_change_log_commit_IdCommit",
|
||||
column: x => x.IdCommit,
|
||||
principalTable: "change_log_commit",
|
||||
principalColumn: "Id",
|
||||
onDelete: ReferentialAction.Cascade);
|
||||
});
|
||||
|
||||
migrationBuilder.CreateTable(
|
||||
name: "tech_message",
|
||||
columns: table => new
|
||||
@ -120,6 +140,11 @@ namespace DD.Persistence.Database.Postgres.Migrations
|
||||
onDelete: ReferentialAction.Cascade);
|
||||
});
|
||||
|
||||
migrationBuilder.CreateIndex(
|
||||
name: "IX_change_log_IdCommit",
|
||||
table: "change_log",
|
||||
column: "IdCommit");
|
||||
|
||||
migrationBuilder.CreateIndex(
|
||||
name: "IX_tech_message_SystemId",
|
||||
table: "tech_message",
|
||||
@ -147,6 +172,9 @@ namespace DD.Persistence.Database.Postgres.Migrations
|
||||
migrationBuilder.DropTable(
|
||||
name: "timestamped_values");
|
||||
|
||||
migrationBuilder.DropTable(
|
||||
name: "change_log_commit");
|
||||
|
||||
migrationBuilder.DropTable(
|
||||
name: "data_source_system");
|
||||
}
|
@ -38,14 +38,14 @@ namespace DD.Persistence.Database.Postgres.Migrations
|
||||
.HasColumnType("uuid")
|
||||
.HasComment("Автор изменения");
|
||||
|
||||
b.Property<Guid>("IdCommit")
|
||||
.HasColumnType("uuid")
|
||||
.HasComment("Id коммита");
|
||||
|
||||
b.Property<Guid>("IdDiscriminator")
|
||||
.HasColumnType("uuid")
|
||||
.HasComment("Дискриминатор таблицы");
|
||||
|
||||
b.Property<Guid?>("IdEditor")
|
||||
.HasColumnType("uuid")
|
||||
.HasComment("Редактор");
|
||||
|
||||
b.Property<Guid?>("IdNext")
|
||||
.HasColumnType("uuid")
|
||||
.HasComment("Id заменяющей записи");
|
||||
@ -61,9 +61,36 @@ namespace DD.Persistence.Database.Postgres.Migrations
|
||||
|
||||
b.HasKey("Id");
|
||||
|
||||
b.HasIndex("IdCommit");
|
||||
|
||||
b.ToTable("change_log");
|
||||
});
|
||||
|
||||
modelBuilder.Entity("DD.Persistence.Database.Entity.ChangeLogCommit", b =>
|
||||
{
|
||||
b.Property<Guid>("Id")
|
||||
.ValueGeneratedOnAdd()
|
||||
.HasColumnType("uuid")
|
||||
.HasComment("Id коммита");
|
||||
|
||||
b.Property<string>("Comment")
|
||||
.IsRequired()
|
||||
.HasColumnType("text")
|
||||
.HasComment("Комментарий к коммиту");
|
||||
|
||||
b.Property<DateTimeOffset>("Creation")
|
||||
.HasColumnType("timestamp with time zone")
|
||||
.HasComment("Дата создания коммита");
|
||||
|
||||
b.Property<Guid>("IdCommitAuthor")
|
||||
.HasColumnType("uuid")
|
||||
.HasComment("Пользователь, создавший коммит");
|
||||
|
||||
b.HasKey("Id");
|
||||
|
||||
b.ToTable("change_log_commit");
|
||||
});
|
||||
|
||||
modelBuilder.Entity("DD.Persistence.Database.Entity.DataSourceSystem", b =>
|
||||
{
|
||||
b.Property<Guid>("SystemId")
|
||||
@ -211,6 +238,17 @@ namespace DD.Persistence.Database.Postgres.Migrations
|
||||
b.ToTable("timestamped_values");
|
||||
});
|
||||
|
||||
modelBuilder.Entity("DD.Persistence.Database.Entity.ChangeLog", b =>
|
||||
{
|
||||
b.HasOne("DD.Persistence.Database.Entity.ChangeLogCommit", "Commit")
|
||||
.WithMany("ChangeLogItems")
|
||||
.HasForeignKey("IdCommit")
|
||||
.OnDelete(DeleteBehavior.Cascade)
|
||||
.IsRequired();
|
||||
|
||||
b.Navigation("Commit");
|
||||
});
|
||||
|
||||
modelBuilder.Entity("DD.Persistence.Database.Entity.TechMessage", b =>
|
||||
{
|
||||
b.HasOne("DD.Persistence.Database.Entity.DataSourceSystem", "System")
|
||||
@ -221,6 +259,11 @@ namespace DD.Persistence.Database.Postgres.Migrations
|
||||
|
||||
b.Navigation("System");
|
||||
});
|
||||
|
||||
modelBuilder.Entity("DD.Persistence.Database.Entity.ChangeLogCommit", b =>
|
||||
{
|
||||
b.Navigation("ChangeLogItems");
|
||||
});
|
||||
#pragma warning restore 612, 618
|
||||
}
|
||||
}
|
||||
|
@ -22,9 +22,6 @@ public class ChangeLog : IChangeLog
|
||||
[Comment("Автор изменения")]
|
||||
public Guid IdAuthor { get; set; }
|
||||
ng.frolov
commented
Комментарий про денормализацию БД Комментарий про денормализацию БД
|
||||
|
||||
[Comment("Редактор")]
|
||||
public Guid? IdEditor { get; set; }
|
||||
|
||||
[Comment("Дата создания записи")]
|
||||
public DateTimeOffset Creation { get; set; }
|
||||
|
||||
@ -36,4 +33,10 @@ public class ChangeLog : IChangeLog
|
||||
|
||||
[Column(TypeName = "jsonb"), Comment("Значение")]
|
||||
public required IDictionary<string, object> Value { get; set; }
|
||||
|
||||
[Required, Comment("Id коммита")]
|
||||
public Guid IdCommit { get; set; }
|
||||
ng.frolov
commented
Для устаревших записей у нас есть 2 коммита: один при создании записи и еще один при устаревании. Для устаревших записей у нас есть 2 коммита: один при создании записи и еще один при устаревании.
Кстати туда же можно унести инфо о пользователях и датах.
|
||||
|
||||
[Required, ForeignKey(nameof(IdCommit)), Comment("Коммит пользователя")]
|
||||
public virtual ChangeLogCommit Commit { get; set; } = null!;
|
||||
}
|
||||
|
32
DD.Persistence.Database/Entity/ChangeLogCommit.cs
Normal file
@ -0,0 +1,32 @@
|
||||
using Microsoft.EntityFrameworkCore;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.ComponentModel.DataAnnotations;
|
||||
using System.ComponentModel.DataAnnotations.Schema;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using System.Threading.Tasks;
|
||||
|
||||
namespace DD.Persistence.Database.Entity;
|
||||
|
||||
/// <summary>
|
||||
/// Таблица c коммитами пользователей
|
||||
/// </summary>
|
||||
[Table("change_log_commit")]
|
||||
public class ChangeLogCommit
|
||||
{
|
||||
[Key, Comment("Id коммита")]
|
||||
public Guid Id { get; set; }
|
||||
|
||||
[Comment("Пользователь, создавший коммит")]
|
||||
public Guid IdCommitAuthor { get; set; }
|
||||
|
||||
[Comment("Дата создания коммита")]
|
||||
public DateTimeOffset Creation { get; set; }
|
||||
|
||||
[Comment("Комментарий к коммиту")]
|
||||
public required string Comment { get; set; }
|
||||
|
||||
[Required, InverseProperty(nameof(ChangeLog.Commit)), Comment("Журнал изменений")]
|
||||
public virtual ICollection<ChangeLog> ChangeLogItems { get; set; } = null!;
|
||||
}
|
@ -17,15 +17,15 @@ public class TechMessage : ITimestampedItem
|
||||
[Comment("Дата возникновения")]
|
||||
public DateTimeOffset Timestamp { get; set; }
|
||||
|
||||
[Column(TypeName = "varchar(512)"), Comment("Текст сообщения")]
|
||||
public required string Text { get; set; }
|
||||
[Column(TypeName = "varchar(512)"), Comment("Текст сообщения")]
|
||||
public required string Text { get; set; }
|
||||
|
||||
[Required, Comment("Id системы, к которой относится сообщение")]
|
||||
public required Guid SystemId { get; set; }
|
||||
[Required, Comment("Id системы, к которой относится сообщение")]
|
||||
public required Guid SystemId { get; set; }
|
||||
|
||||
[Required, ForeignKey(nameof(SystemId)), Comment("Система, к которой относится сообщение")]
|
||||
public virtual required DataSourceSystem System { get; set; }
|
||||
[Required, ForeignKey(nameof(SystemId)), Comment("Система, к которой относится сообщение")]
|
||||
public virtual required DataSourceSystem System { get; set; }
|
||||
|
||||
[Comment("Статус события")]
|
||||
public int EventState { get; set; }
|
||||
}
|
||||
[Comment("Статус события")]
|
||||
public int EventState { get; set; }
|
||||
}
|
||||
|
@ -15,11 +15,6 @@ public interface IChangeLog
|
||||
/// </summary>
|
||||
public Guid IdAuthor { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Редактор
|
||||
/// </summary>
|
||||
public Guid? IdEditor { get; set; }
|
||||
ng.frolov
commented
Свойства не должны быть реализованы в интерфейсе. Свойства не должны быть реализованы в интерфейсе.
А почему автор коммита устаревания удален, а автор коммита создания нет?
|
||||
|
||||
/// <summary>
|
||||
/// Дата создания записи
|
||||
/// </summary>
|
||||
|
@ -16,6 +16,8 @@ public class PersistenceDbContext : DbContext
|
||||
|
||||
public DbSet<ChangeLog> ChangeLog => Set<ChangeLog>();
|
||||
|
||||
public DbSet<ChangeLogCommit> ChangeLogAction => Set<ChangeLogCommit>();
|
||||
|
||||
public DbSet<TechMessage> TechMessage => Set<TechMessage>();
|
||||
|
||||
public DbSet<ParameterData> ParameterData => Set<ParameterData>();
|
||||
|
@ -18,12 +18,15 @@ public class ChangeLogRepository : IChangeLogRepository
|
||||
this.db = db;
|
||||
}
|
||||
|
||||
public async Task<int> AddRange(Guid idAuthor, Guid idDiscriminator, IEnumerable<ChangeLogValuesDto> dtos, CancellationToken token)
|
||||
public async Task<int> AddRange(Guid idDiscriminator, ChangeLogCommitDto commitDto, CancellationToken token)
|
||||
{
|
||||
var commit = CreateCommit(commitDto);
|
||||
db.Set<ChangeLogCommit>().Add(commit);
|
||||
|
||||
var entities = new List<ChangeLog>();
|
||||
foreach (var dto in dtos)
|
||||
foreach (var values in commitDto.ChangeLogItems)
|
||||
{
|
||||
var entity = CreateEntityFromDto(idAuthor, idDiscriminator, dto);
|
||||
var entity = CreateChangeLogFromDto(idDiscriminator, commit.Id, commit.IdCommitAuthor, values);
|
||||
entities.Add(entity);
|
||||
}
|
||||
db.Set<ChangeLog>().AddRange(entities);
|
||||
@ -71,20 +74,20 @@ public class ChangeLogRepository : IChangeLogRepository
|
||||
foreach (var entity in entities)
|
||||
{
|
||||
entity.Obsolete = updateTime;
|
||||
entity.IdEditor = idEditor;
|
||||
//entity.IdEditor = idEditor;
|
||||
}
|
||||
|
||||
return await db.SaveChangesAsync(token);
|
||||
}
|
||||
|
||||
public async Task<int> ClearAndAddRange(Guid idAuthor, Guid idDiscriminator, IEnumerable<ChangeLogValuesDto> dtos, CancellationToken token)
|
||||
public async Task<int> ClearAndAddRange(Guid idDiscriminator, ChangeLogCommitDto commitDto, CancellationToken token)
|
||||
{
|
||||
var result = 0;
|
||||
|
||||
ng.frolov
commented
Этот метод должен помечать все записи относящиеся к дискриминатору как удаленные и добавлять новые. Этот метод должен помечать все записи относящиеся к дискриминатору как удаленные и добавлять новые.
|
||||
using var transaction = await db.Database.BeginTransactionAsync(token);
|
||||
|
||||
result += await MarkAsDeleted(idAuthor, idDiscriminator, token);
|
||||
result += await AddRange(idAuthor, idDiscriminator, dtos, token);
|
||||
result += await MarkAsDeleted(commitDto.IdAuthor, idDiscriminator, token);
|
||||
result += await AddRange(idDiscriminator, commitDto, token);
|
||||
ng.frolov
commented
эта логкальная переменная дальше нигде не используется. Зачем она здесь? эта логкальная переменная дальше нигде не используется. Зачем она здесь?
|
||||
|
||||
await transaction.CommitAsync(token);
|
||||
|
||||
@ -92,19 +95,26 @@ public class ChangeLogRepository : IChangeLogRepository
|
||||
return result;
|
||||
}
|
||||
|
||||
public async Task<int> UpdateRange(Guid idEditor, IEnumerable<ChangeLogValuesDto> dtos, CancellationToken token)
|
||||
public async Task<int> UpdateRange(ChangeLogCommitDto commitDto, CancellationToken token)
|
||||
{
|
||||
var dbSet = db.Set<ChangeLog>();
|
||||
|
||||
var updatedIds = dtos.Select(d => d.Id);
|
||||
var updatedIds = commitDto.ChangeLogItems.Select(d => d.Id);
|
||||
var updatedEntities = dbSet
|
||||
.Where(s => updatedIds.Contains(s.Id))
|
||||
.ToDictionary(s => s.Id);
|
||||
|
||||
var result = 0;
|
||||
using var transaction = await db.Database.BeginTransactionAsync(token);
|
||||
|
||||
foreach (var dto in dtos)
|
||||
var commit = CreateCommit(commitDto);
|
||||
db.Set<ChangeLogCommit>().Add(commit);
|
||||
ng.frolov
commented
Linq очень не оптимально материализует в словари.
Linq очень не оптимально материализует в словари.
Тут лучше материализовать сперва в массив, а затем массив в словарь.
+ Используй асинхронные методы материализации в асинхронных методах репозиториев
|
||||
db.SaveChanges();
|
||||
|
||||
//using var transaction = await db.Database.BeginTransactionAsync(token);
|
||||
|
||||
|
||||
|
||||
foreach (var dto in commitDto.ChangeLogItems)
|
||||
{
|
||||
var updatedEntity = updatedEntities.GetValueOrDefault(dto.Id);
|
||||
if (updatedEntity is null)
|
||||
@ -112,16 +122,15 @@ public class ChangeLogRepository : IChangeLogRepository
|
||||
throw new ArgumentException($"Entity with id = {dto.Id} doesn't exist in Db", nameof(dto));
|
||||
}
|
||||
|
||||
var newEntity = CreateEntityFromDto(idEditor, updatedEntity.IdDiscriminator, dto);
|
||||
var newEntity = CreateChangeLogFromDto(commitDto.IdAuthor, updatedEntity.IdDiscriminator, commit.Id, dto);
|
||||
dbSet.Add(newEntity);
|
||||
|
||||
updatedEntity.IdNext = newEntity.Id;
|
||||
updatedEntity.Obsolete = DateTimeOffset.UtcNow;
|
||||
updatedEntity.IdEditor = idEditor;
|
||||
}
|
||||
|
||||
result = await db.SaveChangesAsync(token);
|
||||
await transaction.CommitAsync(token);
|
||||
//await transaction.CommitAsync(token);
|
||||
|
||||
return result;
|
||||
|
||||
@ -195,7 +204,7 @@ public class ChangeLogRepository : IChangeLogRepository
|
||||
return datesOnly;
|
||||
}
|
||||
|
||||
private static ChangeLog CreateEntityFromDto(Guid idAuthor, Guid idDiscriminator, ChangeLogValuesDto dto)
|
||||
private static ChangeLog CreateChangeLogFromDto(Guid idDiscriminator, Guid idCommit, Guid idAuthor, ChangeLogValuesDto dto)
|
||||
{
|
||||
var entity = new ChangeLog()
|
||||
{
|
||||
@ -203,14 +212,23 @@ public class ChangeLogRepository : IChangeLogRepository
|
||||
Creation = DateTimeOffset.UtcNow,
|
||||
IdAuthor = idAuthor,
|
||||
IdDiscriminator = idDiscriminator,
|
||||
IdEditor = idAuthor,
|
||||
|
||||
Value = dto.Value
|
||||
Value = dto.Value,
|
||||
IdCommit = idCommit,
|
||||
};
|
||||
|
||||
return entity;
|
||||
}
|
||||
|
||||
private static ChangeLogCommit CreateCommit(ChangeLogCommitDto commitDto)
|
||||
{
|
||||
return new ChangeLogCommit()
|
||||
{
|
||||
Comment = commitDto.Comment,
|
||||
Creation = DateTimeOffset.UtcNow,
|
||||
IdCommitAuthor = commitDto.IdAuthor
|
||||
};
|
||||
}
|
||||
|
||||
public async Task<IEnumerable<ChangeLogValuesDto>> GetGtDate(Guid idDiscriminator, DateTimeOffset dateBegin, CancellationToken token)
|
||||
{
|
||||
var date = dateBegin.ToUniversalTime();
|
||||
|
33
DD.Persistence.Models/Requests/ChangeLogCommitDto.cs
Normal file
@ -0,0 +1,33 @@
|
||||
namespace DD.Persistence.Models.Requests;
|
||||
|
||||
/// <summary>
|
||||
/// Модель коммита с изменениями
|
||||
/// </summary>
|
||||
public class ChangeLogCommitDto
|
||||
{
|
||||
/// <summary>
|
||||
/// Пользователь, совершающий коммит
|
||||
/// </summary>
|
||||
public Guid IdAuthor { get; set; }
|
||||
ng.frolov
commented
По правильному стоит разделить эту Dto на 2. Сделать отдельную dto для создания нового коммита, так как это поле генерируется внутри репозитория. По правильному стоит разделить эту Dto на 2. Сделать отдельную dto для создания нового коммита, так как это поле генерируется внутри репозитория.
|
||||
|
||||
/// <summary>
|
||||
/// Комментарий
|
||||
/// </summary>
|
||||
public string Comment { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Набор изменений
|
||||
/// </summary>
|
||||
public IEnumerable<ChangeLogValuesDto> ChangeLogItems { get; set; }
|
||||
|
||||
/// <summary>
|
||||
///
|
||||
/// </summary>
|
||||
public ChangeLogCommitDto(Guid idAuthor, string comment, IEnumerable<ChangeLogValuesDto> changeLogItems)
|
||||
{
|
||||
IdAuthor = idAuthor;
|
||||
Comment = comment;
|
||||
ChangeLogItems = changeLogItems;
|
||||
}
|
||||
|
||||
}
|
@ -14,9 +14,10 @@ public interface IChangeLogApi : ISyncWithDiscriminatorApi<ChangeLogValuesDto>
|
||||
/// </summary>
|
||||
/// <param name="idDiscriminator"></param>
|
||||
/// <param name="dtos"></param>
|
||||
/// <param name="comment"></param>
|
||||
/// <param name="token"></param>
|
||||
/// <returns></returns>
|
||||
Task<IActionResult> ClearAndAddRange(Guid idDiscriminator, IEnumerable<ChangeLogValuesDto> dtos, CancellationToken token);
|
||||
Task<IActionResult> ClearAndAddRange(Guid idDiscriminator, IEnumerable<ChangeLogValuesDto> dtos, string comment, CancellationToken token);
|
||||
|
||||
/// <summary>
|
||||
/// Получение данных на текущую дату (с пагинацией)
|
||||
@ -52,34 +53,38 @@ public interface IChangeLogApi : ISyncWithDiscriminatorApi<ChangeLogValuesDto>
|
||||
/// </summary>
|
||||
/// <param name="idDiscriminator"></param>
|
||||
/// <param name="dto"></param>
|
||||
/// <param name="comment">комментарий</param>
|
||||
/// <param name="token"></param>
|
||||
/// <returns></returns>
|
||||
Task<IActionResult> Add(Guid idDiscriminator, ChangeLogValuesDto dto, CancellationToken token);
|
||||
Task<IActionResult> Add(Guid idDiscriminator, ChangeLogValuesDto dto, string comment, CancellationToken token);
|
||||
|
||||
/// <summary>
|
||||
/// Добавить несколько записей
|
||||
/// </summary>
|
||||
/// <param name="idDiscriminator"></param>
|
||||
/// <param name="dtos"></param>
|
||||
/// <param name="comment">комментарий</param>
|
||||
/// <param name="token"></param>
|
||||
/// <returns></returns>
|
||||
Task<IActionResult> AddRange(Guid idDiscriminator, IEnumerable<ChangeLogValuesDto> dtos, CancellationToken token);
|
||||
Task<IActionResult> AddRange(Guid idDiscriminator, IEnumerable<ChangeLogValuesDto> dtos, string comment, CancellationToken token);
|
||||
|
||||
/// <summary>
|
||||
/// Обновить одну запись
|
||||
/// </summary>
|
||||
/// <param name="dto"></param>
|
||||
/// <param name="comment"></param>
|
||||
/// <param name="token"></param>
|
||||
/// <returns></returns>
|
||||
Task<IActionResult> Update(ChangeLogValuesDto dto, CancellationToken token);
|
||||
Task<IActionResult> Update(ChangeLogValuesDto dto, string comment, CancellationToken token);
|
||||
|
||||
/// <summary>
|
||||
/// Обновить несколько записей
|
||||
/// </summary>
|
||||
/// <param name="dtos"></param>
|
||||
/// <param name="comment">комментарий</param>
|
||||
/// <param name="token"></param>
|
||||
/// <returns></returns>
|
||||
Task<IActionResult> UpdateRange(IEnumerable<ChangeLogValuesDto> dtos, CancellationToken token);
|
||||
Task<IActionResult> UpdateRange(IEnumerable<ChangeLogValuesDto> dtos, string comment, CancellationToken token);
|
||||
|
||||
/// <summary>
|
||||
/// Удалить одну запись
|
||||
|
@ -1,24 +1,23 @@
|
||||
using DD.Persistence.Models;
|
||||
using DD.Persistence.Models.Common;
|
||||
using DD.Persistence.Models.Requests;
|
||||
using Microsoft.EntityFrameworkCore.Storage.ValueConversion.Internal;
|
||||
|
||||
namespace DD.Persistence.Repositories;
|
||||
|
||||
/// <summary>
|
||||
/// Интерфейс для работы с историческими данными
|
||||
/// </summary>
|
||||
/// <typeparam name="TDto"></typeparam>
|
||||
public interface IChangeLogRepository : ISyncWithDiscriminatorRepository<ChangeLogValuesDto>
|
||||
{
|
||||
/// <summary>
|
||||
/// Добавление записей
|
||||
/// </summary>
|
||||
/// <param name="idAuthor">пользователь, который добавляет</param>
|
||||
/// <param name="idDiscriminator">ключ справочника</param>
|
||||
/// <param name="dtos"></param>
|
||||
/// <param name="dto">коммит с изменениями</param>
|
||||
/// <param name="token"></param>
|
||||
/// <returns></returns>
|
||||
Task<int> AddRange(Guid idAuthor, Guid idDiscriminator, IEnumerable<ChangeLogValuesDto> dtos, CancellationToken token);
|
||||
Task<int> AddRange(Guid idDiscriminator, ChangeLogCommitDto dto, CancellationToken token);
|
||||
|
||||
/// <summary>
|
||||
/// Пометить записи как удаленные
|
||||
@ -41,21 +40,19 @@ public interface IChangeLogRepository : ISyncWithDiscriminatorRepository<ChangeL
|
||||
/// <summary>
|
||||
/// Очистить и добавить новые
|
||||
/// </summary>
|
||||
/// <param name="idAuthor"></param>
|
||||
/// <param name="idDiscriminator"></param>
|
||||
/// <param name="dtos"></param>
|
||||
/// <param name="commitDto">коммит с изменениями</param>
|
||||
/// <param name="token"></param>
|
||||
/// <returns></returns>
|
||||
Task<int> ClearAndAddRange(Guid idAuthor, Guid idDiscriminator, IEnumerable<ChangeLogValuesDto> dtos, CancellationToken token);
|
||||
Task<int> ClearAndAddRange(Guid idDiscriminator, ChangeLogCommitDto commitDto, CancellationToken token);
|
||||
|
||||
/// <summary>
|
||||
/// Редактирование записей
|
||||
/// </summary>
|
||||
/// <param name="idEditor">пользователь, который редактирует</param>
|
||||
/// <param name="dtos"></param>
|
||||
/// <param name="commitDto">коммит с изменениями</param>
|
||||
/// <param name="token"></param>
|
||||
/// <returns></returns>
|
||||
Task<int> UpdateRange(Guid idEditor, IEnumerable<ChangeLogValuesDto> dtos, CancellationToken token);
|
||||
Task<int> UpdateRange(ChangeLogCommitDto commitDto, CancellationToken token);
|
||||
|
||||
/// <summary>
|
||||
/// Получение актуальных записей на определенный момент времени (с пагинацией)
|
||||
|
Должен остаться только один