### FILE: C:\Users\SaherElm\Documents\Projects\xSaherelmWorkspace\Modules\xDataService\Configuration\XDataBaseConfiguration.cs
using System.Collections.Generic;
using xDataService.Constants;
namespace xDataService.Configuration
{
///
/// Describe a Database ...
///
public class XDataBaseConfiguration
{
///
/// Provider Type ...
///
///
public XDbProviders Provider { get; set; }
///
/// Connection String which provide Requires Data to Connect to Db Provider ...
///
///
public string ConnectionString { get; set; }
///
/// Holds Seeding items ...
/// nameof(TEntity) => TEntity
///
public IDictionary> SeedItems { get; set; } = new Dictionary>();
}
}
### FILE: C:\Users\SaherElm\Documents\Projects\xSaherelmWorkspace\Modules\xDataService\Configuration\XDataServiceConfiguration.cs
using System.Collections.Generic;
using xDataService.Constants;
namespace xDataService.Configuration
{
///
/// Represent Configurations of DataService Module ...
///
public partial class XDataServiceConfiguration
{
///
/// the base path for providing GraphQL ...
///
///
public string GraphQLBasePath { get; set; } = "/graphql";
///
/// Data Bases Configuration ...
///
///
public IDictionary Databases { get; set; } = new Dictionary();
///
/// Enable Soft Delete Entities or Not ...
///
///
public bool EnableSoftDelete { get; set; }
///
/// Specified Seeding Mode ...
///
public XDbSeedingMode SeedingMode { get; set; } = XDbSeedingMode.None;
///
/// Enable Tracking of Entities ...
/// Only Used on EFCore ...
///
///
public bool EnableTracking { get; set; } = false;
///
/// Enable Logging Details of Errors ...
/// Only Used on EFCore ...
///
///
public bool EnableDetailedErrors { get; set; } = false;
///
/// Enable Logging Sensitive Data ...
/// Only Used on EFCore ...
///
///
public bool EnableSensitiveDataLogging { get; set; } = false;
///
/// this is a way to provide Default Pagination Data on XQuery based requests ...
///
///
public PagingConfiguration PagingConfiguration { get; set; } = new PagingConfiguration();
}
///
/// this is a way to provide Default Pagination Data on XQuery based requests ...
///
public partial class PagingConfiguration
{
///
/// Default Page Size ...
///
///
public int DefaultPageSize { get; set; } = XDataServiceConstants.DEFAULT_PAGE_SIZE;
///
/// restrict Maximum Page Size ...
///
///
public int MaxAvailablePageSize { get; set; } = XDataServiceConstants.MAX_AVAILABLE_PAGE_SIZE;
///
/// restrice Minimum Page Size ...
///
///
public int MinAvailablePageSize { get; set; } = XDataServiceConstants.MIN_AVAILABLE_PAGE_SIZE;
}
}
### FILE: C:\Users\SaherElm\Documents\Projects\xSaherelmWorkspace\Modules\xDataService\Constants\ConfigurationNodeNames.cs
namespace xDataService.Constants {
public partial struct ConfigurationNodeNames {
public const string DB_PROVIDER_NODE = "XDBProvider";
public const string DATA_SERVICE_NODE = "DataServiceConfiguration";
public const string DATA_SERVICE_DB_SEED_NODE = "DbSeeder";
}
}
### FILE: C:\Users\SaherElm\Documents\Projects\xSaherelmWorkspace\Modules\xDataService\Constants\XDataServiceConstants.cs
namespace xDataService.Constants {
///
/// Default Pagination Values ...
///
public partial struct XDataServiceConstants {
public static int DEFAULT_PAGE_SIZE = 50;
public static int MAX_AVAILABLE_PAGE_SIZE = 500;
public static int MIN_AVAILABLE_PAGE_SIZE = 20;
}
}
### FILE: C:\Users\SaherElm\Documents\Projects\xSaherelmWorkspace\Modules\xDataService\Constants\XDbProviders.cs
namespace xDataService.Constants {
///
/// Represent Supported DBMS for Managing Data ...
///
public enum XDbProviders {
None,
MySQL,
SQLite,
Oracle,
SQLServer,
MongoDB,
}
///
/// Represent Supported DBMS for Managing Data ...
///
public partial struct ProviderType {
public const string MySQL = "MYSQL";
public const string SQLite = "SQLITE";
public const string Oracle = "ORACLE";
public const string MongoDB = "MONGODB";
public const string SQLServer = "SQLSERVER";
}
}
### FILE: C:\Users\SaherElm\Documents\Projects\xSaherelmWorkspace\Modules\xDataService\Constants\XDbSeedingMode.cs
namespace xDataService.Constants
{
///
/// All Seeding Data Mode ...
///
public enum XDbSeedingMode
{
///
/// No Seed Data ...
///
None,
///
/// Seed Only New Items ...
///
AddIfNotExists,
///
/// Seed Force (Add/Update) ...
///
AddOrUpdate,
}
}
### FILE: C:\Users\SaherElm\Documents\Projects\xSaherelmWorkspace\Modules\xDataService\Constants\XRepositoryType.cs
using xExceptions.Attributes;
namespace xDataService.Constants
{
public enum XRepositoryType
{
[StringValue("EF")]
EF,
[StringValue("Mongo")]
Mongo,
[StringValue("InMemory")]
InMemory
}
}
### FILE: C:\Users\SaherElm\Documents\Projects\xSaherelmWorkspace\Modules\xDataService\Controllers\XBaseRepositoryController.cs
using System;
using System.Collections.Generic;
using System.Threading.Tasks;
using Microsoft.AspNetCore.Mvc;
using Microsoft.Extensions.Logging;
using xCommons.Configurations;
using xCommons.Extensions;
using xCommons.Providers;
using xExceptions.Constants;
using xModels.Base;
using xModels.Dtos;
using xDataService.Interfaces;
using System.Linq;
using Microsoft.EntityFrameworkCore.Query;
using System.Threading;
using xCommons.Controllers;
using Microsoft.AspNetCore.Authorization;
namespace xDataService.Controllers
{
///
/// an Abstract Controller for Providing Entity Repository Actions Implementatin ...
///
///
///
[AllowAnonymous]
public abstract class XBaseRepositoryController : XBaseApiV1Controller, IXBaseRepositoryController
where TEntity : XBaseEntity
{
//
#region Properties ...
public IXBaseRepository Repository { get; }
public Func, IOrderedQueryable> DefaultOrderBuilder { get; }
public Func, IIncludableQueryable> DefaultIncludeBuilder { get; }
#endregion
//
#region Constructor ...
protected XBaseRepositoryController(
ILogger> logger,
XAppConfiguration appConfiguration,
XValidationProvider validationProvider,
IXBaseRepository repository,
Func, IOrderedQueryable> defaultOrderBuilder = null,
Func, IIncludableQueryable> defaultIncludeBuilder = null
) : base(
logger,
appConfiguration,
validationProvider
)
{
//
Repository = repository;
DefaultOrderBuilder = defaultOrderBuilder;
DefaultIncludeBuilder = defaultIncludeBuilder;
}
#endregion
//
#region Actions ...
//
#region Add ...
///
/// Add Specified Item ...
///
///
///
///
///
///
[HttpPost]
public virtual async Task> Add(
[FromBody] TEntity item,
CancellationToken cancellationToken = default
)
{
//
try
{
//
// Validate Args ...
if (!ModelState.IsValid)
{
XException.InvalidArgs.Throw();
}
ValidationProvider.NotNull(item);
//
// Get Result ...
var result = await Repository
.AddAsync(
item,
saveChanges: true,
cancellationToken: cancellationToken
);
//
return Ok(result
.ToDynamicObject());
}
catch (Exception ex)
{
//
var result = GetExceptionActionResult(ex);
return result;
}
}
///
/// Add or Update Specified Item ...
///
///
///
///
///
///
[HttpPost("AddOrUpdate")]
public virtual async Task> AddOrUpdate(
[FromBody] TEntity item,
CancellationToken cancellationToken = default
)
{
//
try
{
//
// Validate Args ...
if (!ModelState.IsValid)
{
XException.InvalidArgs.Throw();
}
ValidationProvider.NotNull(item);
//
// Get Result ...
var result = await Repository
.AddOrUpdateAsync(
item,
saveChanges: true,
cancellationToken: cancellationToken
);
//
return Ok(result
.ToDynamicObject());
}
catch (Exception ex)
{
//
var result = GetExceptionActionResult(ex);
return result;
}
}
///
/// Add a Collection of Items ...
///
///
///
///
///
///
[HttpPost("AddMany")]
public virtual async Task AddMany(
[FromBody] XBaseRangeRequest request,
CancellationToken cancellationToken = default
)
{
//
try
{
//
// Validate Args ...
if (!ModelState.IsValid)
{
XException.InvalidArgs.Throw();
}
await ValidationProvider
.GroupValidationBuilder()
.AddNotNull(request)
.AddNotZeroChilds(request.Items)
.ValidateGroupAsync();
//
// Get Result ...
await Repository
.AddRangeAsync(
request.Items,
saveChanges: true,
cancellationToken: cancellationToken
);
//
return Ok();
}
catch (Exception ex)
{
//
var result = GetExceptionActionResult(ex);
return result;
}
}
#endregion
//
#region Retrieve ...
///
/// Get Specified Item ...
///
///
///
///
///
///
///
///
[HttpGet("{id}")]
public virtual async Task> Get(
[FromRoute] TKey id,
[FromQuery] bool ignoreSoftDeleteds = true,
[FromQuery] bool useDefaultIncludes = false,
CancellationToken cancellationToken = default
)
{
//
try
{
//
// Validate Args ...
ValidationProvider.NotNull(id);
//
// Get Result ...
var result = await Repository
.GetAsync(
id,
includeBuilder: useDefaultIncludes
? DefaultIncludeBuilder
: null,
cancellationToken: cancellationToken,
ignoreSoftDeleteds: ignoreSoftDeleteds
);
//
return Ok(result
.ToDynamicObject());
}
catch (Exception ex)
{
//
var result = GetExceptionActionResult(ex);
return result;
}
}
///
/// Get All Items ...
///
///
///
///
///
///
///
///
[HttpGet]
public virtual async Task>> GetAll(
[FromQuery] bool ignoreSoftDeleteds = true,
[FromQuery] bool useDefaultOrders = false,
[FromQuery] bool useDefaultIncludes = false,
CancellationToken cancellationToken = default
)
{
//
try
{
//
// Get Result ...
var result = await Repository
.GetAllAsync(
orderBuilder: useDefaultOrders
? DefaultOrderBuilder
: null,
includeBuilder: useDefaultIncludes
? DefaultIncludeBuilder
: null,
cancellationToken: cancellationToken,
ignoreSoftDeleteds: ignoreSoftDeleteds
);
//
return Ok(result
.ToDynamicObject());
}
catch (Exception ex)
{
//
var result = GetExceptionActionResult(ex);
return result;
}
}
///
/// Find Specified Item ...
///
///
///
///
///
///
///
///
[HttpGet("FindOne/{query}")]
public virtual async Task> FindOne(
[FromRoute] string query,
[FromQuery] bool ignoreSoftDeleteds = true,
[FromQuery] bool useDefaultIncludes = false,
CancellationToken cancellationToken = default
)
{
//
try
{
//
// Validate Args ...
ValidationProvider.NotEmpty(query);
//
// Get Result ...
var result = await Repository
.FindOneAsync(
predicate: t =>
t.PropValuesContains(query),
includeBuilder: useDefaultIncludes
? DefaultIncludeBuilder
: null,
cancellationToken: cancellationToken,
ignoreSoftDeleteds: ignoreSoftDeleteds
);
//
return Ok(result
.ToDynamicObject());
}
catch (Exception ex)
{
//
var result = GetExceptionActionResult(ex);
return result;
}
}
///
/// Find Many Items ...
///
///
///
///
///
///
///
///
///
[HttpGet("FindMany/{query}")]
public virtual async Task>> FindMany(
[FromRoute] string query,
[FromQuery] bool ignoreSoftDeleteds = true,
[FromQuery] bool useDefaultOrders = false,
[FromQuery] bool useDefaultIncludes = false,
CancellationToken cancellationToken = default
)
{
//
try
{
//
// Validate Args ...
ValidationProvider.NotEmpty(query);
//
// Get Result ...
var result = await Repository
.FindManyAsync(
predicate: t =>
t.PropValuesContains(query),
orderBuilder: useDefaultOrders
? DefaultOrderBuilder
: null,
includeBuilder: useDefaultIncludes
? DefaultIncludeBuilder
: null,
cancellationToken: cancellationToken,
ignoreSoftDeleteds: ignoreSoftDeleteds
);
//
return Ok(result
.ToDynamicObject());
}
catch (Exception ex)
{
//
var result = GetExceptionActionResult(ex);
return result;
}
}
///
/// Retrieve Items Based on Query Mechanism ...
///
///
///
///
///
///
///
///
///
[HttpGet("Query")]
public virtual async Task>> Query(
[FromQuery] XQuery query,
[FromQuery] bool ignoreSoftDeleteds = true,
[FromQuery] bool useDefaultOrders = false,
[FromQuery] bool useDefaultIncludes = false,
CancellationToken cancellationToken = default
)
{
//
try
{
//
// Validate Args ...
ValidationProvider.NotNull(query);
//
// Get Result ...
var result = await Repository
.QueryAsync(
query: query,
orderBuilder: useDefaultOrders
? DefaultOrderBuilder
: null,
includeBuilder: useDefaultIncludes
? DefaultIncludeBuilder
: null,
cancellationToken: cancellationToken,
ignoreSoftDeleteds: ignoreSoftDeleteds
);
//
return Ok(result
.ToDynamicObject());
}
catch (Exception ex)
{
//
var result = GetExceptionActionResult(ex);
return result;
}
}
#endregion
//
#region Update ...
///
/// Update Item ...
///
///
///
///
///
///
///
[HttpPut("{id}")]
public virtual async Task> Update(
[FromRoute] TKey id,
[FromBody] TEntity item,
CancellationToken cancellationToken = default
)
{
//
try
{
//
// Validate Args ...
if (!ModelState.IsValid)
{
XException.InvalidArgs.Throw();
}
await ValidationProvider
.GroupValidationBuilder()
.AddNotNull(id, item)
.ValidateGroupAsync();
//
// Get Result ...
var result = await Repository
.UpdateAsync(
id: id,
item: item,
saveChanges: true,
cancellationToken: cancellationToken
);
//
return Ok(result
.ToDynamicObject());
}
catch (Exception ex)
{
//
var result = GetExceptionActionResult(ex);
return result;
}
}
///
/// Update a Collection of items ...
///
///
///
///
///
///
[HttpPost("UpdateMany")]
public virtual async Task> UpdateMany(
[FromBody] XBaseRangeRequest request,
CancellationToken cancellationToken = default
)
{
//
try
{
//
// Validate Args ...
if (!ModelState.IsValid)
{
XException.InvalidArgs.Throw();
}
await ValidationProvider
.GroupValidationBuilder()
.AddNotNull(request)
.AddNotZeroChilds(request.Items)
.ValidateGroupAsync();
//
// Get Result ...
var result = await Repository
.UpdateRangeAsync(
saveChanges: true,
items: request.Items,
cancellationToken: cancellationToken
);
//
return Ok(result
.ToDynamicObject());
}
catch (Exception ex)
{
//
var result = GetExceptionActionResult(ex);
return result;
}
}
#endregion
//
#region Exists ...
///
///Check an Item Exists or not ...
///
///
///
///
///
///
///
[HttpGet("{id}/IsExists")]
public virtual async Task> IsExists(
[FromRoute] TKey id,
[FromQuery] bool ignoreSoftDeleteds = true,
CancellationToken cancellationToken = default
)
{
//
try
{
//
// Validate Args ...
ValidationProvider.NotNull(id);
//
// Get Result ...
var result = await Repository
.IsExistsAsync(
id: id,
cancellationToken: cancellationToken,
ignoreSoftDeleteds: ignoreSoftDeleteds
);
//
return Ok(result
.ToDynamicObject());
}
catch (Exception ex)
{
//
var result = GetExceptionActionResult(ex);
return result;
}
}
#endregion
//
#region Remove ...
///
/// Remove an Items ...
///
///
///
///
///
///
///
[HttpDelete("{id}")]
public virtual async Task> Remove(
[FromRoute] TKey id,
[FromQuery] bool softDelete = true,
CancellationToken cancellationToken = default
)
{
//
try
{
//
// Validate Args ...
ValidationProvider.NotNull(id);
//
// Get Result ...
var result = await Repository
.RemoveAsync(
id: id,
saveChanges: true,
softDelete: softDelete,
cancellationToken: cancellationToken
);
//
return Ok(result
.ToDynamicObject());
}
catch (Exception ex)
{
//
var result = GetExceptionActionResult(ex);
return result;
}
}
///
/// Remove Many Items ...
///
///
///
///
///
///
///
[HttpPost("RemoveMany")]
public virtual async Task RemoveMany(
[FromBody] XBaseRangeRequest request,
[FromQuery] bool softDelete = true,
CancellationToken cancellationToken = default
)
{
//
try
{
//
// Validate Args ...
await ValidationProvider
.GroupValidationBuilder()
.AddNotNull(request)
.AddNotZeroChilds(request.Items)
.ValidateGroupAsync();
//
// Get Result ...
await Repository
.RemoveRangeAsync(
saveChanges: true,
items: request.Items,
softDelete: softDelete,
cancellationToken: cancellationToken
);
//
return Ok();
}
catch (Exception ex)
{
//
var result = GetExceptionActionResult(ex);
return result;
}
}
#endregion
#endregion
}
}
### FILE: C:\Users\SaherElm\Documents\Projects\xSaherelmWorkspace\Modules\xDataService\Controllers\XBaseServiceController.cs
using System;
using System.Collections.Generic;
using System.Linq;
using System.Threading;
using System.Threading.Tasks;
using Microsoft.AspNetCore.Authorization;
using Microsoft.AspNetCore.Mvc;
using Microsoft.EntityFrameworkCore.Query;
using Microsoft.Extensions.Logging;
using xCommons.Configurations;
using xCommons.Controllers;
using xCommons.Extensions;
using xCommons.Providers;
using xDataService.Interfaces;
using xExceptions.Constants;
using xModels.Base;
using xModels.Dtos;
namespace xDataService.Controllers
{
///
/// an Abstract Controller for Providing Entity Dto Repository Service Actions Implementatin ...
///
///
///
///
[AllowAnonymous]
public abstract class XBaseServiceController : XBaseApiV1Controller, IXBaseServiceController
where TEntity : XBaseEntity
where TDto : XBaseEntityDto
{
//
#region Properties ...
public IXBaseRepositoryService RepositoryService { get; }
public Func, IOrderedQueryable> DefaultOrderBuilder { get; }
public Func, IIncludableQueryable> DefaultIncludeBuilder { get; }
#endregion
//
#region Constructor ...
protected XBaseServiceController(
ILogger> logger,
XAppConfiguration appConfiguration,
XValidationProvider validationProvider,
IXBaseRepositoryService repositoryService,
Func, IOrderedQueryable> defaultOrderBuilder = null,
Func, IIncludableQueryable> defaultIncludeBuilder = null
) : base(
logger,
appConfiguration,
validationProvider
)
{
//
RepositoryService = repositoryService;
DefaultOrderBuilder = defaultOrderBuilder;
DefaultIncludeBuilder = defaultIncludeBuilder;
}
#endregion
//
#region Actions ...
//
#region Add ...
///
/// Add Specified Item ...
///
///
///
///
///
///
[HttpPost]
public virtual async Task> Add(
[FromBody] TDto item,
CancellationToken cancellationToken = default
)
{
//
try
{
//
// Validate Args ...
if (!ModelState.IsValid)
{
XException.InvalidArgs.Throw();
}
ValidationProvider.NotNull(item);
//
// Get Result ...
var result = await RepositoryService
.AddAsync(
item,
saveChanges: true,
cancellationToken: cancellationToken
);
//
return Ok(result
.ToDynamicObject());
}
catch (Exception ex)
{
//
var result = GetExceptionActionResult(ex);
return result;
}
}
///
/// Add or Update Specified Item ...
///
///
///
///
///
///
[HttpPost("AddOrUpdate")]
public virtual async Task> AddOrUpdate(
[FromBody] TDto item,
CancellationToken cancellationToken = default
)
{
//
try
{
//
// Validate Args ...
if (!ModelState.IsValid)
{
XException.InvalidArgs.Throw();
}
ValidationProvider.NotNull(item);
//
// Get Result ...
var result = await RepositoryService
.AddOrUpdateAsync(
item,
saveChanges: true,
cancellationToken: cancellationToken
);
//
return Ok(result
.ToDynamicObject());
}
catch (Exception ex)
{
//
var result = GetExceptionActionResult(ex);
return result;
}
}
///
/// Add a Collection of Items ...
///
///
///
///
///
///
[HttpPost("AddMany")]
public virtual async Task AddMany(
[FromBody] XBaseRangeRequest request,
CancellationToken cancellationToken = default
)
{
//
try
{
//
// Validate Args ...
if (!ModelState.IsValid)
{
XException.InvalidArgs.Throw();
}
await ValidationProvider
.GroupValidationBuilder()
.AddNotNull(request)
.AddNotZeroChilds(request.Items)
.ValidateGroupAsync();
//
// Get Result ...
await RepositoryService
.AddRangeAsync(
request.Items,
saveChanges: true,
cancellationToken: cancellationToken
);
//
return Ok();
}
catch (Exception ex)
{
//
var result = GetExceptionActionResult(ex);
return result;
}
}
#endregion
//
#region Retrieve ...
///
/// Get Specified Item ...
///
///
///
///
///
///
///
///
[HttpGet("{id}")]
public virtual async Task> Get(
[FromRoute] TKey id,
[FromQuery] bool ignoreSoftDeleteds = true,
[FromQuery] bool useDefaultIncludes = false,
CancellationToken cancellationToken = default
)
{
//
try
{
//
// Validate Args ...
ValidationProvider.NotNull(id);
//
// Get Result ...
var result = await RepositoryService
.GetAsync(
id,
includeBuilder: useDefaultIncludes
? DefaultIncludeBuilder
: null,
cancellationToken: cancellationToken,
ignoreSoftDeleteds: ignoreSoftDeleteds
);
//
return Ok(result
.ToDynamicObject());
}
catch (Exception ex)
{
//
var result = GetExceptionActionResult(ex);
return result;
}
}
///
/// Get All Items ...
///
///
///
///
///
///
///
///
[HttpGet]
public virtual async Task>> GetAll(
[FromQuery] bool ignoreSoftDeleteds = true,
[FromQuery] bool useDefaultOrders = false,
[FromQuery] bool useDefaultIncludes = false,
CancellationToken cancellationToken = default
)
{
//
try
{
//
// Get Result ...
var result = await RepositoryService
.GetAllAsync(
orderBuilder: useDefaultOrders
? DefaultOrderBuilder
: null,
includeBuilder: useDefaultIncludes
? DefaultIncludeBuilder
: null,
cancellationToken: cancellationToken,
ignoreSoftDeleteds: ignoreSoftDeleteds
);
//
return Ok(result
.ToDynamicObject());
}
catch (Exception ex)
{
//
var result = GetExceptionActionResult(ex);
return result;
}
}
///
/// Find Specified Item ...
///
///
///
///
///
///
///
///
[HttpGet("FindOne/{query}")]
public virtual async Task> FindOne(
[FromRoute] string query,
[FromQuery] bool ignoreSoftDeleteds = true,
[FromQuery] bool useDefaultIncludes = false,
CancellationToken cancellationToken = default
)
{
//
try
{
//
// Validate Args ...
ValidationProvider.NotEmpty(query);
//
// Get Result ...
var result = await RepositoryService
.FindOneAsync(
predicate: t =>
t.PropValuesContains(query),
includeBuilder: useDefaultIncludes
? DefaultIncludeBuilder
: null,
cancellationToken: cancellationToken,
ignoreSoftDeleteds: ignoreSoftDeleteds
);
//
return Ok(result
.ToDynamicObject());
}
catch (Exception ex)
{
//
var result = GetExceptionActionResult(ex);
return result;
}
}
///
/// Find Many Items ...
///
///
///
///
///
///
///
///
///
[HttpGet("FindMany/{query}")]
public virtual async Task>> FindMany(
[FromRoute] string query,
[FromQuery] bool ignoreSoftDeleteds = true,
[FromQuery] bool useDefaultOrders = false,
[FromQuery] bool useDefaultIncludes = false,
CancellationToken cancellationToken = default
)
{
//
try
{
//
// Validate Args ...
ValidationProvider.NotEmpty(query);
//
// Get Result ...
var result = await RepositoryService
.FindManyAsync(
predicate: t =>
t.PropValuesContains(query),
orderBuilder: useDefaultOrders
? DefaultOrderBuilder
: null,
includeBuilder: useDefaultIncludes
? DefaultIncludeBuilder
: null,
cancellationToken: cancellationToken,
ignoreSoftDeleteds: ignoreSoftDeleteds
);
//
return Ok(result
.ToDynamicObject());
}
catch (Exception ex)
{
//
var result = GetExceptionActionResult(ex);
return result;
}
}
///
/// Retrieve Items Based on Query Mechanism ...
///
///
///
///
///
///
///
///
///
[HttpGet("Query")]
public virtual async Task>> Query(
[FromQuery] XQuery query,
[FromQuery] bool ignoreSoftDeleteds = true,
[FromQuery] bool useDefaultOrders = false,
[FromQuery] bool useDefaultIncludes = false,
CancellationToken cancellationToken = default
)
{
//
try
{
//
// Validate Args ...
ValidationProvider.NotNull(query);
//
// Get Result ...
var result = await RepositoryService
.QueryAsync(
query: query,
orderBuilder: useDefaultOrders
? DefaultOrderBuilder
: null,
includeBuilder: useDefaultIncludes
? DefaultIncludeBuilder
: null,
cancellationToken: cancellationToken,
ignoreSoftDeleteds: ignoreSoftDeleteds
);
//
return Ok(result
.ToDynamicObject());
}
catch (Exception ex)
{
//
var result = GetExceptionActionResult(ex);
return result;
}
}
#endregion
//
#region Update ...
///
/// Update Item ...
///
///
///
///
///
///
///
[HttpPut("{id}")]
public virtual async Task> Update(
[FromRoute] TKey id,
[FromBody] TDto item,
CancellationToken cancellationToken = default
)
{
//
try
{
//
// Validate Args ...
if (!ModelState.IsValid)
{
XException.InvalidArgs.Throw();
}
await ValidationProvider
.GroupValidationBuilder()
.AddNotNull(id, item)
.ValidateGroupAsync();
//
// Get Result ...
var result = await RepositoryService
.UpdateAsync(
id: id,
item: item,
saveChanges: true,
cancellationToken: cancellationToken
);
//
return Ok(result
.ToDynamicObject());
}
catch (Exception ex)
{
//
var result = GetExceptionActionResult(ex);
return result;
}
}
///
/// Update a Collection of items ...
///
///
///
///
///
///
[HttpPost("UpdateMany")]
public virtual async Task> UpdateMany(
[FromBody] XBaseRangeRequest request,
CancellationToken cancellationToken = default
)
{
//
try
{
//
// Validate Args ...
if (!ModelState.IsValid)
{
XException.InvalidArgs.Throw();
}
await ValidationProvider
.GroupValidationBuilder()
.AddNotNull(request)
.AddNotZeroChilds(request.Items)
.ValidateGroupAsync();
//
// Get Result ...
var result = await RepositoryService
.UpdateRangeAsync(
saveChanges: true,
items: request.Items,
cancellationToken: cancellationToken
);
//
return Ok(result
.ToDynamicObject());
}
catch (Exception ex)
{
//
var result = GetExceptionActionResult(ex);
return result;
}
}
#endregion
//
#region Exists ...
///
///Check an Item Exists or not ...
///
///
///
///
///
///
///
[HttpGet("{id}/IsExists")]
public virtual async Task> IsExists(
[FromRoute] TKey id,
[FromQuery] bool ignoreSoftDeleteds = true,
CancellationToken cancellationToken = default
)
{
//
try
{
//
// Validate Args ...
ValidationProvider.NotNull(id);
//
// Get Result ...
var result = await RepositoryService
.IsExistsAsync(
id: id,
cancellationToken: cancellationToken,
ignoreSoftDeleteds: ignoreSoftDeleteds
);
//
return Ok(result
.ToDynamicObject());
}
catch (Exception ex)
{
//
var result = GetExceptionActionResult(ex);
return result;
}
}
#endregion
//
#region Remove ...
///
/// Remove an Items ...
///
///
///
///
///
///
///
[HttpDelete("{id}")]
public virtual async Task> Remove(
[FromRoute] TKey id,
[FromQuery] bool softDelete = true,
CancellationToken cancellationToken = default
)
{
//
try
{
//
// Validate Args ...
ValidationProvider.NotNull(id);
//
// Get Result ...
var result = await RepositoryService
.RemoveAsync(
id: id,
saveChanges: true,
softDelete: softDelete,
cancellationToken: cancellationToken
);
//
return Ok(result
.ToDynamicObject());
}
catch (Exception ex)
{
//
var result = GetExceptionActionResult(ex);
return result;
}
}
///
/// Remove Many Items ...
///
///
///
///
///
///
///
[HttpPost("RemoveMany")]
public virtual async Task RemoveMany(
[FromBody] XBaseRangeRequest request,
[FromQuery] bool softDelete = true,
CancellationToken cancellationToken = default
)
{
//
try
{
//
// Validate Args ...
await ValidationProvider
.GroupValidationBuilder()
.AddNotNull(request)
.AddNotZeroChilds(request.Items)
.ValidateGroupAsync();
//
// Get Result ...
await RepositoryService
.RemoveRangeAsync(
saveChanges: true,
items: request.Items,
softDelete: softDelete,
cancellationToken: cancellationToken
);
//
return Ok();
}
catch (Exception ex)
{
//
var result = GetExceptionActionResult(ex);
return result;
}
}
#endregion
#endregion
}
}
### FILE: C:\Users\SaherElm\Documents\Projects\xSaherelmWorkspace\Modules\xDataService\Db\XDbContext.cs
using System;
using System.Linq;
using Microsoft.EntityFrameworkCore;
using xCommons.Extensions;
using xDataService.Configuration;
using xDataService.Helpers;
using xDataService.Providers;
namespace xDataService.Db
{
///
/// Provide an abstraction layout arround DBContext ...
/// Only Used on EFCore ...
///
public abstract class XDbContext : DbContext
{
//
#region Properties ...
private readonly string database;
private readonly XDataServiceConfiguration config;
private readonly string[] dynamicEntityRegisterarsNames;
private readonly XEntityRegisterarHandlerService dynamicEntityHandlers;
#endregion
//
#region Entities ...
//
// Register Default and Base Entities ...
#endregion
//
#region Constructor ...
public XDbContext(
string database,
DbContextOptions options,
XDataServiceConfiguration config,
XEntityRegisterarHandlerService dynamicEntityHandlers,
string[] dynamicEntityRegisterarsNames = null
) : base(options)
{
//
try
{
Database.EnsureCreated();
Database.Migrate();
}
catch { }
//
this.config = config;
this.database = database;
this.dynamicEntityHandlers = dynamicEntityHandlers;
this.dynamicEntityRegisterarsNames = dynamicEntityRegisterarsNames;
//
// Handling DbSets of Dynamic Entities ...
if (!dynamicEntityHandlers.IsNull())
{
//
// Configure XEntityRegisterarHandlerService ...
dynamicEntityHandlers.HandleRegisteredEntities();
//
// Loop through Entity Types ...
foreach (var entityType in dynamicEntityHandlers.GetEntityTypes(dynamicEntityRegisterarsNames))
{
//
try
{
//
// Use reflection to call Set()
var method = typeof(XDbContext)
.GetMethod(nameof(XDbContext.Set), Type.EmptyTypes)
.MakeGenericMethod(entityType);
if (!method.IsNull())
{
method.Invoke(this, null);
}
}
catch { }
}
}
}
#endregion
///
/// Extract Current Database Configuration ...
///
///
public XDataBaseConfiguration GetDatabaseConfiguration()
{
//
XDataBaseConfiguration result =
config.Databases.FirstOrDefault(db => string
.Equals(db.Key, database, StringComparison.InvariantCultureIgnoreCase)).Value;
//
return result;
}
//
#region Overrides ...
//
// Prepare Model Configs ...
protected override void OnModelCreating(ModelBuilder modelBuilder)
{
//
OnXModelCreating(modelBuilder);
//
// Automatically apply all IEntityTypeConfiguration in this assembly
modelBuilder.ApplyConfigurationsFromAssembly(typeof(XDbContext).Assembly);
//
// Check Dynamic Registered Service is Exists or not ...
if (!dynamicEntityHandlers.IsNull())
{
//
// Set Entity of Dynamically Registered Entities ...
foreach (var entityType in dynamicEntityHandlers.GetEntityTypes(dynamicEntityRegisterarsNames))
{
modelBuilder.Entity(entityType);
}
//
// Configure Entity using Provided Registerar ...
dynamicEntityHandlers
.HandleApplyRegisteredEntitiesConfigurations(modelBuilder, dynamicEntityRegisterarsNames);
}
//
// Since this class inherit from Identity Db Context,
// we have to pass this to Building Identity Models ...
base.OnModelCreating(modelBuilder);
}
//
// Prepare Configuring ...
protected override void OnConfiguring(DbContextOptionsBuilder optionsBuilder)
{
//
if (config.EnableDetailedErrors)
{
optionsBuilder.EnableDetailedErrors();
}
//
if (config.EnableSensitiveDataLogging)
{
optionsBuilder.EnableSensitiveDataLogging();
}
//
if (config.EnableTracking)
{
optionsBuilder.UseQueryTrackingBehavior(QueryTrackingBehavior.TrackAll);
}
else
{
optionsBuilder.UseQueryTrackingBehavior(QueryTrackingBehavior.NoTracking);
}
//
OnXConfiguring(optionsBuilder);
//
base.OnConfiguring(optionsBuilder);
}
#endregion
//
#region Abstracts ...
//
public abstract void OnXModelCreating(ModelBuilder modelBuilder);
//
public abstract void OnXConfiguring(DbContextOptionsBuilder optionsBuilder);
#endregion
//
#region Dynamic DbSet(s) ...
public override DbSet Set()
where TEntity : class
{
return base.Set();
}
#endregion
}
}
### FILE: C:\Users\SaherElm\Documents\Projects\xSaherelmWorkspace\Modules\xDataService\Db\XUnitOfWorks.cs
using System.Threading;
using System.Threading.Tasks;
using Microsoft.EntityFrameworkCore;
using xDataService.Interfaces;
using xModels.Base;
namespace xDataService.Db {
///
/// Provide Unit Of Works Design Pattern for Db Transactions ...
/// Only Used on EFCore ...
///
///
public class XUnitOfWorks : IXUnitOfWorks
where TDbContext : XDbContext {
public TDbContext DbContext { get; }
public XUnitOfWorks (TDbContext context) {
this.DbContext = context;
}
public DbSet GetDbSet ()
where T : XBaseEntity {
return DbContext.Set ();
}
///
/// Save Changes
///
public int SaveChanges () {
return DbContext.SaveChanges ();
}
///
/// Save Changes Async
///
///
///
public async Task SaveChangesAsync (
CancellationToken cancellationToken = default
) {
return await DbContext.SaveChangesAsync (cancellationToken);
}
public void Dispose () {
DbContext.Dispose ();
}
}
}
### FILE: C:\Users\SaherElm\Documents\Projects\xSaherelmWorkspace\Modules\xDataService\DI\XDIHelperExtension.cs
using System;
using System.Collections.Generic;
using System.Linq;
using Microsoft.AspNetCore.Builder;
using Microsoft.EntityFrameworkCore.Infrastructure;
using Microsoft.Extensions.Configuration;
using Microsoft.Extensions.DependencyInjection;
using xCommons.Extensions;
using xCommons.Helpers;
using xDataService.Configuration;
using xDataService.Constants;
using xDataService.Extensions;
using xDataService.Helpers;
using xDataService.Models;
using xDataService.Providers;
using xExceptions.Constants;
namespace xDataService.DI
{
public static partial class XDIHelperExtension
{
///
/// Retrive XDataService Configurations
///
///
///
public static XDataServiceConfiguration GetXDataServiceConfiguration(
this IConfiguration source
)
{
//
var xDataServiceConfigSection = source
.GetSection(ConfigurationNodeNames.DATA_SERVICE_NODE);
var result = xDataServiceConfigSection.Get();
//
// Reading Seeders ...
if (!result.IsNull() &&
result.Databases.HasChild())
{
//
result
.Databases
.ToList()
.ForEach(db =>
{
//
var seedItemsSectionName = $"{ConfigurationNodeNames.DATA_SERVICE_NODE}:{nameof(XDataServiceConfiguration.Databases)}:{db.Key}:{nameof(XDataBaseConfiguration.SeedItems)}";
var section = source.GetSection(seedItemsSectionName);
var sectionJson = source.GetSectionAsJson(seedItemsSectionName);
var sectionDict = sectionJson.FromJSON>>();
if (!sectionDict.IsNull() &&
sectionDict.Values.HasChild())
{
//
sectionDict
.Keys
.ToList()
.ForEach(entity =>
{
//
// Setting Values to Result ...
result.Databases[db.Key].SeedItems[entity] = sectionDict[entity];
});
}
});
}
//
return result;
}
///
/// Register XDataService Configuration ...
///
///
///
public static void AddXDataServiceConfiguration(
this IServiceCollection source,
IConfiguration configuration
)
{
//
var config = configuration.GetXDataServiceConfiguration();
if (config.IsNullOrDefault())
{
//
Log("Configurations Not Founded ...");
XException.NotFound.Throw();
}
//
source.AddSingleton(config);
}
///
/// Register XDataService Configuration ...
///
///
///
public static void AddXDataServiceConfiguration(
this IServiceCollection source,
XDataServiceConfiguration configuration
)
{
//
if (configuration.IsNullOrDefault())
{
//
Log("Configurations Not Founded ...");
XException.NotFound.Throw();
}
//
source.AddSingleton(configuration);
}
///
/// Register a Data Base using Descriptor ...
///
///
///
///
///
public static void AddXDatabase(
this IServiceCollection source,
IConfiguration configuration,
XDatabaseDescriptor descriptor,
ServiceLifetime lifeTime = ServiceLifetime.Scoped
)
{
//
// Validate Database Descriptor ...
var isValid =
!descriptor.IsNullOrDefault() &&
!descriptor.Name.IsNullOrEmpty();
if (!isValid)
{
//
Log("Invalid Database Descriptor ...");
return;
}
//
// Check Service Collection Validation ...
isValid =
!source.IsNull() &&
!configuration.IsNull();
if (!isValid)
{
//
Log("Invalid Service Provider or Configuration ...");
return;
}
//
// Get Registere Data Service Configuration ...
var xDataServiceConfiguration = source
.GetRegisteredService();
isValid = !xDataServiceConfiguration.IsNullOrDefault();
if (!isValid)
{
//
// Extract Configuration from Configuration ...
xDataServiceConfiguration = configuration.GetXDataServiceConfiguration();
isValid = !xDataServiceConfiguration.IsNullOrDefault();
if (!isValid)
{
//
Log("DataService Configuration not provided ...");
return;
}
//
// Register Configuration in DI ...
source.AddSingleton(xDataServiceConfiguration);
}
//
// Check Data Service Configuration has Database ...
isValid =
!xDataServiceConfiguration.Databases.IsNullOrDefault() &&
xDataServiceConfiguration.Databases.HasChild() &&
xDataServiceConfiguration.Databases.Keys.Contains(descriptor.Name);
if (!isValid)
{
//
Log("Invalid Database Descriptor ...");
return;
}
//
// Register Handler Service ...
source.AddSingleton();
//
// Configure Database Descriptor ...
descriptor.Configure(source);
//
// Register Context ...
if (!descriptor.Context.IsNull() &&
descriptor.Provider != XDbProviders.None &&
!descriptor.ConnectionString.IsNullOrEmpty())
{
//
try
{
//
typeof(XDataServiceHelper).InvokeGenericMethod(
methodName: "AddXDbContext",
runtimeType: descriptor.Context,
args: [
source,
descriptor,
lifeTime
]
);
//
Log($"DbContext: {descriptor.Name} Registered Successfully ...");
}
catch (Exception ex)
{
Log($"DbContext: {descriptor.Name} Registration failed due {ex.Message} ...");
}
}
//
// Register Repositories ...
if (!descriptor.Repositories.IsNull() &&
descriptor.Repositories.HasChild())
{
//
descriptor.Repositories.ToList().ForEach(r =>
{
//
source.AddXRepository(
descriptor: r,
lifeTime: lifeTime
);
});
}
}
public static void AddXRepository(
this IServiceCollection source,
XRepositoryDescriptor descriptor,
ServiceLifetime lifeTime = ServiceLifetime.Scoped
)
{
//
// Preparing Runtime Types ...
Type[] runtimeTypes = descriptor.GetType().GenericTypeArguments;
//
try
{
//
typeof(XDataServiceHelper).InvokeGenericMethod(
methodName: "AddXRepository",
runtimeTypes: runtimeTypes,
args: [
source,
descriptor,
lifeTime
]
);
//
Log($"Repository of: {runtimeTypes[0]}, Registered Successfully ...");
}
catch (Exception ex)
{
Log($"Repository of: {runtimeTypes[0]}, Registration failed due {ex.Message} ...");
}
}
public static void UseXDatabase(
this IApplicationBuilder source,
XDatabaseDescriptor descriptor,
bool isDevelopmentEnvironment = false
)
{
//
// Validate ...
var isValid =
!source.IsNull() &&
descriptor.IsValid();
if (!isValid)
{
//
Log("Invalid Database Configuration ...");
XException.InvalidArgs.Throw();
}
//
// Check Repositories Exists ...
isValid = descriptor.HasRepositories();
if (isValid)
{
//
// Loop through Repositories ...
descriptor.Repositories
.ToList()
.ForEach(r =>
{
//
source.UseXRepository(
descriptor: r,
isDevelopmentEnvironment: isDevelopmentEnvironment
);
});
}
}
///
/// Use a Repository Middlewares by Providing it's Descriptor ...
///
///
///
///
public static void UseXRepository(
this IApplicationBuilder source,
XRepositoryDescriptor descriptor,
bool isDevelopmentEnvironment = false
)
{
//
Log($"Start Using Repository of: {descriptor.Entity}");
//
var withPlayground = false;
if (isDevelopmentEnvironment)
{
withPlayground = true;
}
//
// Create an Scope for Services Acces ...
using (var scope = source.ApplicationServices.CreateScope())
{
//
// Inject XDataServiceConfiguration ForMake Sure DataService Registration ...
var dataServiceConfiguration = scope.ServiceProvider.GetService();
var isValid = !dataServiceConfiguration.IsNullOrDefault();
if (isValid)
{
//
// Check Seeder Exists ...
// Execute Seeding Data Task if Exists ...
isValid = descriptor.HasSeeder();
if (isValid)
{
//
var seeder = (dynamic)scope.ServiceProvider.GetService(descriptor.SeederService);
isValid = seeder != null;
if (isValid)
{
//
Log($"Start Seeding {descriptor.Entity} ...");
//
// Seeding ...
seeder
.Seed()
.GetAwaiter()
.GetResult();
}
}
//
// Check GraphQL Support ...
isValid = descriptor.HasGraphSupport();
if (isValid)
{
//
// Use WebSockets ...
source.UseWebSockets();
//
// Inject GraphQL Type Helper ...
var helper = (dynamic)scope.ServiceProvider.GetService(descriptor.GraphTypeHelperService);
isValid = helper != null;
if (isValid)
{
//
var graphPath = $"{helper.GetGraphQLPath()}";
var graphBasePath = $"{dataServiceConfiguration.GraphQLBasePath}";
typeof(XDataServiceHelper).InvokeGenericMethod(
methodName: "UseXGraphQL",
runtimeTypes: [
descriptor.Entity,
descriptor.Key,
descriptor.GraphType,
descriptor.GraphTypeKey,
descriptor.GraphQuery,
descriptor.GraphTypeHelperService,
descriptor.GraphTypeHelperImplementation,
descriptor.GraphSchema
],
args: [
source,
graphBasePath,
graphPath,
withPlayground
]
);
//
Log($"Register GraphQL: {graphPath}");
}
}
}
}
}
//
#region Private ...
///
/// a LogTag for xDataService ...
///
private static string XLogTag = "xDataService";
///
/// print a log in Console ...
///
///
private static void Log(string message)
{
Console.WriteLine($"{XLogTag} => {message}");
}
#endregion
}
}
### FILE: C:\Users\SaherElm\Documents\Projects\xSaherelmWorkspace\Modules\xDataService\Extensions\DbContextOptionExtensions.cs
using System;
using Microsoft.EntityFrameworkCore.Infrastructure;
using MySql.EntityFrameworkCore.Infrastructure;
namespace xDataService.Extensions {
public static class DbContextOptionExtensions {
///
/// convert dynamic object to MySqlDbContextOptionBuilder ...
/// Only Used in EFCore ...
///
///
///
public static Action ToMySQLDbContextOptionsBuilder (
this Action source
) {
return ((Action) source);
}
///
/// convert dynamic object to SqliteDbContextOptionBuilder ...
/// Only Used in EFCore ...
///
///
///
public static Action ToSqliteDbContextOptionsBuilder (
this Action source
) {
return ((Action) source);
}
///
/// convert dynamic object to SqlServerDbContextOptionBuilder ...
/// Only Used in EFCore ...
///
///
///
public static Action ToSqlServerDbContextOptionsBuilder (
this Action source
) {
return ((Action) source);
}
}
}
### FILE: C:\Users\SaherElm\Documents\Projects\xSaherelmWorkspace\Modules\xDataService\Extensions\EntityExtensions.cs
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 {
///
/// return all values of an entity properties as a json string ...
///
///
///
///
public static string GetPropValues (this T item)
where T : XBaseEntity {
//
var props = item.GetType ().GetProperties ();
var vals = props.Select (p => p.GetValue (item));
//
return vals.ToJSON ();
}
///
/// check values of all properties of an Entity contains specific value or not ...
///
///
///
///
///
public static bool PropValuesContains (this T item, string value)
where T : XBaseEntity => item.GetPropValues ()
.ToNormalString ()
.Contains (value);
///
/// Retrieve Default Column Map of specific Entity ...
///
///
///
///
public static IDictionary>> GetDefaultColumnsMap (this T item)
where T : XBaseEntity {
//
if (item.IsNull ()) {
return null;
}
//
var result = new Dictionary>> ();
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;
}
///
/// Check a Type is XBaseEntity or not ...
///
///
///
public static bool IsXEntity(this Type source)
{
//
var result = !source.IsNull();
if (!result)
{
return result;
}
//
var baseType = source.BaseType;
while(!baseType.IsNull() && baseType != typeof(object))
{
//
if (baseType.IsGenericType &&
baseType.GetGenericTypeDefinition() == typeof(XBaseEntity<>))
{
result = true;
break;
}
//
baseType = baseType.BaseType;
}
//
return result;
}
}
}
### FILE: C:\Users\SaherElm\Documents\Projects\xSaherelmWorkspace\Modules\xDataService\Extensions\IQueryableExtensions.cs
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.Configuration;
using xDataService.Constants;
using xExceptions.Constants;
using xModels.Base;
using xModels.Dtos;
namespace xDataService.Extensions
{
public static class IQueryableExtensions
{
///
/// Apply Search Filter on a Query
///
///
///
///
///
public static IQueryable ApplyFilter(
this IQueryable source,
string filter
)
where T : XBaseEntity
{
//
// Apply Filter ...
return source.Where(r => r.PropValuesContains(filter));
}
///
/// Apply Search Filter on a Query
///
///
///
///
///
public static async Task> ApplyFilterAsync(
this IQueryable source,
string filter
)
where T : XBaseEntity
{
//
// Where Clause ...
Expression> whereClause = r => r
.PropValuesContains(filter);
//
// Generate Where Function ...
var whereFunc = whereClause.Compile();
//
// Get Enumerable ...
var enumerator = source
.AsAsyncEnumerable();
//
var result = new List();
await
foreach (var entity in enumerator)
{
//
var isApproved = whereFunc(entity);
if (isApproved)
{
result.Add(entity);
}
}
//
return result.AsQueryable();
}
///
/// Apply Search Filter on a Enumerable
///
///
///
///
///
public static async Task> ApplyFilterAsync(
this IEnumerable source,
string filter
)
where T : XBaseEntity
{
//
// Where Clause ...
Expression> whereClause = r => r
.PropValuesContains(filter);
//
// Generate Where Function ...
var whereFunc = whereClause.Compile();
//
// Get Enumerable ...
var enumerator = source
.ToList()
.AsQueryable();
//
var result = new List();
foreach (var entity in enumerator)
{
//
var isApproved = whereFunc(entity);
if (isApproved)
{
result.Add(entity);
}
}
//
return result
.AsEnumerable();
}
///
/// Apply Search Filter on a Enumerable
///
///
///
///
///
public static IEnumerable ApplyFilter(
this IEnumerable source,
string filter
)
where T : class
{
//
// Apply Filter ...
return source.Where(r => r.PropValuesContains(filter));
}
///
/// provide a way to Order an IQueryable by string FieldName ...
///
///
///
///
///
public static IOrderedQueryable OrderBy(
this IQueryable 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 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)genericMethod
.Invoke(genericMethod, new object[] { query, selector });
//
return newQuery;
}
///
/// provide a way to Order an IEnumerable by string FieldName ...
///
///
///
///
///
public static IOrderedEnumerable OrderBy(
this IEnumerable 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));
}
///
/// provide a way to Order an IQueryable by string FieldName ...
///
///
///
///
///
public static IOrderedQueryable OrderByDescending(
this IQueryable 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 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)genericMethod
.Invoke(genericMethod, new object[] { query, selector });
//
return newQuery;
}
///
/// provide a way to Order an IEnumerable by string FieldName ...
///
///
///
///
///
public static IOrderedEnumerable OrderByDescending(
this IEnumerable 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));
}
///
/// Apply Sorting on a query
///
///
///
///
///
///
///
public static IQueryable ApplySorting(
this IQueryable source,
string sortBy,
bool isAscending,
IDictionary>> columnsMap = null
)
where T : XBaseEntity
{
//
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);
}
}
///
/// Apply Sorting on a query
///
///
///
///
///
///
///
public static IEnumerable ApplySorting(
this IEnumerable source,
string sortBy,
bool isAscending,
IDictionary>> columnsMap = null
)
where T : XBaseEntity
{
//
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);
}
}
///
/// Apply Sorting on a Enumerable
///
///
///
///
///
///
///
public static IEnumerable ApplySorting(
this IEnumerable source,
string sortBy,
bool isAscending,
IDictionary>> 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);
}
}
///
/// Apply Paging on a qury
///
///
///
///
///
///
public static IQueryable ApplyPaging(
this IQueryable 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);
}
///
/// Apply Paging on a Enumerable
///
///
///
///
///
///
public static IEnumerable ApplyPaging(
this IEnumerable 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);
}
///
/// Count Query Pages based on Specified Total Number ...
///
///
///
///
public static int CountPages(this XQuery source, int totalItems)
{
//
int result = 0;
//
// Validate and Calculate ...
if (!source.IsNull() && source.PageSize > 0 && totalItems > 0)
{
//
result = totalItems / source.PageSize;
if (totalItems % source.PageSize > 0)
{
result++;
}
}
//
return result;
}
///
/// Normalize an XQuery based on Data Service Configurations ...
///
///
///
///
public static XQuery NormalizeQuery(
this XQuery source,
XDataServiceConfiguration configuration //
)
{
//
if (source.IsNull())
{
source = new XQuery();
}
//
// Page Size Normalization ...
if (source.PageSize < configuration.PagingConfiguration.MinAvailablePageSize)
{
source.PageSize = configuration.PagingConfiguration.MinAvailablePageSize;
}
if (source.PageSize > configuration.PagingConfiguration.MaxAvailablePageSize)
{
source.PageSize = configuration.PagingConfiguration.MaxAvailablePageSize;
}
//
return source;
}
}
}
### FILE: C:\Users\SaherElm\Documents\Projects\xSaherelmWorkspace\Modules\xDataService\Extensions\XDatabaseDescriptorExtensions.cs
using xCommons.Extensions;
using xDataService.Constants;
using xDataService.Models;
namespace xDataService.Extensions
{
public static class XDatabaseDescriptorExtensions
{
///
/// Validate a Database Descriptor ...
///
///
///
public static bool IsValid(this XDatabaseDescriptor source)
{
//
var result =
!source.IsNull() &&
!source.Name.IsNullOrEmpty();
//
return result;
}
///
/// Chack a Descriptor Has Provider or not ...
///
///
///
public static bool HasProvider(this XDatabaseDescriptor source)
{
//
var result =
source.IsValid() &&
source.Provider != XDbProviders.None;
//
return result;
}
///
/// Check a Descriptor Has EF Core Context or not ...
///
///
///
public static bool HasContext(this XDatabaseDescriptor source)
{
//
var result =
source.IsValid() &&
source.HasProvider() &&
source.Provider != XDbProviders.MongoDB &&
!source.Context.IsNull();
//
return result;
}
///
/// Check a Descriptor Has Repositories or not ...
///
///
///
public static bool HasRepositories(this XDatabaseDescriptor source)
{
//
var result =
source.IsValid() &&
source.HasProvider() &&
!source.Repositories.IsNull() &&
source.Repositories.HasChild();
//
return result;
}
///
/// Check a Descriptor Has MongoDB Convention Packs ...
///
///
///
public static bool HasConventionPacks(this XDatabaseDescriptor source)
{
//
var result =
source.IsValid() &&
source.HasProvider() &&
source.Provider == XDbProviders.MongoDB &&
!source.ConventionPacks.IsNull();
//
return result;
}
}
}
### FILE: C:\Users\SaherElm\Documents\Projects\xSaherelmWorkspace\Modules\xDataService\Extensions\XDataServiceConfigurationExtensions.cs
using System.Linq;
using xCommons.Extensions;
using xDataService.Configuration;
using xDataService.Constants;
namespace xDataService.Extensions {
public static class XDataServiceConfigurationExtensions {
///
/// Extract Provider enum from Provider Type ...
///
///
///
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;
}
///
/// Retrieve Mongo URI from ConnectionString
///
///
///
public static string GetMongoDbURI (this XDataBaseConfiguration source) {
//
var parts = source.GetConnectionParts ();
var result = parts
.Where (p => p.Trim ().StartsWith ("Uri="))
.FirstOrDefault ();
result = result.Replace ("Uri=", "").Trim ();
//
return result;
}
///
/// Retrieve Mongo Database Name from Connaction string
///
///
///
public static string GetMongoDbDatabase (this XDataBaseConfiguration 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 XDataBaseConfiguration source) {
//
var result = source.ConnectionString.Split (';');
//
return result;
}
#endregion
}
}
### FILE: C:\Users\SaherElm\Documents\Projects\xSaherelmWorkspace\Modules\xDataService\Extensions\XGraphQLExtensions.cs
using GraphQL;
using GraphQL.Types;
using xDataService.Constants;
using xModels.Dtos;
namespace xDataService.Extensions {
public static class XGraphQLExtensions {
public static TKey GetIdArgument (this IResolveFieldContext