/// <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); }
internal static bool IsAssociation(MemberInfo member, IEntityMetadataProvider classMetadataProvider, out bool isScalar, out Type memberType) { memberType = member.GetUnderlyingType(); if (memberType == typeof(string)) { isScalar = false; return(false); } if (memberType.TryGetGenericType(typeof(IEnumerable <>), out var genericType)) { isScalar = false; memberType = genericType.GetGenericArguments()[0]; } else if (typeof(IEnumerable).IsAssignableFrom(memberType)) { memberType = null; isScalar = false; return(true); // To be safe in case the enumerable is an uninitialized NHibernate collection } else { isScalar = true; } return(classMetadataProvider.IsEntityType(memberType)); }
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; } } }
private bool IsEntityType(Type type) { return(_entityMetadataProvider.IsEntityType(type)); }
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 )); }
private Predicate <object> CreateShouldSerialize(Type memberType, Predicate <object> currentPredicate, Func <object, object> getValue) { return(_entityMetadataProvider.IsEntityType(memberType) ? MergePredicates(currentPredicate, o => NHibernateUtil.IsInitialized(getValue(o))) : currentPredicate); }
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); } }