Skip to content
This repository has been archived by the owner on Jun 19, 2024. It is now read-only.

Commit

Permalink
Nullable better support
Browse files Browse the repository at this point in the history
  • Loading branch information
DefGh committed Mar 1, 2024
1 parent 7c0dbb3 commit 270bdfd
Show file tree
Hide file tree
Showing 16 changed files with 434 additions and 77 deletions.
6 changes: 5 additions & 1 deletion IEnumerableExtenders/Converters/DirectConverter.cs
Original file line number Diff line number Diff line change
@@ -1,7 +1,11 @@
namespace PandaTech.IEnumerableFilters.Converters;
using Microsoft.EntityFrameworkCore;

namespace PandaTech.IEnumerableFilters.Converters;

public class DirectConverter : IConverter<object, object>
{
public DbContext Context { get; set; }

Check warning on line 7 in IEnumerableExtenders/Converters/DirectConverter.cs

View workflow job for this annotation

GitHub Actions / deploy (8.x.x)

Non-nullable property 'Context' must contain a non-null value when exiting constructor. Consider declaring the property as nullable.

Check warning on line 7 in IEnumerableExtenders/Converters/DirectConverter.cs

View workflow job for this annotation

GitHub Actions / deploy (8.x.x)

Non-nullable property 'Context' must contain a non-null value when exiting constructor. Consider declaring the property as nullable.

public object ConvertTo(object from)
{
return from;
Expand Down
7 changes: 5 additions & 2 deletions IEnumerableExtenders/Converters/EncryptedConverter.cs
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
using Pandatech.Crypto;
using Microsoft.EntityFrameworkCore;
using Pandatech.Crypto;

namespace PandaTech.IEnumerableFilters.Converters;

Expand All @@ -8,7 +9,9 @@ public class EncryptedConverter : IConverter<string, byte[]>
{
Key = Environment.GetEnvironmentVariable("AES_KEY") ?? ""
});


public DbContext Context { get; set; }

Check warning on line 13 in IEnumerableExtenders/Converters/EncryptedConverter.cs

View workflow job for this annotation

GitHub Actions / deploy (8.x.x)

Non-nullable property 'Context' must contain a non-null value when exiting constructor. Consider declaring the property as nullable.

Check warning on line 13 in IEnumerableExtenders/Converters/EncryptedConverter.cs

View workflow job for this annotation

GitHub Actions / deploy (8.x.x)

Non-nullable property 'Context' must contain a non-null value when exiting constructor. Consider declaring the property as nullable.

public byte[] ConvertTo(string from)
{
return Aes256.Encrypt(from);
Expand Down
Original file line number Diff line number Diff line change
@@ -1,9 +1,12 @@
using BaseConverter;
using Microsoft.EntityFrameworkCore;

namespace PandaTech.IEnumerableFilters.Converters;

public class FilterNullablePandaBaseConverter : IConverter<string?, long?>
{
public DbContext Context { get; set; }

Check warning on line 8 in IEnumerableExtenders/Converters/FilterNullablePandaBaseConverter.cs

View workflow job for this annotation

GitHub Actions / deploy (8.x.x)

Non-nullable property 'Context' must contain a non-null value when exiting constructor. Consider declaring the property as nullable.

Check warning on line 8 in IEnumerableExtenders/Converters/FilterNullablePandaBaseConverter.cs

View workflow job for this annotation

GitHub Actions / deploy (8.x.x)

Non-nullable property 'Context' must contain a non-null value when exiting constructor. Consider declaring the property as nullable.

public long? ConvertTo(string? from)
{
if (from is null) return null;
Expand Down
3 changes: 3 additions & 0 deletions IEnumerableExtenders/Converters/FilterPandaBaseConverter.cs
Original file line number Diff line number Diff line change
@@ -1,9 +1,12 @@
using BaseConverter;
using Microsoft.EntityFrameworkCore;

namespace PandaTech.IEnumerableFilters.Converters;

public class FilterPandaBaseConverter : IConverter<string, long>
{
public DbContext Context { get; set; }

Check warning on line 8 in IEnumerableExtenders/Converters/FilterPandaBaseConverter.cs

View workflow job for this annotation

GitHub Actions / deploy (8.x.x)

Non-nullable property 'Context' must contain a non-null value when exiting constructor. Consider declaring the property as nullable.

Check warning on line 8 in IEnumerableExtenders/Converters/FilterPandaBaseConverter.cs

View workflow job for this annotation

GitHub Actions / deploy (8.x.x)

Non-nullable property 'Context' must contain a non-null value when exiting constructor. Consider declaring the property as nullable.

public long ConvertTo(string from)
{
return PandaBaseConverter.Base36ToBase10(from)!.Value;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -13,9 +13,9 @@ namespace PandaTech.IEnumerableFilters.Extensions;
public static class DistinctColumnValuesExtensions
{
private static IQueryable<object> GenerateBaseQueryable<TModel>(this IQueryable<TModel> dbSet,
List<FilterDto> filters) where TModel : class
List<FilterDto> filters, DbContext? context) where TModel : class
{
var query = dbSet.ApplyFilters(filters);
var query = dbSet.ApplyFilters(filters, context);


return query;
Expand Down Expand Up @@ -49,7 +49,7 @@ static Type GetEnumerableType(Type type)
}

public static DistinctColumnValuesResult DistinctColumnValues<TModel>(this IQueryable<TModel> dbSet,
List<FilterDto> filters, string columnName, int pageSize, int page) where TModel : class
List<FilterDto> filters, string columnName, int pageSize, int page, DbContext? context) where TModel : class
{
var result = new DistinctColumnValuesResult();

Expand Down Expand Up @@ -79,7 +79,7 @@ public static DistinctColumnValuesResult DistinctColumnValues<TModel>(this IQuer
return result;
}

var query = GenerateBaseQueryable(dbSet, filters);
var query = GenerateBaseQueryable(dbSet, filters, context);
IQueryable<object> query2;

// check for ICollection<>
Expand Down Expand Up @@ -125,11 +125,13 @@ public static DistinctColumnValuesResult DistinctColumnValues<TModel>(this IQuer
public static async Task<DistinctColumnValuesResult> DistinctColumnValuesAsync<TModel>(
this IQueryable<TModel> dbSet,
List<FilterDto> filters,
string columnName, int pageSize, int page, CancellationToken cancellationToken = default) where TModel : class
string columnName, int pageSize, int page, DbContext? context = null, CancellationToken cancellationToken = default) where TModel : class
{
var result = new DistinctColumnValuesResult();

var targetProperty = typeof(TModel).GetTargetType().GetProperties()
var targetProperty = typeof(TModel)
.GetTargetType()
.GetProperties()
.Where(x => x.GetCustomAttribute<MappedToPropertyAttribute>() != null)
.FirstOrDefault(x => x.Name == columnName);

Expand All @@ -154,7 +156,7 @@ public static async Task<DistinctColumnValuesResult> DistinctColumnValuesAsync<T
return result;
}

var query = GenerateBaseQueryable(dbSet, filters);
var query = GenerateBaseQueryable(dbSet, filters, context);
IQueryable<object> query2;

// check for ICollection<>
Expand Down
4 changes: 2 additions & 2 deletions IEnumerableExtenders/Extensions/FilterExtensions.cs
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@ namespace PandaTech.IEnumerableFilters.Extensions;
public static class FilterExtensions
{
//public static IQueryable<TModel> ApplyFilters<TModel, TDto>(this IQueryable<TModel> dbSet, List<FilterDto> filters)
public static IQueryable<TModel> ApplyFilters<TModel>(this IQueryable<TModel> dbSet, List<FilterDto> filters)
public static IQueryable<TModel> ApplyFilters<TModel>(this IQueryable<TModel> dbSet, List<FilterDto> filters, DbContext? context = null)
{
var q = dbSet;

Expand All @@ -35,7 +35,7 @@ public static IQueryable<TModel> ApplyFilters<TModel>(this IQueryable<TModel> db
if (targetType.IsIEnumerable() && !mappedToPropertyAttribute.Encrypted)
targetType = targetType.GetCollectionType();
var method = typeof(PropertyHelper).GetMethod("GetValues")!.MakeGenericMethod(targetType);
var values = method.Invoke(null, [filter, mappedToPropertyAttribute]);
var values = method.Invoke(null, [filter, mappedToPropertyAttribute, context]);

if (mappedToPropertyAttribute.Encrypted)
{
Expand Down
5 changes: 4 additions & 1 deletion IEnumerableExtenders/IConverter.cs
Original file line number Diff line number Diff line change
@@ -1,7 +1,10 @@
namespace PandaTech.IEnumerableFilters;
using Microsoft.EntityFrameworkCore;

namespace PandaTech.IEnumerableFilters;

public interface IConverter<TFrom, TTo>
{
public DbContext Context { get; set; }
public TTo ConvertTo(TFrom from);

public TFrom ConvertFrom(TTo to);
Expand Down
2 changes: 1 addition & 1 deletion IEnumerableExtenders/IEnumerableExtenders.csproj
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@
<ImplicitUsings>enable</ImplicitUsings>
<Nullable>enable</Nullable>
<RootNamespace>PandaTech.IEnumerableFilters</RootNamespace>
<Version>4.0.17</Version>
<Version>4.0.18</Version>
<Authors>PandaTech</Authors>
<Description>This NuGet helps with filtering tables.</Description>
<RepositoryUrl>https://github.com/PandaTechAM/be-lib-ienumerable-extenders-filters.git</RepositoryUrl>
Expand Down
35 changes: 30 additions & 5 deletions IEnumerableExtenders/PropertyHelper.cs
Original file line number Diff line number Diff line change
@@ -1,5 +1,7 @@
using System.Linq.Expressions;
using System.Text.Json;
using Microsoft.EntityFrameworkCore;
using Org.BouncyCastle.Asn1.X509.Qualified;
using PandaTech.IEnumerableFilters.Attributes;
using PandaTech.IEnumerableFilters.Converters;
using PandaTech.IEnumerableFilters.Dto;
Expand All @@ -10,7 +12,7 @@ namespace PandaTech.IEnumerableFilters;

internal static class PropertyHelper
{
public static List<T> GetValues<T>(this FilterDto filter, MappedToPropertyAttribute propertyAttribute)
public static List<T> GetValues<T>(this FilterDto filter, MappedToPropertyAttribute propertyAttribute, DbContext? context = null)
{
var converterType = propertyAttribute.Encrypted
? typeof(EncryptedConverter)
Expand All @@ -22,6 +24,10 @@ public static List<T> GetValues<T>(this FilterDto filter, MappedToPropertyAttrib
? typeof(T)
: converterType.GetMethod("ConvertFrom")!.ReturnType;
var converter = Activator.CreateInstance(converterType);

if (context is not null)
converter!.GetType().GetProperty("Context")!.SetValue(converter, context);

var method = converter!.GetType().GetMethods().First(x => x.Name == "ConvertTo");

var list = new List<T>();
Expand All @@ -44,17 +50,36 @@ public static List<T> GetValues<T>(this FilterDto filter, MappedToPropertyAttrib
if (typeof(T).EnumCheck())
return (T)Enum.Parse(typeof(T).GetEnumType(), val.GetString()!, true);

var name = attribute.Encrypted ? "String" : typeof(T).Name;
var type = attribute.Encrypted ? typeof(string) : typeof(T);

if (val.ValueKind == JsonValueKind.Null)
return default;

if (val.ValueKind == JsonValueKind.Undefined)
return default;

return (T)(name switch
if (type == typeof(string))
return (T)(object)(attribute.Encrypted ? val.GetString()! : val.GetString()!.ToLower());

if (type == typeof(int) || type == typeof(long) || type == typeof(decimal) || type == typeof(double) || type == typeof(float) || type == typeof(short) || type == typeof(byte)
|| type == typeof(int?) || type == typeof(long?) || type == typeof(decimal?) || type == typeof(double?) || type == typeof(float?) || type == typeof(short?) || type == typeof(byte?))
return (T)(object)val.GetInt64();

if (type == typeof(bool) || type == typeof(bool?))
return val.GetBoolean() ? (T)(object)true : (T)(object)false;

if (type == typeof(DateTime) || type == typeof(DateTime?))
return (T)(object)val.GetDateTime();

if (type == typeof(Guid) || type == typeof(Guid?))
return (T)(object)val.GetGuid();

return Activator.CreateInstance<T>()!;


/*return (T)(name switch
{
"String" => attribute.Encrypted ? val.GetString()! : val.GetString()!.ToLower(),
typeof(string) => attribute.Encrypted ? val.GetString()! : val.GetString()!.ToLower(),
"Int32" => val.GetInt32(),
"Int64" => val.GetInt64(),
"Boolean" => val.GetBoolean(),
Expand All @@ -64,7 +89,7 @@ public static List<T> GetValues<T>(this FilterDto filter, MappedToPropertyAttrib
"Single" => val.GetSingle(),
"Guid" => val.GetGuid(),
_ => Activator.CreateInstance(typeof(T))!
});
});*/
}

public static string GetPropertyLambda(MappedToPropertyAttribute propertyAttribute)
Expand Down
113 changes: 66 additions & 47 deletions TestFilters/Components/Pages/TableCompany.razor
Original file line number Diff line number Diff line change
Expand Up @@ -17,34 +17,50 @@
<button @onclick="Generate">Generate 1000</button>
<button @onclick="Refresh">Refresh</button>

<table>
<table class="my-table">
<thead>
<tr>
<th @onclick="() => SetOrder(Colls.Id)"> Id</th>
<th @onclick="() => SetOrder(Colls.Age)"> Age</th>
<th @onclick="() => SetOrder(Colls.InfoName)"> InfoName</th>
<th @onclick="() => SetOrder(Colls.Name)">Name</th>
<th @onclick="() => SetOrder(Colls.NameEncrypted)">Name Encrypted</th>
<th @onclick="() => SetOrder(Colls.IsEnabled)">IsEnabled</th>
<th @onclick="() => SetOrder(Colls.Type)">Type</th>
<th @onclick="() => SetOrder(Colls.Types)">Types</th>
<th @onclick="() => SetOrder(Colls.NullableString)">NullableString</th>
</tr>
@foreach(var coll in Enum.GetValues(typeof(Colls)).Cast<Colls>())
{
<th @onclick="() => SetOrder(coll)"> @coll.ToString()</th>
}
</tr>
</thead>
<tbody>
@foreach (var r in _data)
{
<tr>

<td>@r.Id</td>
<td>@r.Age</td>
<td>@r.Info.Name</td>
<td>@r.Name</td>
<td>@Aes256.Decrypt(r.NameEncrypted)</td>
<td>@r.IsEnabled</td>
<td>@r.Type</td>
<td>@string.Join(';', r.Types.Select(x => x.ToString())) </td>
<td>@r.NullableString</td>
@foreach(var coll in Enum.GetValues(typeof(Colls)).Cast<Colls>())
{
switch (coll)
{
case Colls.Types:
<td>@string.Join(';', r.Types.Select(x => x.ToString())) </td>
break;
case Colls.NameEncrypted:
<td>@Aes256.Decrypt(r.NameEncrypted)</td>
break;
case Colls.SomeClass:
<td>@r.SomeClass?.Name</td>
break;
case Colls.SomeClassN:
<td>@r.SomeClass?.NullableString</td>
break;
case Colls.SomeClassNN:
<td>@Aes256.Decrypt(r.SomeClass?.NameEncrypted)</td>
break;
case Colls.SomeClassList:
<td>@string.Join(';', r.SomeClassList.Select(x => x.Name)) </td>
break;
default:
{
var prop = r.GetType().GetProperty(coll.ToString());
var val = prop?.GetValue(r);
<td>@val</td>
break;
}
}
}
</tr>
}

Expand Down Expand Up @@ -86,12 +102,31 @@
border-radius: 5px;
min-width: 10px;
}
.my-table {
border-collapse: collapse;
border: 1px solid black;
}
.my-table th {
border: 1px solid black;
padding: 5px;
cursor: pointer;
}
.my-table td {
border: 1px solid black;
padding: 5px;
}
</style>

@code {

enum Colls
{
SomeClassList,
Id,
Name,
NameEncrypted,
Expand All @@ -100,21 +135,15 @@
Age,
IsEnabled,
InfoName,
NullableString
NullableString,
SomeClass,
SomeClassN,
SomeClassNN,
}

readonly Dictionary<Colls, string> _filters = new()
{
{ Colls.Id, "" },
{ Colls.Name, "" },
{ Colls.Type, "" },
{ Colls.Types, "" },
{ Colls.Age, "" },
{ Colls.IsEnabled, "" },
{ Colls.NameEncrypted, "" },
{ Colls.InfoName, "" },
{ Colls.NullableString, "" }
};
private static List<Colls> _enumValues = Enum.GetValues(typeof(Colls)).Cast<Colls>().ToList();

readonly Dictionary<Colls, string> _filters = _enumValues.ToDictionary(x => x, _ => "");

private int _selectedPage = 1;
private int _selectedPageSize = 10;
Expand All @@ -126,18 +155,7 @@
private string? _filterDtosString;

readonly Dictionary<Colls, DistinctColumnValuesResult> _distinctColumnValuesResult =
new()
{
{ Colls.Id, new DistinctColumnValuesResult() },
{ Colls.Name, new DistinctColumnValuesResult() },
{ Colls.Type, new DistinctColumnValuesResult() },
{ Colls.Types, new DistinctColumnValuesResult() },
{ Colls.Age, new DistinctColumnValuesResult() },
{ Colls.IsEnabled, new DistinctColumnValuesResult() },
{ Colls.NameEncrypted, new DistinctColumnValuesResult() },
{ Colls.InfoName, new DistinctColumnValuesResult() },
{ Colls.NullableString, new DistinctColumnValuesResult() }
};
_enumValues.ToDictionary(x => x, _ => new DistinctColumnValuesResult());


protected override async Task OnInitializedAsync()
Expand Down Expand Up @@ -191,7 +209,7 @@
Colls.NameEncrypted => filter.Value.Split(";").Select(x => x as object).Take(1).ToList(),
Colls.InfoName => filter.Value.Split(";").Select(x => x as object).ToList(),
Colls.NullableString => filter.Value.Split(";").Select(x => x == "null" ? null : (x as object)).ToList(),
_ => throw new ArgumentOutOfRangeException()
_ => filter.Value.Split(";").Select(x => x == "null" ? null : (x as object)).ToList(),
};

if (values.Any())
Expand All @@ -203,6 +221,7 @@
ComparisonType =
filter.Key switch
{
Colls.SomeClassList => ComparisonType.Contains,
Colls.Name => values.Count > 1
? ComparisonType.In
: ComparisonType.Contains,
Expand Down
Loading

0 comments on commit 270bdfd

Please sign in to comment.