Initial Commit ...

This commit is contained in:
2024-01-25 04:41:17 +03:30
commit ff4d0d5dcb
51 changed files with 5949 additions and 0 deletions
+43
View File
@@ -0,0 +1,43 @@
using System;
using Microsoft.EntityFrameworkCore.Infrastructure;
using MySql.EntityFrameworkCore.Infrastructure;
namespace xDataService.Extensions {
public static class DbContextOptionExtensions {
/// <summary>
/// convert dynamic object to MySqlDbContextOptionBuilder ...
/// Only Used in EFCore ...
/// </summary>
/// <param name="source"></param>
/// <returns></returns>
public static Action<MySQLDbContextOptionsBuilder> ToMySQLDbContextOptionsBuilder (
this Action<dynamic> source
) {
return ((Action<MySQLDbContextOptionsBuilder>) source);
}
/// <summary>
/// convert dynamic object to SqliteDbContextOptionBuilder ...
/// Only Used in EFCore ...
/// </summary>
/// <param name="source"></param>
/// <returns></returns>
public static Action<SqliteDbContextOptionsBuilder> ToSqliteDbContextOptionsBuilder (
this Action<dynamic> source
) {
return ((Action<SqliteDbContextOptionsBuilder>) source);
}
/// <summary>
/// convert dynamic object to SqlServerDbContextOptionBuilder ...
/// Only Used in EFCore ...
/// </summary>
/// <param name="source"></param>
/// <returns></returns>
public static Action<SqlServerDbContextOptionsBuilder> ToSqlServerDbContextOptionsBuilder (
this Action<dynamic> source
) {
return ((Action<SqlServerDbContextOptionsBuilder>) source);
}
}
}
+67
View File
@@ -0,0 +1,67 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Linq.Expressions;
using xCommons.Extensions;
using xModels.Base;
namespace xDataService.Extensions {
public static class EntityExtensions {
/// <summary>
/// return all values of an entity properties as a json string ...
/// </summary>
/// <param name="item"></param>
/// <typeparam name="T"></typeparam>
/// <returns></returns>
public static string GetPropValues<T> (this T item)
where T : XBaseEntity<T> {
//
var props = item.GetType ().GetProperties ();
var vals = props.Select (p => p.GetValue (item));
//
return vals.ToJSON ();
}
/// <summary>
/// check values of all properties of an Entity contains specific value or not ...
/// </summary>
/// <param name="item"></param>
/// <param name="value"></param>
/// <typeparam name="T"></typeparam>
/// <returns></returns>
public static bool PropValuesContains<T> (this T item, string value)
where T : XBaseEntity<T> => item.GetPropValues ()
.ToNormalString ()
.Contains (value);
/// <summary>
/// Retrieve Default Column Map of specific Entity ...
/// </summary>
/// <param name="item"></param>
/// <typeparam name="T"></typeparam>
/// <returns></returns>
public static IDictionary<string, Expression<Func<T, object>>> GetDefaultColumnsMap<T> (this T item)
where T : XBaseEntity<T> {
//
if (item.IsNull ()) {
return null;
}
//
var result = new Dictionary<string, Expression<Func<T, object>>> ();
var props = item.GetType ().GetProperties ();
//
foreach (var prop in props) {
result.Add (
prop.Name,
t => t.GetType ().GetProperty (prop.Name).GetValue (t, null));
}
//
return result;
}
}
}
+503
View File
@@ -0,0 +1,503 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Linq.Expressions;
using System.Reflection;
using System.Threading.Tasks;
using Microsoft.EntityFrameworkCore;
using xCommons.Extensions;
using xDataService.Constants;
using xExceptions.Constants;
using xModels.Base;
namespace xDataService.Extensions {
public static class IQueryableExtensions {
/// <summary>
/// Apply Search Filter on a Query
/// </summary>
/// <param name="source"></param>
/// <param name="filter"></param>
/// <typeparam name="T"></typeparam>
/// <returns></returns>
public static IQueryable<T> ApplyFilter<T, TKey> (
this IQueryable<T> source,
string filter
)
where T : XBaseEntity<TKey> {
//
// Apply Filter ...
return source.Where (r => r.PropValuesContains (filter));
}
/// <summary>
/// Apply Search Filter on a Query
/// </summary>
/// <param name="source"></param>
/// <param name="filter"></param>
/// <typeparam name="T"></typeparam>
/// <returns></returns>
public static async Task<IQueryable<T>> ApplyFilterAsync<T, TKey> (
this IQueryable<T> source,
string filter
)
where T : XBaseEntity<TKey> {
//
// Where Clause ...
Expression<Func<T, bool>> whereClause = r => r
.PropValuesContains (filter);
//
// Generate Where Function ...
var whereFunc = whereClause.Compile ();
//
// Get Enumerable ...
var enumerator = source
.AsAsyncEnumerable ();
//
var result = new List<T> ();
await
foreach (var entity in enumerator) {
//
var isApproved = whereFunc (entity);
if (isApproved) {
result.Add (entity);
}
}
//
return result.AsQueryable ();
}
/// <summary>
/// Apply Search Filter on a Enumerable
/// </summary>
/// <param name="source"></param>
/// <param name="filter"></param>
/// <typeparam name="T"></typeparam>
/// <returns></returns>
public static async Task<IEnumerable<T>> ApplyFilterAsync<T, TKey> (
this IEnumerable<T> source,
string filter
)
where T : XBaseEntity<TKey> {
//
// Where Clause ...
Expression<Func<T, bool>> whereClause = r => r
.PropValuesContains (filter);
//
// Generate Where Function ...
var whereFunc = whereClause.Compile ();
//
// Get Enumerable ...
var enumerator = source
.AsQueryable ()
.AsAsyncEnumerable ();
//
var result = new List<T> ();
await
foreach (var entity in enumerator) {
//
var isApproved = whereFunc (entity);
if (isApproved) {
result.Add (entity);
}
}
//
return result
.AsEnumerable ();
}
/// <summary>
/// Apply Search Filter on a Enumerable
/// </summary>
/// <param name="source"></param>
/// <param name="filter"></param>
/// <typeparam name="T"></typeparam>
/// <returns></returns>
public static IEnumerable<T> ApplyFilter<T> (
this IEnumerable<T> source,
string filter
)
where T : class {
//
// Apply Filter ...
return source.Where (r => r.PropValuesContains (filter));
}
/// <summary>
/// provide a way to Order an IQueryable by string FieldName ...
/// </summary>
/// <param name="query"></param>
/// <param name="propertyName"></param>
/// <typeparam name="TSource"></typeparam>
/// <returns></returns>
public static IOrderedQueryable<TSource> OrderBy<TSource> (
this IQueryable<TSource> query,
string propertyName
) {
//
var entityType = typeof (TSource);
//
// Create x => x.PropName
var propertyInfo = entityType.GetProperty (propertyName);
if (propertyInfo.IsNull ()) {
XException.InvalidArgs.Throw ();
}
//
ParameterExpression arg = Expression.Parameter (entityType, "x");
MemberExpression property = Expression.Property (arg, propertyName);
var selector = Expression.Lambda (property, new ParameterExpression[] { arg });
//
// Get System.Linq.Queryable.OrderBy() method.
var enumarableType = typeof (System.Linq.Queryable);
var method = enumarableType.GetMethods ()
.Where (m => m.Name == "OrderBy" && m.IsGenericMethodDefinition)
.Where (m => {
//
var parameters = m.GetParameters ().ToList ();
//
// Put more restriction here to ensure selecting the right overload
return parameters.Count == 2; // overload that has 2 parameters
}).Single ();
//
// The linq's OrderBy<TSource, TKey> has two generic types, which provided here ...
MethodInfo genericMethod = method
.MakeGenericMethod (entityType, propertyInfo.PropertyType);
/*
Call query.OrderBy(selector), with query and selector: x=> x.PropName
Note that we pass the selector as Expression to the method and we don't compile it.
By doing so EF can extract "order by" columns and generate SQL for it.
*/
var newQuery = (IOrderedQueryable<TSource>) genericMethod
.Invoke (genericMethod, new object[] { query, selector });
//
return newQuery;
}
/// <summary>
/// provide a way to Order an IEnumerable by string FieldName ...
/// </summary>
/// <param name="query"></param>
/// <param name="propertyName"></param>
/// <typeparam name="TSource"></typeparam>
/// <returns></returns>
public static IOrderedEnumerable<TSource> OrderBy<TSource> (
this IEnumerable<TSource> query,
string propertyName
) {
//
var entityType = typeof (TSource);
var propertyInfo = entityType.GetProperty (propertyName);
if (propertyInfo.IsNull ()) {
XException.InvalidArgs.Throw ();
}
//
return query.OrderBy (x => propertyInfo.GetValue (x, null));
}
/// <summary>
/// provide a way to Order an IQueryable by string FieldName ...
/// </summary>
/// <param name="query"></param>
/// <param name="propertyName"></param>
/// <typeparam name="TSource"></typeparam>
/// <returns></returns>
public static IOrderedQueryable<TSource> OrderByDescending<TSource> (
this IQueryable<TSource> query,
string propertyName
) {
//
var entityType = typeof (TSource);
//
// Create x => x.PropName
var propertyInfo = entityType.GetProperty (propertyName);
if (propertyInfo.IsNull ()) {
XException.InvalidArgs.Throw ();
}
//
ParameterExpression arg = Expression.Parameter (entityType, "x");
MemberExpression property = Expression.Property (arg, propertyName);
var selector = Expression.Lambda (property, new ParameterExpression[] { arg });
//
// Get System.Linq.Queryable.OrderBy() method.
var enumarableType = typeof (System.Linq.Queryable);
var method = enumarableType.GetMethods ()
.Where (m => m.Name == "OrderByDescending" && m.IsGenericMethodDefinition)
.Where (m => {
//
var parameters = m.GetParameters ().ToList ();
//
// Put more restriction here to ensure selecting the right overload
return parameters.Count == 2; // overload that has 2 parameters
}).Single ();
//
// The linq's OrderBy<TSource, TKey> has two generic types, which provided here ...
MethodInfo genericMethod = method
.MakeGenericMethod (entityType, propertyInfo.PropertyType);
/*
Call query.OrderBy(selector), with query and selector: x=> x.PropName
Note that we pass the selector as Expression to the method and we don't compile it.
By doing so EF can extract "order by" columns and generate SQL for it.
*/
var newQuery = (IOrderedQueryable<TSource>) genericMethod
.Invoke (genericMethod, new object[] { query, selector });
//
return newQuery;
}
/// <summary>
/// provide a way to Order an IEnumerable by string FieldName ...
/// </summary>
/// <param name="query"></param>
/// <param name="propertyName"></param>
/// <typeparam name="TSource"></typeparam>
/// <returns></returns>
public static IOrderedEnumerable<TSource> OrderByDescending<TSource> (
this IEnumerable<TSource> query,
string propertyName
) {
//
var entityType = typeof (TSource);
var propertyInfo = entityType.GetProperty (propertyName);
if (propertyInfo.IsNull ()) {
XException.InvalidArgs.Throw ();
}
//
return query.OrderByDescending (x => propertyInfo.GetValue (x, null));
}
/// <summary>
/// Apply Sorting on a query
/// </summary>
/// <param name="source"></param>
/// <param name="sortBy"></param>
/// <param name="isAscending"></param>
/// <param name="columnsMap"></param>
/// <typeparam name="T"></typeparam>
/// <returns></returns>
public static IQueryable<T> ApplySorting<T, TKey> (
this IQueryable<T> source,
string sortBy,
bool isAscending,
IDictionary<string, Expression<Func<T, object>>> columnsMap = null
)
where T : XBaseEntity<TKey> {
//
if (columnsMap == null) {
//
columnsMap = source.FirstOrDefault ()
.GetDefaultColumnsMap ();
//
if (columnsMap == null) {
return source;
}
}
//
// Validate SortBy ...
var sortByItem = columnsMap.Keys
.FirstOrDefault (p =>
p.ToNormalString () == sortBy.ToNormalString ());
if (sortByItem.IsNullOrEmpty ()) {
return source;
}
//
// Apply Sorting ...
if (isAscending) {
return source.OrderBy (sortByItem);
} else {
return source.OrderByDescending (sortByItem);
}
}
/// <summary>
/// Apply Sorting on a query
/// </summary>
/// <param name="source"></param>
/// <param name="sortBy"></param>
/// <param name="isAscending"></param>
/// <param name="columnsMap"></param>
/// <typeparam name="T"></typeparam>
/// <returns></returns>
public static IEnumerable<T> ApplySorting<T, TKey> (
this IEnumerable<T> source,
string sortBy,
bool isAscending,
IDictionary<string, Expression<Func<T, object>>> columnsMap = null
)
where T : XBaseEntity<TKey> {
//
if (columnsMap == null) {
//
columnsMap = source.FirstOrDefault ()
.GetDefaultColumnsMap ();
//
if (columnsMap == null) {
return source;
}
}
//
// Validate SortBy ...
var sortByItem = columnsMap.Keys
.FirstOrDefault (p =>
p.ToNormalString () == sortBy.ToNormalString ());
if (sortByItem.IsNullOrEmpty ()) {
return source;
}
//
// Apply Sorting ...
if (isAscending) {
return source.OrderBy (sortByItem);
} else {
return source.OrderByDescending (sortByItem);
}
}
/// <summary>
/// Apply Sorting on a Enumerable
/// </summary>
/// <param name="source"></param>
/// <param name="sortBy"></param>
/// <param name="isAscending"></param>
/// <param name="columnsMap"></param>
/// <typeparam name="T"></typeparam>
/// <returns></returns>
public static IEnumerable<T> ApplySorting<T> (
this IEnumerable<T> source,
string sortBy,
bool isAscending,
IDictionary<string, Expression<Func<T, object>>> columnsMap = null
)
where T : class {
//
if (columnsMap == null) {
//
columnsMap = source.FirstOrDefault ()
.GetDefaultColumnsMap ();
//
if (columnsMap == null) {
return source;
}
}
//
// Validate SortBy ...
var sortByItem = columnsMap.Keys
.FirstOrDefault (p =>
p.ToNormalString () == sortBy.ToNormalString ());
if (sortByItem.IsNullOrEmpty ()) {
return source;
}
//
// Apply Sorting ...
if (isAscending) {
return source.OrderBy (sortByItem);
} else {
return source.OrderByDescending (sortByItem);
}
}
/// <summary>
/// Apply Paging on a qury
/// </summary>
/// <param name="source"></param>
/// <param name="page"></param>
/// <param name="pageSize"></param>
/// <typeparam name="T"></typeparam>
/// <returns></returns>
public static IQueryable<T> ApplyPaging<T> (
this IQueryable<T> source,
int? page,
int? pageSize
) {
//
if (!page.HasValue ||
page <= 0) {
page = 1;
}
//
if (!pageSize.HasValue ||
pageSize <= 0 ||
pageSize > XDataServiceConstants.MAX_AVAILABLE_PAGE_SIZE) {
pageSize = XDataServiceConstants.DEFAULT_PAGE_SIZE;
}
//
var pageVal = page.GetValueOrDefault ();
var pageSizeVal = pageSize.GetValueOrDefault ();
//
return source
.Skip ((pageVal - 1) * pageSizeVal)
.Take (pageSizeVal);
}
/// <summary>
/// Apply Paging on a Enumerable
/// </summary>
/// <param name="source"></param>
/// <param name="page"></param>
/// <param name="pageSize"></param>
/// <typeparam name="T"></typeparam>
/// <returns></returns>
public static IEnumerable<T> ApplyPaging<T> (
this IEnumerable<T> source,
int? page,
int? pageSize
) {
//
if (!page.HasValue ||
page <= 0) {
page = 1;
}
//
if (!pageSize.HasValue ||
pageSize <= 0 ||
pageSize > XDataServiceConstants.MAX_AVAILABLE_PAGE_SIZE) {
pageSize = XDataServiceConstants.DEFAULT_PAGE_SIZE;
}
//
var pageVal = page.GetValueOrDefault ();
var pageSizeVal = pageSize.GetValueOrDefault ();
//
return source
.Skip ((pageVal - 1) * pageSizeVal)
.Take (pageSizeVal);
}
}
}
@@ -0,0 +1,82 @@
using System.Linq;
using xCommons.Extensions;
using xDataService.Configuration;
using xDataService.Constants;
namespace xDataService.Extensions {
public static class XDataServiceConfigurationExtensions {
/// <summary>
/// Extract Provider enum from Provider Type ...
/// </summary>
/// <param name="source"></param>
/// <returns></returns>
public static XDbProviders ToDbProvider (this string source) {
//
if (source.IsNullOrEmpty ()) {
return XDbProviders.None;
}
//
source = source.ToNormalString ();
//
var result = source == ProviderType.MySQL.ToNormalString () ?
XDbProviders.MySQL :
source == ProviderType.SQLite.ToNormalString () ?
XDbProviders.SQLite :
source == ProviderType.SQLServer.ToNormalString () ?
XDbProviders.SQLServer :
source == ProviderType.MongoDB.ToNormalString () ?
XDbProviders.MongoDB :
XDbProviders.None;
//
return result;
}
/// <summary>
/// Retrieve Mongo URI from ConnectionString
/// </summary>
/// <param name="source"></param>
/// <returns></returns>
public static string GetMongoDbURI (this XDataServiceConfiguration source) {
//
var parts = source.GetConnectionParts ();
var result = parts
.Where (p => p.Trim ().StartsWith ("Uri="))
.FirstOrDefault ();
result = result.Replace ("Uri=", "").Trim ();
//
return result;
}
/// <summary>
/// Retrieve Mongo Database Name from Connaction string
/// </summary>
/// <param name="source"></param>
/// <returns></returns>
public static string GetMongoDbDatabase (this XDataServiceConfiguration source) {
//
var parts = source.GetConnectionParts ();
var result = parts
.Where (p => p.Trim ().StartsWith ("Database="))
.FirstOrDefault ();
result = result.Replace ("Database=", "").Trim ();
//
return result;
}
//
#region Private ...
private static string[] GetConnectionParts (this XDataServiceConfiguration source) {
//
var result = source.ConnectionString.Split (';');
//
return result;
}
#endregion
}
}
+28
View File
@@ -0,0 +1,28 @@
using GraphQL;
using GraphQL.Types;
using xDataService.Constants;
using xModels.Dtos;
namespace xDataService.Extensions {
public static class XGraphQLExtensions {
public static TKey GetIdArgument<TKey> (this IResolveFieldContext<object> source) {
return source.GetArgument<TKey> (XGraphQLHelper.GetIdArgument<IntGraphType>().Name);
}
public static bool GetIgnoreSoftDeletedArgument<T> (this IResolveFieldContext<T> source) {
return source.GetArgument<bool> (XGraphQLHelper.IgnoreSoftDeletedArgument.Name);
}
public static bool GetContainsDetailArgument<T> (this IResolveFieldContext<T> source) {
return source.GetArgument<bool> (XGraphQLHelper.ContainsDetailArgument.Name);
}
public static string GetSearchQueryArgument<T> (this IResolveFieldContext<T> source) {
return source.GetArgument<string> (XGraphQLHelper.SearchQueryArgument.Name);
}
public static XQuery GetQueryArgument<T> (this IResolveFieldContext<T> source) {
return source.GetArgument<XQuery> (XGraphQLHelper.QueryArgument.Name);
}
}
}
+61
View File
@@ -0,0 +1,61 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Threading;
using System.Threading.Tasks;
using MongoDB.Bson;
using MongoDB.Driver;
using MongoDB.Driver.Core.Bindings;
using MongoDB.Driver.Core.Clusters;
using MongoDB.Driver.Core.Servers;
using MongoDB.Driver.Core.WireProtocol.Messages.Encoders;
using MongoDB.Driver.Linq;
using xDataService.Mongo;
namespace xDataService.Extensions {
public static class XMongoDbExtensions {
public static Guid ToGuid (this ObjectId source) {
//
var bytes = source
.ToByteArray ()
.Concat (new byte[] { 5, 5, 5, 5 })
.ToArray ();
//
var result = new Guid (bytes);
//
return result;
}
public static ObjectId ToObjectId (this Guid source) {
//
var bytes = source
.ToByteArray ()
.Take (12)
.ToArray ();
//
var result = new ObjectId (bytes);
//
return result;
}
public static IAsyncEnumerable<T> ToAsyncEnumerable<T> (this IAsyncCursorSource<T> asyncCursorSource) {
return new XAsyncEnumerableAdapter<T> (asyncCursorSource);
}
public static async IAsyncEnumerable<T> ToAsyncEnumerable<T> (this IAsyncCursor<T> source) {
while (await source.MoveNextAsync ()) {
foreach (var current in source.Current) {
yield return current;
}
}
}
public static XMongoAsyncCursor<T> ToAsyncCursor<T> (this IQueryable<T> source) {
return new XMongoAsyncCursor<T> (source);
}
}
}