using Coscine.Database.DataModel; using Coscine.Database.Util; using Microsoft.EntityFrameworkCore; using System; using System.Collections.Generic; using System.Linq; using System.Linq.Expressions; using LinqKit; namespace Coscine.Database.Models { public abstract class DatabaseModel<T> where T : class { public abstract Expression<Func<T, Guid>> GetIdFromObject(); public abstract void SetObjectId(T databaseObject, Guid id); public abstract Microsoft.EntityFrameworkCore.DbSet<T> GetITableFromDatabase(CoscineDB db); // GetById utilizes the Expression functionality since Linq2Sql does not support method calls // This is therefore a workaround for getting the Id parameter public virtual T GetById(Guid id) { Expression<Func<T, Guid>> expression = GetIdFromObject(); return DatabaseConnection.ConnectToDatabase((db) => { return (from tableEntry in GetITableFromDatabase(db).AsExpandable() where expression.Invoke(tableEntry) == id select tableEntry).FirstOrDefault(); }); } public virtual T GetWhere(Expression<Func<T, bool>> whereClause) { return DatabaseConnection.ConnectToDatabase((db) => { return (from tableEntry in GetITableFromDatabase(db).AsExpandable() where whereClause.Invoke(tableEntry) select tableEntry).FirstOrDefault(); }); } public virtual IEnumerable<T> GetAll() { return DatabaseConnection.ConnectToDatabase((db) => { return (from tableEntry in GetITableFromDatabase(db) select tableEntry).ToList(); }); } public virtual IEnumerable<T> GetAllWhere(Expression<Func<T, bool>> whereClause) { return DatabaseConnection.ConnectToDatabase((db) => { return (from tableEntry in GetITableFromDatabase(db).AsExpandable() where whereClause.Invoke(tableEntry) select tableEntry).ToList(); }); } public virtual int Update(T databaseObject) { return DatabaseConnection.ConnectToDatabase((db) => { return (int) db.Update(databaseObject).State; }); } public virtual int Insert(T databaseObject) { if (GetIdFromObject().Compile()(databaseObject) == new Guid("00000000-0000-0000-0000-000000000000")) { SetObjectId(databaseObject, Guid.NewGuid()); } return DatabaseConnection.ConnectToDatabase((db) => { return db.Insert(databaseObject); }); } public virtual int Delete(T databaseObject) { return DatabaseConnection.ConnectToDatabase((db) => { return db.Delete(databaseObject); }); } } }