/// <summary> /// Get the value of the foreign key property. This comes from the entity, but if that value is /// null, and the entity is deleted, we try to get it from the originalValuesMap. /// </summary> /// <param name="entityInfo">Breeze EntityInfo</param> /// <param name="meta">Metadata for the entity class</param> /// <param name="foreignKeyName">Name of the foreign key property of the entity, e.g. "CustomerID"</param> /// <returns></returns> private object GetForeignKeyValue(EntityInfo entityInfo, IClassMetadata meta, string foreignKeyName) { var entity = entityInfo.Entity; object id = null; if (foreignKeyName == meta.IdentifierPropertyName) { id = meta.GetIdentifier(entity, EntityMode.Poco); } else if (meta.PropertyNames.Contains(foreignKeyName)) { id = meta.GetPropertyValue(entity, foreignKeyName, EntityMode.Poco); } else if (meta.IdentifierType.IsComponentType) { // compound key var compType = meta.IdentifierType as ComponentType; var index = Array.IndexOf <string>(compType.PropertyNames, foreignKeyName); if (index >= 0) { var idComp = meta.GetIdentifier(entity, EntityMode.Poco); id = compType.GetPropertyValue(idComp, index, EntityMode.Poco); } } if (id == null && entityInfo.EntityState == EntityState.Deleted) { entityInfo.OriginalValuesMap.TryGetValue(foreignKeyName, out id); } return(id); }
/// <summary> /// Get the identifier value for the entity. If the entity does not have an /// identifier property, or natural identifiers defined, then the entity itself is returned. /// </summary> /// <param name="entity"></param> /// <param name="meta"></param> /// <returns></returns> private object GetIdentifier(object entity, IClassMetadata meta = null) { var type = entity.GetType(); meta = meta ?? session.SessionFactory.GetClassMetadata(type); if (meta.IdentifierType != null) { var id = meta.GetIdentifier(entity, EntityMode.Poco); if (meta.IdentifierType.IsComponentType) { var compType = (ComponentType)meta.IdentifierType; return(compType.GetPropertyValues(id, EntityMode.Poco)); } else { return(id); } } else if (meta.HasNaturalIdentifier) { var idprops = meta.NaturalIdentifierProperties; var values = meta.GetPropertyValues(entity, EntityMode.Poco); var idvalues = idprops.Select(i => values[i]).ToArray(); return(idvalues); } return(entity); }
/// <summary> /// /// </summary> /// <param name="entity">an actual entity object, not a proxy!</param> /// <param name="entityMode"></param> /// <returns></returns> public string ToString(object entity, EntityMode entityMode) { IClassMetadata cm = _factory.GetClassMetadata(entity.GetType()); if (cm == null) { return(entity.GetType().FullName); } IDictionary <string, string> result = new Dictionary <string, string>(); if (cm.HasIdentifierProperty) { result[cm.IdentifierPropertyName] = cm.IdentifierType.ToLoggableString(cm.GetIdentifier(entity, entityMode), _factory); } IType[] types = cm.PropertyTypes; string[] names = cm.PropertyNames; object[] values = cm.GetPropertyValues(entity, entityMode); for (int i = 0; i < types.Length; i++) { result[names[i]] = types[i].ToLoggableString(values[i], _factory); } return(cm.EntityName + CollectionPrinter.ToString(result)); }
/// <summary> /// Get the identifier value for the entity. If the entity does not have an /// identifier property, or natural identifiers defined, then the entity itself is returned. /// </summary> /// <param name="entity"></param> /// <param name="meta"></param> /// <returns></returns> protected object GetIdentifier(object entity, IClassMetadata meta = null) { var type = Session.GetProxyRealType(entity); meta = meta ?? Session.SessionFactory.GetClassMetadata(type); if (meta.IdentifierType != null) { var id = meta.GetIdentifier(entity); if (meta.IdentifierType.IsComponentType) { var compType = (ComponentType)meta.IdentifierType; return(compType.GetPropertyValues(id)); } return(id); } if (meta.HasNaturalIdentifier) { var idprops = meta.NaturalIdentifierProperties; var values = meta.GetPropertyValues(entity); var idvalues = idprops.Select(i => values[i]).ToArray(); return(idvalues); } return(entity); }
/// <summary> /// Return the property value for the given entity. /// </summary> /// <param name="meta"></param> /// <param name="entity"></param> /// <param name="propName">If null, the identifier property will be returned.</param> /// <returns></returns> private object GetPropertyValue(IClassMetadata meta, object entity, string propName) { if (propName == null || propName == meta.IdentifierPropertyName) { return(meta.GetIdentifier(entity)); } else { return(meta.GetPropertyValue(entity, propName)); } }
private bool SetupEntityInfoForSerialization(Type entityType, EntityInfo entityInfo, IClassMetadata meta) { if (!_removeMode || !_clientEntityObjects.ContainsKey(entityInfo)) { return(false); } var clientEntity = _clientEntityObjects[entityInfo]; var id = meta.GetIdentifier(entityInfo.Entity); meta.SetIdentifier(clientEntity, id); //We have to set the properties from the client object var propNames = meta.PropertyNames; var propTypes = meta.PropertyTypes; for (var i = 0; i < propNames.Length; i++) { var propType = propTypes[i]; var propName = propNames[i]; if (propType.IsAssociationType) { continue; } if (propType.IsComponentType) { var compType = (ComponentType)propType; var compPropNames = compType.PropertyNames; var compPropTypes = compType.Subtypes; var component = GetPropertyValue(meta, entityInfo.Entity, propName); var compValues = compType.GetPropertyValues(component); for (var j = 0; j < compPropNames.Length; j++) { var compPropType = compPropTypes[j]; if (!compPropType.IsAssociationType) { continue; } compValues[j] = null; } var clientCompVal = GetPropertyValue(meta, clientEntity, propName); compType.SetPropertyValues(clientCompVal, compValues); } else { var val = meta.GetPropertyValue(entityInfo.Entity, propName); meta.SetPropertyValue(clientEntity, propName, val); } } // TODO: update unmapped properties typeof(EntityInfo).GetProperty("Entity").SetValue(entityInfo, clientEntity); return(true); }
/// <summary> /// Return an empty placeholder object with the Identifier set. We can safely access the identifier /// property without the object being initialized. /// </summary> /// <typeparam name="T"> /// Тип /// </typeparam> /// <param name="persistentObject"> /// The persistent Object. /// </param> /// <param name="persistentType"> /// The persistent Type. /// </param> /// <param name="classMetadata"> /// The class Metadata. /// </param> /// <returns> /// The <see cref="T"/>. /// </returns> private static T CreatePlaceholder <T>(T persistentObject, Type persistentType, IClassMetadata classMetadata) { var placeholderObject = (T)Activator.CreateInstance(persistentType); if (classMetadata.HasIdentifierProperty) { var identifier = classMetadata.GetIdentifier(persistentObject, EntityMode.Poco); classMetadata.SetIdentifier(placeholderObject, identifier, EntityMode.Poco); } return(placeholderObject); }
/// <summary> /// Gets the value. /// </summary> /// <param name="targetResource">The target resource.</param> /// <param name="propertyName">Name of the property.</param> /// <returns></returns> object IUpdatable.GetValue(object targetResource, string propertyName) { IClassMetadata metadata = session.SessionFactory.GetClassMetadata(targetResource.GetType().FullName); if (metadata == null) { throw new DataServiceException("Type not recognized as a valid type for this Context"); } // If if (metadata.IdentifierPropertyName == propertyName) { return(metadata.GetIdentifier(targetResource, EntityMode.Poco)); } else { return(metadata.GetPropertyValue(targetResource, propertyName, EntityMode.Poco)); } }
/// <summary> /// Retrieves the Id of an existing entity /// </summary> /// <param name="instance"></param> /// <returns></returns> protected override string GetId(object instance) { IClassMetadata metadata = sessionFactory.GetClassMetadata(instance.GetType().BaseType); IEntityPersister persister = sessionFactory.GetEntityPersister(instance.GetType().BaseType.ToString()); ((IGraphInstance)instance).SuspendNotifications = true; object id = metadata.GetIdentifier(instance, EntityMode.Poco); ((IGraphInstance)instance).SuspendNotifications = false; // This is a bit of a hack. if (persister.EntityMetamodel.IdentifierProperty.UnsavedValue.IsUnsaved(id).GetValueOrDefault()) { return(null); } string idString = TypeDescriptor.GetConverter(id).ConvertToString(id); return(idString); }
/// <summary> /// /// </summary> /// <param name="entity">an actual entity object, not a proxy!</param> /// <returns></returns> public string ToString(object entity) { IClassMetadata cm = _factory.GetClassMetadata(entity.GetType()); if (cm == null) { return(entity.GetType().FullName); } IDictionary <string, string> result = new Dictionary <string, string>(); if (cm.HasIdentifierProperty) { result[cm.IdentifierPropertyName] = cm.IdentifierType.ToLoggableString(cm.GetIdentifier(entity), _factory); } IType[] types = cm.PropertyTypes; string[] names = cm.PropertyNames; object[] values = cm.GetPropertyValues(entity); for (int i = 0; i < types.Length; i++) { var value = values[i]; if (Equals(LazyPropertyInitializer.UnfetchedProperty, value) || Equals(BackrefPropertyAccessor.Unknown, value)) { result[names[i]] = value.ToString(); } else { result[names[i]] = types[i].ToLoggableString(value, _factory); } } return(cm.EntityName + CollectionPrinter.ToString(result)); }
/// <summary> /// Return the property value for the given entity. /// </summary> /// <param name="meta"></param> /// <param name="entity"></param> /// <param name="propName">If null, the identifier property will be returned.</param> /// <returns></returns> private object GetPropertyValue(IClassMetadata meta, object entity, string propName) { if (propName == null || propName == meta.IdentifierPropertyName) return meta.GetIdentifier(entity, EntityMode.Poco); else return meta.GetPropertyValue(entity, propName, EntityMode.Poco); }
/// <summary> /// Get the value of the foreign key property. This comes from the entity, but if that value is /// null, and the entity is deleted, we try to get it from the originalValuesMap. /// </summary> /// <param name="entityInfo">Breeze EntityInfo</param> /// <param name="meta">Metadata for the entity class</param> /// <param name="foreignKeyName">Name of the foreign key property of the entity, e.g. "CustomerID"</param> /// <returns></returns> private object GetForeignKeyValue(EntityInfo entityInfo, IClassMetadata meta, string foreignKeyName) { var entity = entityInfo.Entity; object id = null; if (foreignKeyName == meta.IdentifierPropertyName) id = meta.GetIdentifier(entity, EntityMode.Poco); else if (meta.PropertyNames.Contains(foreignKeyName)) id = meta.GetPropertyValue(entity, foreignKeyName, EntityMode.Poco); else if (meta.IdentifierType.IsComponentType) { // compound key var compType = meta.IdentifierType as ComponentType; var index = Array.IndexOf<string>(compType.PropertyNames, foreignKeyName); if (index >= 0) { var idComp = meta.GetIdentifier(entity, EntityMode.Poco); id = compType.GetPropertyValue(idComp, index, EntityMode.Poco); } } if (id == null && entityInfo.EntityState == EntityState.Deleted) { entityInfo.OriginalValuesMap.TryGetValue(foreignKeyName, out id); } return id; }
/// <summary> /// Get the value of the foreign key property. This comes from the entity, but if that value is /// null, and the entity is deleted, we try to get it from the originalValuesMap. /// </summary> /// <param name="entityInfo">Breeze EntityInfo</param> /// <param name="meta">Metadata for the entity class</param> /// <param name="foreignKeyName">Name of the foreign key property of the entity, e.g. "CustomerID"</param> /// <returns></returns> private object GetForeignKeyValue(EntityInfo entityInfo, IClassMetadata meta, string foreignKeyName) { var entity = entityInfo.Entity; object id = null; if (foreignKeyName == meta.IdentifierPropertyName) { id = meta.GetIdentifier(entity); } else if (meta.PropertyNames.Contains(foreignKeyName)) { id = meta.GetPropertyValue(entity, foreignKeyName); } else if (meta.IdentifierType.IsComponentType) { // compound key var compType = meta.IdentifierType as ComponentType; var index = Array.IndexOf <string>(compType.PropertyNames, foreignKeyName); if (index >= 0) { var idComp = meta.GetIdentifier(entity); id = compType.GetPropertyValue(idComp, index); } } if (id == null && entityInfo.EntityState == EntityState.Deleted) { entityInfo.OriginalValuesMap.TryGetValue(foreignKeyName, out id); } var syntheticProperties = _session.SessionFactory.GetSyntheticProperties(); // If id is still null try get from a unmapped values (synthetic properties) if (entityInfo.UnmappedValuesMap == null || !entityInfo.UnmappedValuesMap.ContainsKey(foreignKeyName) || syntheticProperties == null || entityInfo.Entity == null) { return(id); } var entityType = entityInfo.Entity.GetType(); if (!syntheticProperties.ContainsKey(entityType)) { return(id); } var synColumn = syntheticProperties[entityType].FirstOrDefault(o => o.Name == foreignKeyName); if (synColumn == null) { return(id); } // We have to convert the value in the propriate type id = entityInfo.UnmappedValuesMap[foreignKeyName]; if (id != null) { // Here we first convert id to string so that we wont get exception like: Cannot convert from Int64 to Int32 id = TypeDescriptor.GetConverter(synColumn.PkType.ReturnedClass).ConvertFromInvariantString(id.ToString()); } return(id); }
private bool SetupEntityInfoForSaving(Type entityType, EntityInfo entityInfo, IClassMetadata meta) { var id = meta.GetIdentifier(entityInfo.Entity); var sessionImpl = _session.GetSessionImplementation(); object dbEntity; string[] propNames; if (entityInfo.EntityState == EntityState.Added) { //meta.Instantiate(id) -> Instantiate method can create a proxy when formulas are present. Saving non persistent proxies will throw an exception dbEntity = Activator.CreateInstance(entityType, true); meta.SetIdentifier(dbEntity, id); } else { //dbEntity = session.Get(entityType, id); Get is not good as it can return a proxy if (meta.IdentifierType.IsComponentType) { // for entities with composite key the identifier is the entity itself // we need to create a copy as ImmediateLoad will fill the given entity var componentType = (ComponentType)meta.IdentifierType; dbEntity = Activator.CreateInstance(entityType, true); // We need to check if the primary key was changed var oldKeyValues = new object[componentType.PropertyNames.Length]; var keyModified = false; for (var i = 0; i < componentType.PropertyNames.Length; i++) { var propName = componentType.PropertyNames[i]; if (entityInfo.OriginalValuesMap.ContainsKey(propName)) { oldKeyValues[i] = entityInfo.OriginalValuesMap[propName]; keyModified = true; } else { oldKeyValues[i] = componentType.GetPropertyValue(entityInfo.Entity, i); } } componentType.SetPropertyValues(dbEntity, oldKeyValues); dbEntity = sessionImpl.ImmediateLoad(entityType.FullName, dbEntity); // As NHibernate does not support updating the primary key we need to do it manually using hql if (keyModified) { var newKeyValues = componentType.GetPropertyValues(entityInfo.Entity); var parameters = new Dictionary <string, KeyValuePair <object, IType> >(); var setStatement = "set "; var whereStatement = "where "; for (var i = 0; i < componentType.PropertyNames.Length; i++) { if (i > 0) { setStatement += ", "; whereStatement += " and "; } var propName = componentType.PropertyNames[i]; var paramName = string.Format("new{0}", propName); setStatement += string.Format("{0}=:{1}", propName, paramName); parameters.Add(paramName, new KeyValuePair <object, IType>(newKeyValues[i], componentType.Subtypes[i])); paramName = string.Format("old{0}", propName); whereStatement += string.Format("{0}=:{1}", propName, paramName); parameters.Add(paramName, new KeyValuePair <object, IType>(oldKeyValues[i], componentType.Subtypes[i])); } var updateQuery = sessionImpl.CreateQuery(new StringQueryExpression(string.Format("update {0} {1} {2}", entityType.Name, setStatement, whereStatement))); foreach (var pair in parameters) { updateQuery.SetParameter(pair.Key, pair.Value.Key, pair.Value.Value); } var count = updateQuery.ExecuteUpdate(); if (count != 1) { throw new InvalidOperationException(string.Format("Query for updating composite key updated '{0}' rows instead of '1'", count)); } componentType.SetPropertyValues(dbEntity, componentType.GetPropertyValues(entityInfo.Entity)); } } else { dbEntity = sessionImpl.ImmediateLoad(entityType.FullName, id); } //dbEntity = session.Get(entityType, id, LockMode.None); } if (dbEntity == null) { throw new NullReferenceException(string.Format("Entity of type '{0}' with id '{1}' does not exists in database", entityType.FullName, id)); } //var modelConfig = BreezeModelConfigurator.GetModelConfiguration(entityType); //Save the original client object _clientEntityObjects[entityInfo] = entityInfo.Entity; //We have to set the properties from the client object propNames = meta.PropertyNames; var propTypes = meta.PropertyTypes; var config = _breezeConfigurator.GetModelConfiguration(entityType); // TODO: set only modified properties for (var i = 0; i < propNames.Length; i++) { var propType = propTypes[i]; var propName = propNames[i]; var memberConfig = config.MemberConfigurations.ContainsKey(propName) ? config.MemberConfigurations[propName] : null; if (memberConfig != null && ( (memberConfig.Ignored.HasValue && memberConfig.Ignored.Value) || (memberConfig.Writable.HasValue && !memberConfig.Writable.Value) || (memberConfig.ShouldDeserializePredicate != null && memberConfig.ShouldDeserializePredicate.Invoke(entityInfo.Entity) == false) )) { continue; } if (propType.IsAssociationType) { continue; } if (propType.IsComponentType) { var compType = (ComponentType)propType; var componentVal = GetPropertyValue(meta, entityInfo.Entity, propName); var dbComponentVal = GetPropertyValue(meta, dbEntity, propName); var compPropsVal = compType.GetPropertyValues(componentVal); compType.SetPropertyValues(dbComponentVal, compPropsVal); } else { var val = meta.GetPropertyValue(entityInfo.Entity, propName); meta.SetPropertyValue(dbEntity, propName, val); } } typeof(EntityInfo).GetProperty("Entity").SetValue(entityInfo, dbEntity); return(true); }
private bool SetupEntityInfoForSerialization(Type entityType, EntityInfo entityInfo, IClassMetadata meta) { if (!_removeMode || !_clientEntityObjects.ContainsKey(entityInfo)) { return(false); } var clientEntity = _clientEntityObjects[entityInfo]; var id = meta.GetIdentifier(entityInfo.Entity); meta.SetIdentifier(clientEntity, id); //We have to set the properties from the client object var propNames = meta.PropertyNames; var propTypes = meta.PropertyTypes; using (var childSession = _session.SessionWithOptions().Connection().OpenSession()) { for (var i = 0; i < propNames.Length; i++) { var propType = propTypes[i]; var propName = propNames[i]; if (propType is IAssociationType associationType) { if (entityInfo.UnmappedValuesMap != null && new[] { "Id", "Code" }.Any(x => entityInfo.UnmappedValuesMap.ContainsKey(propName + x))) { var associatedEntityName = associationType.GetAssociatedEntityName((ISessionFactoryImplementor)_session.SessionFactory); var associatedEntityMetadata = _session.SessionFactory.GetClassMetadata(associatedEntityName); var associatedEntityValue = GetPropertyValue(meta, entityInfo.Entity, propName); if (associatedEntityValue != null) { clientEntity.SetMemberValue(propName, childSession.Load(associatedEntityName, GetPropertyValue(associatedEntityMetadata, associatedEntityValue, null))); } } } else if (propType.IsComponentType) { var compType = (ComponentType)propType; var compPropNames = compType.PropertyNames; var compPropTypes = compType.Subtypes; var component = GetPropertyValue(meta, entityInfo.Entity, propName); var compValues = compType.GetPropertyValues(component); for (var j = 0; j < compPropNames.Length; j++) { var compPropType = compPropTypes[j]; if (!compPropType.IsAssociationType) { continue; } compValues[j] = null; } var clientCompVal = GetPropertyValue(meta, clientEntity, propName); compType.SetPropertyValues(clientCompVal, compValues); } else { var val = meta.GetPropertyValue(entityInfo.Entity, propName); meta.SetPropertyValue(clientEntity, propName, val); } } } // TODO: update unmapped properties typeof(EntityInfo).GetProperty("Entity").SetValue(entityInfo, clientEntity); return(true); }