using System.Linq.Dynamic.Core; using IronPython.Hosting; using Microsoft.EntityFrameworkCore; using Microsoft.IdentityModel.Tokens; using Microsoft.Scripting.Hosting; using SiteManagementSystem_SoftwareEngineering_.Entity; using SiteManagementSystem_SoftwareEngineering_.Interface; namespace SiteManagementSystem_SoftwareEngineering_.Service { public enum FieldType { Unspecified, Tennis, Basketball, Badminton } public class FieldService : IFieldService { private readonly EntityFrameworkPythonCompatibilityAndInterpretationLayer _layer; private readonly ScriptEngine _engine = Python.CreateEngine(); private readonly dynamic _service; public FieldService(SQLService storageService,ICacheServicecacheService) { _layer = new EntityFrameworkPythonCompatibilityAndInterpretationLayer(storageService,cacheService); var _engine = Python.CreateEngine(); var searchPaths = _engine.GetSearchPaths(); searchPaths.Add(@"./Service/PythonServiceFile/"); _engine.SetSearchPaths(searchPaths); var source = _engine.CreateScriptSourceFromFile(@"./Service/PythonServiceFile/demo.py"); var scope = _engine.CreateScope(); scope.SetVariable("LAYER", _layer); source.Execute(scope); _service = scope.GetVariable("Service")(); } public void RedisKeyExpired(string key) { var keys = key.Split('$', 2); _service.RedisKeyExpired(keys[0], keys[1]); } public void AddField(string name, string value) { try { var t = (bool) _service.AddAppointment( new FieldRecord { Fid = Guid.NewGuid(), Uid = Guid.NewGuid(), StartTime = DateTime.Now, EndTime = DateTime.Now + TimeSpan.FromMinutes(30) } ); } catch (Exception) { } Console.WriteLine(_layer.RecordDb.FindAll("Uid",Guid.Parse("bd422092-7f2b-4f53-ad08-47a75aa089ea")).First().StartTime); Console.WriteLine(DateTime.Now); //Console.WriteLine(_service.AddField()); throw new NotImplementedException(); } public void RentField() { throw new NotImplementedException(); } } public class EntityFrameworkPythonCompatibilityAndInterpretationLayer { public readonly SQLHelperService FieldDb; public readonly SQLHelperService RecordDb; public readonly SQLHelperService FinishedFieldRecordDb; private readonly ICacheService _cacheService; public EntityFrameworkPythonCompatibilityAndInterpretationLayer(SQLService storageService, ICacheService cacheService) { _cacheService = cacheService; FieldDb = new SQLHelperService(storageService, nameof(storageService.Fields)); RecordDb = new SQLHelperService( storageService, nameof(storageService.UserFieldRecords) ); FinishedFieldRecordDb = new SQLHelperService(storageService,nameof(storageService.FinishedFieldRecords)); } public void SetTimeOut(DateTime endTime,string info) { var now = DateTime.Now; if (endTime <= now) throw new InvalidOperationException("The end must be later than now."); var span = endTime - now; _cacheService.SetAsync(endTime.ToString() + "$" + info, "", span); } } public class SQLHelperService where TEntity : class, new() { private readonly SQLService _sqlService; private readonly DbSet _dbSet; public SQLHelperService(SQLService sqlService, string dbName) { _sqlService = sqlService; if (dbName.IsNullOrEmpty()) dbName = typeof(TEntity).Name; _dbSet = _sqlService.GetType().GetProperty(dbName)?.GetValue(_sqlService) as DbSet ?? throw new InvalidOperationException( $"SQLHelper don't have DbSet which named {dbName}." ); } public SQLHelperService Add(TEntity entity) => Process((dbSet) => dbSet.Add(entity)); private SQLHelperService Update(TEntity oldEntity, TEntity newEntity) => Process( (dbSet) => { dbSet.Remove(oldEntity); dbSet.Add(newEntity); } ); public SQLHelperService Update(TEntity entity, string key, TValue value) { var t = FindAll(key, value); switch (t.Count()) { case 0: throw new InvalidOperationException("No values match the criteria!"); case 1: Update(t.First(), entity); break; default: throw new InvalidOperationException("Multiple values match the criteria!"); } return this; } public SQLHelperService AddOrUpdate( TEntity entity, string key, TValue value ) { var t = FindAll(key, value); switch (t.Count()) { case 0: Add(entity); break; case 1: Update(t.First(), entity); break; default: throw new InvalidOperationException("Multiple values match the criteria!"); } return this; } public TEntity? FindFirst(string key, TValue value) { TEntity? ans = null; if (value is null) Process(key, (dbSet) => ans = dbSet.Where($"{key} == null").FirstOrDefault()); else Process(key, (dbSet) => ans = dbSet.Where($"{key} == @0", value).FirstOrDefault()); return ans; } public IEnumerable FindAll(string key, TValue value) { IEnumerable ans = null!; var y = typeof(TEntity).GetType().GetProperty(key); if (value is null) Process(key, (dbSet) => ans = dbSet.Where($"{key} == null").ToList()); else Process(key, (dbSet) => ans = dbSet.Where($"{key} == @0", value).ToList()); return ans; } public IEnumerable GetFirstNElements(int n) { List ans = null!; Process((dbSet) => ans = dbSet.Take(n).ToList()); return ans; } public SQLHelperService Delete(TEntity entity) => Process((dbSet) => dbSet.Remove(entity)); public SQLHelperService TryDelete(string key, TValue value) { var t = FindFirst(key, value); if (t is null) return this; return Process((dbSet) => dbSet.Remove(t)); } public SQLHelperService Save() { _sqlService.SaveChanges(); return this; } public SQLHelperService DeleteAll(string key, TValue value) => Process((dbSet) => dbSet.RemoveRange(FindAll(key, value))); public SQLHelperService Process(Action> action) { action(_dbSet); _sqlService.SaveChanges(); return this; } public TEntity GetDefaultEntity() => new(); public SQLHelperService Process(string key, Action> action) { if (typeof(TEntity).GetProperty(key) is null) throw new InvalidOperationException( $"{typeof(TEntity).Name} does not have the property key: {key}" ); action(_dbSet); _sqlService.SaveChanges(); return this; } } }