Project cleanup

This commit is contained in:
Оля Бизюкова 2024-12-10 10:43:12 +05:00
parent 48dd53fce4
commit a6e611ec0d
27 changed files with 617 additions and 633 deletions

View File

@ -12,7 +12,7 @@ namespace Persistence.API.Controllers;
[Route("api/[controller]")]
public class ChangeLogController : ControllerBase, IChangeLogApi
{
private IChangeLogRepository repository;
private readonly IChangeLogRepository repository;
public ChangeLogController(IChangeLogRepository repository)
{

View File

@ -1,9 +1,9 @@
using System.Net;
using Microsoft.AspNetCore.Authorization;
using Microsoft.AspNetCore.Authorization;
using Microsoft.AspNetCore.Mvc;
using Persistence.Models;
using Persistence.Models.Requests;
using Persistence.Repositories;
using System.Net;
namespace Persistence.API.Controllers;
@ -16,7 +16,7 @@ namespace Persistence.API.Controllers;
public class TechMessagesController : ControllerBase
{
private readonly ITechMessagesRepository techMessagesRepository;
private static readonly Dictionary<int, string> categories = new Dictionary<int, string>()
private static readonly Dictionary<int, string> categories = new()
{
{ 0, "System" },
{ 1, "Авария" },

View File

@ -28,12 +28,11 @@ public static class DependencyInjection
c.MapType<DateOnly>(() => new OpenApiSchema { Type = "string", Format = "date" });
c.MapType<JsonValue>(() => new OpenApiSchema
{
AnyOf = new OpenApiSchema[]
{
AnyOf = [
new OpenApiSchema {Type = "string", Format = "string" },
new OpenApiSchema {Type = "number", Format = "int32" },
new OpenApiSchema {Type = "number", Format = "float" },
}
new OpenApiSchema {Type = "number", Format = "float" }
]
});
c.CustomOperationIds(e =>
@ -45,8 +44,8 @@ public static class DependencyInjection
var needUseKeyCloak = configuration.GetSection("NeedUseKeyCloak").Get<bool>();
if (needUseKeyCloak)
c.AddKeycloackSecurity(configuration);
else c.AddDefaultSecurity(configuration);
c.AddKeycloakSecurity(configuration);
else c.AddDefaultSecurity();
var xmlFile = $"{Assembly.GetExecutingAssembly().GetName().Name}.xml";
var xmlPath = Path.Combine(AppContext.BaseDirectory, xmlFile);
@ -134,12 +133,12 @@ public static class DependencyInjection
}
#endregion
#region Security (Swagger)
private static void AddKeycloackSecurity(this SwaggerGenOptions options, IConfiguration configuration)
#region Keycloak
private static void AddKeycloakSecurity(this SwaggerGenOptions options, IConfiguration configuration)
{
options.AddSecurityDefinition("Keycloack", new OpenApiSecurityScheme
options.AddSecurityDefinition("Keycloak", new OpenApiSecurityScheme
{
Description = @"JWT Authorization header using the Bearer scheme. Enter 'Bearer' [space] and then your token in the text input below. Example: 'Bearer 12345abcdef'",
Description = @"JWT Authorization header using the Bearer scheme. Enter 'Bearer' [space] and then your token in the text input below. Example: 'Bearer 12345token'",
Name = "Authorization",
In = ParameterLocation.Header,
Type = SecuritySchemeType.OAuth2,
@ -147,7 +146,7 @@ public static class DependencyInjection
{
Implicit = new OpenApiOAuthFlow
{
AuthorizationUrl = new Uri(configuration["Authentication:AuthorizationUrl"]),
AuthorizationUrl = new Uri(configuration["Authentication:AuthorizationUrl"]!),
}
}
});
@ -160,7 +159,7 @@ public static class DependencyInjection
Reference = new OpenApiReference
{
Type = ReferenceType.SecurityScheme,
Id = "Keycloack"
Id = "Keycloak"
},
Scheme = "Bearer",
Name = "Bearer",
@ -171,11 +170,11 @@ public static class DependencyInjection
});
}
private static void AddDefaultSecurity(this SwaggerGenOptions options, IConfiguration configuration)
private static void AddDefaultSecurity(this SwaggerGenOptions options)
{
options.AddSecurityDefinition("Bearer", new OpenApiSecurityScheme
{
Description = @"JWT Authorization header using the Bearer scheme. Enter 'Bearer' [space] and then your token in the text input below. Example: 'Bearer 12345abcdef'",
Description = @"JWT Authorization header using the Bearer scheme. Enter 'Bearer' [space] and then your token in the text input below. Example: 'Bearer 12345token'",
Name = "Authorization",
In = ParameterLocation.Header,
Type = SecuritySchemeType.ApiKey,

View File

@ -7,8 +7,7 @@ public static class Extensions
{
public static T GetUserId<T>(this ClaimsPrincipal principal)
{
if (principal == null)
throw new ArgumentNullException(nameof(principal));
ArgumentNullException.ThrowIfNull(principal, nameof(principal));
var loggedInUserId = principal.FindFirstValue(ClaimTypes.NameIdentifier);

View File

@ -1,11 +1,11 @@
using System.IdentityModel.Tokens.Jwt;
using System.Net.Http.Headers;
using System.Security.Claims;
using System.Text.Json;
using Microsoft.Extensions.Configuration;
using Microsoft.Extensions.Configuration;
using Microsoft.IdentityModel.Tokens;
using Persistence.Models.Configurations;
using RestSharp;
using System.IdentityModel.Tokens.Jwt;
using System.Net.Http.Headers;
using System.Security.Claims;
using System.Text.Json;
namespace Persistence.Client.Helpers;
public static class ApiTokenHelper
@ -36,8 +36,7 @@ public static class ApiTokenHelper
new("client_id", authUser.ClientId),
new("username", authUser.Username),
new("password", authUser.Password),
new("grant_type", authUser.GrantType),
new(ClaimTypes.NameIdentifier.ToString(), Guid.NewGuid().ToString())
new("grant_type", authUser.GrantType)
};
var tokenDescriptor = new SecurityTokenDescriptor
@ -63,10 +62,10 @@ public static class ApiTokenHelper
request.AddParameter("client_id", authUser.ClientId);
request.AddParameter("grant_type", authUser.GrantType);
var keyCloackResponse = restClient.Post(request);
if (keyCloackResponse.IsSuccessful && !String.IsNullOrEmpty(keyCloackResponse.Content))
var keycloakResponse = restClient.Post(request);
if (keycloakResponse.IsSuccessful && !String.IsNullOrEmpty(keycloakResponse.Content))
{
var token = JsonSerializer.Deserialize<JwtToken>(keyCloackResponse.Content)!;
var token = JsonSerializer.Deserialize<JwtToken>(keycloakResponse.Content)!;
return token.AccessToken;
}

View File

@ -16,7 +16,7 @@ namespace Persistence.Client
PropertyNameCaseInsensitive = true
};
private static readonly RefitSettings RefitSettings = new(new SystemTextJsonContentSerializer(JsonSerializerOptions));
private HttpClient httpClient;
private readonly HttpClient httpClient;
public PersistenceClientFactory(IHttpClientFactory httpClientFactory, IConfiguration configuration)
{
this.httpClient = httpClientFactory.CreateClient();

View File

@ -1,7 +1,6 @@
using Microsoft.EntityFrameworkCore;
using Microsoft.Extensions.Configuration;
using Microsoft.Extensions.DependencyInjection;
using Npgsql;
namespace Persistence.Database.Model;

View File

@ -1,8 +1,8 @@

using System.ComponentModel.DataAnnotations.Schema;
using System.ComponentModel.DataAnnotations;
using Microsoft.EntityFrameworkCore;
using Persistence.Models;
using System.ComponentModel.DataAnnotations;
using System.ComponentModel.DataAnnotations.Schema;
namespace Persistence.Database.Model;

View File

@ -3,8 +3,7 @@ using Persistence.Database.Model;
using Xunit;
namespace Persistence.IntegrationTests;
public abstract class BaseIntegrationTest : IClassFixture<WebAppFactoryFixture>,
IDisposable
public abstract class BaseIntegrationTest : IClassFixture<WebAppFactoryFixture>, IDisposable
{
protected readonly IServiceScope scope;
@ -21,5 +20,6 @@ public abstract class BaseIntegrationTest : IClassFixture<WebAppFactoryFixture>,
{
scope.Dispose();
dbContext.Dispose();
GC.SuppressFinalize(this);
}
}

View File

@ -13,7 +13,7 @@ namespace Persistence.IntegrationTests.Controllers;
public class ChangeLogControllerTest : BaseIntegrationTest
{
private readonly IChangeLogClient client;
private static Random generatorRandomDigits = new Random();
private static readonly Random generatorRandomDigits = new();
public ChangeLogControllerTest(WebAppFactoryFixture factory) : base(factory)
{
@ -28,7 +28,7 @@ public class ChangeLogControllerTest : BaseIntegrationTest
{
// arrange
var idDiscriminator = Guid.NewGuid();
var dtos = Generate(2, DateTimeOffset.UtcNow);
var dtos = Generate(2);
// act
var result = await client.ClearAndAddRange(idDiscriminator, dtos);
@ -52,7 +52,7 @@ public class ChangeLogControllerTest : BaseIntegrationTest
// assert
Assert.Equal(HttpStatusCode.OK, result.StatusCode);
Assert.Equal(insertedCount*2, result.Content);
Assert.Equal(insertedCount * 2, result.Content);
}
[Fact]
@ -61,7 +61,7 @@ public class ChangeLogControllerTest : BaseIntegrationTest
// arrange
var count = 1;
var idDiscriminator = Guid.NewGuid();
var dtos = Generate(count, DateTimeOffset.UtcNow);
var dtos = Generate(count);
var dto = dtos.FirstOrDefault()!;
// act
@ -78,7 +78,7 @@ public class ChangeLogControllerTest : BaseIntegrationTest
// arrange
var count = 3;
var idDiscriminator = Guid.NewGuid();
var dtos = Generate(count, DateTimeOffset.UtcNow);
var dtos = Generate(count);
// act
var result = await client.AddRange(idDiscriminator, dtos);
@ -93,7 +93,7 @@ public class ChangeLogControllerTest : BaseIntegrationTest
{
// arrange
var idDiscriminator = Guid.NewGuid();
var dtos = Generate(1, DateTimeOffset.UtcNow);
var dtos = Generate(1);
var dto = dtos.FirstOrDefault()!;
var result = await client.Add(idDiscriminator, dto);
Assert.Equal(HttpStatusCode.Created, result.StatusCode);
@ -102,7 +102,7 @@ public class ChangeLogControllerTest : BaseIntegrationTest
.Where(x => x.IdDiscriminator == idDiscriminator)
.FirstOrDefault();
dto = entity.Adapt<DataWithWellDepthAndSectionDto>();
dto.DepthEnd = dto.DepthEnd + 10;
dto.DepthEnd += 10;
// act
result = await client.Update(dto);
@ -143,7 +143,7 @@ public class ChangeLogControllerTest : BaseIntegrationTest
{
// arrange
var count = 2;
var dtos = Generate(count, DateTimeOffset.UtcNow);
var dtos = Generate(count);
var entities = dtos.Select(d => d.Adapt<ChangeLog>()).ToArray();
dbContext.ChangeLog.AddRange(entities);
dbContext.SaveChanges();
@ -169,7 +169,7 @@ public class ChangeLogControllerTest : BaseIntegrationTest
public async Task Delete_returns_success()
{
// arrange
var dtos = Generate(1, DateTimeOffset.UtcNow);
var dtos = Generate(1);
var dto = dtos.FirstOrDefault()!;
var entity = dto.Adapt<ChangeLog>();
dbContext.ChangeLog.Add(entity);
@ -188,7 +188,7 @@ public class ChangeLogControllerTest : BaseIntegrationTest
{
// arrange
var count = 10;
var dtos = Generate(count, DateTimeOffset.UtcNow);
var dtos = Generate(count);
var entities = dtos.Select(d => d.Adapt<ChangeLog>()).ToArray();
dbContext.ChangeLog.AddRange(entities);
dbContext.SaveChanges();
@ -294,7 +294,7 @@ public class ChangeLogControllerTest : BaseIntegrationTest
foreach (var entity in entities)
{
entity.DepthEnd = entity.DepthEnd + 10;
entity.DepthEnd += 10;
}
var dtos = entities.Select(e => e.Adapt<DataWithWellDepthAndSectionDto>()).ToArray();
await client.UpdateRange(dtos);
@ -311,7 +311,7 @@ public class ChangeLogControllerTest : BaseIntegrationTest
}
private static IEnumerable<DataWithWellDepthAndSectionDto> Generate(int count, DateTimeOffset from)
private static IEnumerable<DataWithWellDepthAndSectionDto> Generate(int count)
{
for (int i = 0; i < count; i++)
yield return new DataWithWellDepthAndSectionDto()
@ -334,7 +334,7 @@ public class ChangeLogControllerTest : BaseIntegrationTest
var maxDayCount = daysRange.Item2;
Guid idDiscriminator = Guid.NewGuid();
var dtos = Generate(count, DateTimeOffset.UtcNow);
var dtos = Generate(count);
var entities = dtos.Select(d =>
{
var entity = d.Adapt<ChangeLog>();

View File

@ -28,7 +28,7 @@ public class DataSaubControllerTest : TimeSeriesBaseControllerTest<DataSaub, Dat
WellDepth = 18,
};
private readonly DataSaub entity = new DataSaub()
private readonly DataSaub entity = new()
{
AxialLoad = 1,
BitDepth = 2,

View File

@ -9,11 +9,11 @@ namespace Persistence.IntegrationTests.Controllers
{
public class SetpointControllerTest : BaseIntegrationTest
{
private ISetpointClient setpointClient;
private readonly ISetpointClient setpointClient;
private class TestObject
{
public string? value1 { get; set; }
public int? value2 { get; set; }
public string? Value1 { get; set; }
public int? Value2 { get; set; }
}
public SetpointControllerTest(WebAppFactoryFixture factory) : base(factory)
{
@ -224,8 +224,8 @@ namespace Persistence.IntegrationTests.Controllers
var setpointKey = Guid.NewGuid();
var setpointValue = new TestObject()
{
value1 = "1",
value2 = 2
Value1 = "1",
Value2 = 2
};
//act

View File

@ -1,11 +1,11 @@
using System.Net;
using Microsoft.Extensions.Caching.Memory;
using Microsoft.Extensions.Caching.Memory;
using Microsoft.Extensions.DependencyInjection;
using Persistence.Client;
using Persistence.Client.Clients;
using Persistence.Database.Entity;
using Persistence.Models;
using Persistence.Models.Requests;
using System.Net;
using Xunit;
namespace Persistence.IntegrationTests.Controllers
@ -85,7 +85,7 @@ namespace Persistence.IntegrationTests.Controllers
//arrange
var dtos = new List<TechMessageDto>()
{
new TechMessageDto()
new()
{
EventId = Guid.NewGuid(),
CategoryId = -1, // < 0
@ -149,11 +149,11 @@ namespace Persistence.IntegrationTests.Controllers
dbContext.CleanupDbSet<TechMessage>();
dbContext.CleanupDbSet<Database.Entity.DrillingSystem>();
var imortantId = 1;
var importantId = 1;
var autoDrillingSystem = nameof(TechMessageDto.System);
//act
var response = await techMessagesClient.GetStatistics(autoDrillingSystem, imortantId, new CancellationToken());
var response = await techMessagesClient.GetStatistics(autoDrillingSystem, importantId, new CancellationToken());
//assert
Assert.Equal(HttpStatusCode.OK, response.StatusCode);
@ -165,13 +165,13 @@ namespace Persistence.IntegrationTests.Controllers
public async Task GetStatistics_AfterSave_returns_success()
{
//arrange
var imortantId = 0;
var importantId = 0;
var autoDrillingSystem = nameof(TechMessageDto.System);
var dtos = await InsertRange();
var filteredDtos = dtos.Where(e => e.CategoryId == imortantId && e.System == autoDrillingSystem);
var filteredDtos = dtos.Where(e => e.CategoryId == importantId && e.System == autoDrillingSystem);
//act
var response = await techMessagesClient.GetStatistics(autoDrillingSystem, imortantId, new CancellationToken());
var response = await techMessagesClient.GetStatistics(autoDrillingSystem, importantId, new CancellationToken());
//assert
Assert.Equal(HttpStatusCode.OK, response.StatusCode);
@ -253,7 +253,7 @@ namespace Persistence.IntegrationTests.Controllers
var dtos = new List<TechMessageDto>()
{
new TechMessageDto()
new()
{
EventId = Guid.NewGuid(),
CategoryId = 1,
@ -263,7 +263,7 @@ namespace Persistence.IntegrationTests.Controllers
System = nameof(TechMessageDto.System).ToLower(),
UserId = Guid.NewGuid()
},
new TechMessageDto()
new()
{
EventId = Guid.NewGuid(),
CategoryId = 2,

View File

@ -12,7 +12,7 @@ public abstract class TimeSeriesBaseControllerTest<TEntity, TDto> : BaseIntegrat
where TEntity : class, ITimestampedData, new()
where TDto : class, new()
{
private ITimeSeriesClient<TDto> timeSeriesClient;
private readonly ITimeSeriesClient<TDto> timeSeriesClient;
public TimeSeriesBaseControllerTest(WebAppFactoryFixture factory) : base(factory)
{
@ -31,7 +31,7 @@ public abstract class TimeSeriesBaseControllerTest<TEntity, TDto> : BaseIntegrat
var expected = dto.Adapt<TDto>();
//act
var response = await timeSeriesClient.AddRange(new TDto[] { expected });
var response = await timeSeriesClient.AddRange([expected]);
//assert
Assert.Equal(HttpStatusCode.OK, response.StatusCode);
@ -116,7 +116,7 @@ public abstract class TimeSeriesBaseControllerTest<TEntity, TDto> : BaseIntegrat
}
else
{
Assert.Equal(entities.Count(), response.Content.Count());
Assert.Equal(entities.Count, response.Content.Count());
}

View File

@ -111,7 +111,7 @@ public class TimestampedSetControllerTest : BaseIntegrationTest
Guid idDiscriminator = Guid.NewGuid();
int count = 10;
IEnumerable<TimestampedSetDto> testSets = Generate(count, DateTimeOffset.Now.ToOffset(TimeSpan.FromHours(7)));
var insertResponse = await client.AddRange(idDiscriminator, testSets);
await client.AddRange(idDiscriminator, testSets);
var expectedCount = count / 2;
// act
@ -133,7 +133,7 @@ public class TimestampedSetControllerTest : BaseIntegrationTest
var expectedCount = 1;
int count = 10 + expectedCount;
IEnumerable<TimestampedSetDto> testSets = Generate(count, DateTimeOffset.Now.ToOffset(TimeSpan.FromHours(7)));
var insertResponse = await client.AddRange(idDiscriminator, testSets);
await client.AddRange(idDiscriminator, testSets);
// act
var response = await client.Get(idDiscriminator, null, null, count - expectedCount, count);
@ -174,7 +174,7 @@ public class TimestampedSetControllerTest : BaseIntegrationTest
var dateMin = DateTimeOffset.Now;
var dateMax = DateTimeOffset.Now.AddSeconds(count - 1);
IEnumerable<TimestampedSetDto> testSets = Generate(count, dateMin.ToOffset(TimeSpan.FromHours(7)));
var insertResponse = await client.AddRange(idDiscriminator, testSets);
await client.AddRange(idDiscriminator, testSets);
var tolerance = TimeSpan.FromSeconds(1);
// act
@ -195,7 +195,7 @@ public class TimestampedSetControllerTest : BaseIntegrationTest
Guid idDiscriminator = Guid.NewGuid();
int count = 144;
IEnumerable<TimestampedSetDto> testSets = Generate(count, DateTimeOffset.Now.ToOffset(TimeSpan.FromHours(7)));
var insertResponse = await client.AddRange(idDiscriminator, testSets);
await client.AddRange(idDiscriminator, testSets);
// act
var response = await client.Count(idDiscriminator);

View File

@ -60,5 +60,7 @@ public class WebAppFactoryFixture : WebApplicationFactory<Startup>
.Options);
await dbContext.Database.EnsureDeletedAsync();
GC.SuppressFinalize(dbContext);
}
}

View File

@ -44,7 +44,7 @@ public static class EFExtensionsSortBy
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 selector = Expression.Lambda(property, [ arg ]);
var typeAccessor = new TypeAccessor
{
KeySelector = selector,
@ -261,7 +261,7 @@ public static class EFExtensionsSortBy
: orderByAscending;
var newQuery = (IOrderedQueryable<TSource>)genericMethod
.Invoke(genericMethod, [ query, lambdaExpression ])!;
.Invoke(genericMethod, [query, lambdaExpression])!;
return newQuery;
}
}

View File

@ -29,7 +29,7 @@ public static class QueryBuilders
return query;
}
public static IQueryable<TEntity> Apply<TEntity>(this IQueryable<TEntity> query,DateTimeOffset momentUtc)
public static IQueryable<TEntity> Apply<TEntity>(this IQueryable<TEntity> query, DateTimeOffset momentUtc)
where TEntity : class, IChangeLog
{
momentUtc = momentUtc.ToUniversalTime();

View File

@ -9,7 +9,7 @@ using UuidExtensions;
namespace Persistence.Repository.Repositories;
public class ChangeLogRepository : IChangeLogRepository
{
private DbContext db;
private readonly DbContext db;
public ChangeLogRepository(DbContext db)
{

View File

@ -5,7 +5,7 @@ using Persistence.Database.Entity;
using Persistence.Models;
using Persistence.Models.Requests;
using Persistence.Repositories;
using Persistence.Repository.Extensions;
using UuidExtensions;
namespace Persistence.Repository.Repositories
{
@ -14,7 +14,7 @@ namespace Persistence.Repository.Repositories
private static readonly string SystemCacheKey = $"{typeof(Database.Entity.DrillingSystem).FullName}CacheKey";
private const int CacheExpirationInMinutes = 60;
private readonly IMemoryCache memoryCache;
private DbContext db;
private readonly DbContext db;
public TechMessagesRepository(DbContext db, IMemoryCache memoryCache)
{
@ -31,10 +31,10 @@ namespace Persistence.Repository.Repositories
var count = await query.CountAsync(token);
var sort = request.SortSettings != string.Empty
? request.SortSettings
? request.SortSettings!
: nameof(TechMessage.Timestamp);
var entities = await query
.SortBy(request.SortSettings)
.SortBy(sort)
.Skip(request.Skip)
.Take(request.Take)
.ToArrayAsync(token);
@ -55,12 +55,12 @@ namespace Persistence.Repository.Repositories
var query = GetQueryReadOnly();
var systems = autoDrillingSystem.Select(s => s.ToLower().Trim());
var result = await query
.Where(e => systems.Count() == 0 || systems.Contains(e.System.Name.ToLower().Trim()))
.Where(e => !systems.Any() || systems.Contains(e.System.Name.ToLower().Trim()))
.GroupBy(e => e.System.Name, (key, group) => new
{
System = key,
Categories = group
.Where(g => categoryIds.Count() == 0 || categoryIds.Contains(g.CategoryId))
.Where(g => !categoryIds.Any() || categoryIds.Contains(g.CategoryId))
})
.ToArrayAsync(token);
@ -163,13 +163,13 @@ namespace Persistence.Repository.Repositories
{
memoryCache.Remove(SystemCacheKey);
var entity = new Database.Entity.DrillingSystem()
var entity = new DrillingSystem()
{
SystemId = default,
SystemId = Uuid7.Guid(),
Name = name.ToLower().Trim()
};
await db.Set<Database.Entity.DrillingSystem>().AddAsync(entity);
await db.Set<DrillingSystem>().AddAsync(entity, token);
await db.SaveChangesAsync(token);
return entity.SystemId;

View File

@ -9,7 +9,7 @@ public class TimeSeriesDataRepository<TEntity, TDto> : ITimeSeriesDataRepository
where TEntity : class, ITimestampedData, new()
where TDto : class, ITimeSeriesAbstractDto, new()
{
private DbContext db;
private readonly DbContext db;
public TimeSeriesDataRepository(DbContext db)
{

View File

@ -1,5 +1,4 @@
using Microsoft.AspNetCore.Mvc;
using Persistence.Models;
namespace Persistence.API;

View File

@ -1,16 +1,11 @@
using System;
using System.Collections.Concurrent;
using System.Collections.Generic;
using System.Linq;
using System.Collections.Concurrent;
using System.Linq.Expressions;
using System.Reflection;
using System.Text;
using System.Threading.Tasks;
namespace Persistence;
public static class EFExtensions
{
struct TypeAcessor
struct TypeAccessor
{
public LambdaExpression KeySelector { get; set; }
public MethodInfo OrderBy { get; set; }
@ -25,7 +20,7 @@ public static class EFExtensions
private static readonly MethodInfo methodThenBy = GetExtOrderMethod("ThenBy");
private static readonly MethodInfo methodThenByDescending = GetExtOrderMethod("ThenByDescending");
private static ConcurrentDictionary<Type, Dictionary<string, TypeAcessor>> TypePropSelectors { get; set; } = new();
private static ConcurrentDictionary<Type, Dictionary<string, TypeAccessor>> TypePropSelectors { get; set; } = new();
private static MethodInfo GetExtOrderMethod(string methodName)
=> typeof(System.Linq.Queryable)
@ -35,17 +30,17 @@ public static class EFExtensions
m.GetParameters().Length == 2 &&
m.GetParameters()[1].ParameterType.IsAssignableTo(typeof(LambdaExpression)))
.Single();
private static Dictionary<string, TypeAcessor> MakeTypeAcessors(Type type)
private static Dictionary<string, TypeAccessor> MakeTypeAccessors(Type type)
{
var propContainer = new Dictionary<string, TypeAcessor>();
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 TypeAcessor
var selector = Expression.Lambda(property, [arg]);
var typeAccessor = new TypeAccessor
{
KeySelector = selector,
OrderBy = methodOrderBy.MakeGenericMethod(type, propertyInfo.PropertyType),
@ -99,16 +94,16 @@ public static class EFExtensions
string propertyName,
bool isDesc)
{
var typePropSelector = TypePropSelectors.GetOrAdd(typeof(TSource), MakeTypeAcessors);
var propertyNamelower = propertyName.ToLower();
var typeAccessor = typePropSelector[propertyNamelower];
var typePropSelector = TypePropSelectors.GetOrAdd(typeof(TSource), MakeTypeAccessors);
var propertyNameLower = propertyName.ToLower();
var typeAccessor = typePropSelector[propertyNameLower];
var genericMethod = isDesc
? typeAccessor.OrderByDescending
: typeAccessor.OrderBy;
var newQuery = (IOrderedQueryable<TSource>)genericMethod
.Invoke(genericMethod, new object[] { query, typeAccessor.KeySelector })!;
.Invoke(genericMethod, [query, typeAccessor.KeySelector])!;
return newQuery;
}
}

View File

@ -1,10 +1,4 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace Persistence.Models;
namespace Persistence.Models;
/// <summary>
/// Dto для хранения записей, содержащих начальную и конечную глубину забоя, а также секцию

View File

@ -11,7 +11,7 @@ public class PaginationContainer<T>
/// </summary>
public PaginationContainer()
{
Items = Enumerable.Empty<T>();
Items = [];
}
/// <summary>

View File

@ -1,6 +1,4 @@
using Persistence.Models;
namespace Persistence.Repositories;
namespace Persistence.Repositories;
/// <summary>
/// Интерфейс по работе с прореженными данными