Доработать хранение технологических сообщений
This commit is contained in:
parent
153f5894ad
commit
acc9e6494a
@ -15,11 +15,15 @@ namespace Persistence.API.Controllers
|
||||
this.techMessagesRepository = techMessagesRepository;
|
||||
}
|
||||
|
||||
public Task<ActionResult<PaginationContainer<TechMessageDto>>> GetPage(RequestDto request, CancellationToken token)
|
||||
[HttpGet]
|
||||
public async Task<ActionResult<PaginationContainer<TechMessageDto>>> GetPage([FromQuery] RequestDto request, CancellationToken token)
|
||||
{
|
||||
throw new NotImplementedException();
|
||||
var result = await techMessagesRepository.GetPage(request, token);
|
||||
|
||||
return Ok(result);
|
||||
}
|
||||
|
||||
[HttpGet("statistics")]
|
||||
public async Task<ActionResult<int>> GetStatistics(int importantId, string autoDrillingSystem, CancellationToken token)
|
||||
{
|
||||
var result = await techMessagesRepository.GetStatistics(importantId, autoDrillingSystem, token);
|
||||
@ -27,6 +31,7 @@ namespace Persistence.API.Controllers
|
||||
return Ok(result);
|
||||
}
|
||||
|
||||
[HttpGet("systems")]
|
||||
public async Task<ActionResult<IEnumerable<string>>> GetSystems(CancellationToken token)
|
||||
{
|
||||
var result = await techMessagesRepository.GetSystems(token);
|
||||
@ -34,7 +39,8 @@ namespace Persistence.API.Controllers
|
||||
return Ok(result);
|
||||
}
|
||||
|
||||
public async Task<ActionResult<int>> InsertRange(IEnumerable<TechMessageDto> dtos, CancellationToken token)
|
||||
[HttpPost]
|
||||
public async Task<ActionResult<int>> InsertRange([FromBody] IEnumerable<TechMessageDto> dtos, CancellationToken token)
|
||||
{
|
||||
var result = await techMessagesRepository.InsertRange(dtos, token);
|
||||
|
||||
|
175
Persistence.Database.Postgres/Migrations/20241126044756_TechMessageMigration.Designer.cs
generated
Normal file
175
Persistence.Database.Postgres/Migrations/20241126044756_TechMessageMigration.Designer.cs
generated
Normal file
@ -0,0 +1,175 @@
|
||||
// <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 Persistence.Database.Model;
|
||||
|
||||
#nullable disable
|
||||
|
||||
namespace Persistence.Database.Postgres.Migrations
|
||||
{
|
||||
[DbContext(typeof(PersistenceDbContext))]
|
||||
[Migration("20241126044756_TechMessageMigration")]
|
||||
partial class TechMessageMigration
|
||||
{
|
||||
/// <inheritdoc />
|
||||
protected override void BuildTargetModel(ModelBuilder modelBuilder)
|
||||
{
|
||||
#pragma warning disable 612, 618
|
||||
modelBuilder
|
||||
.UseCollation("Russian_Russia.1251")
|
||||
.HasAnnotation("ProductVersion", "8.0.10")
|
||||
.HasAnnotation("Relational:MaxIdentifierLength", 63);
|
||||
|
||||
NpgsqlModelBuilderExtensions.HasPostgresExtension(modelBuilder, "adminpack");
|
||||
NpgsqlModelBuilderExtensions.UseIdentityByDefaultColumns(modelBuilder);
|
||||
|
||||
modelBuilder.Entity("Persistence.Database.Entity.TechMessage", b =>
|
||||
{
|
||||
b.Property<Guid>("EventId")
|
||||
.ValueGeneratedOnAdd()
|
||||
.HasColumnType("uuid")
|
||||
.HasComment("Id события");
|
||||
|
||||
b.Property<string>("AutoDrillingSystem")
|
||||
.HasColumnType("varchar(256)")
|
||||
.HasComment("Система автобурения, к которой относится сообщение");
|
||||
|
||||
b.Property<double?>("Depth")
|
||||
.HasColumnType("double precision")
|
||||
.HasComment("Глубина забоя");
|
||||
|
||||
b.Property<int>("ImportantId")
|
||||
.HasColumnType("integer")
|
||||
.HasComment("Id Категории важности");
|
||||
|
||||
b.Property<string>("MessageText")
|
||||
.HasColumnType("varchar(512)")
|
||||
.HasComment("Текст сообщения");
|
||||
|
||||
b.Property<DateTimeOffset>("OccurrenceDate")
|
||||
.HasColumnType("timestamp with time zone")
|
||||
.HasComment("Дата возникновения");
|
||||
|
||||
b.Property<Guid>("UserId")
|
||||
.HasColumnType("uuid")
|
||||
.HasComment("Id пользователя за пультом бурильщика");
|
||||
|
||||
b.HasKey("EventId");
|
||||
|
||||
b.ToTable("TechMessage");
|
||||
});
|
||||
|
||||
modelBuilder.Entity("Persistence.Database.Model.DataSaub", b =>
|
||||
{
|
||||
b.Property<DateTimeOffset>("Date")
|
||||
.HasColumnType("timestamp with time zone")
|
||||
.HasColumnName("date");
|
||||
|
||||
b.Property<double?>("AxialLoad")
|
||||
.HasColumnType("double precision")
|
||||
.HasColumnName("axialLoad");
|
||||
|
||||
b.Property<double?>("BitDepth")
|
||||
.HasColumnType("double precision")
|
||||
.HasColumnName("bitDepth");
|
||||
|
||||
b.Property<double?>("BlockPosition")
|
||||
.HasColumnType("double precision")
|
||||
.HasColumnName("blockPosition");
|
||||
|
||||
b.Property<double?>("BlockSpeed")
|
||||
.HasColumnType("double precision")
|
||||
.HasColumnName("blockSpeed");
|
||||
|
||||
b.Property<double?>("Flow")
|
||||
.HasColumnType("double precision")
|
||||
.HasColumnName("flow");
|
||||
|
||||
b.Property<double?>("HookWeight")
|
||||
.HasColumnType("double precision")
|
||||
.HasColumnName("hookWeight");
|
||||
|
||||
b.Property<int>("IdFeedRegulator")
|
||||
.HasColumnType("integer")
|
||||
.HasColumnName("idFeedRegulator");
|
||||
|
||||
b.Property<int?>("Mode")
|
||||
.HasColumnType("integer")
|
||||
.HasColumnName("mode");
|
||||
|
||||
b.Property<double?>("Mse")
|
||||
.HasColumnType("double precision")
|
||||
.HasColumnName("mse");
|
||||
|
||||
b.Property<short>("MseState")
|
||||
.HasColumnType("smallint")
|
||||
.HasColumnName("mseState");
|
||||
|
||||
b.Property<double?>("Pressure")
|
||||
.HasColumnType("double precision")
|
||||
.HasColumnName("pressure");
|
||||
|
||||
b.Property<double?>("Pump0Flow")
|
||||
.HasColumnType("double precision")
|
||||
.HasColumnName("pump0Flow");
|
||||
|
||||
b.Property<double?>("Pump1Flow")
|
||||
.HasColumnType("double precision")
|
||||
.HasColumnName("pump1Flow");
|
||||
|
||||
b.Property<double?>("Pump2Flow")
|
||||
.HasColumnType("double precision")
|
||||
.HasColumnName("pump2Flow");
|
||||
|
||||
b.Property<double?>("RotorSpeed")
|
||||
.HasColumnType("double precision")
|
||||
.HasColumnName("rotorSpeed");
|
||||
|
||||
b.Property<double?>("RotorTorque")
|
||||
.HasColumnType("double precision")
|
||||
.HasColumnName("rotorTorque");
|
||||
|
||||
b.Property<string>("User")
|
||||
.HasColumnType("text")
|
||||
.HasColumnName("user");
|
||||
|
||||
b.Property<double?>("WellDepth")
|
||||
.HasColumnType("double precision")
|
||||
.HasColumnName("wellDepth");
|
||||
|
||||
b.HasKey("Date");
|
||||
|
||||
b.ToTable("DataSaub");
|
||||
});
|
||||
|
||||
modelBuilder.Entity("Persistence.Database.Model.Setpoint", b =>
|
||||
{
|
||||
b.Property<Guid>("Key")
|
||||
.HasColumnType("uuid")
|
||||
.HasComment("Ключ");
|
||||
|
||||
b.Property<DateTimeOffset>("Created")
|
||||
.HasColumnType("timestamp with time zone")
|
||||
.HasComment("Дата создания уставки");
|
||||
|
||||
b.Property<int>("IdUser")
|
||||
.HasColumnType("integer")
|
||||
.HasComment("Id автора последнего изменения");
|
||||
|
||||
b.Property<object>("Value")
|
||||
.IsRequired()
|
||||
.HasColumnType("jsonb")
|
||||
.HasComment("Значение уставки");
|
||||
|
||||
b.HasKey("Key", "Created");
|
||||
|
||||
b.ToTable("Setpoint");
|
||||
});
|
||||
#pragma warning restore 612, 618
|
||||
}
|
||||
}
|
||||
}
|
@ -0,0 +1,59 @@
|
||||
using System;
|
||||
using Microsoft.EntityFrameworkCore.Migrations;
|
||||
|
||||
#nullable disable
|
||||
|
||||
namespace Persistence.Database.Postgres.Migrations
|
||||
{
|
||||
/// <inheritdoc />
|
||||
public partial class TechMessageMigration : Migration
|
||||
{
|
||||
/// <inheritdoc />
|
||||
protected override void Up(MigrationBuilder migrationBuilder)
|
||||
{
|
||||
migrationBuilder.AlterColumn<DateTimeOffset>(
|
||||
name: "Created",
|
||||
table: "Setpoint",
|
||||
type: "timestamp with time zone",
|
||||
nullable: false,
|
||||
comment: "Дата создания уставки",
|
||||
oldClrType: typeof(DateTimeOffset),
|
||||
oldType: "timestamp with time zone",
|
||||
oldComment: "Дата изменения уставки");
|
||||
|
||||
migrationBuilder.CreateTable(
|
||||
name: "TechMessage",
|
||||
columns: table => new
|
||||
{
|
||||
EventId = table.Column<Guid>(type: "uuid", nullable: false, comment: "Id события"),
|
||||
ImportantId = table.Column<int>(type: "integer", nullable: false, comment: "Id Категории важности"),
|
||||
OccurrenceDate = table.Column<DateTimeOffset>(type: "timestamp with time zone", nullable: false, comment: "Дата возникновения"),
|
||||
Depth = table.Column<double>(type: "double precision", nullable: true, comment: "Глубина забоя"),
|
||||
MessageText = table.Column<string>(type: "varchar(512)", nullable: true, comment: "Текст сообщения"),
|
||||
AutoDrillingSystem = table.Column<string>(type: "varchar(256)", nullable: true, comment: "Система автобурения, к которой относится сообщение"),
|
||||
UserId = table.Column<Guid>(type: "uuid", nullable: false, comment: "Id пользователя за пультом бурильщика")
|
||||
},
|
||||
constraints: table =>
|
||||
{
|
||||
table.PrimaryKey("PK_TechMessage", x => x.EventId);
|
||||
});
|
||||
}
|
||||
|
||||
/// <inheritdoc />
|
||||
protected override void Down(MigrationBuilder migrationBuilder)
|
||||
{
|
||||
migrationBuilder.DropTable(
|
||||
name: "TechMessage");
|
||||
|
||||
migrationBuilder.AlterColumn<DateTimeOffset>(
|
||||
name: "Created",
|
||||
table: "Setpoint",
|
||||
type: "timestamp with time zone",
|
||||
nullable: false,
|
||||
comment: "Дата изменения уставки",
|
||||
oldClrType: typeof(DateTimeOffset),
|
||||
oldType: "timestamp with time zone",
|
||||
oldComment: "Дата создания уставки");
|
||||
}
|
||||
}
|
||||
}
|
@ -24,6 +24,42 @@ namespace Persistence.Database.Postgres.Migrations
|
||||
NpgsqlModelBuilderExtensions.HasPostgresExtension(modelBuilder, "adminpack");
|
||||
NpgsqlModelBuilderExtensions.UseIdentityByDefaultColumns(modelBuilder);
|
||||
|
||||
modelBuilder.Entity("Persistence.Database.Entity.TechMessage", b =>
|
||||
{
|
||||
b.Property<Guid>("EventId")
|
||||
.ValueGeneratedOnAdd()
|
||||
.HasColumnType("uuid")
|
||||
.HasComment("Id события");
|
||||
|
||||
b.Property<string>("AutoDrillingSystem")
|
||||
.HasColumnType("varchar(256)")
|
||||
.HasComment("Система автобурения, к которой относится сообщение");
|
||||
|
||||
b.Property<double?>("Depth")
|
||||
.HasColumnType("double precision")
|
||||
.HasComment("Глубина забоя");
|
||||
|
||||
b.Property<int>("ImportantId")
|
||||
.HasColumnType("integer")
|
||||
.HasComment("Id Категории важности");
|
||||
|
||||
b.Property<string>("MessageText")
|
||||
.HasColumnType("varchar(512)")
|
||||
.HasComment("Текст сообщения");
|
||||
|
||||
b.Property<DateTimeOffset>("OccurrenceDate")
|
||||
.HasColumnType("timestamp with time zone")
|
||||
.HasComment("Дата возникновения");
|
||||
|
||||
b.Property<Guid>("UserId")
|
||||
.HasColumnType("uuid")
|
||||
.HasComment("Id пользователя за пультом бурильщика");
|
||||
|
||||
b.HasKey("EventId");
|
||||
|
||||
b.ToTable("TechMessage");
|
||||
});
|
||||
|
||||
modelBuilder.Entity("Persistence.Database.Model.DataSaub", b =>
|
||||
{
|
||||
b.Property<DateTimeOffset>("Date")
|
||||
@ -115,7 +151,7 @@ namespace Persistence.Database.Postgres.Migrations
|
||||
|
||||
b.Property<DateTimeOffset>("Created")
|
||||
.HasColumnType("timestamp with time zone")
|
||||
.HasComment("Дата изменения уставки");
|
||||
.HasComment("Дата создания уставки");
|
||||
|
||||
b.Property<int>("IdUser")
|
||||
.HasColumnType("integer")
|
||||
|
@ -17,6 +17,7 @@ public static class DependencyInjection
|
||||
|
||||
services.AddTransient<ITimeSeriesDataRepository<DataSaubDto>, TimeSeriesDataRepository<DataSaub, DataSaubDto>>();
|
||||
services.AddTransient<ISetpointRepository, SetpointRepository>();
|
||||
services.AddTransient<ITechMessagesRepository, TechMessagesRepository>();
|
||||
|
||||
return services;
|
||||
}
|
||||
|
267
Persistence.Repository/Extensions/EFExtensionsSortBy.cs
Normal file
267
Persistence.Repository/Extensions/EFExtensionsSortBy.cs
Normal file
@ -0,0 +1,267 @@
|
||||
using System.Collections.Concurrent;
|
||||
using System.Linq.Expressions;
|
||||
using System.Reflection;
|
||||
|
||||
namespace Persistence.Repository.Extensions;
|
||||
|
||||
public static class EFExtensionsSortBy
|
||||
{
|
||||
struct TypeAccessor
|
||||
{
|
||||
public LambdaExpression KeySelector { get; set; }
|
||||
public MethodInfo OrderBy { get; set; }
|
||||
public MethodInfo OrderByDescending { get; set; }
|
||||
public MethodInfo ThenBy { get; set; }
|
||||
public MethodInfo ThenByDescending { get; set; }
|
||||
}
|
||||
|
||||
private static ConcurrentDictionary<Type, Dictionary<string, TypeAccessor>> TypePropSelectors { get; set; } =
|
||||
new();
|
||||
|
||||
private static readonly MethodInfo methodOrderBy = GetExtOrderMethod("OrderBy");
|
||||
|
||||
private static readonly MethodInfo methodOrderByDescending = GetExtOrderMethod("OrderByDescending");
|
||||
|
||||
private static readonly MethodInfo methodThenBy = GetExtOrderMethod("ThenBy");
|
||||
|
||||
private static readonly MethodInfo methodThenByDescending = GetExtOrderMethod("ThenByDescending");
|
||||
|
||||
private static MethodInfo GetExtOrderMethod(string methodName)
|
||||
=> typeof(Queryable)
|
||||
.GetMethods()
|
||||
.Where(m => m.Name == methodName &&
|
||||
m.IsGenericMethodDefinition &&
|
||||
m.GetParameters().Length == 2 &&
|
||||
m.GetParameters()[1].ParameterType.IsAssignableTo(typeof(LambdaExpression)))
|
||||
.Single();
|
||||
|
||||
private static Dictionary<string, TypeAccessor> MakeTypeAccessors(Type type)
|
||||
{
|
||||
var propContainer = new Dictionary<string, TypeAccessor>();
|
||||
var properties = type.GetProperties();
|
||||
foreach (var propertyInfo in properties)
|
||||
{
|
||||
var name = propertyInfo.Name.ToLower();
|
||||
ParameterExpression arg = Expression.Parameter(type, "x");
|
||||
MemberExpression property = Expression.Property(arg, propertyInfo.Name);
|
||||
var selector = Expression.Lambda(property, new ParameterExpression[] { arg });
|
||||
var typeAccessor = new TypeAccessor
|
||||
{
|
||||
KeySelector = selector,
|
||||
OrderBy = methodOrderBy.MakeGenericMethod(type, propertyInfo.PropertyType),
|
||||
OrderByDescending = methodOrderByDescending.MakeGenericMethod(type, propertyInfo.PropertyType),
|
||||
ThenBy = methodThenBy.MakeGenericMethod(type, propertyInfo.PropertyType),
|
||||
ThenByDescending = methodThenByDescending.MakeGenericMethod(type, propertyInfo.PropertyType),
|
||||
};
|
||||
|
||||
propContainer.Add(name, typeAccessor);
|
||||
}
|
||||
|
||||
return propContainer;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Добавить в запрос сортировку по возрастанию или убыванию.
|
||||
/// </summary>
|
||||
/// <typeparam name="TSource"></typeparam>
|
||||
/// <param name="query"></param>
|
||||
/// <param name="propertySort">
|
||||
/// Свойство сортировки.
|
||||
/// Состоит из названия свойства (в любом регистре)
|
||||
/// и опционально указания направления сортировки "asc" или "desc"
|
||||
/// </param>
|
||||
/// <example>
|
||||
/// var query = query("Date desc");
|
||||
/// </example>
|
||||
/// <returns>Запрос с примененной сортировкой</returns>
|
||||
public static IOrderedQueryable<TSource> SortBy<TSource>(
|
||||
this IQueryable<TSource> query,
|
||||
IEnumerable<string> propertySorts)
|
||||
{
|
||||
if (propertySorts?.Any() != true)
|
||||
return (IOrderedQueryable<TSource>)query;
|
||||
|
||||
var sortEnum = propertySorts.GetEnumerator();
|
||||
sortEnum.MoveNext();
|
||||
var orderedQuery = query.SortBy(sortEnum.Current);
|
||||
|
||||
while (sortEnum.MoveNext())
|
||||
orderedQuery = orderedQuery.ThenSortBy(sortEnum.Current);
|
||||
|
||||
return orderedQuery;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Добавить в запрос сортировку по возрастанию или убыванию.
|
||||
/// Этот метод сбросит ранее наложенные сортировки.
|
||||
/// </summary>
|
||||
/// <typeparam name="TSource"></typeparam>
|
||||
/// <param name="query"></param>
|
||||
/// <param name="propertySort">
|
||||
/// Свойство сортировки.
|
||||
/// Состоит из названия свойства (в любом регистре)
|
||||
/// и опционально указания направления сортировки "asc" или "desc"
|
||||
/// </param>
|
||||
/// <example>
|
||||
/// var query = query("Date desc");
|
||||
/// </example>
|
||||
/// <returns>Запрос с примененной сортировкой</returns>
|
||||
public static IOrderedQueryable<TSource> SortBy<TSource>(
|
||||
this IQueryable<TSource> query,
|
||||
string propertySort)
|
||||
{
|
||||
var parts = propertySort.Split(" ", 2, StringSplitOptions.RemoveEmptyEntries);
|
||||
var isDesc = parts.Length >= 2 && parts[1].ToLower().Trim() == "desc";
|
||||
var propertyName = parts[0];
|
||||
|
||||
var newQuery = query.SortBy(propertyName, isDesc);
|
||||
return newQuery;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Добавить в запрос дополнительную сортировку по возрастанию или убыванию.
|
||||
/// </summary>
|
||||
/// <typeparam name="TSource"></typeparam>
|
||||
/// <param name="query"></param>
|
||||
/// <param name="propertySort">
|
||||
/// Свойство сортировки.
|
||||
/// Состоит из названия свойства (в любом регистре)
|
||||
/// и опционально указания направления сортировки "asc" или "desc"
|
||||
/// </param>
|
||||
/// <example>
|
||||
/// var query = query("Date desc");
|
||||
/// </example>
|
||||
/// <returns>Запрос с примененной сортировкой</returns>
|
||||
public static IOrderedQueryable<TSource> ThenSortBy<TSource>(
|
||||
this IOrderedQueryable<TSource> query,
|
||||
string propertySort)
|
||||
{
|
||||
var parts = propertySort.Split(" ", 2, StringSplitOptions.RemoveEmptyEntries);
|
||||
var isDesc = parts.Length >= 2 && parts[1].ToLower().Trim() == "desc";
|
||||
var propertyName = parts[0];
|
||||
|
||||
var newQuery = query.ThenSortBy(propertyName, isDesc);
|
||||
return newQuery;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Добавить в запрос сортировку по возрастанию или убыванию
|
||||
/// </summary>
|
||||
/// <typeparam name="TSource"></typeparam>
|
||||
/// <param name="query"></param>
|
||||
/// <param name="propertyName">Название свойства (в любом регистре)</param>
|
||||
/// <param name="isDesc">Сортировать по убыванию</param>
|
||||
/// <returns>Запрос с примененной сортировкой</returns>
|
||||
public static IOrderedQueryable<TSource> SortBy<TSource>(
|
||||
this IQueryable<TSource> query,
|
||||
string propertyName,
|
||||
bool isDesc)
|
||||
{
|
||||
Type rootType = typeof(TSource);
|
||||
var typePropSelector = TypePropSelectors.GetOrAdd(rootType, MakeTypeAccessors);
|
||||
var propertyNameLower = propertyName.ToLower();
|
||||
|
||||
MethodInfo orderByDescending;
|
||||
MethodInfo orderByAscending;
|
||||
|
||||
LambdaExpression? lambdaExpression = null;
|
||||
|
||||
if (propertyName.Contains('.'))
|
||||
{
|
||||
Type type = rootType;
|
||||
ParameterExpression rootExpression = Expression.Parameter(rootType, "x");
|
||||
Expression expr = rootExpression;
|
||||
|
||||
var propertyPath = propertyName.Split(".", StringSplitOptions.RemoveEmptyEntries);
|
||||
|
||||
for (int i = 0; i < propertyPath.Length; i++)
|
||||
{
|
||||
PropertyInfo pi = type.GetProperty(propertyPath[i])!;
|
||||
expr = Expression.Property(expr, pi);
|
||||
type = pi.PropertyType;
|
||||
}
|
||||
|
||||
Type delegateType = typeof(Func<,>).MakeGenericType(rootType, type);
|
||||
lambdaExpression = Expression.Lambda(delegateType, expr, rootExpression);
|
||||
|
||||
orderByAscending = methodOrderBy.MakeGenericMethod(rootType, type);
|
||||
orderByDescending = methodOrderByDescending.MakeGenericMethod(rootType, type);
|
||||
}
|
||||
else
|
||||
{
|
||||
var rootTypeAccessor = typePropSelector[propertyNameLower];
|
||||
orderByAscending = rootTypeAccessor.OrderBy;
|
||||
orderByDescending = rootTypeAccessor.OrderByDescending;
|
||||
lambdaExpression = rootTypeAccessor.KeySelector;
|
||||
}
|
||||
|
||||
var genericMethod = isDesc
|
||||
? orderByDescending
|
||||
: orderByAscending;
|
||||
|
||||
var newQuery = (IOrderedQueryable<TSource>)genericMethod
|
||||
.Invoke(genericMethod, new object[] { query, lambdaExpression })!;
|
||||
return newQuery;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Добавить в запрос дополнительную сортировку по возрастанию или убыванию
|
||||
/// </summary>
|
||||
/// <typeparam name="TSource"></typeparam>
|
||||
/// <param name="query"></param>
|
||||
/// <param name="propertyName">Название свойства (в любом регистре)</param>
|
||||
/// <param name="isDesc">Сортировать по убыванию</param>
|
||||
/// <returns>Запрос с примененной сортировкой</returns>
|
||||
public static IOrderedQueryable<TSource> ThenSortBy<TSource>(
|
||||
this IOrderedQueryable<TSource> query,
|
||||
string propertyName,
|
||||
bool isDesc)
|
||||
{
|
||||
Type rootType = typeof(TSource);
|
||||
var typePropSelector = TypePropSelectors.GetOrAdd(rootType, MakeTypeAccessors);
|
||||
var propertyNameLower = propertyName.ToLower();
|
||||
|
||||
MethodInfo orderByDescending;
|
||||
MethodInfo orderByAscending;
|
||||
|
||||
LambdaExpression? lambdaExpression = null;
|
||||
|
||||
// TODO: Устранить дублирование кода
|
||||
if (propertyName.Contains('.'))
|
||||
{
|
||||
Type type = rootType;
|
||||
ParameterExpression rootExpression = Expression.Parameter(rootType, "x");
|
||||
Expression expr = rootExpression;
|
||||
|
||||
var propertyPath = propertyName.Split(".", StringSplitOptions.RemoveEmptyEntries);
|
||||
|
||||
for (int i = 0; i < propertyPath.Length; i++)
|
||||
{
|
||||
PropertyInfo pi = type.GetProperty(propertyPath[i])!;
|
||||
expr = Expression.Property(expr, pi);
|
||||
type = pi.PropertyType;
|
||||
}
|
||||
|
||||
Type delegateType = typeof(Func<,>).MakeGenericType(rootType, type);
|
||||
lambdaExpression = Expression.Lambda(delegateType, expr, rootExpression);
|
||||
|
||||
orderByAscending = methodThenBy.MakeGenericMethod(rootType, type);
|
||||
orderByDescending = methodThenByDescending.MakeGenericMethod(rootType, type);
|
||||
}
|
||||
else
|
||||
{
|
||||
var rootTypeAccessor = typePropSelector[propertyNameLower];
|
||||
orderByAscending = rootTypeAccessor.ThenBy;
|
||||
orderByDescending = rootTypeAccessor.ThenByDescending;
|
||||
lambdaExpression = rootTypeAccessor.KeySelector;
|
||||
}
|
||||
|
||||
var genericMethod = isDesc
|
||||
? orderByDescending
|
||||
: orderByAscending;
|
||||
|
||||
var newQuery = (IOrderedQueryable<TSource>)genericMethod
|
||||
.Invoke(genericMethod, new object[] { query, lambdaExpression })!;
|
||||
return newQuery;
|
||||
}
|
||||
}
|
@ -16,6 +16,25 @@ namespace Persistence.Repository.Repositories
|
||||
|
||||
protected virtual IQueryable<TechMessage> GetQueryReadOnly() => db.Set<TechMessage>();
|
||||
|
||||
public async Task<PaginationContainer<TechMessageDto>> GetPage(RequestDto request, CancellationToken token)
|
||||
{
|
||||
var query = GetQueryReadOnly();
|
||||
var entities = await query
|
||||
.SortBy(request.SortSettings)
|
||||
.Skip(request.Skip)
|
||||
.Take(request.Take)
|
||||
.ToListAsync();
|
||||
var dto = new PaginationContainer<TechMessageDto>()
|
||||
{
|
||||
Skip = request.Skip,
|
||||
Take = request.Take,
|
||||
Count = entities.Count,
|
||||
Items = entities.Select(e => e.Adapt<TechMessageDto>())
|
||||
};
|
||||
|
||||
return dto;
|
||||
}
|
||||
|
||||
public async Task<int> GetStatistics(int importantId, string autoDrillingSystem, CancellationToken token)
|
||||
{
|
||||
var query = GetQueryReadOnly();
|
||||
|
@ -7,13 +7,13 @@ namespace Persistence.Repositories;
|
||||
/// </summary>
|
||||
public interface ISetpointRepository
|
||||
{
|
||||
/// <summary>
|
||||
/// Получить значения уставок по набору ключей
|
||||
/// </summary>
|
||||
/// <param name="setpointKeys"></param>
|
||||
/// <param name="token"></param>
|
||||
/// <returns></returns>
|
||||
Task<IEnumerable<SetpointValueDto>> GetCurrent(IEnumerable<Guid> setpointKeys, CancellationToken token);
|
||||
/// <summary>
|
||||
/// Получить значения уставок по набору ключей
|
||||
/// </summary>
|
||||
/// <param name="setpointKeys"></param>
|
||||
/// <param name="token"></param>
|
||||
/// <returns></returns>
|
||||
Task<IEnumerable<SetpointValueDto>> GetCurrent(IEnumerable<Guid> setpointKeys, CancellationToken token);
|
||||
|
||||
/// <summary>
|
||||
/// Получить значения уставок за определенный момент времени
|
||||
|
@ -7,6 +7,14 @@ namespace Persistence.Repositories
|
||||
/// </summary>
|
||||
public interface ITechMessagesRepository
|
||||
{
|
||||
/// <summary>
|
||||
/// Получить страницу списка объектов
|
||||
/// </summary>
|
||||
/// <param name="request"></param>
|
||||
/// <param name="token"></param>
|
||||
/// <returns></returns>
|
||||
Task<PaginationContainer<TechMessageDto>> GetPage(RequestDto request, CancellationToken token);
|
||||
|
||||
/// <summary>
|
||||
/// Добавление новых сообщений
|
||||
/// </summary>
|
||||
|
Loading…
Reference in New Issue
Block a user