/// <summary> /// Loads the refrence for the entity /// return true if the entity reference changed /// </summary> /// <param name="entity"></param> /// <param name="dbReference"></param> /// <returns></returns> private bool LoadDbMultiReference(IDbEntity entity, IList dbMultiRefs) { // if null // do nothing if (dbMultiRefs == null) { return(false); } bool changed = false; for (int i = dbMultiRefs.Count - 1; i >= 0; i--) { IDbReference reference = (IDbReference)dbMultiRefs[i]; IDbEntity otherRef = FindEntity(reference.EntityType, reference.ReferenceId.Value); // if other ref is null // that means that the link between the entities is gone // so delete from the list if (otherRef == null) { dbMultiRefs.RemoveAt(i); changed = true; } } return(changed); }
/// <summary> /// Wire up the references of an entity /// </summary> /// <param name="entity"></param> private void InjectSingleReferences(IDbEntity entity) { Type entityType = entity.GetType(); EntityInfo infos = GetEntityInfo(entityType); bool changed = false; // single refs foreach (SingleReferenceProperty referenceProperty in infos.SingleReferenceInjectors) { IDbReference dbReference = (IDbReference)referenceProperty.PropertyAccessor.GetValue(entity); if (LoadSingleDbReference(entityType, entity, dbReference)) { changed = true; } } // trigger if event is entity is changed if (changed) { OnEntityChanged?.Invoke(entity); } }
/// <summary> /// Remove entity from Db /// </summary> /// <typeparam name="T"></typeparam> /// <param name="t"></param> public void Remove <T>(T t) where T : IDbEntity { AddType <T>(); Type type = typeof(T); Database[type].Remove(t); // check entity references foreach (KeyValuePair <Type, HashSet <IDbEntity> > kv in Database) { Type entityType = kv.Key; EntityInfo infos = GetEntityInfo(entityType); foreach (IDbEntity entity in kv.Value) { bool changed = false; // single refs foreach (SingleReferenceProperty referenceProperty in infos.SingleReferenceInjectors) { IDbReference dbReference = (IDbReference)referenceProperty.PropertyAccessor.GetValue(entity); if (dbReference.ReferenceId == t.EntityId && dbReference.EntityType == type) { dbReference.ReferenceId = null; dbReference.Entity = null; changed = true; } } // multiple refs foreach (MultipleReferenceProperty referenceProperty in infos.MultipleReferenceInjectors) { IList dbReference = (IList)referenceProperty.PropertyAccessor.GetValue(entity); if (dbReference == null) { continue; } for (int i = dbReference.Count - 1; i >= 0; i--) { IDbReference reference = (IDbReference)dbReference[i]; if (reference.ReferenceId == t.EntityId && reference.EntityType == type) { dbReference.RemoveAt(i); changed = true; } } } if (changed) { OnEntityChanged?.Invoke(entity); } } } OnDatabaseChanged?.Invoke(this); OnEntityRemoved?.Invoke(t); }
/// <summary> /// Loads the refrence for the entity /// return true if the entity reference changed /// </summary> /// <param name="entity"></param> /// <param name="dbReference"></param> /// <returns></returns> private bool LoadSingleDbReference(Type entityType, IDbEntity entity, IDbReference dbReference) { // if null // do nothing if (dbReference == null) { return(false); } // if refrence id doesn't exist // then set to null if (!dbReference.ReferenceId.HasValue && dbReference.Entity != null) { dbReference.Entity = null; return(true); } // else if id exists but instance isn't linked // then inject the value from the db else if (dbReference.ReferenceId.HasValue) { IDbEntity searchReference = null; // if entity is null // or if different id // then load from db if (dbReference.Entity == null || dbReference.Entity.EntityId != dbReference.ReferenceId) { searchReference = Database[dbReference.EntityType].FirstOrDefault(e => e.EntityId == dbReference.ReferenceId.Value); if (searchReference == null) { dbReference.ReferenceId = null; throw new Exception($"Entity doesn't exist ( type : { dbReference.EntityType.Name } , id : { dbReference.ReferenceId.Value } )"); } } else { searchReference = dbReference.Entity; } List <MultipleReferenceProperty> otherMultiRef = EntityInfos[dbReference.EntityType].MultipleReferenceInjectors.Where(i => i.ReferenceType == entityType).ToList(); if (otherMultiRef != null) { foreach (MultipleReferenceProperty mutli in otherMultiRef) { IList multiRefList = (IList)mutli.PropertyAccessor.GetValue(searchReference); // if the multi list doesn't already contain a reference to the current entity // add a new reference to the list if (multiRefList.Cast <IDbReference>().FirstOrDefault(r => r.ReferenceId == entity.EntityId) == null) { IDbReference reference = mutli.ReferenceCreator(); reference.Entity = entity; reference.ReferenceId = entity.EntityId; multiRefList.Add(reference); } } } List <SingleReferenceProperty> otherSingleRef = EntityInfos[dbReference.EntityType].SingleReferenceInjectors.Where(i => i.ReferenceType == entityType).ToList(); if (otherSingleRef != null) { foreach (SingleReferenceProperty single in otherSingleRef) { IDbReference singleReference = (IDbReference)single.PropertyAccessor.GetValue(searchReference); if (singleReference.ReferenceId != entity.EntityId) { singleReference.Entity = entity; singleReference.ReferenceId = entity.EntityId; } } } dbReference.Entity = searchReference; return(true); } return(false); }