/// <summary>
        /// Set an association value based on the value of the foreign key.  This updates the property of the entity.
        /// </summary>
        /// <param name="propName">Name of the navigation/association property of the entity, e.g. "Customer".  May be null if the property is the entity's identifier.</param>
        /// <param name="propType">Type of the property</param>
        /// <param name="entityInfo">Breeze EntityInfo</param>
        /// <param name="meta">Metadata for the entity class</param>
        private void FixupRelationship(string propName, EntityType propType, EntityInfo entityInfo, IClassMetadata meta)
        {
            var entity = entityInfo.Entity;

            if (removeMode)
            {
                meta.SetPropertyValue(entity, propName, null, EntityMode.Poco);
                return;
            }
            object relatedEntity = GetPropertyValue(meta, entity, propName);

            if (relatedEntity != null)
            {
                // entities are already connected - still need to add to dependency graph
                EntityInfo relatedEntityInfo = FindInSaveMapByEntity(propType.ReturnedClass, relatedEntity);
                MaybeAddToGraph(entityInfo, relatedEntityInfo, propType);
                return;
            }

            relatedEntity = GetRelatedEntity(propName, propType, entityInfo, meta);

            if (relatedEntity != null)
            {
                meta.SetPropertyValue(entity, propName, relatedEntity, EntityMode.Poco);
            }
        }
示例#2
0
        protected override int ExecuteInsert(IDictionary values)
        {
            ActiveRecordDataSourceCreateEventArgs args = new ActiveRecordDataSourceCreateEventArgs();

            args.ModelType    = BuildManager.GetType(Source.TypeName, false, true);
            args.CreateValues = values;

            CreateValuesFromCreateParameters(args);

            IClassMetadata meta = ActiveRecordMediator.GetSessionFactoryHolder().GetSessionFactory(args.ModelType).GetClassMetadata(args.ModelType);

            if (!meta.HasIdentifierProperty)
            {
                throw new ApplicationException("ActiveRecordDataSourceView requires a primary key for the update method.");
            }

            Source.OnBeforeCreate(args);

            if (args.Cancel)
            {
                return(0);
            }

            try
            {
                if (args.Entity == null)
                {
                    args.Entity = Activator.CreateInstance(args.ModelType);
                }

                foreach (string key in args.CreateValues.Keys)
                {
                    meta.SetPropertyValue(args.Entity, key, args.CreateValues[key]);
                }

                ActiveRecordMediator.Create(args.Entity);
            }
            catch (Exception e)
            {
                args.Exception = e;
                args.WasError  = true;

                Source.OnCreateError(args);

                if (Source.ThrowOnError && !args.DoNotThrow)
                {
                    throw;
                }

                return(0);
            }

            Source.OnCreate(args);

            return(1);
        }
示例#3
0
        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);
        }
示例#4
0
        /// <summary>
        /// Set an association value based on the value of the foreign key.  This updates the property of the entity.
        /// </summary>
        /// <param name="propName">Name of the navigation/association property of the entity, e.g. "Customer".  May be null if the property is the entity's identifier.</param>
        /// <param name="propType">Type of the property</param>
        /// <param name="entityInfo">Breeze EntityInfo</param>
        /// <param name="meta">Metadata for the entity class</param>
        private void FixupRelationship(string propName, EntityType propType, EntityInfo entityInfo, IClassMetadata meta)
        {
            var entity = entityInfo.Entity;

            if (removeMode)
            {
                meta.SetPropertyValue(entity, propName, null, EntityMode.Poco);
                return;
            }
            object relatedEntity = GetPropertyValue(meta, entity, propName);

            if (relatedEntity != null)
            {
                return;                           // entities are already connected
            }
            relatedEntity = GetRelatedEntity(propName, propType, entityInfo, meta);

            if (relatedEntity != null)
            {
                meta.SetPropertyValue(entity, propName, relatedEntity, EntityMode.Poco);
            }
        }
示例#5
0
        /// <summary>
        /// Restore the old value of the concurrency column so Hibernate will save the entity.
        /// Otherwise it will complain because Breeze has already changed the value.
        /// </summary>
        /// <param name="entityInfo"></param>
        /// <param name="classMeta"></param>
        private void RestoreOldVersionValue(EntityInfo entityInfo, IClassMetadata classMeta)
        {
            var    vcol  = classMeta.VersionProperty;
            var    vname = classMeta.PropertyNames[vcol];
            object oldVersion;

            if (entityInfo.OriginalValuesMap.TryGetValue(vname, out oldVersion))
            {
                var entity = entityInfo.Entity;
                var vtype  = classMeta.PropertyTypes[vcol].ReturnedClass;
                oldVersion = Convert.ChangeType(oldVersion, vtype);     // because JsonConvert makes all integers Int64
                classMeta.SetPropertyValue(entity, vname, oldVersion, EntityMode.Poco);
            }
        }
示例#6
0
        /// <summary>
        /// Set the navigation properties to null on the given entity.
        /// </summary>
        /// <param name="entityInfo"></param>
        /// <param name="meta"></param>
        private void RemoveRelationships(EntityInfo entityInfo, IClassMetadata meta)
        {
            var entity    = entityInfo.Entity;
            var propNames = meta.PropertyNames;
            var propTypes = meta.PropertyTypes;

            for (int i = 0; i < propNames.Length; i++)
            {
                var propType = propTypes[i];
                if (propType.IsAssociationType && propType.IsEntityType)
                {
                    meta.SetPropertyValue(entity, propNames[i], null, EntityMode.Poco);
                }
            }
        }
示例#7
0
        /// <summary>
        /// Set an association value based on the value of the foreign key.  This updates the property of the entity.
        /// </summary>
        /// <param name="propName">Name of the navigation/association property of the entity, e.g. "Customer".  May be null if the property is the entity's identifier.</param>
        /// <param name="propType">Type of the property</param>
        /// <param name="entityInfo">Breeze EntityInfo</param>
        /// <param name="meta">Metadata for the entity class</param>
        private void FixupRelationship(string propName, EntityType propType, EntityInfo entityInfo, IClassMetadata meta)
        {
            var entity = entityInfo.Entity;

            if (_removeMode)
            {
                var foreignKeyName = FindForeignKey(propName, meta);
                var id             = GetForeignKeyValue(entityInfo, meta, foreignKeyName);
                meta.SetPropertyValue(entity, propName, null);
                if (id != null)
                {
                    meta.SetPropertyValue(entity, foreignKeyName, id); //Set the foreigenkey as the foreign key property may be computed (resets when the relation is set)
                }

                return;
            }
            //object relatedEntity = GetPropertyValue(meta, entity, propName);
            //if (relatedEntity != null) return;    // entities are already connected

            var relatedEntity = GetRelatedEntity(propName, propType, entityInfo, meta);

            //if (relatedEntity != null) Unset if the synthetic property is not set
            meta.SetPropertyValue(entity, propName, relatedEntity);
        }
        /// <summary>
        /// Sets the value.
        /// </summary>
        /// <param name="targetResource">The target resource.</param>
        /// <param name="propertyName">Name of the property.</param>
        /// <param name="propertyValue">The property value.</param>
        void IUpdatable.SetValue(object targetResource, string propertyName, object propertyValue)
        {
            IClassMetadata metadata = session.SessionFactory.GetClassMetadata(targetResource.GetType().FullName);

            if (metadata == null)
            {
                throw new DataServiceException("Type not recognized as a valid type for this Context");
            }

            // See if its the Key property first
            if (metadata.IdentifierPropertyName == propertyName)
            {
                metadata.SetIdentifier(targetResource, propertyValue, EntityMode.Poco);
            }
            else             // Else set the property
            {
                metadata.SetPropertyValue(targetResource, propertyName, propertyValue, EntityMode.Poco);
            }
        }
示例#9
0
        /// <summary>
        /// Connect the related entities based on the foreign key values.
        /// Note that this may cause related entities to be loaded from the DB if they are not already in the session.
        /// </summary>
        /// <param name="entityInfo">Entity that will be saved</param>
        /// <param name="meta">Metadata about the entity type</param>
        private void FixupRelationships(EntityInfo entityInfo, IClassMetadata meta)
        {
            var propNames = meta.PropertyNames;
            var propTypes = meta.PropertyTypes;

            if (meta.IdentifierType != null)
            {
                var propType = meta.IdentifierType;
                if (propType.IsAssociationType && propType.IsEntityType)
                {
                    FixupRelationship(meta.IdentifierPropertyName, (EntityType)propType, entityInfo, meta);
                }
                else if (propType.IsComponentType)
                {
                    FixupComponentRelationships(meta.IdentifierPropertyName, (ComponentType)propType, entityInfo, meta);
                }
            }

            for (var i = 0; i < propNames.Length; i++)
            {
                var propType = propTypes[i];
                if (propType.IsAssociationType && propType.IsEntityType)
                {
                    FixupRelationship(propNames[i], (EntityType)propTypes[i], entityInfo, meta);
                    var oneToManyType = propType as ManyToOneType;
                    if (oneToManyType != null && !_removeMode)
                    {
                        TryToFindAndLinkBidirectionalRelation(oneToManyType, (EntityType)propTypes[i], propNames[i], entityInfo, meta);
                    }
                }
                else if (propType.IsComponentType)
                {
                    FixupComponentRelationships(propNames[i], (ComponentType)propType, entityInfo, meta);
                }
                else if (propType.IsAssociationType && propType.IsCollectionType && _removeMode)
                {
                    meta.SetPropertyValue(entityInfo.Entity, propNames[i], null);
                }
            }
        }
        /// <summary>
        /// Set an association value based on the value of the foreign key.  This updates the property of the entity.
        /// </summary>
        /// <param name="propName">Name of the navigation/association property of the entity, e.g. "Customer".  May be null if the property is the entity's identifier.</param>
        /// <param name="propType">Type of the property</param>
        /// <param name="entityInfo">Breeze EntityInfo</param>
        /// <param name="meta">Metadata for the entity class</param>
        private void FixupRelationship(string propName, EntityType propType, EntityInfo entityInfo, IClassMetadata meta)
        {
            var entity = entityInfo.Entity;
            if (removeMode)
            {
                meta.SetPropertyValue(entity, propName, null, EntityMode.Poco);
                return;
            }
            object relatedEntity = GetPropertyValue(meta, entity, propName);
            if (relatedEntity != null) return;    // entities are already connected

            relatedEntity = GetRelatedEntity(propName, propType, entityInfo, meta);

            if (relatedEntity != null)
                meta.SetPropertyValue(entity, propName, relatedEntity, EntityMode.Poco);
        }
示例#11
0
        /// <summary>
        /// Find out if a bidirectional relation exists, if exists then add entity to the collection
        /// </summary>
        /// <param name="manyToOneType">Many to one relation</param>
        /// <param name="childEntityType">Entity type of the child</param>
        /// <param name="propertyName">Property name of the ManyToOne realtion</param>
        /// <param name="childEntityInfo">Entity info of the child</param>
        /// <param name="childMeta">Child metadata</param>
        /// <returns>true if the child entity was added or removed from the parent entity collection, otherwise false</returns>
        private bool TryToFindAndLinkBidirectionalRelation(ManyToOneType manyToOneType,
                                                           EntityType childEntityType, string propertyName,
                                                           EntityInfo childEntityInfo, IClassMetadata childMeta)
        {
            var fk             = FindForeignKey(propertyName, childMeta);
            var parentMeta     = _session.SessionFactory.GetClassMetadata(manyToOneType.ReturnedClass);
            var propNames      = parentMeta.PropertyNames;
            var propTypes      = parentMeta.PropertyTypes;
            var childPersister = childMeta as AbstractEntityPersister;

            if (childPersister == null)
            {
                return(false);
            }
            var colProp = new Dictionary <string, string>();

            for (var i = 0; i < childPersister.PropertyNames.Length; i++)
            {
                var propName = childPersister.PropertyNames[i];
                var propType = childPersister.GetPropertyType(propName);
                if (propType.IsAssociationType)
                {
                    continue;
                }
                foreach (var col in childPersister.GetPropertyColumnNames(i))
                {
                    if (col == null)
                    {
                        continue; // formula
                    }
                    if (!colProp.ContainsKey(col))
                    {
                        colProp.Add(col, propName);
                    }
                }
            }
            if (childPersister.IdentifierType.IsComponentType)
            {
                var componentType = (ComponentType)childPersister.IdentifierType;
                for (var i = 0; i < componentType.PropertyNames.Length; i++)
                {
                    colProp.Add(childPersister.IdentifierColumnNames[i], componentType.PropertyNames[i]);
                }
            }
            else
            {
                foreach (var col in childPersister.IdentifierColumnNames)
                {
                    colProp.Add(col, childPersister.IdentifierPropertyName);
                }
            }


            for (var i = 0; i < propNames.Length; i++)
            {
                var propType = propTypes[i];
                var propName = propNames[i];
                if (!propType.IsAssociationType || !propType.IsCollectionType)
                {
                    continue;
                }
                var colType = (CollectionType)propType;

                var refCols  = colType.GetReferencedColumns(_session.GetSessionImplementation().Factory);
                var refProps = refCols.Select(refCol => !colProp.ContainsKey(refCol) ? refCol : colProp[refCol]).ToArray();
                if (NHMetadataBuilder.CatColumnNames(refProps) != fk)
                {
                    continue;
                }

                var elmType = colType.GetElementType(_session.GetSessionImplementation().Factory);
                if (!elmType.ReturnedClass.IsAssignableFrom(childMeta.MappedClass))
                {
                    continue;
                }

                var parentEntity = GetRelatedEntity(propertyName, childEntityType, childEntityInfo, childMeta);
                if (parentEntity == null)
                {
                    return(false);
                }

                var coll = parentMeta.GetPropertyValue(parentEntity, propName) as IEnumerable;

                if (coll == null) //Should happen only if the parent entity is not in db
                {
                    //TODO: instantiate collection
                    continue;
                }
                var collType = coll.GetType();

                //Initialize collection in order to prevent flushing
                if (!NHibernateUtil.IsInitialized(coll))
                {
                    NHibernateUtil.Initialize(coll);
                }

                if (colType.ReturnedClass.IsGenericType)
                {
                    var state = childEntityInfo.EntityState;
                    if (_saveMap.ContainsKey(manyToOneType.ReturnedClass))
                    {
                        var parentEntityInfo =
                            _saveMap[manyToOneType.ReturnedClass].FirstOrDefault(o => o.Entity == parentEntity);
                        if (parentEntityInfo != null)
                        {
                            switch (parentEntityInfo.EntityState)
                            {
                            case EntityState.Added:
                                //if the parent is added then we need to add child to the collection even if the it is only updated or unmodified
                                if (state != EntityState.Deleted)
                                {
                                    state = EntityState.Added;
                                }
                                break;

                            case EntityState.Deleted:
                                //TODO: check for cascade option
                                break;

                            case EntityState.Modified:
                                break;
                            }
                        }
                    }

                    //TODO: check if parent is new
                    switch (state)
                    {
                    case EntityState.Deleted:
                        var removeMethod = collType.GetMethod("Remove") ??
                                           collType.GetInterfaces()
                                           .Select(o => o.GetMethod("Remove"))
                                           .FirstOrDefault(o => o != null);
                        var removed = false;
                        if (removeMethod != null)
                        {
                            IEqualityComparer comparer = new EntityComparer(childMeta);

                            foreach (var item in coll)
                            {
                                if (comparer.Equals(item, childEntityInfo.Entity))
                                {
                                    removed = (bool)removeMethod.Invoke(coll, new[] { item });
                                    break;
                                }
                            }
                        }
                        childMeta.SetPropertyValue(childEntityInfo.Entity, propertyName, null);    //Remove relation on both sides
                        return(removed);

                    case EntityState.Added:
                        var addMethod = collType.GetMethod("Add") ??
                                        collType.GetInterfaces()
                                        .Select(o => o.GetMethod("Add"))
                                        .FirstOrDefault(o => o != null);
                        if (addMethod != null)
                        {
                            addMethod.Invoke(coll, new[] { childEntityInfo.Entity });
                            return(true);
                        }
                        break;
                    }
                }
                //TODO: non generic collections
            }
            return(false);
        }
示例#12
0
        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);
        }
        /// <summary>
        /// Set an association value based on the value of the foreign key.  This updates the property of the entity.
        /// </summary>
        /// <param name="propName">Name of the navigation/association property of the entity, e.g. "Customer".  May be null if the property is the entity's identifier.</param>
        /// <param name="propType">Type of the property</param>
        /// <param name="entityInfo">Breeze EntityInfo</param>
        /// <param name="meta">Metadata for the entity class</param>
        private void FixupRelationship(string propName, EntityType propType, EntityInfo entityInfo, IClassMetadata meta)
        {
            var entity = entityInfo.Entity;
            if (removeMode)
            {
                meta.SetPropertyValue(entity, propName, null, EntityMode.Poco);
                return;
            }
            object relatedEntity = GetPropertyValue(meta, entity, propName);
            if (relatedEntity != null)
            {
                // entities are already connected - still need to add to dependency graph
                EntityInfo relatedEntityInfo = FindInSaveMapByEntity(propType.ReturnedClass, relatedEntity);
                MaybeAddToGraph(entityInfo, relatedEntityInfo, propType);
                return;
            }

            relatedEntity = GetRelatedEntity(propName, propType, entityInfo, meta);

            if (relatedEntity != null)
                meta.SetPropertyValue(entity, propName, relatedEntity, EntityMode.Poco);
        }
示例#14
0
        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);
        }
示例#15
0
        /// <summary>
        /// Set an association value based on the value of the foreign key.  This updates the property of the entity.
        /// </summary>
        /// <param name="propName">Name of the navigation/association property of the entity, e.g. "Customer".  May be null if the property is the entity's identifier.</param>
        /// <param name="propType">Type of the property</param>
        /// <param name="entityInfo">Breeze EntityInfo</param>
        /// <param name="meta">Metadata for the entity class</param>
        /// <param name="canUseSession">Whether we can load the related entity via the Session.  
        /// If false, we only connect entities that are also in the saveMap</param>
        private void FixupRelationship(string propName, IType propType, EntityInfo entityInfo, IClassMetadata meta, bool canUseSession)
        {
            var entity = entityInfo.Entity;
            object relatedEntity = GetPropertyValue(meta, entity, propName);
            if (relatedEntity != null) return;    // entities are already connected

            relatedEntity = GetRelatedEntity(propName, propType, entityInfo, meta, canUseSession);

            if (relatedEntity != null)
                meta.SetPropertyValue(entity, propName, relatedEntity, EntityMode.Poco);
        }