protected override Expression VisitMethodCall(MethodCallExpression node) { if (node.Arguments.Count > 0 && node.Arguments[0] is MemberExpression navigationPropertyExpression) { Type?innerItemType = OeExpressionHelper.GetCollectionItemTypeOrNull(navigationPropertyExpression.Type); if (innerItemType != null) { IEdmModel edmModel = _edmModel.GetEdmModel(innerItemType) ?? throw new InvalidOperationException("Cannot find IEdmModel for type " + innerItemType.FullName); Db.OeDataAdapter dataAdapter = edmModel.GetDataAdapter(edmModel.EntityContainer); Db.OeEntitySetAdapter?innerEntitySetAdapter = dataAdapter.EntitySetAdapters.Find(innerItemType); if (innerEntitySetAdapter == null) { throw new InvalidOperationException("OeEntitySetAdapter not found for type " + innerItemType.Name); } IEdmEntitySet entitySet = edmModel.FindDeclaredEntitySet(innerEntitySetAdapter.EntitySetName); ConstantExpression innerSource = OeEnumerableStub.CreateEnumerableStubExpression(innerEntitySetAdapter.EntityType, entitySet); IEdmNavigationProperty navigationProperty = GetEdmNavigationProperty(dataAdapter, navigationPropertyExpression); Expression[] arguments = node.Arguments.ToArray(); arguments[0] = GetJoin(innerSource, navigationProperty); return(node.Update(node.Object !, arguments)); } } return(base.VisitMethodCall(node)); }
private MethodCallExpression?GetJoin(Expression outer, MemberExpression navigationProperty) { Type outerType = outer.Type; Type innerType = navigationProperty.Type; IEdmModel?edmModel = _edmModel.GetEdmModel(outerType); if (edmModel == null) { return(null); } Db.OeDataAdapter dataAdapter = edmModel.GetDataAdapter(edmModel.EntityContainer); Db.OeEntitySetAdapter?outerEntitySetAdapter = dataAdapter.EntitySetAdapters.Find(outerType); if (outerEntitySetAdapter == null) { throw new InvalidOperationException("OeEntitySetAdapter not found for type " + outerType.Name); } IEdmEntitySet outerEntitySet = OeEdmClrHelper.GetEntitySet(_edmModel, outerEntitySetAdapter.EntitySetName); IEdmNavigationProperty edmNavigationProperty = outerEntitySet.EntityType().NavigationProperties().Single(p => p.Name == navigationProperty.Member.Name); Db.OeEntitySetAdapter?innerEntitySetAdapter = dataAdapter.EntitySetAdapters.Find(innerType); if (innerEntitySetAdapter == null) { throw new InvalidOperationException("OeEntitySetAdapter not found for type " + innerType.Name); } IEdmEntitySet entitySet = edmModel.FindDeclaredEntitySet(innerEntitySetAdapter.EntitySetName); ConstantExpression innerSource = OeEnumerableStub.CreateEnumerableStubExpression(innerType, entitySet); return(GetJoin(outer, innerSource, edmNavigationProperty)); }