private bool IsDerivedCollection(Type CollectionType) { var itemType = TypesUtil.GetGenericArgumentForBaseType(CollectionType, typeof(IEnumerable <>)); //if entityType is a non-entity, it will not have any mapping. return(typeTranslationUtil.GetMapping <IModelEntityMapping>(itemType) is IDerivedModelEntityMapping); }
public static object GetCollectionInstance(Type collectionType, List <object> collection) { //Arrays if (collectionType.IsArray) { var array = Activator.CreateInstance(collectionType, collection.Count) as Array; for (int i = 0; i < collection.Count; i++) { array.SetValue(collection[i], i); } return(array); } //lists with indexers else if (collectionType.IsGenericType && collectionType.IsInterface && TypesUtil.IsNonPrimitiveCollection(collectionType)) { var list = Activator.CreateInstance(typeof(List <>) .MakeGenericType(TypesUtil.GetGenericArgumentForBaseType(collectionType, typeof(ICollection <>)))) as IList; collection.ForEach(item => list.Add(item)); return(list); } //Custom generic collections .. assume they have default constructor and Add method else if (collectionType.IsGenericType && TypesUtil.IsNonPrimitiveCollection(collectionType) && collectionType.GetConstructor(Type.EmptyTypes) != null) { var customCollection = Activator.CreateInstance(collectionType); var addMethod = collectionType.GetMethod("Add"); collection.ForEach(item => addMethod.Invoke(customCollection, new object[] { item })); return(customCollection); } throw new NotSupportedException("Only Arrays, Lists, ICollection<> and Custom collection types with default constructor are supported."); }
public static SimpleType GetMember(SimpleType source, MemberExpression memberExp, MemberExpression translatedMemberExp, TypeTranslationUtil typeTranslationUtil) { SimpleType result; if (source != null) { result = source.GetMemberType(memberExp); if (result != null) { return(result); } } var includes = (source != null) ? source.GetMemberIncludes(memberExp) : new List <IncludeDirective>(); var memberIsCollection = TypesUtil.IsNonPrimitiveCollection(memberExp.Type); var classMapping = typeTranslationUtil.GetMapping <IModelEntityMapping>(memberExp.Member.DeclaringType); if (memberIsCollection && classMapping != null) { //Getting the many-to-many maps for the declaringType var manyToManyRelationship = classMapping.GetManyToManyRelationships() .FirstOrDefault(m => ((MemberExpression)m.RelatedEntitySelector.Body).Member.Name == memberExp.Member.Name); if (manyToManyRelationship != null) { var otherEndSelector = manyToManyRelationship.RelatedEntitySelectorFromMap.Body as MemberExpression; var param = Expression.Parameter(typeTranslationUtil.GetTranslatedType(manyToManyRelationship.MapType), "x"); var translatedOtherEndSelector = typeTranslationUtil.GetMemberExpression (manyToManyRelationship.MapType, otherEndSelector.Member.Name, param); var map = new ManyToManyMapType(manyToManyRelationship.MapType, param.Type, TypesUtil.GetGenericArgumentForBaseType(memberExp.Type, typeof(ICollection <>)), manyToManyRelationship, translatedOtherEndSelector.Member) { Includes = includes }; return(new SimpleType(memberExp.Type, translatedMemberExp.Type) { NonPrimitiveEnumerableItemType = map }); } } result = new SimpleType(memberExp.Type, translatedMemberExp.Type); if (memberIsCollection) { var itemType = TypesUtil.GetGenericArgumentForBaseType(memberExp.Type, typeof(IEnumerable <>)); var translatedItemType = TypesUtil.GetGenericArgumentForBaseType(translatedMemberExp.Type, typeof(IEnumerable <>)); var innerType = new SimpleType(itemType, translatedItemType) { Includes = includes }; result.NonPrimitiveEnumerableItemType = innerType; } else { result.Includes = includes; } return(result); }
public void GetGenericArgumentForBaseType_BaseClass1() { Type finalType = typeof(ArgForGetGenericArgumentForBaseType); Type specificBaseType = typeof(ArgForGetGenericArgumentForBaseTypeBase <>); Type expected = typeof(string); Type actual; actual = TypesUtil.GetGenericArgumentForBaseType(finalType, specificBaseType); Assert.AreEqual(expected, actual); }
public void GetGenericArgumentForBaseType_ExceptionOnNonGenericInput() { Type finalType = typeof(ArgForGetGenericArgumentForBaseType); Type specificBaseType = typeof(IEnumerable); Type expected = typeof(int); Type actual; actual = TypesUtil.GetGenericArgumentForBaseType(finalType, specificBaseType); Assert.AreEqual(expected, actual); }
private SimpleType GetQueryableType(Type originalType, Type translatedType) { if (!TypesUtil.IsNonPrimitiveCollection(originalType)) { return(new SimpleType(originalType, translatedType)); } else { var itemType = TypesUtil.GetGenericArgumentForBaseType(originalType, typeof(IEnumerable <>)); var translatedItemType = TypesUtil.GetGenericArgumentForBaseType(translatedType, typeof(IEnumerable <>)); return(RuntimeTypes.CreateEnumerable(new SimpleType(itemType, translatedItemType))); } }
private Func <EntityContext, object[], TResult> GetFunc <TResult>(LambdaExpression query) { var analyzer = new CompilableQueryAnalyzer(query, GetTypeTranslationUtil()); var analysisResult = analyzer.GetResult(); //Find L2S.CompiledQuery.Compile<...>() // and invoke the backend compiler; backendCompiledMethod is a Func<,..> var compiledBackendMethod = GetCompileMethod(analysisResult).Invoke(null, new object[] { analysisResult.TranslatedCompilableLambda }); //Compile the client-side part of the expression and get a Func<> // This function the materialized form and works on it (like call a ToList() for instance). object postMaterializationLambda = null; if (analysisResult.PostMaterializationLambda != null) { postMaterializationLambda = analysisResult.PostMaterializationLambda.Compile(); } //l2sCompileResult lambda can return two types // 1. IQueryable // 2. An Entity itself, as a result of the call to First(), Single() etc. if (!TypesUtil.IsNonPrimitiveCollection(analysisResult.MaterializableExpression.Type)) { return((context, args) => { var backendResults = InvokeCompiledMethod(compiledBackendMethod, context as EntityContext, args); var singleObjectMaterializer = Activator.CreateInstance(typeof(SingleObjectMaterializer <>) .MakeGenericType(analysisResult.MaterializableExpression.Type), new object[] { context }); var materializedResult = singleObjectMaterializer.GetType().GetMethod("MakeResult") .Invoke(singleObjectMaterializer, new object[] { backendResults, analysisResult.QueryableType }); return (TResult)InvokePostMaterializationLambda_IfExists(materializedResult, postMaterializationLambda); }); } else { return((context, args) => { var queryType = TypesUtil.GetGenericArgumentForBaseType(analysisResult.MaterializableExpression.Type, typeof(IQueryable <>)); var compiledQuery = Activator.CreateInstance(typeof(CompiledQuery <>).MakeGenericType(queryType), new object[] { GetQueryProvider(context as EntityContext), this, args, compiledBackendMethod, analysisResult.QueryableType.NonPrimitiveEnumerableItemType }); return (TResult)InvokePostMaterializationLambda_IfExists(compiledQuery, postMaterializationLambda); }); } }
private bool NeedsProjectionModification(Expression currentExpression) { //Get the T, when the query returns T or IQueryable<T> var genericTypeOfResult = typeof(IQueryable).IsAssignableFrom(currentExpression.Type) ? TypesUtil.GetGenericArgumentForBaseType(currentExpression.Type, typeof(IQueryable <>)) : currentExpression.Type; //If this is the outermost method, and it is a Non-Primitive Type, we need to modify the Projection // so that we can add implicit includes (like Inhertiance) and user-requested Includes (Prefetch Paths) //There are two cases: // 1) If IQueryable<NonPrimitiveType>, add a Select around translated mce (eg: Where, Select etc) // 2) If just NonPrimitiveType, add a Select around translatedFirstArg (eg: First, Single etc) return(AnalysisContext.ModifyProjection && //Don't modify if context.ModifyProjection is false !(AnalysisContext.QueryableType.NonPrimitiveEnumerableItemType is ProjectedType) && //Don't modify if already modified, that is - context.QueryableType is ProjectedType !TypesUtil.IsPrimitiveDataType(genericTypeOfResult)); //Don't modify if Primitive Type. }
//Make an enumerable of type enumerableType and fill it with items. private object MakeEnumerable(Type enumerableType, List <object> items) { if (enumerableType.IsGenericType && TypesUtil.GenericTypeIsAssignableFrom(enumerableType, typeof(ICollection <>))) { return(MakeListOfType(TypesUtil.GetGenericArgumentForBaseType(enumerableType, typeof(ICollection <>)), items)); } else if (enumerableType.IsArray) { var list = MakeListOfType(enumerableType.GetElementType(), items); return(list.GetType().GetMethod("ToArray").Invoke(list, null)); } else { throw new NotSupportedException("The collection of type " + enumerableType.ToString() + " cannot be bound to the context."); } }
public override PostProjectionLoadedResult GetResult(IUnprojectedBinding binding, List <object> objects) { var result = new PostProjectionLoadedResult(); result.ProjectionBinding = binding; var targetType = TypesUtil.GetGenericArgumentForBaseType(binding.TargetBinding.Type, typeof(IEnumerable <>)); Func <AnonymousType, object> valueGetter = ao => Get_GetProjectedValue_Computation(binding.TargetBinding)(new TableEntityRow(ao)); var query = GetQuery(objects, valueGetter, targetType); query = LoadIncludes(query, targetType, GetIncludes(binding)); result.Value = MethodFinder.EnumerableMethods.ToList(targetType).Invoke(null, new object[] { query }) as IList; return(result); }
private void SetEnumerableProperty(object instance, PropertyInfo property, object items) { var propVal = property.GetValue(instance, null); if (property.PropertyType.IsArray || propVal == null) { property.SetValue(instance, items, null); } //If the instance is IEntity, we should go through Materialization methods to avoid triggering Reverse Reference setting. else if (instance is IEntity) { var intermediateInstance = (instance as IEntity)._getIntermediateEntity(); var collectionOnIntermediate = intermediateInstance.GetType().GetProperty(property.Name) .GetValue(intermediateInstance) as IIntermediateEntityContainer; foreach (var item in (items as IEnumerable)) { collectionOnIntermediate.MaterializationAddReference((item as IEntity)._getIntermediateEntity()); } } //Not an IEntity or an Array. //Assume this is a collection and call the "Add" method. else { var typeOfCollection = TypesUtil.GetGenericArgumentForBaseType(property.PropertyType, typeof(ICollection <>)); var addMethod = propVal.GetType().GetMethod("Add", new Type[] { typeOfCollection }); foreach (var item in items as IEnumerable) { addMethod.Invoke(propVal, new object[] { item }); } } }
private Func <object, TableEntityRow, object> Get_GetOrCreateEntityOrCollection_Computation(IncludeBinding includeBinding, MaterializationData data) { if (entityContext._InternalServices.TypeTranslationUtil.IsEntityCollection(includeBinding.Type)) { var unprojectedBinding = data.ProjectedType.UnprojectedBindings .Find(ub => (ub is UnprojectedCollectionBinding || ub is UnprojectedManyToManyBinding) && ub.TargetBinding == includeBinding); if (unprojectedBinding != null) { if (unprojectedBinding is UnprojectedManyToManyBinding) { return(Get_GetUnprojectedCollections_Computation(unprojectedBinding, data.ManyToManyMaps)); } else { return(Get_GetUnprojectedCollections_Computation(unprojectedBinding, data.InheritanceChains)); } } else { var collItemType = TypesUtil.GetGenericArgumentForBaseType(includeBinding.Type, typeof(ICollection <>)); var collectionEntityConstructor = new EntityConstructor(entityContext, collItemType); return((tableEntity, source) => { var list = new List <object>(); foreach (var item in (tableEntity as IEnumerable)) { list.Add(collectionEntityConstructor.GetOrCreateEntity(new object[] { item })); } return list; }); } } return(Get_GetOrCreateEntity_Computation(includeBinding, data)); }