Esempio n. 1
0
        /// <summary>
        /// Applies expand for the given <see cref="IQueryable"/>.
        /// </summary>
        /// <param name="queryable">The queryable to expand.</param>
        /// <param name="entityQuery">The entity query containing the expand information.</param>
        /// <param name="elementType">The element type of the queryable.</param>
        /// <param name="postExecuteExpandPaths">An output parameter with expand paths that have to be expanded after the query execution.</param>
        /// <returns>The expanded queryable.</returns>
        protected virtual IQueryable ApplyExpand(IQueryable queryable, EntityQuery entityQuery, Type elementType, out List <string> postExecuteExpandPaths)
        {
            postExecuteExpandPaths = null;
            if (EntityQuery.ApplyExpand != null)
            {
                return(EntityQuery.ApplyExpand(entityQuery, queryable, elementType));
            }

            if (entityQuery.ExpandClause == null)
            {
                return(queryable);
            }

            if (!_entityMetadataProvider.IsEntityType(elementType))
            {
                throw new InvalidOperationException($"Unknown entity type {elementType}.");
            }

            var metadata = _entityMetadataProvider.GetMetadata(elementType);

            if (!CanApplyQueryExpands(queryable, metadata, entityQuery))
            {
                postExecuteExpandPaths = entityQuery.ExpandClause.PropertyPaths.ToList();
                return(queryable);
            }

            foreach (var propertyPath in entityQuery.ExpandClause.PropertyPaths)
            {
                queryable = ApplyQueryExpand(queryable, propertyPath.Replace('/', '.'));
            }

            return(queryable);
        }
Esempio n. 2
0
        private EntityMetadata GetMetadata(string entityTypeName)
        {
            var entityName = BreezeHelper.GetEntityName(entityTypeName);
            var metadata   = _classMetadataProvider.Get(entityName);

            if (metadata == null)
            {
                throw new InvalidOperationException($"Unknown entity name: {entityName}");
            }

            return(_entityMetadataProvider.GetMetadata(metadata.MappedClass));
        }
Esempio n. 3
0
        private ModelMetadata GetTypeMetadata(Type type)
        {
            if (_entityMetadataProvider.IsEntityType(type))
            {
                return(_entityMetadataProvider.GetMetadata(type));
            }

            if (_clientModelMetadataProvider.IsClientModel(type))
            {
                return(_clientModelMetadataProvider.GetMetadata(type));
            }

            return(null);
        }
        /// <summary>
        /// Builds <see cref="BreezeMetadata"/>.
        /// </summary>
        /// <returns>The breeze metadata.</returns>
        public BreezeMetadata Build()
        {
            var metadata = new BreezeMetadata
            {
                StructuralTypes             = new List <StructuralType>(),
                ResourceEntityTypeMap       = new Dictionary <string, string>(),
                EnumTypes                   = new List <EnumType>(),
                LocalQueryComparisonOptions = _localQueryComparisonOptions ?? "caseInsensitiveSQL"
            };

            _addedTypes.Clear();
            _entityMetadata = _classMetadataProvider.GetAll()
                              .Select(o => o.MappedClass)
                              .Where(o => o != null)
                              .Where(o => _includePredicate?.Invoke(o) ?? true)
                              .Distinct()
                              .Select(o => new { MappedClass = o, Metadata = _entityMetadataProvider.GetMetadata(o) })
                              .ToDictionary(o => o.MappedClass, o => o.Metadata);

            foreach (var entityMetadata in _entityMetadata.Values)
            {
                AddEntityType(entityMetadata, metadata);
            }

            if (_clientModelAssemblies == null)
            {
                return(metadata);
            }

            // Add client models
            _clientModelMetadata = _clientModelAssemblies?.SelectMany(assembly => assembly.GetTypes()
                                                                      .Where(t => t.IsClass && !t.IsAbstract && _clientModelMetadataProvider.IsClientModel(t)))
                                   .Where(t => _includePredicate?.Invoke(t) ?? true)
                                   .Select(o => _clientModelMetadataProvider.GetMetadata(o))
                                   .ToDictionary(o => o.Type, o => o);

            foreach (var modelMetadata in _clientModelMetadata.Values)
            {
                AddClientModelType(modelMetadata, metadata);
            }

            return(metadata);
        }
Esempio n. 5
0
        private static IEnumerable <PropertyInfo> GetProperties(Type instanceType, String propertyPath, IEntityMetadataProvider entityMetadataProvider,
                                                                ICollection <PropertyInfo> syntheticProperties, bool throwOnError = true)
        {
            var propertyNames = propertyPath.Split('.');

            var nextInstanceType = instanceType;
            var nextMetadata     = entityMetadataProvider.IsEntityType(nextInstanceType) ? entityMetadataProvider.GetMetadata(instanceType) : null;

            foreach (var propertyName in propertyNames)
            {
                PropertyInfo property;
                if (nextMetadata != null && nextMetadata.SyntheticForeignKeyProperties.TryGetValue(propertyName, out var syntheticProperty))
                {
                    yield return(GetProperty(nextInstanceType, syntheticProperty.AssociationPropertyName, throwOnError));

                    property = GetProperty(syntheticProperty.EntityType, syntheticProperty.IdentifierPropertyName, throwOnError);
                    syntheticProperties?.Add(property);
                }
                else
                {
                    property = GetProperty(nextInstanceType, propertyName, throwOnError);
                }

                if (property != null)
                {
                    yield return(property);

                    nextInstanceType = property.PropertyType;
                    nextMetadata     = entityMetadataProvider.IsEntityType(nextInstanceType) ? entityMetadataProvider.GetMetadata(nextInstanceType) : null;
                }
                else
                {
                    break;
                }
            }
        }
Esempio n. 6
0
        public SaveBundle GetSaveBundle()
        {
            var entities   = new List <JObject>();
            var saveBundle = new SaveBundle
            {
                Entities    = entities,
                SaveOptions = new SaveOptions()
            };


            foreach (var pair in _typeEntities)
            {
                var session        = _sessionProvider.Get(pair.Key);
                var sessionImpl    = session.GetSessionImplementation();
                var context        = sessionImpl.PersistenceContext;
                var entityType     = pair.Key;
                var entityTypeInfo = pair.Value;
                var entityMetadata = entityTypeInfo.EntityMetadata;
                var persister      = entityMetadata.EntityPersister;
                foreach (var entityInfo in entityTypeInfo.EntitiesInfo.Values)
                {
                    var entity         = entityInfo.Entity;
                    var originalValues = new JObject();
                    var unmappedValues = new JObject();
                    var entityAspect   = new JObject
                    {
                        ["entityTypeName"]    = $"{entityType.Name}:#{entityType.Namespace}",
                        ["originalValuesMap"] = originalValues,
                        ["entityState"]       = entityInfo.EntityState.ToString()
                    };
                    if (entityMetadata.AutoGeneratedKeyType != AutoGeneratedKeyType.None)
                    {
                        var autoGeneratedKey =
                            new JObject
                        {
                            ["propertyName"]         = entityMetadata.IdentifierPropertyNames[0],
                            ["autoGeneratedKeyType"] = entityMetadata.AutoGeneratedKeyType.ToString()
                        };
                        entityAspect["autoGeneratedKey"] = autoGeneratedKey;
                    }

                    var entityData = new JObject();
                    for (var i = 0; i < entityMetadata.IdentifierPropertyNames.Count; i++)
                    {
                        var idPropertyName = entityMetadata.IdentifierPropertyNames[i];
                        var idValue        = GetToken(entityMetadata.IdentifierPropertyGetters[i](entity));
                        if (entityMetadata.SyntheticForeignKeyProperties.ContainsKey(idPropertyName))
                        {
                            unmappedValues.Add(idPropertyName, idValue);
                        }
                        else
                        {
                            entityData.Add(idPropertyName, idValue);
                        }
                    }

                    var propertyTypes = persister.PropertyTypes;
                    for (var i = 0; i < propertyTypes.Length; i++)
                    {
                        var propertyType = propertyTypes[i];
                        var propertyName = persister.PropertyNames[i];
                        if (propertyType.IsCollectionType)
                        {
                            continue;
                        }

                        var currentValue = persister.GetPropertyValue(entity, i);
                        if (entityMetadata.Associations.TryGetValue(propertyName, out var association))
                        {
                            var associatedEntityMetadata = _entityMetadataProvider.GetMetadata(association.EntityType);
                            for (var j = 0; j < association.ForeignKeyPropertyNames.Count; j++)
                            {
                                var fkValue        = currentValue != null ? associatedEntityMetadata.IdentifierPropertyGetters[j](currentValue) : null;
                                var fkPropertyName = association.ForeignKeyPropertyNames[j];
                                if (entityMetadata.SyntheticForeignKeyProperties.ContainsKey(fkPropertyName))
                                {
                                    unmappedValues.Add(fkPropertyName, GetToken(fkValue));
                                }
                            }

                            continue;
                        }

                        entityData.Add(propertyName, GetToken(currentValue));
                    }

                    if (context.IsEntryFor(entity))
                    {
                        var entry   = context.GetEntry(entity);
                        var idTypes = entityTypeInfo.IdentifierTypes;
                        for (var i = 0; i < idTypes.Length; i++)
                        {
                            var newId = entityMetadata.IdentifierPropertyGetters[i](entity);
                            if (idTypes[i].IsDirty(entityInfo.IdentifierValues[i], newId, sessionImpl))
                            {
                                originalValues[entityMetadata.IdentifierPropertyNames[i]] = GetToken(newId);
                            }
                        }

                        for (var i = 0; i < propertyTypes.Length; i++)
                        {
                            var propertyType = propertyTypes[i];
                            if (propertyType.IsCollectionType)
                            {
                                continue;
                            }

                            var propertyName  = persister.PropertyNames[i];
                            var originalValue = entry.LoadedState[i];
                            var currentValue  = persister.GetPropertyValue(entity, i);
                            if (!propertyTypes[i].IsDirty(originalValue, currentValue, sessionImpl))
                            {
                                continue;
                            }

                            if (entityMetadata.Associations.TryGetValue(propertyName, out var association))
                            {
                                foreach (var fkProperty in association.ForeignKeyPropertyNames)
                                {
                                    if (entityMetadata.SyntheticForeignKeyProperties.TryGetValue(fkProperty, out var syntheticProperty))
                                    {
                                        originalValues[fkProperty] = GetToken(syntheticProperty.GetIdentifierFunction(originalValue));
                                    }
                                }
                            }
                            else
                            {
                                originalValues[propertyName] = GetToken(originalValue);
                            }
                        }
                    }

                    entityData.Add("__unmapped", unmappedValues);
                    entityData.Add("entityAspect", entityAspect);
                    entities.Add(entityData);
                }
            }

            return(saveBundle);
        }
Esempio n. 7
0
        private ClientModelMetadata Create(Type clientType)
        {
            if (!IsClientModel(clientType))
            {
                return(null);
            }

            var properties          = clientType.GetProperties().ToDictionary(o => o.Name);
            var syntheticProperties = new List <SyntheticForeignKeyProperty>();
            var associations        = new Dictionary <string, Association>();
            var clientProperties    = new List <ClientModelProperty>(properties.Count);

            foreach (var property in clientType.GetProperties())
            {
                var propertyType = property.PropertyType;
                if (property.GetCustomAttribute <ComplexTypeAttribute>() != null)
                {
                    clientProperties.Add(new ClientModelProperty(
                                             property.Name,
                                             propertyType,
                                             true,
                                             null,
                                             true,
                                             false,
                                             false,
                                             false));
                    continue;
                }


                var isCollection          = propertyType.IsGenericType && typeof(IEnumerable).IsAssignableFrom(propertyType);
                var elementType           = isCollection ? propertyType.GetGenericArguments()[0] : propertyType;
                var relatedEntityMetadata = _entityMetadataProvider.IsEntityType(elementType)
                    ? _entityMetadataProvider.GetMetadata(elementType)
                    : null;

                if (relatedEntityMetadata != null || IsClientModel(elementType))
                {
                    clientProperties.Add(
                        isCollection
                        // Add a one to many relation
                            ? CreateCollectionNavigationProperty(
                            clientType,
                            property,
                            elementType,
                            relatedEntityMetadata,
                            associations)
                        // Add a many to one relation
                            : CreateEntityNavigationProperty(
                            clientType,
                            property,
                            properties,
                            relatedEntityMetadata,
                            syntheticProperties,
                            associations)
                        );

                    continue;
                }

                clientProperties.Add(new ClientModelProperty(
                                         property.Name,
                                         propertyType,
                                         false,
                                         _dataTypeProvider.GetDataType(propertyType),
                                         BreezeHelper.IsNullable(propertyType),
                                         property.Name == nameof(IClientModel.Id),
                                         false,
                                         false));
            }

            return(new ClientModelMetadata(
                       clientType,
                       null, // TODO: base type
                       AutoGeneratedKeyType.KeyGenerator,
                       clientProperties,
                       syntheticProperties.ToDictionary(o => o.Name),
                       new List <Type>(),   // TODO: base type
                       new List <string>(), // TODO: base type
                       IdentifierPropertyNames,
                       IdentifierPropertyGetters,
                       IdentifierPropertyTypes,
                       IdentifierPropertyDataTypes,
                       IdentifierPropertyTypeLengths,
                       new HashSet <string>(associations.Values.Where(o => o.IsScalar).SelectMany(o => o.ForeignKeyPropertyNames)),
                       associations
                       ));
        }
        public override IEnumerable <Validator> GetValidators(DataProperty dataProperty, Type type)
        {
            Validator validator;
            var       addedValidators = new HashSet <string>();

            if (!dataProperty.IsNullable)
            {
                ModelMetadata modelMetadata = null;
                if (_entityMetadataProvider.IsEntityType(type))
                {
                    modelMetadata = _entityMetadataProvider.GetMetadata(type);
                }
                else if (_clientModelMetadataProvider.IsClientModel(type))
                {
                    modelMetadata = _clientModelMetadataProvider.GetMetadata(type);
                }

                // Do not permit default values for foreign key properties
                if (modelMetadata?.ForeignKeyPropertyNames.Contains(dataProperty.NameOnServer) == true || dataProperty.DataType == DataType.String)
                {
                    addedValidators.Add("fvNotEmpty");
                    validator = new Validator("fvNotEmpty");
                    validator.MergeLeft(FluentValidators.GetParameters(new NotEmptyValidator(null)));
                    yield return(validator);
                }
                else
                {
                    addedValidators.Add("fvNotNull");
                    validator = new Validator("fvNotNull");
                    validator.MergeLeft(FluentValidators.GetParameters(new NotNullValidator()));
                    yield return(validator);
                }
            }

            if (dataProperty.MaxLength.HasValue)
            {
                addedValidators.Add("fvLength");
                validator = new Validator("fvLength");
                validator.MergeLeft(FluentValidators.GetParameters(new LengthValidator(0, dataProperty.MaxLength.Value)));
                yield return(validator);
            }

            if (dataProperty.DataType.HasValue && TryGetDataTypeValidator(dataProperty.DataType.Value, out validator))
            {
                yield return(validator);
            }

            if (!_typePropertyValidators.TryGetValue(type, out var propertyValidators))
            {
                if (!(_validatorFactory.GetValidator(type) is IEnumerable <IValidationRule> validationRules))
                {
                    yield break;
                }

                propertyValidators = validationRules.OfType <PropertyRule>().Where(IsRuleSupported).ToLookup(o => o.PropertyName);
                _typePropertyValidators.Add(type, propertyValidators);
            }

            // Add fluent validations
            foreach (var propertyRule in propertyValidators[dataProperty.NameOnServer])
            {
                var currentValidator = propertyRule.CurrentValidator;
                var name             = FluentValidators.GetName(currentValidator);
                if (string.IsNullOrEmpty(name) || addedValidators.Contains(name))
                {
                    continue;
                }

                validator = new Validator(name);
                validator.MergeLeft(FluentValidators.GetParameters(currentValidator));
                yield return(validator);
            }
        }