/// <summary> /// Applies the changes of the entity to the context. /// </summary> /// <param name="entity">The entity to manage.</param> internal void ManageEntity(IEntityObjectIdentifier entity) { var currentState = GetEntityState(entity); var targetState = GetEntityStateTargeted(entity, currentState); ManageEntity(entity, currentState, targetState); }
/// <summary> /// Applies the changes of the entity to the context. /// </summary> /// <param name="entity">The entity to manage.</param> /// <param name="currentState">The original state (optional).</param> /// <param name="targetState">The chosen state.</param> internal void ManageEntity(IEntityObjectIdentifier entity, EntityState?currentState, EntityState targetState) { if (gate.Configuration.CanUseLogging) { gate.Configuration.Log(string.Format(CultureInfo.InvariantCulture, Resources.ChangeEntityToState, entity, targetState)); } if (targetState == EntityState.Detached) { throw new EntityGateProviderException(string.Format(CultureInfo.InvariantCulture, Resources.UnexpectedEntityState, targetState, entity)); } // The current state is not needed for an addition. if (!currentState.HasValue && targetState != EntityState.Added) { currentState = GetEntityState(entity); } // If the entity is detached, check the consistency. if (currentState.HasValue && currentState == EntityState.Detached) { var entityTracked = GetEntityTracked(entity, targetState != EntityState.Deleted); entity = entityTracked ?? entity; } GetEntityEntry(entity).State = targetState; }
/// <summary> /// Attempt to find information about the state of the entity. /// </summary> /// <param name="entity">The entity to manage.</param> /// <param name="entry">Information about the state of the entity</param> /// <returns></returns> private bool TryGetEntityStateEntry(IEntityObjectIdentifier entity, ref ObjectStateEntry entry) { return(entity != null && model.GetObjectContext() .ObjectStateManager .TryGetObjectStateEntry(entity, out entry)); }
/// <summary> /// Returns the entity information from the trace. /// </summary> /// <param name="entity">The entity to manage.</param> /// <returns></returns> private DbEntityEntry GetEntityEntryTracked(IEntityObjectIdentifier entity) { var sourceType = entity.GetType(); return(GetEntriesTracked() .FirstOrDefault(entry => entry.Entity.GetType() == sourceType && ((IEntityObjectIdentifier)entry.Entity).Identifier.Equals(entity.Identifier))); }
/// <summary> /// Refreshes the entity via the context. /// </summary> /// <param name="entity"></param> internal void RefreshChanges(IEntityObjectIdentifier entity) { if (entity == null) { throw new ProviderEntityGateCoreException(Resources.InvalidEntityRefreshChanges); } GetEntityEntry(entity).Reload(); }
/// <summary> /// Refreshes the entity via the context. /// </summary> /// <param name="entity"></param> internal void RefreshChanges(IEntityObjectIdentifier entity) { if (entity == null) { throw new EntityGateProviderException(Resources.InvalidEntityRefreshChanges); } model.GetObjectContext().Refresh(RefreshMode.ClientWins, entity); }
/// <summary> /// Returns the typed entity after checking its compatibility. /// </summary> /// <typeparam name="TEntity">The type of the entity.</typeparam> /// <param name="entity">The entity to check.</param> /// <returns></returns> public static TEntity CheckEntityType <TEntity>(IEntityObjectIdentifier entity) where TEntity : class, IEntityObjectIdentifier { if (entity == null || typeof(TEntity) != entity.GetType()) { throw new EntityGateCoreException(string.Format(CultureInfo.InvariantCulture, Resources.InvalidEntityType, entity != null ? entity.GetType().ToString() : "null")); } return((TEntity)entity); }
/// <summary> /// Returns the specific name of the entity (<see cref="IEntityObjectNameable"/>). /// </summary> /// <param name="entityObject">The instance of the entity.</param> /// <returns></returns> public static string GetEntityName(this IEntityObjectIdentifier entityObject) { string name = null; if (entityObject.IsEntityNameable()) { name = ((IEntityObjectNameable)entityObject)?.Name; } return(name); }
/// <summary> /// Returns the code of the entity (<see cref="IEntityObjectRecognizableCode"/>). /// </summary> /// <param name="entityObject">The instance of the entity.</param> /// <returns></returns> public static string GetEntityCodeName(this IEntityObjectIdentifier entityObject) { string name = null; if (entityObject.HasEntityRecognizableCode()) { name = ((IEntityObjectRecognizableCode)entityObject)?.CodeName; } return(name); }
/// <summary> /// Returns the unique value of the entity (<see cref="IEntityObjectSingleValue"/>). /// </summary> /// <param name="entityObject">The instance of the entity.</param> /// <returns></returns> public static string GetEntitySingleValue(this IEntityObjectIdentifier entityObject) { string name = null; if (entityObject.HasEntitySingleValue()) { name = ((IEntityObjectSingleValue)entityObject)?.SingleValue; } return(name); }
/// <summary> /// Returns the names of the primary key columns. /// </summary> /// <returns></returns> internal IEnumerable <string> GetPrimaryKeys(IEntityObjectIdentifier entity) { var entityType = HasPocoEntityType() ? GetPocoEntityType() : entity.GetType(); var key = GetEntityTypeInfo(entityType).FindPrimaryKey(); if (key == null) { throw new ProviderEntityGateCoreException(string.Format(CultureInfo.InvariantCulture, Resources.EntityKeyNotFound, entity, entityType.Name)); } return(key.Properties.Select(prop => prop.Name)); }
/// <summary> /// Returns the key of the entity. /// </summary> /// <param name="entity">The entity to manage.</param> /// <returns></returns> private EntityKey GetEntityKey(IEntityObjectIdentifier entity) { EntityKey result = null; var ose = GetEntityStateEntry(entity); if (ose != null) { result = ose.EntityKey; } return(result); }
/// <summary> /// Returns the handler for the requested entity. /// </summary> /// <typeparam name="TContext">The type of context.</typeparam> /// <param name="component">An instance of an entity.</param> /// <returns></returns> public static EntityGateContext <TContext> GetEntityGate <TContext>(ref IEntityObjectIdentifier component) where TContext : DbContext { var gate = new EntityGateContext <TContext>(component); if (!gate.IsNewEntity) { gate.Load(); } component = gate.Entity; return(gate); }
/// <summary> /// Affects the state to follow. /// </summary> /// <param name="entity">The entity to follow.</param> /// <param name="state">The state to follow.</param> /// <param name="isMainEntity">Indicates that it is the main entity.</param> private void SetState(IEntityObjectIdentifier entity, EntityState state, bool isMainEntity) { var trackingIndex = FindEntityIndex(entity); if (trackingIndex >= 0) { entities[trackingIndex].State = state; } else { entities.Add(new EntityStateTracking(entity, state, isMainEntity)); } }
/// <summary> /// Returns the value of the requested field. /// </summary> /// <param name="entity">The entity to check.</param> /// <param name="entityType">The type of the entity.</param> /// <param name="fieldName">Name of the column.</param> /// <returns></returns> internal static object GetFieldValue(IEntityObjectIdentifier entity, Type entityType, string fieldName) { object value = null; if (entity != null && fieldName.IsNotNullOrEmpty() && ReflectionHelper.IsValidEntityType(entityType)) { var fieldInfo = entityType.GetProperty(fieldName, BindingFlags.Public | BindingFlags.Instance); if (fieldInfo != null) { value = fieldInfo.GetValue(entity, null); } } return(value); }
/// <summary> /// Returns the information about the state of the entity. /// </summary> /// <param name="entity">The entity to manage.</param> /// <returns></returns> private ObjectStateEntry GetEntityStateEntry(IEntityObjectIdentifier entity) { ObjectStateEntry result = null; if (!TryGetEntityStateEntry(entity, ref result) || result == null) { if (gate.Configuration.CanUseLogging) { // It's not necessarily a problem. // This means that the object is currently not followed in the context. gate.Configuration.Log(string.Format(CultureInfo.InvariantCulture, Resources.ObjectStateEntryNotFound, entity)); } } return(result); }
/// <summary> /// Determines if the key appears valid. /// </summary> /// <param name="entity">The instance of the entity.</param> /// <returns></returns> public static bool HasValidEntityKey(this IEntityObjectIdentifier entity) { var valid = false; if (entity != null) { valid = entity.Identifier != null && !entity.Identifier.Equals(null); if (valid && entity.Identifier.GetType().IsPrimitive) { valid = Convert.ToInt64(entity.Identifier, CultureInfo.InvariantCulture) > 0; } } return(valid); }
/// <summary> /// Returns the instance of the entity since the trace, with update if requested. /// </summary> /// <param name="entity">The entity to manage.</param> /// <param name="updateValues">Update the tracked entity with the values of the entity to be managed.</param> /// <returns></returns> private IEntityObjectIdentifier GetEntityTracked(IEntityObjectIdentifier entity, bool updateValues) { IEntityObjectIdentifier trackedEntity = null; var currentEntry = GetEntityEntryTracked(entity); if (currentEntry != null) { if (updateValues) { currentEntry.CurrentValues.SetValues(entity); } trackedEntity = (IEntityObjectIdentifier)currentEntry.Entity; } return(trackedEntity); }
/// <summary> /// Track the entity with its state. /// </summary> /// <param name="entity">The entity to follow.</param> /// <param name="state">The state to follow.</param> /// <param name="isMainEntity">Indicates that it is the main entity.</param> private void Mark(IEntityObjectIdentifier entity, EntityState state, bool isMainEntity) { switch (state) { case EntityState.Deleted: case EntityState.Added: case EntityState.Modified: case EntityState.Unchanged: { SetState(entity, state, isMainEntity); break; } default: { throw new EntityGateCoreException(string.Format(CultureInfo.InvariantCulture, Resources.InvalidEntityStateForTracking, state, entity)); } } }
/// <summary> /// Returns the entity's information as a string. /// </summary> /// <param name="entity">The instance of the entity.</param> /// <returns></returns> public static string GetContentInfo(this IEntityObjectIdentifier entity) { var content = new StringBuilder(); if (entity != null) { content.Append(entity); content.Append(" ("); ReflectionHelper.BuiltContentInfo(entity, content); content.Append(")"); } else { content.Append("Entity is null"); } return(content.ToString()); }
/// <summary> /// Returns an entity instance manageable by the current context. /// </summary> /// <param name="externalEntity">The entity to check.</param> /// <param name="contextEntityType">The type of the entity or null.</param> /// <returns></returns> internal IEntityObjectIdentifier GetManagedOrPocoEntity(IEntityObjectIdentifier externalEntity, Type contextEntityType) { if (!HasEntity(externalEntity)) { // Search in instances already followed. var entityTracked = GetEntityTracked(externalEntity, true); if (entityTracked != null) { // This is an optimization, instead of cloning stupidly, we reuse the known instance with a merge managed by EF. externalEntity = entityTracked; } else { // Creation of a pure entity if necessary. externalEntity = PocoHelper.GetPocoEntity(externalEntity, contextEntityType, withDataRelation: true); } } return(externalEntity); }
/// <summary> /// Returns the record of the original values of the entity. /// </summary> /// <param name="entity">The entity to check.</param> /// <param name="allProperties">Return all properties or just the modified ones.</param> /// <returns></returns> internal KeyValuePair <string, object>[] GetOriginalValues(IEntityObjectIdentifier entity, bool allProperties) { var values = new List <KeyValuePair <string, object> >(); var entityEntry = GetEntityEntry(entity); var modifiedProperties = !allProperties?entityEntry.Properties.Where(prop => prop.IsModified).Select(prop => prop.Metadata.Name).ToArray() : null; var originalValues = entityEntry.OriginalValues; foreach (var originalValue in originalValues.Properties) { var fieldName = originalValue.Name; if (modifiedProperties != null && !modifiedProperties.Any(name => name.EqualsIgnoreCase(fieldName))) { continue; } values.Add(new KeyValuePair <string, object>(originalValue.Name, originalValues.GetValue <object>(originalValue.Name))); } return(values.ToArray()); }
/// <summary> /// Returns the state to apply to the entity. /// </summary> /// <param name="entity">The entity to manage.</param> /// <param name="currentState">The original state.</param> /// <returns></returns> private EntityState GetEntityStateTargeted(IEntityObjectIdentifier entity, EntityState currentState) { var targetState = currentState; // Request the addition if necessary. if (targetState != EntityState.Added || !HasEntity(entity)) { // Protection against inconsistent states. if (!entity.HasValidEntityKey()) { targetState = EntityState.Added; } } // Ask for attachment if necessary. if (targetState == EntityState.Detached) { targetState = EntityState.Modified; } return(targetState); }
/// <summary> /// Returns the record of the original values of the entity. /// </summary> /// <param name="entity">The entity to check.</param> /// <param name="allProperties">Return all properties or just the modified ones.</param> /// <returns></returns> internal KeyValuePair <string, object>[] GetOriginalValues(IEntityObjectIdentifier entity, bool allProperties) { var values = new List <KeyValuePair <string, object> >(); var stateEntry = GetEntityStateEntry(entity); var modifiedProperties = !allProperties?stateEntry.GetModifiedProperties().ToArray() : null; var originalValues = stateEntry.OriginalValues; for (int i = 0, loopTo = originalValues.FieldCount - 1; i <= loopTo; i++) { var fieldName = originalValues.GetName(i); if (modifiedProperties != null && !modifiedProperties.Any(pName => (pName ?? "") == (fieldName ?? ""))) { continue; } values.Add(new KeyValuePair <string, object>(originalValues.GetName(i), originalValues.GetValue(i))); } return(values.ToArray()); }
/// <summary> /// Determines whether the entity should feed a history (<see cref="IEntityObjectArchival"/>). /// </summary> /// <param name="entityObject">The instance of the entity.</param> /// <returns></returns> public static bool IsEntityArchival(this IEntityObjectIdentifier entityObject) { return(entityObject is IEntityObjectArchival); }
/// <summary> /// Determines whether the entity type appears valid. /// </summary> /// <param name="entity">The instance of the entity.</param> /// <returns></returns> public static bool IsValidEntityType(this IEntityObjectIdentifier entity) { return(entity != null && ReflectionHelper.IsRealType(entity.GetType())); }
/// <summary> /// Determines whether the entity has a unique value (<see cref="IEntityObjectSingleValue"/>). /// </summary> /// <param name="entityObject">The instance of the entity.</param> /// <returns></returns> public static bool HasEntitySingleValue(this IEntityObjectIdentifier entityObject) { return(entityObject is IEntityObjectSingleValue); }
/// <summary> /// Determines whether the entity has an identification code (<see cref="IEntityObjectRecognizableCode"/>). /// </summary> /// <param name="entityObject">The instance of the entity.</param> /// <returns></returns> public static bool HasEntityRecognizableCode(this IEntityObjectIdentifier entityObject) { return(entityObject is IEntityObjectRecognizableCode); }
/// <summary> /// Determines whether the entity has a specific name (<see cref="IEntityObjectNameable"/>). /// </summary> /// <param name="entityObject">The instance of the entity.</param> /// <returns></returns> public static bool IsEntityNameable(this IEntityObjectIdentifier entityObject) { return(entityObject is IEntityObjectNameable); }
/// <summary> /// New entity manager. /// </summary> /// <param name="externalEntity">External entity that will be controlled by the manager.</param> /// <param name="connectionName">Name of the connection string.</param> public EntityGateContext(IEntityObjectIdentifier externalEntity = null, string connectionName = null) : base(externalEntity, connectionName) { }