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) { _layer = new EntityFrameworkPythonCompatibilityAndInterpretationLayer(storageService); 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 AddField(string name, string value) { var t = (Field) _service.AddField( new Field { Name = "t1", Position = "t2", OpenTime = "t3" } ); Console.WriteLine( $"{t.Id},{t.Name},{t.Type}" ); //t(); //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 EntityFrameworkPythonCompatibilityAndInterpretationLayer(SQLService storageService) { FieldDb = new SQLHelperService(storageService, nameof(storageService.Fields)); RecordDb = new SQLHelperService( storageService, nameof(storageService.UserFieldRecords) ); } } 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; } } }