The object class calls the static method in the generic parent class to execute CRUD -- the first version, static crud
public abstract class LYEntityDbContext<DB, T> where DB : DbContext, new() where T : LYEntityDbContext<DB, T> { public void GenerateHashCode() { var thisTime = this.GetType().GetProperties().Select(p => p.GetValue(this).GetHashCode()); this.changes.Add(thisTime); } private List<IEnumerable<int>> changes = new List<IEnumerable<int>>(); private bool executed = true; private bool hasChanged { get { if (this.changes.Count < 2) { return false; } var result = !this.changes.First().Except(this.changes.Last()).Any(); return result; } } public bool Executed() { return this.executed; } public static IEnumerable<T> Find(Action<T> action, params object[] keyValues) { return Find(action, true, keyValues); } public static IEnumerable<T> Find(Action<T> action, bool inBatch, params object[] keyValues) { if (inBatch) { using (var db = new DB()) { var hasChanged = false; for (int i = 0; i < keyValues.Length; i++) { var id = keyValues[i]; var t = db.Set<T>().Find(id); yield return t; t.GenerateHashCode(); action(t); t.GenerateHashCode(); if (!hasChanged) { hasChanged = t.hasChanged; } } if (hasChanged) { db.SaveChanges(); } } } else { foreach (var id in keyValues) { yield return Find(action, id); } } } public static T Find(Action<T> action, object id) { using (var db = new DB()) { var t = db.Set<T>().Find(id); t.GenerateHashCode(); action(t); t.GenerateHashCode(); if (t.hasChanged) { try { db.SaveChanges(); t.executed = true; } catch (Exception) { t.executed = false; } } return t; } } public static IEnumerable<T> FindAll<P>(Func<T, bool> where, Func<T, P> orderby, int skip, int take, out int all) { using (var db = new DB()) { if (where == null) { var r = db.Set<T>(); all = r.Count(); return r; } all = db.Set<T>().Count(where); if (orderby == null) { var r = db.Set<T>().Where(where); return r; } if (take <= 0) { var r = db.Set<T>().Where(where).OrderBy(orderby); return r; } if (skip <= 0) { var r = db.Set<T>().Where(where).OrderBy(orderby).Take(take); return r; } var rr = db.Set<T>().Where(where).OrderBy(orderby).Skip(skip).Take(take); return rr; } } }