private Expression CreateCollectionInitializer(LambdaScope lambdaScope, PropertyInfo collectionProperty, Type elementType, QueryLayer layer, LambdaScopeFactory lambdaScopeFactory) { MemberExpression propertyExpression = Expression.Property(lambdaScope.Accessor, collectionProperty); var builder = new QueryableBuilder(propertyExpression, elementType, typeof(Enumerable), _nameFactory, _resourceFactory, _resourceContextProvider, _entityModel, lambdaScopeFactory); Expression layerExpression = builder.ApplyQuery(layer); Type enumerableOfElementType = typeof(IEnumerable <>).MakeGenericType(elementType); Type typedCollection = TypeHelper.ToConcreteCollectionType(collectionProperty.PropertyType); ConstructorInfo typedCollectionConstructor = typedCollection.GetConstructor(new[] { enumerableOfElementType }); if (typedCollectionConstructor == null) { throw new Exception( $"Constructor on '{typedCollection.Name}' that accepts '{enumerableOfElementType.Name}' not found."); } return(Expression.New(typedCollectionConstructor, layerExpression)); }
private Expression CreateCollectionInitializer(LambdaScope lambdaScope, PropertyInfo collectionProperty, Type elementType, QueryLayer layer, LambdaScopeFactory lambdaScopeFactory) { MemberExpression propertyExpression = Expression.Property(lambdaScope.Accessor, collectionProperty); var builder = new QueryableBuilder(propertyExpression, elementType, typeof(Enumerable), _nameFactory, _resourceFactory, _resourceContextProvider, _entityModel, lambdaScopeFactory); Expression layerExpression = builder.ApplyQuery(layer); // Earlier versions of EF Core 3.x failed to understand `query.ToHashSet()`, so we emit `new HashSet(query)` instead. // Interestingly, EF Core 5 RC1 fails to understand `new HashSet(query)`, so we emit `query.ToHashSet()` instead. // https://github.com/dotnet/efcore/issues/22902 if (EntityFrameworkCoreSupport.Version.Major < 5) { Type enumerableOfElementType = typeof(IEnumerable <>).MakeGenericType(elementType); Type typedCollection = CollectionConverter.ToConcreteCollectionType(collectionProperty.PropertyType); ConstructorInfo typedCollectionConstructor = typedCollection.GetConstructor(enumerableOfElementType.AsArray()); if (typedCollectionConstructor == null) { throw new InvalidOperationException($"Constructor on '{typedCollection.Name}' that accepts '{enumerableOfElementType.Name}' not found."); } return(Expression.New(typedCollectionConstructor, layerExpression)); } string operationName = CollectionConverter.TypeCanContainHashSet(collectionProperty.PropertyType) ? "ToHashSet" : "ToList"; return(CopyCollectionExtensionMethodCall(layerExpression, operationName, elementType)); }