using System; using System.Collections.Generic; using System.Linq; using Microsoft.EntityFrameworkCore; using AutoMapper; using System.Linq.Expressions; using TTSW.Common; using TodoAPI2.Models; using Microsoft.AspNetCore.Http; using IdentityModel; using Newtonsoft.Json; using System.Reflection; using System.Data; using System.ComponentModel.DataAnnotations; using TTSW.Utils; namespace TTSW.EF { public class BaseRepository : IBaseRepository where T : class, IBaseEntity { #region Private Variables private DataContext _context; private IMyDatabase _db; public DataContext Context { get { return _context; } } private IHttpContextAccessor _contextAccessor; private LoginProfile _loginProfile; #endregion #region Properties private DbSet _entities; public DbSet Entities { get { return _entities ?? (_entities = _context.Set()); } } #endregion public BaseRepository(DataContext context, IHttpContextAccessor contextAccessor, IMyDatabase mydatabase ) { _context = context; _contextAccessor = contextAccessor; _db = mydatabase; } #region Private Functions private bool SaveToDB() { return (_context.SaveChanges() >= 0); } private T SetCreatorProperties(T entity) { //entity.CreatorId = _userRepository.LoginProfile.Id; entity.created = DateTime.Now; return entity; } private T SetUpdatorProperties(T entity) { //entity.UpdatorId = _userRepository.LoginProfile.Id; entity.updated = DateTime.Now; return entity; } private T SetActiveProperty(T entity) { entity.isActive = true; return entity; } private T SetInActiveProperty(T entity) { entity.isActive = false; return entity; } #endregion #region Public Functions public LoginProfile GetLoginProfile() { // Set login profile in the 1st accessing time only // The user has to login to the system too. if (_loginProfile == null && _contextAccessor.HttpContext.User.Identity.IsAuthenticated) { var dict = new Dictionary(); // A list to keep list of all keys for getting user user claims var userProfileClaimsKey = new List(); userProfileClaimsKey.Add(JwtClaimTypes.GivenName); userProfileClaimsKey.Add(JwtClaimTypes.FamilyName); userProfileClaimsKey.Add(JwtClaimTypes.Email); userProfileClaimsKey.Add("customer_guid"); userProfileClaimsKey.Add("user_guid"); userProfileClaimsKey.Add("permission_level"); userProfileClaimsKey.Add("base_system"); userProfileClaimsKey.Add(JwtClaimTypes.Name); userProfileClaimsKey.Add(JwtClaimTypes.PreferredUserName); userProfileClaimsKey.Add(JwtClaimTypes.PhoneNumber); // Fetch only claims related to user profile _contextAccessor.HttpContext.User.Claims .Where(c=> userProfileClaimsKey.Contains(c.Type)).ToList() .ForEach(item => dict.Add(item.Type, item.Value)); // Map claims to model _loginProfile = new LoginProfile(); //if (dict.ContainsKey(JwtClaimTypes.Subject)) // _loginProfile.Id = dict[JwtClaimTypes.Subject]; if (dict.ContainsKey(JwtClaimTypes.GivenName) && !string.IsNullOrEmpty(dict[JwtClaimTypes.GivenName])) _loginProfile.FirstName = dict[JwtClaimTypes.GivenName]; if (dict.ContainsKey(JwtClaimTypes.FamilyName) && !string.IsNullOrEmpty(dict[JwtClaimTypes.FamilyName])) _loginProfile.LastName = dict[JwtClaimTypes.FamilyName]; if (dict.ContainsKey(JwtClaimTypes.Email) && !string.IsNullOrEmpty(dict[JwtClaimTypes.Email])) _loginProfile.Email = dict[JwtClaimTypes.Email]; if (dict.ContainsKey("customer_guid") && !string.IsNullOrEmpty(dict["customer_guid"])) _loginProfile.CustomerGUID = new Guid(dict["customer_guid"]); if (dict.ContainsKey("user_guid") && !string.IsNullOrEmpty(dict["user_guid"])) _loginProfile.UserGUID = new Guid(dict["user_guid"]); if (dict.ContainsKey("permission_level") && !string.IsNullOrEmpty(dict["permission_level"])) _loginProfile.permission_level = dict["permission_level"]; if (dict.ContainsKey("base_system") && !string.IsNullOrEmpty(dict["base_system"])) _loginProfile.base_system = dict["base_system"]; if (string.IsNullOrEmpty(_loginProfile.base_system)) { _loginProfile.base_system = ""; } if (dict.ContainsKey(JwtClaimTypes.Name) && !string.IsNullOrEmpty(dict[JwtClaimTypes.Name])) _loginProfile.UserName = dict[JwtClaimTypes.Name]; else if (dict.ContainsKey(JwtClaimTypes.PreferredUserName) && !string.IsNullOrEmpty(dict[JwtClaimTypes.PreferredUserName])) _loginProfile.UserName = dict[JwtClaimTypes.PreferredUserName]; if (dict.ContainsKey(JwtClaimTypes.PhoneNumber) && !string.IsNullOrEmpty(dict[JwtClaimTypes.PhoneNumber])) _loginProfile.PhoneNumber = dict[JwtClaimTypes.PhoneNumber]; } return _loginProfile; } #region Query Functions public T Get(Key id) { return Entities //.Include(c => c.Creator) //.Include(c => c.Updator) .FirstOrDefault(c=>c.id.Equals(id)); } public T Get(Key id, params Expression>[] includes) { var query = Entities.AsQueryable(); //Dynamic include columns foreach (var include in includes) query = query.Include(include); return query //.Include(c => c.Creator) //.Include(c => c.Updator) .FirstOrDefault(c => c.id.Equals(id)); } public IQueryable GetQuery() { return Entities.AsNoTracking(); } public List GetList(Expression> predicate) { var query = Entities .AsNoTracking() //.Include(c => c.Creator) //.Include(c => c.Updator) .Where(predicate); return query.ToList(); } public List GetList(Expression> predicate, params Expression>[] includes) { var query = Entities.AsQueryable(); //Dynamic include columns foreach (var include in includes) query = query.Include(include); query = query .AsNoTracking() //.Include(c => c.Creator) //.Include(c => c.Updator) .Where(predicate); return query.ToList(); } #endregion #region Manipulation Functions public T Insert(T entity) { var userLogin = GetLoginProfile(); entity = SetCreatorProperties(entity); entity = SetUpdatorProperties(entity); entity = SetActiveProperty(entity); var log = new activity_log(); log.attributes = entity; log.old = null; var log_message = Newtonsoft.Json.JsonConvert.SerializeObject(log); var activity_log = new activity_log_evaEntity(); activity_log.log_name = entity.GetType().Name.Replace("Entity", ""); activity_log.description = "Add " + entity.GetType().Name.Replace("Entity", ""); activity_log.subject_id = 0; activity_log.subject_type = entity.GetType().Name; activity_log.causer_id = Convert.ToInt32(_contextAccessor.HttpContext.Request.Cookies["user_id"]); activity_log.causer_type = @"App\Models\User"; activity_log.properties = log_message; activity_log.ip_address = _contextAccessor.HttpContext.Connection.RemoteIpAddress.ToString(); activity_log.mac_address = "N/A"; activity_log.created_at = DateTime.Now; activity_log.updated_at = activity_log.created_at; _context.Add(activity_log); var result = Entities.Add(entity); if(!SaveToDB()) throw new NotificationException($"Unable to add new item to database."); return Get(result.Entity.id); } public void Insert(IEnumerable list) { var userLogin = GetLoginProfile(); var insertedList = new List(); foreach(var entity in list) { var newItem = entity; newItem = SetCreatorProperties(newItem); newItem = SetUpdatorProperties(newItem); newItem = SetActiveProperty(newItem); insertedList.Add(newItem); } Entities.AddRange(insertedList); if (!SaveToDB()) throw new NotificationException($"Unable to insert item to database."); } public T Update(Key id, object model) { var userLogin = GetLoginProfile(); var existingItem = Get(id); object old_existingItem; try { var x = MyHelper.GetDataRow(id, model, _db); old_existingItem = MyHelper.GetObject(x, model.GetType().Name.Replace("Entity", "")); } catch(Exception ex) { old_existingItem = null; } if (existingItem == null) throw new NotificationException($"No item in database."); Mapper.Map(model, existingItem); var log = new activity_log(); log.attributes = existingItem; log.old = old_existingItem; var log_message = Newtonsoft.Json.JsonConvert.SerializeObject(log); var activity_log = new activity_log_evaEntity(); activity_log.log_name = existingItem.GetType().Name.Replace("Entity", ""); ; activity_log.description = "Update " + existingItem.GetType().Name.Replace("Entity", ""); ; activity_log.subject_id = 0; activity_log.subject_type = existingItem.GetType().Name; activity_log.causer_id = Convert.ToInt32(_contextAccessor.HttpContext.Request.Cookies["user_id"]); activity_log.causer_type = @"App\Models\User"; activity_log.properties = log_message; activity_log.ip_address = _contextAccessor.HttpContext.Connection.RemoteIpAddress.ToString(); activity_log.mac_address = "N/A"; activity_log.created_at = DateTime.Now; activity_log.updated_at = activity_log.created_at; _context.Add(activity_log); existingItem = SetUpdatorProperties(existingItem); if (!SaveToDB()) throw new NotificationException($"Unable to save item to database."); return existingItem; } public T SetAsInActive(Key id) { var userLogin = GetLoginProfile(); var existingItem = Get(id); if (existingItem == null) throw new NotificationException($"No item in database."); existingItem = SetUpdatorProperties(existingItem); existingItem = SetInActiveProperty(existingItem); if (!SaveToDB()) throw new NotificationException($"Unable to set item as inactive to database."); return existingItem; } public T SetAsActive(Key id) { var userLogin = GetLoginProfile(); var existingItem = Get(id); if (existingItem == null) throw new NotificationException($"No item in database."); existingItem = SetUpdatorProperties(existingItem); existingItem = SetActiveProperty(existingItem); if (!SaveToDB()) throw new NotificationException($"Unable to set item as active to database."); return existingItem; } public void Delete(Key id) { var userLogin = GetLoginProfile(); var existingItem = Get(id); var log = new activity_log(); log.attributes = existingItem; log.old = null; var log_message = Newtonsoft.Json.JsonConvert.SerializeObject(log); var activity_log = new activity_log_evaEntity(); activity_log.log_name = existingItem.GetType().Name.Replace("Entity", ""); ; activity_log.description = "Delete " + existingItem.GetType().Name.Replace("Entity", ""); ; activity_log.subject_id = 0; activity_log.subject_type = existingItem.GetType().Name; activity_log.causer_id = Convert.ToInt32(_contextAccessor.HttpContext.Request.Cookies["user_id"]); activity_log.causer_type = @"App\Models\User"; activity_log.properties = log_message; activity_log.ip_address = _contextAccessor.HttpContext.Connection.RemoteIpAddress.ToString(); activity_log.mac_address = "N/A"; activity_log.created_at = DateTime.Now; activity_log.updated_at = activity_log.created_at; _context.Add(activity_log); if (existingItem == null) throw new NotificationException($"No item in database."); Entities.Remove(existingItem); if (!SaveToDB()) throw new NotificationException($"Unable to delete item from database."); return; } public void Delete(Expression> predicate) { var userLogin = GetLoginProfile(); Entities.RemoveRange(Entities.Where(predicate)); if (!SaveToDB()) throw new NotificationException($"Unable to delete items from database."); } public void InsertWithoutCommit(T entity) { var userLogin = GetLoginProfile(); entity = SetCreatorProperties(entity); entity = SetUpdatorProperties(entity); entity = SetActiveProperty(entity); var result = Entities.Add(entity); } public void UpdateWithoutCommit(Key id, object model) { var userLogin = GetLoginProfile(); var existingItem = Get(id); if (existingItem == null) throw new NotificationException($"No item in database."); Mapper.Map(model, existingItem); existingItem = SetUpdatorProperties(existingItem); } public void DeleteWithoutCommit(Key id) { var userLogin = GetLoginProfile(); var existingItem = Get(id); if (existingItem == null) throw new NotificationException($"No item in database."); Entities.Remove(existingItem); } #endregion #endregion } }