/// <summary>
 /// Recupera as propriedades de persistencia que são usadas pela ação de atualização.
 /// </summary>
 /// <param name="instanceType"></param>
 /// <param name="propertyNames"></param>
 /// <param name="direction"></param>
 /// <param name="typeMetadata"></param>
 /// <param name="isConditional"></param>
 /// <returns></returns>
 private IEnumerable <System.Reflection.PropertyInfo> GetDeletePersistenceProperties(Type instanceType, string[] propertyNames, DirectionPropertiesName direction, ITypeMetadata typeMetadata, bool isConditional)
 {
     if (isConditional)
     {
         return(Enumerable.Empty <System.Reflection.PropertyInfo>());
     }
     else
     {
         return(typeMetadata.GetKeyProperties().Select(f => instanceType.GetProperty(f.Name)).Where(f => f != null));
     }
 }
        /// <summary>
        /// Recupera as propriedades de persistencia que são usadas pela ação de inserção.
        /// </summary>
        /// <param name="instanceType"></param>
        /// <param name="propertyNames"></param>
        /// <param name="direction"></param>
        /// <param name="typeMetadata"></param>
        /// <returns></returns>
        private IEnumerable <System.Reflection.PropertyInfo> GetInsertPersistenceProperties(Type instanceType, string[] propertyNames, DirectionPropertiesName direction, ITypeMetadata typeMetadata)
        {
            var parameterTypes = new PersistenceParameterType[] {
                PersistenceParameterType.Field
            };
            var directions = new DirectionParameter[] {
                DirectionParameter.Output,
                DirectionParameter.InputOptionalOutput,
                DirectionParameter.InputOutput,
                DirectionParameter.OutputOnlyInsert,
                DirectionParameter.OnlyInsert,
                DirectionParameter.InputOptionalOutputOnlyInsert
            };
            var mapping = typeMetadata.Where(f => directions.Contains(f.Direction) && parameterTypes.Contains(f.ParameterType)).ToList();

            FilterMapping(propertyNames, direction, mapping, typeMetadata, PersistenceActionType.Insert);
            var keyMapping = typeMetadata.GetKeyProperties();

            return(mapping.Union(keyMapping, PropertyMetadataEqualityComparer.Instance).Select(f => instanceType.GetProperty(f.Name)).Where(f => f != null));
        }
Exemplo n.º 3
0
        /// <summary>
        /// Cria um registro com base nas chaves do resultado da consulta.
        /// </summary>
        /// <param name="entities"></param>
        /// <param name="keys"></param>
        /// <returns></returns>
        private Record CreateRecord(EntityInfo[] entities, object[] keys)
        {
            var entries = new object[entities.Length];

            for (var i = 0; i < keys.Length; i++)
            {
                if (keys[i] != null)
                {
                    var entry = _cache[keys[i]];
                    if (entry is UserBinaryObject)
                    {
                        var binaryObject = (UserBinaryObject)entry;
                        using (var ms = new System.IO.MemoryStream(binaryObject.GetFullObject(), false))
                            entry = Colosoft.Serialization.Formatters.CompactBinaryFormatter.Deserialize(ms, _cache.Name);
                    }
                    entries[i] = entry;
                }
            }
            PropertyInfo[][] propertyInfos = null;
            if (_descriptor == null)
            {
                var descriptor = new Record.RecordDescriptor();
                _projectionPositions = new List <KeyValuePair <int, string> >();
                if (_query == null || _query.Projection == null || _query.Projection.Count == 0)
                {
                    var entitiesIndex = new List <int>();
                    if (_query != null)
                    {
                        foreach (var info in _query.Entities)
                        {
                            var index = Array.FindIndex(entities, f => !string.IsNullOrEmpty(f.Alias) ? f.Alias == info.Alias : f.FullName == info.FullName);
                            if (index >= 0)
                            {
                                entitiesIndex.Add(index);
                            }
                        }
                    }
                    else
                    {
                        for (var i = 0; i < entities.Length; i++)
                        {
                            entitiesIndex.Add(i);
                        }
                    }
                    foreach (var i in entitiesIndex)
                    {
                        var typeMetadata = GetTypeMetadata(entities[i]);
                        if (typeMetadata == null)
                        {
                            throw new InvalidOperationException(string.Format("Not found TypeMetadata for entity '{0}'", entities[i]));
                        }
                        foreach (var property in typeMetadata)
                        {
                            var index = 0;
                            while (descriptor.Contains(property.Name + (index > 0 ? index.ToString() : "")))
                            {
                                index++;
                            }
                            descriptor.Add(new Record.Field(property.Name + (index > 0 ? index.ToString() : ""), Type.GetType(property.PropertyType, true)));
                            _projectionPositions.Add(new KeyValuePair <int, string>(i, property.Name));
                        }
                        if (typeMetadata.IsVersioned && !descriptor.Contains("RowVersion"))
                        {
                            descriptor.Add(new Record.Field("RowVersion", typeof(long)));
                            _projectionPositions.Add(new KeyValuePair <int, string>(i, "RowVersion"));
                        }
                    }
                }
                else
                {
                    var typeMetadatas = new Dictionary <int, ITypeMetadata>();
                    foreach (var projectionEntry in _query.Projection)
                    {
                        var columnInfo = projectionEntry.GetColumnInfo();
                        if (columnInfo == null)
                        {
                            continue;
                        }
                        var entityInfo = _query.Entities.Where(f => f.Alias == columnInfo.Owner).FirstOrDefault();
                        if (entityInfo == null)
                        {
                            entityInfo = _query.Entities.FirstOrDefault();
                        }
                        var entityIndex = -1;
                        for (var i = 0; i < entities.Length; i++)
                        {
                            if (EntityInfoAliasComparer.Instance.Equals(entities[i], entityInfo))
                            {
                                entityIndex = i;
                                break;
                            }
                        }
                        var name  = columnInfo.Alias ?? columnInfo.Name;
                        var index = 0;
                        while (descriptor.Contains(name + (index > 0 ? index.ToString() : "")))
                        {
                            index++;
                        }
                        if (index > 0)
                        {
                            name += index.ToString();
                        }
                        if (entityIndex < 0)
                        {
                            descriptor.Add(new Record.Field(name, typeof(string)));
                            _projectionPositions.Add(new KeyValuePair <int, string>(-1, null));
                            continue;
                        }
                        ITypeMetadata typeMetadata = null;
                        if (!typeMetadatas.TryGetValue(entityIndex, out typeMetadata))
                        {
                            typeMetadata = GetTypeMetadata(entities[entityIndex]);
                            if (typeMetadata == null)
                            {
                                throw new InvalidOperationException(string.Format("Not found TypeMetadata for entity '{0}'", entities[entityIndex]));
                            }
                            typeMetadatas.Add(entityIndex, typeMetadata);
                        }
                        if (columnInfo.Name == "TableId")
                        {
                            var identityProperty = typeMetadata.GetKeyProperties().FirstOrDefault();
                            if (identityProperty != null)
                            {
                                descriptor.Add(new Record.Field(name, Type.GetType(identityProperty.PropertyType)));
                                _projectionPositions.Add(new KeyValuePair <int, string>(entityIndex, identityProperty.Name));
                            }
                        }
                        else if (columnInfo.Name == Colosoft.Query.DataAccessConstants.RowVersionPropertyName && typeMetadata.IsVersioned)
                        {
                            descriptor.Add(new Record.Field(name, typeof(long)));
                            _projectionPositions.Add(new KeyValuePair <int, string>(entityIndex, Colosoft.Query.DataAccessConstants.RowVersionPropertyName));
                            break;
                        }
                        else
                        {
                            foreach (var property in typeMetadata)
                            {
                                if (property.Name == columnInfo.Name)
                                {
                                    descriptor.Add(new Record.Field(name, Type.GetType(property.PropertyType)));
                                    _projectionPositions.Add(new KeyValuePair <int, string>(entityIndex, property.Name));
                                    break;
                                }
                            }
                        }
                    }
                }
                _descriptor = descriptor;
            }
            object[] values = new object[_descriptor.Count];
            for (var projIndex = 0; projIndex < _projectionPositions.Count; projIndex++)
            {
                var projPosition = _projectionPositions[projIndex];
                if (projPosition.Key < 0)
                {
                    continue;
                }
                var entry = entries[projPosition.Key];
                if (entry == null)
                {
                    continue;
                }
                if (entry is ICacheItemRecord)
                {
                    var itemRecord = (ICacheItemRecord)entry;
                    if (itemRecord.Descriptor.Contains(projPosition.Value))
                    {
                        values[projIndex] = itemRecord.GetValue(projPosition.Value);
                    }
                }
                else
                {
                    if (propertyInfos == null)
                    {
                        propertyInfos = new PropertyInfo[entries.Length][];
                    }
                    if (propertyInfos[projPosition.Key] == null && entry != null)
                    {
                        propertyInfos[projPosition.Key] = entry.GetType().GetProperties(BindingFlags.Public | BindingFlags.Instance).OrderBy(f => f.Name).ToArray();
                    }
                    if (entry != null)
                    {
                        var propertyInfo = propertyInfos[projPosition.Key].Where(f => f.Name == projPosition.Value).FirstOrDefault();
                        if (propertyInfo != null)
                        {
                            values[projIndex] = propertyInfo.GetValue(entry, null);
                        }
                    }
                }
            }
            return(_descriptor.CreateRecord(values));
        }