diff --git a/src/Swastika/Common/Helper/CommonHelper.cs b/src/Swastika/Common/Helper/CommonHelper.cs
index 278b515..20b033c 100644
--- a/src/Swastika/Common/Helper/CommonHelper.cs
+++ b/src/Swastika/Common/Helper/CommonHelper.cs
@@ -302,31 +302,35 @@ public static void WriteBytesToFile(string fullPath, string strBase64)
}
}
- //TODO: Still need?
- //public static string UploadPhoto(string fullPath, Image img)
- //{
- // try
- // {
- // if (!Directory.Exists(fullPath))
- // {
- // Directory.CreateDirectory(fullPath);
- // }
+ public static string ConvertCaseString(string phrase, Case cases)
+ {
+ string[] splittedPhrase = phrase.Split(' ', '-', '.');
+ var sb = new StringBuilder();
- // if (img != null)
- // {
- // //string fileExt = GetFilenameExtension(img.RawFormat);
- // //file_name = (guid + fileExt).Trim();
- // //file_dir = filePath + file_name;
- // //ImageResizer.ResizeStream(TTXConstants.Params.photoSize, img, file_dir);
+ if (cases == Case.CamelCase)
+ {
+ //splittedPhrase[0] = string.Empty;
+ }
+ else if (cases == Case.PascalCase)
+ sb.Append(splittedPhrase[0].ToLower());
+
- // return ImageHelper.ResizeImage(img, fullPath);
- // }
- // }
- // catch (Exception ex) // TODO: Add more specific exeption types instead of Exception only
- // {
- // return string.Empty;
- // }
- // return string.Empty;
- //}
+ foreach (String s in splittedPhrase)
+ {
+ char[] splittedPhraseChars = s.ToCharArray();
+ if (splittedPhraseChars.Length > 0)
+ {
+ splittedPhraseChars[0] = ((new String(splittedPhraseChars[0], 1)).ToUpper().ToCharArray())[0];
+ }
+ sb.Append(new String(splittedPhraseChars));
+ }
+ return sb.ToString();
+ }
+
+ public enum Case
+ {
+ PascalCase,
+ CamelCase
+ }
}
}
diff --git a/src/Swastika/Domain/Core/Repository/DefaultEcmRepositories.cs b/src/Swastika/Domain/Core/Repository/DefaultEcmRepositories.cs
new file mode 100644
index 0000000..c5b7eef
--- /dev/null
+++ b/src/Swastika/Domain/Core/Repository/DefaultEcmRepositories.cs
@@ -0,0 +1,61 @@
+// Licensed to the Swastika I/O Foundation under one or more agreements.
+// The Swastika I/O Foundation licenses this file to you under the GNU General Public License v3.0.
+// See the LICENSE file in the project root for more information.
+
+using Microsoft.EntityFrameworkCore;
+using System;
+
+namespace Swastika.Domain.Data.Repository
+{
+ ///
+ /// Default Repository with view
+ ///
+ /// The type of the database context.
+ /// The type of the model.
+ /// The type of the view.
+ ///
+ public class EcmDefaultRepository :
+ Swastika.Domain.Data.Repository.EcmViewRepositoryBase
+ where TDbContext : DbContext
+ where TModel : class
+ where TView : Swastika.Domain.Data.ViewModels.EcmViewModelBase
+ {
+ ///
+ /// The instance
+ ///
+ private static volatile EcmDefaultRepository instance;
+
+ ///
+ /// The synchronize root
+ ///
+ private static readonly object syncRoot = new Object();
+
+ ///
+ /// Prevents a default instance of the class from being created.
+ ///
+ private EcmDefaultRepository()
+ {
+ }
+
+ ///
+ /// Gets the instance.
+ ///
+ ///
+ /// The instance.
+ ///
+ public static EcmDefaultRepository Instance {
+ get {
+ if (instance == null)
+ {
+ lock (syncRoot)
+ {
+ if (instance == null)
+ instance = new EcmDefaultRepository();
+ }
+ }
+
+ return instance;
+ }
+ }
+ }
+}
diff --git a/src/Swastika/Domain/Core/Repository/ViewEcmRepositoryBase.cs b/src/Swastika/Domain/Core/Repository/ViewEcmRepositoryBase.cs
new file mode 100644
index 0000000..764acf3
--- /dev/null
+++ b/src/Swastika/Domain/Core/Repository/ViewEcmRepositoryBase.cs
@@ -0,0 +1,1668 @@
+// Licensed to the Swastika I/O Foundation under one or more agreements.
+// The Swastika I/O Foundation licenses this file to you under the GNU General Public License v3.0.
+// See the LICENSE file in the project root for more information.
+
+using AutoMapper;
+using Microsoft.Data.OData.Query;
+using Microsoft.EntityFrameworkCore;
+using Microsoft.EntityFrameworkCore.Storage;
+using Swastika.Common.Helper;
+using Swastika.Domain.Core.ViewModels;
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Linq.Expressions;
+using System.Reflection;
+using System.Threading.Tasks;
+
+namespace Swastika.Domain.Data.Repository
+{
+ ///
+ /// View Repository Base
+ ///
+ /// The type of the database context.
+ /// The type of the model.
+ /// The type of the view.
+ public abstract class EcmViewRepositoryBase
+ where TDbContext : DbContext
+ where TModel : class
+ where TView : ViewModels.EcmViewModelBase
+ {
+ ///
+ /// Initializes a new instance of the class.
+ ///
+ protected EcmViewRepositoryBase()
+ {
+ //RegisterAutoMapper();
+ }
+
+ ///
+ /// Checks the is exists.
+ ///
+ /// The entity.
+ /// The context.
+ /// The transaction.
+ ///
+ public virtual bool CheckIsExists(TModel entity, TDbContext _context = null, IDbContextTransaction _transaction = null)
+ {
+ UnitOfWorkHelper.InitTransaction(_context, _transaction, out TDbContext context, out IDbContextTransaction transaction, out bool isRoot);
+ try
+ {
+ //For the former case use:
+ return context.Set().Any(e => e == entity);
+
+ //For the latter case use(it will check loaded entities as well):
+ //return (_context.Set().Find(keys) != null);
+ }
+ catch (Exception ex) // TODO: Add more specific exeption types instead of Exception only
+ {
+ LogErrorMessage(ex);
+ if (isRoot)
+ {
+ transaction.Rollback();
+ }
+ return false;
+ }
+ finally
+ {
+ if (isRoot)
+ {
+ //if current Context is Root
+ transaction.Dispose();
+ context.Dispose();
+ }
+ }
+ }
+
+ ///
+ /// Checks the is exists.
+ ///
+ /// The predicate.
+ /// The context.
+ /// The transaction.
+ ///
+ public bool CheckIsExists(System.Func predicate, TDbContext _context = null, IDbContextTransaction _transaction = null)
+ {
+ UnitOfWorkHelper.InitTransaction(_context, _transaction, out TDbContext context, out IDbContextTransaction transaction, out bool isRoot);
+ try
+ {
+ //For the former case use:
+ return context.Set().Any(predicate);
+
+ //For the latter case use(it will check loaded entities as well):
+ //return (_context.Set().Find(keys) != null);
+ }
+ catch (Exception ex) // TODO: Add more specific exeption types instead of Exception only
+ {
+ LogErrorMessage(ex);
+ if (isRoot)
+ {
+ transaction.Rollback();
+ }
+ return false;
+ }
+ finally
+ {
+ if (isRoot)
+ {
+ //if current Context is Root
+ transaction.Dispose();
+ context.Dispose();
+ }
+ }
+ }
+
+ ///
+ /// Creates the model.
+ ///
+ /// The view.
+ /// The context.
+ /// The transaction.
+ ///
+ public virtual RepositoryResponse CreateModel(TView view
+ , TDbContext _context = null, IDbContextTransaction _transaction = null)
+ {
+ bool isRoot = _context == null;
+ TDbContext context = _context ?? InitContext();
+ var transaction = _transaction ?? context.Database.BeginTransaction();
+ RepositoryResponse result = new RepositoryResponse() { IsSucceed = true };
+ try
+ {
+ context.Entry(view.Model).State = EntityState.Added;
+ result.IsSucceed = context.SaveChanges() > 0;
+ result.Data = view;
+ UnitOfWorkHelper.HandleTransaction(result.IsSucceed, isRoot, transaction);
+ return result;
+ }
+ catch (Exception ex) // TODO: Add more specific exeption types instead of Exception only
+ {
+ LogErrorMessage(ex);
+ result.IsSucceed = false;
+ result.Exception = ex;
+ if (isRoot)
+ {
+ transaction.Rollback();
+ }
+ return result;
+ }
+ finally
+ {
+ if (isRoot)
+ {
+ //if current Context is Root
+ transaction.Dispose();
+ context.Dispose();
+ }
+ }
+ }
+
+ ///
+ /// Creates the model asynchronous.
+ ///
+ /// The view.
+ /// The context.
+ /// The transaction.
+ ///
+ public virtual async Task> CreateModelAsync(TView view
+ , TDbContext _context = null, IDbContextTransaction _transaction = null)
+ {
+ UnitOfWorkHelper.InitTransaction(_context, _transaction, out TDbContext context, out IDbContextTransaction transaction, out bool isRoot);
+ RepositoryResponse result = new RepositoryResponse() { IsSucceed = true };
+ try
+ {
+ context.Entry(view.Model).State = EntityState.Added;
+ result.IsSucceed = await context.SaveChangesAsync().ConfigureAwait(false) > 0;
+ result.Data = view;
+ UnitOfWorkHelper.HandleTransaction(result.IsSucceed, isRoot, transaction);
+ return result;
+ }
+ catch (Exception ex) // TODO: Add more specific exeption types instead of Exception only
+ {
+ return UnitOfWorkHelper.HandleException(ex, isRoot, transaction);
+ }
+ finally
+ {
+ if (isRoot)
+ {
+ //if current Context is Root
+ transaction.Dispose();
+ context.Dispose();
+ }
+ }
+ }
+
+ ///
+ /// Edits the model.
+ ///
+ /// The view.
+ /// The context.
+ /// The transaction.
+ ///
+ public virtual RepositoryResponse EditModel(TView view
+ , TDbContext _context = null, IDbContextTransaction _transaction = null)
+ {
+ UnitOfWorkHelper.InitTransaction(_context, _transaction, out TDbContext context, out IDbContextTransaction transaction, out bool isRoot);
+ RepositoryResponse result = new RepositoryResponse() { IsSucceed = true };
+ try
+ {
+ //context.Entry(view.Model).State = EntityState.Modified;
+ context.Set().Update(view.Model);
+ result.IsSucceed = context.SaveChanges() > 0;
+ result.Data = view;
+ UnitOfWorkHelper.HandleTransaction(result.IsSucceed, isRoot, transaction);
+
+ return result;
+ }
+ catch (Exception ex) // TODO: Add more specific exeption types instead of Exception only
+ {
+ return UnitOfWorkHelper.HandleException(ex, isRoot, transaction);
+ }
+ finally
+ {
+ if (isRoot)
+ {
+ //if current Context is Root
+ transaction.Dispose();
+ context.Dispose();
+ }
+ }
+ }
+
+ ///
+ /// Edits the model asynchronous.
+ ///
+ /// The view.
+ /// The context.
+ /// The transaction.
+ ///
+ public virtual async Task> EditModelAsync(TView view, TDbContext _context = null, IDbContextTransaction _transaction = null)
+ {
+ UnitOfWorkHelper.InitTransaction(_context, _transaction, out TDbContext context, out IDbContextTransaction transaction, out bool isRoot);
+ RepositoryResponse result = new RepositoryResponse() { IsSucceed = true };
+ try
+ {
+ //context.Entry(view.Model).State = EntityState.Modified;
+ context.Set().Update(view.Model);
+ result.IsSucceed = await context.SaveChangesAsync().ConfigureAwait(false) > 0;
+ result.Data = view;
+ UnitOfWorkHelper.HandleTransaction(result.IsSucceed, isRoot, transaction);
+ return result;
+ }
+ catch (Exception ex) // TODO: Add more specific exeption types instead of Exception only
+ {
+ return UnitOfWorkHelper.HandleException(ex, isRoot, transaction);
+ }
+ finally
+ {
+ if (isRoot)
+ {
+ //if current Context is Root
+ context.Dispose();
+ }
+ }
+ }
+
+ ///
+ /// Gets the single model.
+ ///
+ /// The predicate.
+ /// The context.
+ /// The transaction.
+ ///
+ public virtual RepositoryResponse GetSingleModel(
+ Expression> predicate
+ , TDbContext _context = null, IDbContextTransaction _transaction = null)
+ {
+ UnitOfWorkHelper.InitTransaction(_context, _transaction, out TDbContext context, out IDbContextTransaction transaction, out bool isRoot);
+ try
+ {
+ context = _context ?? InitContext();
+ transaction = _transaction ?? context.Database.BeginTransaction();
+
+ TModel model = context.Set().SingleOrDefault(predicate);
+ if (model != null)
+ {
+ context.Entry(model).State = EntityState.Detached;
+ var viewResult = ParseView(model, context, transaction);
+ return new RepositoryResponse()
+ {
+ IsSucceed = true,
+ Data = viewResult
+ };
+ }
+ else
+ {
+ return new RepositoryResponse()
+ {
+ IsSucceed = false,
+ Data = default
+ };
+ }
+ }
+ catch (Exception ex) // TODO: Add more specific exeption types instead of Exception only
+ {
+ return UnitOfWorkHelper.HandleException(ex, isRoot, transaction);
+ }
+ finally
+ {
+ if (isRoot)
+ {
+ //if current Context is Root
+ context?.Dispose();
+ }
+ }
+ }
+
+ ///
+ /// Gets the single model asynchronous.
+ ///
+ /// The predicate.
+ /// The context.
+ /// The transaction.
+ ///
+ public virtual async Task> GetSingleModelAsync(
+ Expression> predicate
+ , TDbContext _context = null, IDbContextTransaction _transaction = null)
+ {
+ UnitOfWorkHelper.InitTransaction(_context, _transaction, out TDbContext context, out IDbContextTransaction transaction, out bool isRoot);
+ try
+ {
+ TModel model = await context.Set().SingleOrDefaultAsync(predicate).ConfigureAwait(false);
+ if (model != null)
+ {
+ context.Entry(model).State = EntityState.Detached;
+
+ var viewResult = ParseView(model, context, transaction);
+ return new RepositoryResponse()
+ {
+ IsSucceed = true,
+ Data = viewResult
+ };
+ }
+ else
+ {
+ return new RepositoryResponse()
+ {
+ IsSucceed = false,
+ Data = default
+ };
+ }
+ }
+ catch (Exception ex) // TODO: Add more specific exeption types instead of Exception only
+ {
+ return UnitOfWorkHelper.HandleException(ex, isRoot, transaction);
+ }
+ finally
+ {
+ if (isRoot)
+ {
+ //if current Context is Root
+ context.Dispose();
+ }
+ }
+ }
+
+ ///
+ /// Initializes the context.
+ ///
+ ///
+ public virtual TDbContext InitContext()
+ {
+ Type classType = typeof(TDbContext);
+ ConstructorInfo classConstructor = classType.GetConstructor(new Type[] { });
+ TDbContext context = (TDbContext)classConstructor.Invoke(new object[] { });
+
+ return context;
+ }
+
+ ///
+ /// Logs the error message. User.Claims.ToList() error CS0103: The name 'User' does not exist in the current context
+ ///
+ /// The ex.
+ public virtual void LogErrorMessage(Exception ex)
+ {
+ }
+
+ ///
+ /// Parses the paging query.
+ ///
+ /// The query.
+ /// Name of the order by property.
+ /// The direction.
+ /// Size of the page.
+ /// Index of the page.
+ /// The context.
+ /// The transaction.
+ ///
+ public virtual PaginationModel ParsePagingQuery(IQueryable query
+ , string orderByPropertyName, int direction
+ , int? pageSize, int? pageIndex
+ , TDbContext context, IDbContextTransaction transaction)
+ {
+ List lstModel = new List();
+
+ PaginationModel result = new PaginationModel()
+ {
+ TotalItems = query.Count(),
+ PageIndex = pageIndex ?? 0
+ };
+ dynamic orderBy = GetLambda(CommonHelper.ConvertCaseString(orderByPropertyName, CommonHelper.Case.CamelCase));
+ IQueryable sorted = null;
+ try
+ {
+ result.PageSize = pageSize ?? result.TotalItems;
+
+ if (pageSize.HasValue)
+ {
+ result.TotalPage = (result.TotalItems / pageSize.Value) + (result.TotalItems % pageSize.Value > 0 ? 1 : 0);
+ }
+
+ switch (direction)
+ {
+ case 1:
+ sorted = Queryable.OrderByDescending(query, orderBy);
+ if (pageSize.HasValue)
+ {
+ lstModel = sorted.Skip(pageIndex.Value * pageSize.Value)
+ .Take(pageSize.Value)
+ .ToList();
+ }
+ else
+ {
+ lstModel = sorted.ToList();
+ }
+ break;
+
+ default:
+ sorted = Queryable.OrderBy(query, orderBy);
+ if (pageSize.HasValue)
+ {
+ lstModel = sorted
+ .Skip(pageIndex.Value * pageSize.Value)
+ .Take(pageSize.Value)
+ .ToList();
+ }
+ else
+ {
+ lstModel = sorted.ToList();
+ }
+ break;
+ }
+ lstModel.ForEach(model => context.Entry(model).State = EntityState.Detached);
+ var lstView = ParseView(lstModel, context, transaction);
+ result.Items = lstView;
+ return result;
+ }
+ catch (Exception ex) // TODO: Add more specific exeption types instead of Exception only
+ {
+ LogErrorMessage(ex);
+ return null;
+ }
+ }
+
+ ///
+ /// Parses the paging query asynchronous.
+ ///
+ /// The query.
+ /// Name of the order by property.
+ /// The direction.
+ /// Size of the page.
+ /// Index of the page.
+ /// The context.
+ /// The transaction.
+ ///
+ public virtual async Task> ParsePagingQueryAsync(IQueryable query
+ , string orderByPropertyName, int direction
+ , int? pageSize, int? pageIndex
+ , TDbContext context, IDbContextTransaction transaction)
+ {
+ List lstModel = new List();
+
+ PaginationModel result = new PaginationModel()
+ {
+ TotalItems = query.Count(),
+ PageIndex = pageIndex ?? 0
+ };
+ dynamic orderBy = GetLambda(CommonHelper.ConvertCaseString(orderByPropertyName, CommonHelper.Case.CamelCase));
+ IQueryable sorted = null;
+ try
+ {
+ result.PageSize = pageSize ?? result.TotalItems;
+
+ if (pageSize.HasValue)
+ {
+ result.TotalPage = (result.TotalItems / pageSize.Value) + (result.TotalItems % pageSize.Value > 0 ? 1 : 0);
+ }
+
+ switch (direction)
+ {
+ case 1:
+ sorted = Queryable.OrderByDescending(query, orderBy);
+ if (pageSize.HasValue)
+ {
+ lstModel = await sorted.Skip(pageIndex.Value * pageSize.Value)
+ .Take(pageSize.Value)
+ .ToListAsync().ConfigureAwait(false);
+ }
+ else
+ {
+ lstModel = sorted.ToList();
+ }
+ break;
+
+ default:
+ sorted = Queryable.OrderBy(query, orderBy);
+ if (pageSize.HasValue)
+ {
+ lstModel = await sorted
+ .Skip(pageIndex.Value * pageSize.Value)
+ .Take(pageSize.Value)
+ .ToListAsync().ConfigureAwait(false);
+ }
+ else
+ {
+ lstModel = await sorted.ToListAsync().ConfigureAwait(false);
+ }
+ break;
+ }
+ lstModel.ForEach(model => context.Entry(model).State = EntityState.Detached);
+ var lstView = ParseView(lstModel, context, transaction);
+ result.Items = lstView;
+ return result;
+ }
+ catch (Exception ex) // TODO: Add more specific exeption types instead of Exception only
+ {
+ LogErrorMessage(ex);
+ return null;
+ }
+ }
+
+ ///
+ /// Parses the view.
+ ///
+ /// The LST models.
+ /// The context.
+ /// The transaction.
+ ///
+ public virtual List ParseView(List lstModels, TDbContext _context = null, IDbContextTransaction _transaction = null)
+ {
+ List lstView = new List();
+ foreach (var model in lstModels)
+ {
+ lstView.Add(ParseView(model, _context, _transaction));
+ }
+
+ return lstView;
+ }
+
+ ///
+ /// Parses the view.
+ ///
+ /// The model.
+ /// The context.
+ /// The transaction.
+ ///
+ public virtual TView ParseView(TModel model, TDbContext _context = null, IDbContextTransaction _transaction = null)
+ {
+ Type classType = typeof(TView);
+ ConstructorInfo classConstructor = classType.GetConstructor(new Type[] { model.GetType(), typeof(TDbContext), typeof(IDbContextTransaction) });
+ if (classConstructor != null)
+ {
+ return (TView)classConstructor.Invoke(new object[] { model, _context, _transaction });
+ }
+ else
+ {
+ classConstructor = classType.GetConstructor(new Type[] { model.GetType() });
+ return (TView)classConstructor.Invoke(new object[] { model });
+ }
+ }
+
+ ///
+ /// Registers the automatic mapper.
+ ///
+ public virtual void RegisterAutoMapper()
+ {
+ Mapper.Initialize(cfg =>
+ {
+ cfg.CreateMap();
+ cfg.CreateMap();
+ });
+ }
+
+ #region GetModelList
+
+ ///
+ /// Gets the model list.
+ ///
+ /// The context.
+ /// The transaction.
+ ///
+ public virtual RepositoryResponse> GetModelList(TDbContext _context = null, IDbContextTransaction _transaction = null)
+ {
+ bool isRoot = _context == null;
+ var context = _context ?? InitContext();
+ var transaction = _transaction ?? context.Database.BeginTransaction();
+ List result = new List();
+ try
+ {
+ var lstModel = context.Set().ToList();
+
+ lstModel.ForEach(model => context.Entry(model).State = EntityState.Detached);
+ result = ParseView(lstModel, context, transaction);
+ return new RepositoryResponse>()
+ {
+ IsSucceed = true,
+ Data = result
+ };
+ }
+ catch (Exception ex) // TODO: Add more specific exeption types instead of Exception only
+ {
+ return UnitOfWorkHelper.HandleException>(ex, isRoot, transaction);
+ }
+ finally
+ {
+ if (isRoot)
+ {
+ //if current Context is Root
+ context.Dispose();
+ }
+ }
+ }
+
+ ///
+ /// Gets the model list.
+ ///
+ /// Name of the order by property.
+ /// The direction.
+ /// Size of the page.
+ /// Index of the page.
+ /// The context.
+ /// The transaction.
+ ///
+ public virtual RepositoryResponse> GetModelList(
+ string orderByPropertyName, int direction, int? pageSize, int? pageIndex
+ , TDbContext _context = null, IDbContextTransaction _transaction = null)
+ {
+ bool isRoot = _context == null;
+ var context = _context ?? InitContext();
+ var transaction = _transaction ?? context.Database.BeginTransaction();
+
+ try
+ {
+ var query = context.Set();
+
+ var result = ParsePagingQuery(query, orderByPropertyName, direction, pageSize, pageIndex
+ , context, transaction);
+
+ return new RepositoryResponse>()
+ {
+ IsSucceed = true,
+ Data = result
+ };
+ }
+ catch (Exception ex) // TODO: Add more specific exeption types instead of Exception only
+ {
+ return UnitOfWorkHelper.HandleException>(ex, isRoot, transaction);
+ }
+ finally
+ {
+ if (isRoot)
+ {
+ //if current Context is Root
+ context.Dispose();
+ }
+ }
+ }
+
+ ///
+ /// Gets the model list asynchronous.
+ ///
+ /// The context.
+ /// The transaction.
+ ///
+ public virtual async Task>> GetModelListAsync(TDbContext _context = null, IDbContextTransaction _transaction = null)
+ {
+ bool isRoot = _context == null;
+ var context = _context ?? InitContext();
+ var transaction = _transaction ?? context.Database.BeginTransaction();
+ List result = new List();
+ try
+ {
+ var lstModel = await context.Set().ToListAsync().ConfigureAwait(false);
+
+ lstModel.ForEach(model => context.Entry(model).State = EntityState.Detached);
+ result = ParseView(lstModel, _context, _transaction);
+ return new RepositoryResponse>()
+ {
+ IsSucceed = true,
+ Data = result
+ };
+ }
+ catch (Exception ex) // TODO: Add more specific exeption types instead of Exception only
+ {
+ return UnitOfWorkHelper.HandleException>(ex, isRoot, transaction);
+ }
+ finally
+ {
+ if (isRoot)
+ {
+ //if current Context is Root
+ context.Dispose();
+ }
+ }
+ }
+
+ ///
+ /// Gets the model list asynchronous.
+ ///
+ /// Name of the order by property.
+ /// The direction.
+ /// Size of the page.
+ /// Index of the page.
+ /// The context.
+ /// The transaction.
+ ///
+ public virtual async Task>> GetModelListAsync(
+ string orderByPropertyName, int direction, int? pageSize, int? pageIndex
+ , TDbContext _context = null, IDbContextTransaction _transaction = null)
+ {
+ bool isRoot = _context == null;
+ var context = _context ?? InitContext();
+ var transaction = _transaction ?? context.Database.BeginTransaction();
+
+ try
+ {
+ var query = context.Set();
+
+ var result = await ParsePagingQueryAsync(query, orderByPropertyName, direction, pageSize, pageIndex, context, transaction).ConfigureAwait(false);
+ return new RepositoryResponse>()
+ {
+ IsSucceed = true,
+ Data = result
+ };
+ }
+ catch (Exception ex) // TODO: Add more specific exeption types instead of Exception only
+ {
+ return UnitOfWorkHelper.HandleException>(ex, isRoot, transaction);
+ }
+ finally
+ {
+ if (isRoot)
+ {
+ //if current Context is Root
+ context.Dispose();
+ }
+ }
+ }
+
+ #endregion GetModelList
+
+ #region GetModelListBy
+
+ ///
+ /// Gets the model list by.
+ ///
+ /// The predicate.
+ /// The context.
+ /// The transaction.
+ ///
+ public virtual RepositoryResponse> GetModelListBy(Expression> predicate
+ , TDbContext _context = null, IDbContextTransaction _transaction = null)
+ {
+ UnitOfWorkHelper.InitTransaction(_context, _transaction, out TDbContext context, out IDbContextTransaction transaction, out bool isRoot);
+ try
+ {
+ var lstModel = context.Set().Where(predicate).ToList();
+ lstModel.ForEach(model => context.Entry(model).State = EntityState.Detached);
+ var lstViewResult = ParseView(lstModel, _context, _transaction);
+ return new RepositoryResponse>()
+ {
+ IsSucceed = true,
+ Data = lstViewResult
+ };
+ }
+ catch (Exception ex) // TODO: Add more specific exeption types instead of Exception only
+ {
+ return UnitOfWorkHelper.HandleException>(ex, isRoot, transaction);
+ }
+ finally
+ {
+ if (isRoot)
+ {
+ //if current Context is Root
+ context.Dispose();
+ }
+ }
+ }
+
+ ///
+ /// Gets the model list by.
+ ///
+ /// The predicate.
+ /// Name of the order by property.
+ /// The direction.
+ /// Size of the page.
+ /// Index of the page.
+ /// The context.
+ /// The transaction.
+ ///
+ public virtual RepositoryResponse> GetModelListBy(
+ Expression> predicate, string orderByPropertyName, int direction, int? pageSize, int? pageIndex
+ , TDbContext _context = null, IDbContextTransaction _transaction = null)
+ {
+ UnitOfWorkHelper.InitTransaction(_context, _transaction, out TDbContext context, out IDbContextTransaction transaction, out bool isRoot);
+ try
+ {
+ var query = context.Set().Where(predicate);
+ var result = ParsePagingQuery(query
+ , orderByPropertyName, direction
+ , pageSize, pageIndex
+ , context, transaction);
+ return new RepositoryResponse>()
+ {
+ IsSucceed = true,
+ Data = result
+ };
+ }
+ catch (Exception ex) // TODO: Add more specific exeption types instead of Exception only
+ {
+ return UnitOfWorkHelper.HandleException>(ex, isRoot, transaction);
+ }
+ finally
+ {
+ if (isRoot)
+ {
+ //if current Context is Root
+ context.Dispose();
+ }
+ }
+ }
+
+ ///
+ /// Gets the model list by asynchronous.
+ ///
+ /// The predicate.
+ /// The context.
+ /// The transaction.
+ ///
+ public virtual async Task>> GetModelListByAsync(Expression> predicate
+ , TDbContext _context = null, IDbContextTransaction _transaction = null)
+ {
+ UnitOfWorkHelper.InitTransaction(_context, _transaction, out TDbContext context, out IDbContextTransaction transaction, out bool isRoot);
+
+ try
+ {
+ var query = context.Set().Where(predicate);
+ var lstModel = await query.ToListAsync().ConfigureAwait(false);
+ lstModel.ForEach(model => context.Entry(model).State = EntityState.Detached);
+ var result = ParseView(lstModel, _context, _transaction);
+ return new RepositoryResponse>()
+ {
+ IsSucceed = true,
+ Data = result
+ };
+ }
+ catch (Exception ex) // TODO: Add more specific exeption types instead of Exception only
+ {
+ return UnitOfWorkHelper.HandleException>(ex, isRoot, transaction);
+ }
+ finally
+ {
+ if (isRoot)
+ {
+ //if current Context is Root
+ context.Dispose();
+ }
+ }
+ }
+
+ ///
+ /// Gets the model list by asynchronous.
+ ///
+ /// The predicate.
+ /// Name of the order by property.
+ /// The direction.
+ /// Size of the page.
+ /// Index of the page.
+ /// The context.
+ /// The transaction.
+ ///
+ public virtual async Task>> GetModelListByAsync(
+ Expression> predicate, string orderByPropertyName
+ , int direction, int? pageSize, int? pageIndex
+ , TDbContext _context = null, IDbContextTransaction _transaction = null)
+ {
+ UnitOfWorkHelper.InitTransaction(_context, _transaction, out TDbContext context, out IDbContextTransaction transaction, out bool isRoot);
+ try
+ {
+ var query = context.Set().Where(predicate);
+
+ var result = await ParsePagingQueryAsync(query
+ , orderByPropertyName, direction
+ , pageSize, pageIndex
+ , context, transaction).ConfigureAwait(false);
+ return new RepositoryResponse>()
+ {
+ IsSucceed = true,
+ Data = result
+ };
+ }
+ catch (Exception ex) // TODO: Add more specific exeption types instead of Exception only
+ {
+ return UnitOfWorkHelper.HandleException>(ex, isRoot, transaction);
+ }
+ finally
+ {
+ if (isRoot)
+ {
+ //if current Context is Root
+ context.Dispose();
+ }
+ }
+ }
+
+ #endregion GetModelListBy
+
+ // TODO: Should return return enum status code instead
+ ///
+ /// Removes the list model.
+ ///
+ /// The predicate.
+ /// The context.
+ /// The transaction.
+ ///
+ public virtual RepositoryResponse> RemoveListModel(Expression> predicate
+ , TDbContext _context = null, IDbContextTransaction _transaction = null)
+ {
+ UnitOfWorkHelper.InitTransaction(_context, _transaction, out TDbContext context, out IDbContextTransaction transaction, out bool isRoot);
+ try
+ {
+ var Items = context.Set().Where(predicate).ToList();
+ bool result = true;
+ if (Items != null)
+ {
+ foreach (var model in Items)
+ {
+ if (result)
+ {
+ var r = RemoveModel(model, context, transaction);
+ result = result && r.IsSucceed;
+ }
+ else
+ {
+ break;
+ }
+ }
+
+ UnitOfWorkHelper.HandleTransaction(result, isRoot, transaction);
+
+ return new RepositoryResponse>()
+ {
+ IsSucceed = result,
+ Data = Items
+ };
+ }
+ else
+ {
+ return new RepositoryResponse>()
+ {
+ IsSucceed = result,
+ Data = Items
+ };
+ }
+ }
+ catch (Exception ex) // TODO: Add more specific exeption types instead of Exception only
+ {
+ return UnitOfWorkHelper.HandleException>(ex, isRoot, transaction);
+ }
+ finally
+ {
+ if (isRoot)
+ {
+ //if current Context is Root
+ context.Dispose();
+ }
+ }
+ }
+
+ // TODO: Should return return enum status code instead
+ ///
+ /// Removes the list model asynchronous.
+ ///
+ /// The predicate.
+ /// The context.
+ /// The transaction.
+ ///
+ public virtual async Task>> RemoveListModelAsync(Expression> predicate
+ , TDbContext _context = null, IDbContextTransaction _transaction = null)
+ {
+ UnitOfWorkHelper.InitTransaction(_context, _transaction, out TDbContext context, out IDbContextTransaction transaction, out bool isRoot);
+ try
+ {
+ var Items = await context.Set().Where(predicate).ToListAsync().ConfigureAwait(false);
+ bool result = true;
+ if (Items != null)
+ {
+ foreach (var model in Items)
+ {
+ if (result)
+ {
+ var r = await RemoveModelAsync(model, context, transaction).ConfigureAwait(false);
+ result = result && r.IsSucceed;
+ }
+ else
+ {
+ break;
+ }
+ }
+
+ UnitOfWorkHelper.HandleTransaction(result, isRoot, transaction);
+
+ return new RepositoryResponse>()
+ {
+ IsSucceed = result,
+ Data = Items
+ };
+ }
+ else
+ {
+ return new RepositoryResponse>()
+ {
+ IsSucceed = true,
+ Data = Items
+ };
+ }
+ }
+ catch (Exception ex) // TODO: Add more specific exeption types instead of Exception only
+ {
+ return UnitOfWorkHelper.HandleException>(ex, isRoot, transaction);
+ }
+ finally
+ {
+ if (isRoot)
+ {
+ //if current Context is Root
+ context.Dispose();
+ }
+ }
+ }
+
+ // TODO: Should return return enum status code instead
+ ///
+ /// Removes the model.
+ ///
+ /// The predicate.
+ /// The context.
+ /// The transaction.
+ ///
+ public virtual RepositoryResponse RemoveModel(Expression> predicate, TDbContext _context = null, IDbContextTransaction _transaction = null)
+ {
+ UnitOfWorkHelper.InitTransaction(_context, _transaction, out TDbContext context, out IDbContextTransaction transaction, out bool isRoot);
+ try
+ {
+ TModel model = context.Set().FirstOrDefault(predicate);
+ bool result = true;
+ if (model != null && CheckIsExists(model, context, transaction))
+ {
+ context.Entry(model).State = EntityState.Deleted;
+ result = context.SaveChanges() > 0;
+ }
+
+ UnitOfWorkHelper.HandleTransaction(result, isRoot, transaction);
+
+ return new RepositoryResponse()
+ {
+ IsSucceed = result,
+ Data = model
+ };
+ }
+ catch (Exception ex) // TODO: Add more specific exeption types instead of Exception only
+ {
+ return UnitOfWorkHelper.HandleException(ex, isRoot, transaction);
+ }
+ finally
+ {
+ if (isRoot)
+ {
+ //if current Context is Root
+ context.Dispose();
+ }
+ }
+ }
+
+ // TODO: Should return return enum status code instead
+ ///
+ /// Removes the model.
+ ///
+ /// The model.
+ /// The context.
+ /// The transaction.
+ ///
+ public virtual RepositoryResponse RemoveModel(TModel model, TDbContext _context = null, IDbContextTransaction _transaction = null)
+ {
+ UnitOfWorkHelper.InitTransaction(_context, _transaction, out TDbContext context, out IDbContextTransaction transaction, out bool isRoot);
+ try
+ {
+ bool result = true;
+ if (model != null && CheckIsExists(model, context, transaction))
+ {
+ context.Entry(model).State = EntityState.Deleted;
+ result = context.SaveChanges() > 0;
+ }
+
+ UnitOfWorkHelper.HandleTransaction(result, isRoot, transaction);
+
+ return new RepositoryResponse()
+ {
+ IsSucceed = result,
+ Data = model
+ };
+ }
+ catch (Exception ex) // TODO: Add more specific exeption types instead of Exception only
+ {
+ return UnitOfWorkHelper.HandleException(ex, isRoot, transaction);
+ }
+ finally
+ {
+ if (isRoot)
+ {
+ //if current Context is Root
+ context.Dispose();
+ }
+ }
+ }
+
+ // TODO: Should return return enum status code instead
+ ///
+ /// Removes the model asynchronous.
+ ///
+ /// The predicate.
+ /// The context.
+ /// The transaction.
+ ///
+ public virtual async Task> RemoveModelAsync(Expression> predicate, TDbContext _context = null, IDbContextTransaction _transaction = null)
+ {
+ UnitOfWorkHelper.InitTransaction(_context, _transaction, out TDbContext context, out IDbContextTransaction transaction, out bool isRoot);
+ try
+ {
+ TModel model = await context.Set().FirstOrDefaultAsync(predicate).ConfigureAwait(false);
+ bool result = true;
+ if (model != null && CheckIsExists(model, context, transaction))
+ {
+ context.Entry(model).State = EntityState.Deleted;
+ result = await context.SaveChangesAsync().ConfigureAwait(false) > 0;
+ }
+
+ UnitOfWorkHelper.HandleTransaction(result, isRoot, transaction);
+
+ return new RepositoryResponse()
+ {
+ IsSucceed = result,
+ Data = model
+ };
+ }
+ catch (Exception ex) // TODO: Add more specific exeption types instead of Exception only
+ {
+ return UnitOfWorkHelper.HandleException(ex, isRoot, transaction);
+ }
+ finally
+ {
+ if (isRoot)
+ {
+ //if current Context is Root
+ context.Dispose();
+ }
+ }
+ }
+
+ // TODO: Should return return enum status code instead
+ ///
+ /// Removes the model asynchronous.
+ ///
+ /// The model.
+ /// The context.
+ /// The transaction.
+ ///
+ public virtual async Task> RemoveModelAsync(TModel model, TDbContext _context = null, IDbContextTransaction _transaction = null)
+ {
+ UnitOfWorkHelper.InitTransaction(_context, _transaction, out TDbContext context, out IDbContextTransaction transaction, out bool isRoot);
+ try
+ {
+ bool result = true;
+ if (model != null && CheckIsExists(model, context, transaction))
+ {
+ context.Entry(model).State = EntityState.Deleted;
+ result = await context.SaveChangesAsync().ConfigureAwait(false) > 0;
+ }
+
+ UnitOfWorkHelper.HandleTransaction(result, isRoot, transaction);
+
+ return new RepositoryResponse()
+ {
+ IsSucceed = result,
+ Data = model
+ };
+ }
+ catch (Exception ex) // TODO: Add more specific exeption types instead of Exception only
+ {
+ return UnitOfWorkHelper.HandleException(ex, isRoot, transaction);
+ }
+ finally
+ {
+ if (isRoot)
+ {
+ //if current Context is Root
+ context.Dispose();
+ }
+ }
+ }
+
+ ///
+ /// Saves the model.
+ ///
+ /// The view.
+ /// if set to true [is save sub models].
+ /// The context.
+ /// The transaction.
+ ///
+ public virtual RepositoryResponse SaveModel(TView view, bool isSaveSubModels = false
+ , TDbContext _context = null, IDbContextTransaction _transaction = null)
+ {
+ if (CheckIsExists(view.Model, _context, _transaction))
+ {
+ return EditModel(view, _context, _transaction);
+ }
+ else
+ {
+ return CreateModel(view, _context, _transaction);
+ }
+ }
+
+ ///
+ /// Saves the model asynchronous.
+ ///
+ /// The view.
+ /// if set to true [is save sub models].
+ /// The context.
+ /// The transaction.
+ ///
+ public virtual Task> SaveModelAsync(TView view, bool isSaveSubModels = false
+ , TDbContext _context = null, IDbContextTransaction _transaction = null)
+ {
+ if (CheckIsExists(view.Model, _context, _transaction))
+ {
+ return EditModelAsync(view, _context, _transaction);
+ }
+ else
+ {
+ return CreateModelAsync(view, _context, _transaction);
+ }
+ }
+
+ ///
+ /// Saves the sub model asynchronous.
+ ///
+ /// The model.
+ /// The context.
+ /// The transaction.
+ ///
+ ///
+ public virtual Task SaveSubModelAsync(TModel model, TDbContext context, IDbContextTransaction _transaction)
+ {
+ throw new NotImplementedException();
+ }
+
+ #region Max
+
+ ///
+ /// Maximums the specified predicate.
+ ///
+ /// The predicate.
+ /// The context.
+ /// The transaction.
+ ///
+ public virtual RepositoryResponse Max(Expression> predicate
+ , TDbContext _context = null, IDbContextTransaction _transaction = null)
+ {
+ UnitOfWorkHelper.InitTransaction(_context, _transaction, out TDbContext context, out IDbContextTransaction transaction, out bool isRoot);
+ int total = 0;
+ var result = new RepositoryResponse()
+ {
+ IsSucceed = true,
+ Data = total
+ };
+ try
+ {
+ total = context.Set().Max(predicate);
+ result.Data = total;
+ return result;
+ }
+ catch (Exception ex) // TODO: Add more specific exeption types instead of Exception only
+ {
+ return UnitOfWorkHelper.HandleObjectException(ex, isRoot, transaction);
+ }
+ finally
+ {
+ if (isRoot)
+ {
+ //if current Context is Root
+ context.Dispose();
+ }
+ }
+ }
+
+ ///
+ /// Maximums the asynchronous.
+ ///
+ /// The predicate.
+ /// The context.
+ /// The transaction.
+ ///
+ public virtual async Task> MaxAsync(Expression> predicate
+ , TDbContext _context = null, IDbContextTransaction _transaction = null)
+ {
+ UnitOfWorkHelper.InitTransaction(_context, _transaction, out TDbContext context, out IDbContextTransaction transaction, out bool isRoot);
+ int total = 0;
+ try
+ {
+ total = await context.Set().MaxAsync(predicate).ConfigureAwait(false);
+ return new RepositoryResponse()
+ {
+ IsSucceed = true,
+ Data = total
+ };
+ }
+ catch (Exception ex) // TODO: Add more specific exeption types instead of Exception only
+ {
+ return UnitOfWorkHelper.HandleObjectException(ex, isRoot, transaction);
+ }
+ finally
+ {
+ if (isRoot)
+ {
+ //if current Context is Root
+ context.Dispose();
+ }
+ }
+ }
+
+ #endregion Max
+
+ #region Count
+
+ ///
+ /// Counts the specified predicate.
+ ///
+ /// The predicate.
+ /// The context.
+ /// The transaction.
+ ///
+ public virtual RepositoryResponse Count(Expression> predicate
+ , TDbContext _context = null, IDbContextTransaction _transaction = null)
+ {
+ UnitOfWorkHelper.InitTransaction(_context, _transaction, out TDbContext context, out IDbContextTransaction transaction, out bool isRoot);
+ int total = 0;
+ try
+ {
+ total = context.Set().Count(predicate);
+ return new RepositoryResponse()
+ {
+ IsSucceed = true,
+ Data = total
+ };
+ }
+ catch (Exception ex) // TODO: Add more specific exeption types instead of Exception only
+ {
+ return UnitOfWorkHelper.HandleObjectException(ex, isRoot, transaction);
+ }
+ finally
+ {
+ if (isRoot)
+ {
+ //if current Context is Root
+ context.Dispose();
+ }
+ }
+ }
+
+ ///
+ /// Counts the asynchronous.
+ ///
+ /// The predicate.
+ /// The context.
+ /// The transaction.
+ ///
+ public virtual async Task> CountAsync(Expression> predicate
+ , TDbContext _context = null, IDbContextTransaction _transaction = null)
+ {
+ UnitOfWorkHelper.InitTransaction(_context, _transaction, out TDbContext context, out IDbContextTransaction transaction, out bool isRoot);
+ int total = 0;
+ try
+ {
+ total = await context.Set().CountAsync(predicate).ConfigureAwait(false);
+ return new RepositoryResponse()
+ {
+ IsSucceed = true,
+ Data = total
+ };
+ }
+ catch (Exception ex) // TODO: Add more specific exeption types instead of Exception only
+ {
+ UnitOfWorkHelper.HandleException>(ex, isRoot, transaction);
+ return new RepositoryResponse()
+ {
+ IsSucceed = true,
+ Data = total
+ };
+ }
+ finally
+ {
+ if (isRoot)
+ {
+ //if current Context is Root
+ context.Dispose();
+ }
+ }
+ }
+
+ #endregion Count
+
+ #region Count
+
+ ///
+ /// Counts the specified context.
+ ///
+ /// The context.
+ /// The transaction.
+ ///
+ public virtual RepositoryResponse Count(TDbContext _context = null, IDbContextTransaction _transaction = null)
+ {
+ UnitOfWorkHelper.InitTransaction(_context, _transaction, out TDbContext context, out IDbContextTransaction transaction, out bool isRoot);
+ int total = 0;
+ try
+ {
+ total = context.Set().Count();
+ return new RepositoryResponse()
+ {
+ IsSucceed = true,
+ Data = total
+ };
+ }
+ catch (Exception ex) // TODO: Add more specific exeption types instead of Exception only
+ {
+ return UnitOfWorkHelper.HandleObjectException(ex, isRoot, transaction);
+ }
+ finally
+ {
+ if (isRoot)
+ {
+ //if current Context is Root
+ context.Dispose();
+ }
+ }
+ }
+
+ ///
+ /// Counts the asynchronous.
+ ///
+ /// The context.
+ /// The transaction.
+ ///
+ public virtual async Task> CountAsync(TDbContext _context = null, IDbContextTransaction _transaction = null)
+ {
+ UnitOfWorkHelper.InitTransaction(_context, _transaction, out TDbContext context, out IDbContextTransaction transaction, out bool isRoot);
+ int total = 0;
+ try
+ {
+ total = await context.Set().CountAsync().ConfigureAwait(false);
+ return new RepositoryResponse()
+ {
+ IsSucceed = true,
+ Data = total
+ };
+ }
+ catch (Exception ex) // TODO: Add more specific exeption types instead of Exception only
+ {
+ return UnitOfWorkHelper.HandleObjectException(ex, isRoot, transaction);
+ }
+ finally
+ {
+ if (isRoot)
+ {
+ //if current Context is Root
+ context.Dispose();
+ }
+ }
+ }
+
+ #endregion Count
+
+ #region Update Fields
+
+ ///
+ /// Updates the fields.
+ ///
+ /// The predicate.
+ /// The fields.
+ /// The context.
+ /// The transaction.
+ ///
+ public RepositoryResponse UpdateFields(Expression> predicate
+ , List fields
+ , TDbContext _context = null, IDbContextTransaction _transaction = null)
+ {
+ UnitOfWorkHelper.InitTransaction(_context, _transaction, out TDbContext context, out IDbContextTransaction transaction, out bool isRoot);
+ try
+ {
+ bool result = false;
+ TModel model = context.Set().FirstOrDefault(predicate);
+ if (model != null)
+ {
+ foreach (var field in fields)
+ {
+ field.PropertyName = CommonHelper.ConvertCaseString(field.PropertyName, CommonHelper.Case.CamelCase);
+ var lamda = GetLambda(field.PropertyName, false);
+ if (lamda != null)
+ {
+ var prop = context.Entry(model).Property(field.PropertyName);
+ if (DateTime.TryParse(field.PropertyValue, out DateTime dateValue))
+ {
+ prop.CurrentValue = dateValue;
+ }
+ else if (int.TryParse(field.PropertyValue, out int integerValue))
+ {
+ prop.CurrentValue = integerValue;
+ }
+ else
+ {
+ prop.CurrentValue = field.PropertyValue;
+ }
+
+ context.SaveChanges();
+ result = true;
+ }
+ else
+ {
+ result = false;
+ break;
+ }
+ }
+ }
+
+ UnitOfWorkHelper.HandleTransaction(result, isRoot, transaction);
+
+ return new RepositoryResponse()
+ {
+ IsSucceed = result,
+ Data = model
+ };
+ }
+ catch (Exception ex) // TODO: Add more specific exeption types instead of Exception only
+ {
+ return UnitOfWorkHelper.HandleException(ex, isRoot, transaction);
+ }
+ finally
+ {
+ if (isRoot)
+ {
+ //if current Context is Root
+ context.Dispose();
+ }
+ }
+ }
+
+ ///
+ /// Updates the fields asynchronous.
+ ///
+ /// The predicate.
+ /// The fields.
+ /// The context.
+ /// The transaction.
+ ///
+ public async Task> UpdateFieldsAsync(Expression> predicate
+ , List fields
+ , TDbContext _context = null, IDbContextTransaction _transaction = null)
+ {
+ UnitOfWorkHelper.InitTransaction(_context, _transaction, out TDbContext context, out IDbContextTransaction transaction, out bool isRoot);
+ try
+ {
+ bool result = false;
+ TModel model = await context.Set().FirstOrDefaultAsync(predicate).ConfigureAwait(false);
+ if (model != null)
+ {
+ foreach (var field in fields)
+ {
+ field.PropertyName = CommonHelper.ConvertCaseString(field.PropertyName, CommonHelper.Case.CamelCase);
+ var lamda = GetLambda(field.PropertyName, false);
+ if (lamda != null)
+ {
+ var prop = context.Entry(model).Property(field.PropertyName);
+ if (DateTime.TryParse(field.PropertyValue, out DateTime dateValue))
+ {
+ prop.CurrentValue = dateValue;
+ }
+ else if (int.TryParse(field.PropertyValue, out int integerValue))
+ {
+ prop.CurrentValue = integerValue;
+ }
+ else
+ {
+ prop.CurrentValue = field.PropertyValue;
+ }
+
+ await context.SaveChangesAsync().ConfigureAwait(false);
+ result = true;
+ }
+ else
+ {
+ result = false;
+ break;
+ }
+ }
+ }
+
+ UnitOfWorkHelper.HandleTransaction(result, isRoot, transaction);
+
+ return new RepositoryResponse
+ {
+ IsSucceed = result,
+ Data = model
+ };
+ }
+ catch (Exception ex) // TODO: Add more specific exeption types instead of Exception only
+ {
+ return UnitOfWorkHelper.HandleException(ex, isRoot, transaction);
+ }
+ finally
+ {
+ if (isRoot)
+ {
+ //if current Context is Root
+ context.Dispose();
+ }
+ }
+ }
+
+ #endregion Update Fields
+
+ ///
+ /// Gets the lambda.
+ ///
+ /// Name of the property.
+ /// if set to true [is get default].
+ ///
+ protected LambdaExpression GetLambda(string propName, bool isGetDefault = true)
+ {
+
+ var parameter = Expression.Parameter(typeof(TModel));
+ var type = typeof(TModel);
+ var prop = Array.Find(type.GetProperties(), p => p.Name.ToLower() == propName.ToLower());
+ if (prop == null && isGetDefault)
+ {
+ propName = type.GetProperties().FirstOrDefault()?.Name;
+ }
+ var memberExpression = Expression.Property(parameter, propName);
+ return Expression.Lambda(memberExpression, parameter);
+ }
+ }
+}
diff --git a/src/Swastika/Domain/Core/Repository/ViewRepositoryBase.cs b/src/Swastika/Domain/Core/Repository/ViewRepositoryBase.cs
index a4d8f5d..abc69c0 100644
--- a/src/Swastika/Domain/Core/Repository/ViewRepositoryBase.cs
+++ b/src/Swastika/Domain/Core/Repository/ViewRepositoryBase.cs
@@ -406,7 +406,7 @@ public virtual PaginationModel ParsePagingQuery(IQueryable query
TotalItems = query.Count(),
PageIndex = pageIndex ?? 0
};
- dynamic orderBy = GetLambda(orderByPropertyName);
+ dynamic orderBy = GetLambda(CommonHelper.ConvertCaseString(orderByPropertyName, CommonHelper.Case.CamelCase));
IQueryable sorted = null;
try
{
@@ -483,7 +483,7 @@ public virtual async Task> ParsePagingQueryAsync(IQueryab
TotalItems = query.Count(),
PageIndex = pageIndex ?? 0
};
- dynamic orderBy = GetLambda(orderByPropertyName);
+ dynamic orderBy = GetLambda(CommonHelper.ConvertCaseString(orderByPropertyName, CommonHelper.Case.CamelCase));
IQueryable sorted = null;
try
{
@@ -1520,6 +1520,7 @@ public RepositoryResponse UpdateFields(Expression> pr
{
foreach (var field in fields)
{
+ field.PropertyName = CommonHelper.ConvertCaseString(field.PropertyName, CommonHelper.Case.CamelCase);
var lamda = GetLambda(field.PropertyName, false);
if (lamda != null)
{
@@ -1591,6 +1592,7 @@ public async Task> UpdateFieldsAsync(Expression> UpdateFieldsAsync(Expression
protected LambdaExpression GetLambda(string propName, bool isGetDefault = true)
{
+
var parameter = Expression.Parameter(typeof(TModel));
var type = typeof(TModel);
- var prop = Array.Find(type.GetProperties(), p => p.Name == propName);
+ var prop = Array.Find(type.GetProperties(), p => p.Name.ToLower() == propName.ToLower());
if (prop == null && isGetDefault)
{
propName = type.GetProperties().FirstOrDefault()?.Name;
diff --git a/src/Swastika/Domain/Core/ViewModels/EcmViewModelBase.cs b/src/Swastika/Domain/Core/ViewModels/EcmViewModelBase.cs
new file mode 100644
index 0000000..0e04394
--- /dev/null
+++ b/src/Swastika/Domain/Core/ViewModels/EcmViewModelBase.cs
@@ -0,0 +1,657 @@
+// Licensed to the Swastika I/O Foundation under one or more agreements.
+// The Swastika I/O Foundation licenses this file to you under the GNU General Public License v3.0.
+// See the LICENSE file in the project root for more information.
+
+using AutoMapper;
+using Microsoft.EntityFrameworkCore;
+using Microsoft.EntityFrameworkCore.Storage;
+using Newtonsoft.Json;
+using Swastika.Common.Helper;
+using Swastika.Domain.Core.Models;
+using Swastika.Domain.Core.ViewModels;
+using Swastika.Domain.Data.Repository;
+using System;
+using System.Collections.Generic;
+using System.ComponentModel.DataAnnotations;
+using System.Linq;
+using System.Reflection;
+using System.Threading.Tasks;
+using static Swastika.Common.Utility.Enums;
+
+namespace Swastika.Domain.Data.ViewModels
+{
+ ///
+ ///
+ ///
+ /// The type of the database context.
+ /// The type of the model.
+ /// The type of the view.
+ public abstract class EcmViewModelBase
+ where TDbContext : DbContext
+ where TModel : class
+ where TView : EcmViewModelBase // instance of inherited
+ {
+ #region Properties
+
+ [JsonProperty("priority")]
+ public int Priority { get; set; }
+
+ ///
+ /// Returns true if ... is valid.
+ ///
+ private bool isValid = true;
+
+ ///
+ /// The mapper
+ ///
+ private IMapper _mapper;
+
+ ///
+ /// The model
+ ///
+ private TModel _model;
+
+ ///
+ /// The model mapper
+ ///
+ private IMapper _modelMapper;
+
+ [JsonIgnore]
+ public static readonly EcmDefaultRepository Repository;
+
+ static EcmViewModelBase()
+ {
+ Repository = EcmDefaultRepository.Instance;
+ }
+
+ ///
+ /// Gets or sets the exception.
+ ///
+ ///
+ /// The exception.
+ ///
+ [JsonIgnore]
+ public Exception Exception { get; set; }
+
+ ///
+ /// Gets or sets the mapper.
+ ///
+ ///
+ /// The mapper.
+ ///
+ [JsonIgnore]
+ public IMapper Mapper
+ {
+ get { return _mapper ?? (_mapper = this.CreateMapper()); }
+ set => _mapper = value;
+ }
+
+ ///
+ /// Gets or sets the model.
+ ///
+ ///
+ /// The model.
+ ///
+ [JsonIgnore]
+ public TModel Model
+ {
+ get
+ {
+ if (_model == null)
+ {
+ Type classType = typeof(TModel);
+ ConstructorInfo classConstructor = classType.GetConstructor(new Type[] { });
+ _model = (TModel)classConstructor.Invoke(new object[] { });
+ }
+ return _model;
+ }
+ set => _model = value;
+ }
+
+ ///
+ /// Gets or sets the model mapper.
+ ///
+ ///
+ /// The model mapper.
+ ///
+ [JsonIgnore]
+ public IMapper ModelMapper
+ {
+ get { return _modelMapper ?? (_modelMapper = this.CreateModelMapper()); }
+ set => _modelMapper = value;
+ }
+
+ ///
+ /// Creates the mapper.
+ ///
+ ///
+ private IMapper CreateMapper()
+ {
+ var config = new MapperConfiguration(cfg => cfg.CreateMap().ReverseMap());
+ var mapper = new Mapper(config);
+ return mapper;
+ }
+
+ ///
+ /// Creates the model mapper.
+ ///
+ ///
+ private IMapper CreateModelMapper()
+ {
+ var config = new MapperConfiguration(cfg => cfg.CreateMap().ReverseMap());
+ var mapper = new Mapper(config);
+ return mapper;
+ }
+
+ [JsonIgnore]
+ public List