0

Edit

I'm left now with only one error:

{
  "error":{
    "code":"","message":"An error has occurred.","innererror":{
      "message":"The 'ObjectContent`1' type failed to serialize the response body for content type 'application/json; odata.metadata=minimal'.","type":"System.InvalidOperationException","stacktrace":"","internalexception":{
        "message":"Object reference not set to an instance of an object.","type":"System.NullReferenceException","stacktrace":"   at NHibernate.Linq.Visitors.ExpressionKeyVisitor.VisitConstantExpression(ConstantExpression expression)\r\n   at NHibernate.Linq.Visitors.ExpressionKeyVisitor.VisitBinaryExpression(BinaryExpression expression)\r\n   at NHibernate.Linq.Visitors.ExpressionKeyVisitor.VisitConditionalExpression(ConditionalExpression expression)\r\n   at NHibernate.Linq.Visitors.ExpressionKeyVisitor.VisitMemberExpression(MemberExpression expression)\r\n   at NHibernate.Linq.Visitors.SelectJoinDetector.VisitMemberExpression(MemberExpression expression)\r\n   at Remotion.Linq.Parsing.ExpressionTreeVisitor.VisitConditionalExpression(ConditionalExpression expression)\r\n   at Remotion.Linq.Parsing.ExpressionTreeVisitor.VisitMemberAssignment(MemberAssignment memberAssigment)\r\n   at Remotion.Linq.Parsing.ExpressionTreeVisitor.VisitList[T](ReadOnlyCollection`1 list, Func`2 visitMethod)\r\n   at Remotion.Linq.Parsing.ExpressionTreeVisitor.VisitMemberInitExpression(MemberInitExpression expression)\r\n   at Remotion.Linq.Parsing.ExpressionTreeVisitor.VisitMemberAssignment(MemberAssignment memberAssigment)\r\n   at Remotion.Linq.Parsing.ExpressionTreeVisitor.VisitList[T](ReadOnlyCollection`1 list, Func`2 visitMethod)\r\n   at Remotion.Linq.Parsing.ExpressionTreeVisitor.VisitMemberInitExpression(MemberInitExpression expression)\r\n   at Remotion.Linq.Parsing.ExpressionTreeVisitor.VisitMemberAssignment(MemberAssignment memberAssigment)\r\n   at Remotion.Linq.Parsing.ExpressionTreeVisitor.VisitList[T](ReadOnlyCollection`1 list, Func`2 visitMethod)\r\n   at Remotion.Linq.Parsing.ExpressionTreeVisitor.VisitMemberInitExpression(MemberInitExpression expression)\r\n   at Remotion.Linq.Parsing.ExpressionTreeVisitor.VisitMemberAssignment(MemberAssignment memberAssigment)\r\n   at Remotion.Linq.Parsing.ExpressionTreeVisitor.VisitList[T](ReadOnlyCollection`1 list, Func`2 visitMethod)\r\n   at Remotion.Linq.Parsing.ExpressionTreeVisitor.VisitMemberInitExpression(MemberInitExpression expression)\r\n   at Remotion.Linq.Parsing.ExpressionTreeVisitor.VisitMemberAssignment(MemberAssignment memberAssigment)\r\n   at Remotion.Linq.Parsing.ExpressionTreeVisitor.VisitList[T](ReadOnlyCollection`1 list, Func`2 visitMethod)\r\n   at Remotion.Linq.Parsing.ExpressionTreeVisitor.VisitMemberInitExpression(MemberInitExpression expression)\r\n   at Remotion.Linq.Clauses.SelectClause.TransformExpressions(Func`2 transformation)\r\n   at Remotion.Linq.QueryModelVisitorBase.VisitQueryModel(QueryModel queryModel)\r\n   at NHibernate.Linq.Visitors.QueryModelVisitor.GenerateHqlQuery(QueryModel queryModel, VisitorParameters parameters, Boolean root)\r\n   at NHibernate.Linq.NhLinqExpression.Translate(ISessionFactoryImplementor sessionFactory, Boolean filter)\r\n   at NHibernate.Hql.Ast.ANTLR.ASTQueryTranslatorFactory.CreateQueryTranslators(IQueryExpression queryExpression, String collectionRole, Boolean shallow, IDictionary`2 filters, ISessionFactoryImplementor factory)\r\n   at NHibernate.Engine.Query.QueryExpressionPlan..ctor(IQueryExpression queryExpression, Boolean shallow, IDictionary`2 enabledFilters, ISessionFactoryImplementor factory)\r\n   at NHibernate.Engine.Query.QueryPlanCache.GetHQLQueryPlan(IQueryExpression queryExpression, Boolean shallow, IDictionary`2 enabledFilters)\r\n   at NHibernate.Impl.AbstractSessionImpl.GetHQLQueryPlan(IQueryExpression queryExpression, Boolean shallow)\r\n   at NHibernate.Impl.AbstractSessionImpl.CreateQuery(IQueryExpression queryExpression)\r\n   at NHibernate.Linq.DefaultQueryProvider.Execute(Expression expression)\r\n   at NHibernate.Linq.DefaultQueryProvider.Execute[TResult](Expression expression)\r\n   at Remotion.Linq.QueryableBase`1.System.Collections.IEnumerable.GetEnumerator()\r\n   at System.Web.OData.Formatter.Serialization.ODataFeedSerializer.WriteFeed(IEnumerable enumerable, IEdmTypeReference feedType, ODataWriter writer, ODataSerializerContext writeContext)\r\n   at System.Web.OData.Formatter.ODataMediaTypeFormatter.WriteToStream(Type type, Object value, Stream writeStream, HttpContent content, HttpContentHeaders contentHeaders)\r\n   at System.Web.OData.Formatter.ODataMediaTypeFormatter.WriteToStreamAsync(Type type, Object value, Stream writeStream, HttpContent content, TransportContext transportContext, CancellationToken cancellationToken)\r\n--- End of stack trace from previous location where exception was thrown ---\r\n   at System.Runtime.CompilerServices.TaskAwaiter.ThrowForNonSuccess(Task task)\r\n   at System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task task)\r\n   at System.Web.Http.WebHost.HttpControllerHandler.<WriteBufferedResponseContentAsync>d__1b.MoveNext()"
      }
    }
  }
}

I put together a simple example that illustrates the issue and posted it to the NH users Google group.

Edit re: @MartinSmit

Here's the NH code I mentioned in my SO comment below. I've added some C# comments to this code.

public class ExpressionKeyVisitor : ExpressionTreeVisitor
{
    private readonly IDictionary<ConstantExpression, NamedParameter> _constantToParameterMap;

    private ExpressionKeyVisitor(IDictionary<ConstantExpression, NamedParameter> constantToParameterMap)
    {
        // Don L: When this constructor is called, constantToParameterMap is null.
        _constantToParameterMap = constantToParameterMap;
    }

    protected override Expression VisitConstantExpression(ConstantExpression expression)
    {
        NamedParameter param;

        // Don L: The NullReferenceException occurs here because _constantToParameterMap is null.
        if (_constantToParameterMap.TryGetValue(expression, out param) && insideSelectClause == false)
        {
            // Nulls generate different query plans.  X = variable generates a different query depending on if variable is null or not.
            if (param.Value == null)
                _string.Append("NULL");
            if (param.Value is IEnumerable && !((IEnumerable)param.Value).Cast<object>().Any())
                _string.Append("EmptyList");
            else
                _string.Append(param.Name);
        }
        else
        {
            if (expression.Value == null)
                _string.Append("NULL");
            else
                _string.Append(expression.Value);
        }

        return base.VisitConstantExpression(expression);
    }
}

Original Question

I'm using the OData Web API to create OData 4.0 endpoints, and I'm having trouble with the $expand option. I'm getting an exception when I try to expand:

http://localhost/MyApp/OData/Profile(2385)/AuthorshipsAsAuthor?$expand=Author/ProfileSubject

or

http://localhost/MyApp/OData/Profile(2385)/AuthorshipsAsAuthor?$expand=Author,Author/ProfileSubject

I get:

The query specified in the URI is not valid. Found a path traversing multiple navigation properties. Please rephrase the query such that each expand path contains only type segments and navigation properties.

I can use one-level expansion ($expand=Author,Publication) with no problem. I've also tried $expand=Author($expand=ProfileSubject). That gets me:

The 'ObjectContent``1' type failed to serialize the response body for content type 'application/json; odata.metadata=minimal'.

I've seen OData v4 Web API 2.2 deep level expand not working, but that seems to be a problem with collections, whereas my data model is going from the many side to the one. I've simplified the data model a great deal, so there may be a transcription error.

public class Authorship : IMyDomainObject
{
    public virtual Publication Publication { get; set; }

    public virtual Profile Author { get; set; }
}

public class Profile : IMyDomainObject
{
    public virtual InstitutionalAccount ProfileSubject { get; set; }

    public virtual IList<Authorship> AuthorshipsAsAuthor { get; set; }
}

public abstract class Publication : IMyDomainObject
{
    public virtual IList<Authorship> Authorships { get; set; }
}

I'm using reflection to set up my ODataConvetionModelBuilder.

private static void SetUpODataModel(HttpConfiguration config)
{
    ODataModelBuilder builder = new ODataConventionModelBuilder();

    Type oDataModelBuilderType = builder.GetType();
    MethodInfo entitySetMethodInfo = oDataModelBuilderType.GetMethod("EntitySet");
    Type domainObjectInterfaceType = typeof(IMyDomainObject);

    // Ignore properties when appropriate.
    var institutionalAccountEntityType = 
        builder.EntitySet<InstitutionalAccount>("InstitutionalAccount").EntityType;
    institutionalAccountEntityType.Ignore(ia => ia.SomethingPrivate);

    // This doesn't help.
    //var authorshipEntityType = builder.EntitySet<Authorship>("Authorship").EntityType;
    //authorshipEntityType.ContainsRequired(x => x.Author);
    //var profileEntityType = builder.EntitySet<Profile>("Profile").EntityType;
    //profileEntityType.ContainsRequired(x => x.ProfileSubject);

    foreach (
        Type domainObjectType
        in
        domainObjectInterfaceType
            .Assembly
            .DefinedTypes
            .Where(t => t.GetInterfaces().Any(i => i.Equals(domainObjectInterfaceType)))
            .Where(t => t.IsClass)
    )
    {
        // Skip the type if we've already added it, e.g., it's already
        // been done by hand.
        if (builder.EntitySets.Any(es => es.ClrType.Equals(domainObjectType)))
        {
            continue;
        }

        // This is equivalent to:
        // builder.EntitySet<MyDomainObjectType>("MyDomainObjectType");
        MethodInfo entitySetGenericMethodInfo = entitySetMethodInfo.MakeGenericMethod(domainObjectType);
        Object entitySet = entitySetGenericMethodInfo.Invoke(builder, new[] { domainObjectType.Name });
    }

    config.EnableEnumPrefixFree(true);
    config.MapODataServiceRoute(
        routeName: "ODataRoute",
        routePrefix: "OData",
        model: builder.GetEdmModel());
}

I'm using NHibernate, but I don't think that's relevant here.

edit: I found Failed to serialize the response body for content type without even including NHibernate in the search terms, but that didn't work.

edit: In response to @FanOuyang's comment, I'm still getting the error. My code now looks like var w = new Authorship[] { /* big long mess with no circular references */ }; return w.AsQueryable();

edit: The test code I used didn't do what I thought it was doing. I wrote some new code that copies the result set to new objects, including circular references, and that seems to be working, so the problem does have something to do with NH. The errors I'm getting, depending on what I $expand, are:

{
  "error":{
    "code":"","message":"An error has occurred.","innererror":{
      "message":"The 'ObjectContent`1' type failed to serialize the response body for content type 'application/json; odata.metadata=minimal'.","type":"System.InvalidOperationException","stacktrace":"","internalexception":{
        "message":"Argument types do not match","type":"System.ArgumentException","stacktrace":"   at System.Linq.Expressions.Expression.Condition(Expression test, Expression ifTrue, Expression ifFalse)\r\n   at Remotion.Linq.Parsing.ExpressionTreeVisitor.VisitConditionalExpression(ConditionalExpression expression)\r\n   at NHibernate.Linq.NestedSelects.SelectClauseRewriter.VisitExpression(Expression expression)\r\n   at Remotion.Linq.Parsing.ExpressionTreeVisitor.VisitMemberAssignment(MemberAssignment memberAssigment)\r\n   at Remotion.Linq.Parsing.ExpressionTreeVisitor.VisitList[T](ReadOnlyCollection`1 list, Func`2 visitMethod)\r\n   at Remotion.Linq.Parsing.ExpressionTreeVisitor.VisitMemberInitExpression(MemberInitExpression expression)\r\n   at NHibernate.Linq.NestedSelects.SelectClauseRewriter.VisitExpression(Expression expression)\r\n   at Remotion.Linq.Parsing.ExpressionTreeVisitor.VisitMemberAssignment(MemberAssignment memberAssigment)\r\n   at Remotion.Linq.Parsing.ExpressionTreeVisitor.VisitList[T](ReadOnlyCollection`1 list, Func`2 visitMethod)\r\n   at Remotion.Linq.Parsing.ExpressionTreeVisitor.VisitMemberInitExpression(MemberInitExpression expression)\r\n   at NHibernate.Linq.NestedSelects.SelectClauseRewriter.VisitExpression(Expression expression)\r\n   at Remotion.Linq.Parsing.ExpressionTreeVisitor.VisitMemberAssignment(MemberAssignment memberAssigment)\r\n   at Remotion.Linq.Parsing.ExpressionTreeVisitor.VisitList[T](ReadOnlyCollection`1 list, Func`2 visitMethod)\r\n   at Remotion.Linq.Parsing.ExpressionTreeVisitor.VisitMemberInitExpression(MemberInitExpression expression)\r\n   at NHibernate.Linq.NestedSelects.SelectClauseRewriter.VisitExpression(Expression expression)\r\n   at Remotion.Linq.Parsing.ExpressionTreeVisitor.VisitMemberAssignment(MemberAssignment memberAssigment)\r\n   at Remotion.Linq.Parsing.ExpressionTreeVisitor.VisitList[T](ReadOnlyCollection`1 list, Func`2 visitMethod)\r\n   at Remotion.Linq.Parsing.ExpressionTreeVisitor.VisitMemberInitExpression(MemberInitExpression expression)\r\n   at NHibernate.Linq.NestedSelects.SelectClauseRewriter.VisitExpression(Expression expression)\r\n   at NHibernate.Linq.NestedSelects.NestedSelectRewriter.ReWrite(QueryModel queryModel, ISessionFactory sessionFactory)\r\n   at NHibernate.Linq.Visitors.QueryModelVisitor.GenerateHqlQuery(QueryModel queryModel, VisitorParameters parameters, Boolean root)\r\n   at NHibernate.Linq.NhLinqExpression.Translate(ISessionFactoryImplementor sessionFactory, Boolean filter)\r\n   at NHibernate.Hql.Ast.ANTLR.ASTQueryTranslatorFactory.CreateQueryTranslators(IQueryExpression queryExpression, String collectionRole, Boolean shallow, IDictionary`2 filters, ISessionFactoryImplementor factory)\r\n   at NHibernate.Engine.Query.QueryExpressionPlan..ctor(IQueryExpression queryExpression, Boolean shallow, IDictionary`2 enabledFilters, ISessionFactoryImplementor factory)\r\n   at NHibernate.Engine.Query.QueryPlanCache.GetHQLQueryPlan(IQueryExpression queryExpression, Boolean shallow, IDictionary`2 enabledFilters)\r\n   at NHibernate.Impl.AbstractSessionImpl.GetHQLQueryPlan(IQueryExpression queryExpression, Boolean shallow)\r\n   at NHibernate.Impl.AbstractSessionImpl.CreateQuery(IQueryExpression queryExpression)\r\n   at NHibernate.Linq.DefaultQueryProvider.Execute(Expression expression)\r\n   at NHibernate.Linq.DefaultQueryProvider.Execute[TResult](Expression expression)\r\n   at Remotion.Linq.QueryableBase`1.System.Collections.IEnumerable.GetEnumerator()\r\n   at System.Web.OData.Formatter.Serialization.ODataFeedSerializer.WriteFeed(IEnumerable enumerable, IEdmTypeReference feedType, ODataWriter writer, ODataSerializerContext writeContext)\r\n   at System.Web.OData.Formatter.ODataMediaTypeFormatter.WriteToStream(Type type, Object value, Stream writeStream, HttpContent content, HttpContentHeaders contentHeaders)\r\n   at System.Web.OData.Formatter.ODataMediaTypeFormatter.WriteToStreamAsync(Type type, Object value, Stream writeStream, HttpContent content, TransportContext transportContext, CancellationToken cancellationToken)\r\n--- End of stack trace from previous location where exception was thrown ---\r\n   at System.Runtime.CompilerServices.TaskAwaiter.ThrowForNonSuccess(Task task)\r\n   at System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task task)\r\n   at System.Web.Http.WebHost.HttpControllerHandler.<WriteBufferedResponseContentAsync>d__1b.MoveNext()"
      }
    }
  }
}   

or

{
  "error":{
    "code":"","message":"An error has occurred.","innererror":{
      "message":"The 'ObjectContent`1' type failed to serialize the response body for content type 'application/json; odata.metadata=minimal'.","type":"System.InvalidOperationException","stacktrace":"","internalexception":{
        "message":"Object reference not set to an instance of an object.","type":"System.NullReferenceException","stacktrace":"   at NHibernate.Linq.Visitors.ExpressionKeyVisitor.VisitConstantExpression(ConstantExpression expression)\r\n   at NHibernate.Linq.Visitors.ExpressionKeyVisitor.VisitBinaryExpression(BinaryExpression expression)\r\n   at NHibernate.Linq.Visitors.ExpressionKeyVisitor.VisitConditionalExpression(ConditionalExpression expression)\r\n   at NHibernate.Linq.Visitors.ExpressionKeyVisitor.VisitMemberExpression(MemberExpression expression)\r\n   at NHibernate.Linq.Visitors.SelectJoinDetector.VisitMemberExpression(MemberExpression expression)\r\n   at Remotion.Linq.Parsing.ExpressionTreeVisitor.VisitConditionalExpression(ConditionalExpression expression)\r\n   at Remotion.Linq.Parsing.ExpressionTreeVisitor.VisitMemberAssignment(MemberAssignment memberAssigment)\r\n   at Remotion.Linq.Parsing.ExpressionTreeVisitor.VisitList[T](ReadOnlyCollection`1 list, Func`2 visitMethod)\r\n   at Remotion.Linq.Parsing.ExpressionTreeVisitor.VisitMemberInitExpression(MemberInitExpression expression)\r\n   at Remotion.Linq.Parsing.ExpressionTreeVisitor.VisitMemberAssignment(MemberAssignment memberAssigment)\r\n   at Remotion.Linq.Parsing.ExpressionTreeVisitor.VisitList[T](ReadOnlyCollection`1 list, Func`2 visitMethod)\r\n   at Remotion.Linq.Parsing.ExpressionTreeVisitor.VisitMemberInitExpression(MemberInitExpression expression)\r\n   at Remotion.Linq.Parsing.ExpressionTreeVisitor.VisitMemberAssignment(MemberAssignment memberAssigment)\r\n   at Remotion.Linq.Parsing.ExpressionTreeVisitor.VisitList[T](ReadOnlyCollection`1 list, Func`2 visitMethod)\r\n   at Remotion.Linq.Parsing.ExpressionTreeVisitor.VisitMemberInitExpression(MemberInitExpression expression)\r\n   at Remotion.Linq.Parsing.ExpressionTreeVisitor.VisitMemberAssignment(MemberAssignment memberAssigment)\r\n   at Remotion.Linq.Parsing.ExpressionTreeVisitor.VisitList[T](ReadOnlyCollection`1 list, Func`2 visitMethod)\r\n   at Remotion.Linq.Parsing.ExpressionTreeVisitor.VisitMemberInitExpression(MemberInitExpression expression)\r\n   at Remotion.Linq.Parsing.ExpressionTreeVisitor.VisitMemberAssignment(MemberAssignment memberAssigment)\r\n   at Remotion.Linq.Parsing.ExpressionTreeVisitor.VisitList[T](ReadOnlyCollection`1 list, Func`2 visitMethod)\r\n   at Remotion.Linq.Parsing.ExpressionTreeVisitor.VisitMemberInitExpression(MemberInitExpression expression)\r\n   at Remotion.Linq.Clauses.SelectClause.TransformExpressions(Func`2 transformation)\r\n   at Remotion.Linq.QueryModelVisitorBase.VisitQueryModel(QueryModel queryModel)\r\n   at NHibernate.Linq.Visitors.QueryModelVisitor.GenerateHqlQuery(QueryModel queryModel, VisitorParameters parameters, Boolean root)\r\n   at NHibernate.Linq.NhLinqExpression.Translate(ISessionFactoryImplementor sessionFactory, Boolean filter)\r\n   at NHibernate.Hql.Ast.ANTLR.ASTQueryTranslatorFactory.CreateQueryTranslators(IQueryExpression queryExpression, String collectionRole, Boolean shallow, IDictionary`2 filters, ISessionFactoryImplementor factory)\r\n   at NHibernate.Engine.Query.QueryExpressionPlan..ctor(IQueryExpression queryExpression, Boolean shallow, IDictionary`2 enabledFilters, ISessionFactoryImplementor factory)\r\n   at NHibernate.Engine.Query.QueryPlanCache.GetHQLQueryPlan(IQueryExpression queryExpression, Boolean shallow, IDictionary`2 enabledFilters)\r\n   at NHibernate.Impl.AbstractSessionImpl.GetHQLQueryPlan(IQueryExpression queryExpression, Boolean shallow)\r\n   at NHibernate.Impl.AbstractSessionImpl.CreateQuery(IQueryExpression queryExpression)\r\n   at NHibernate.Linq.DefaultQueryProvider.Execute(Expression expression)\r\n   at NHibernate.Linq.DefaultQueryProvider.Execute[TResult](Expression expression)\r\n   at Remotion.Linq.QueryableBase`1.System.Collections.IEnumerable.GetEnumerator()\r\n   at System.Web.OData.Formatter.Serialization.ODataFeedSerializer.WriteFeed(IEnumerable enumerable, IEdmTypeReference feedType, ODataWriter writer, ODataSerializerContext writeContext)\r\n   at System.Web.OData.Formatter.ODataMediaTypeFormatter.WriteToStream(Type type, Object value, Stream writeStream, HttpContent content, HttpContentHeaders contentHeaders)\r\n   at System.Web.OData.Formatter.ODataMediaTypeFormatter.WriteToStreamAsync(Type type, Object value, Stream writeStream, HttpContent content, TransportContext transportContext, CancellationToken cancellationToken)\r\n--- End of stack trace from previous location where exception was thrown ---\r\n   at System.Runtime.CompilerServices.TaskAwaiter.ThrowForNonSuccess(Task task)\r\n   at System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task task)\r\n   at System.Web.Http.WebHost.HttpControllerHandler.<WriteBufferedResponseContentAsync>d__1b.MoveNext()"
      }
    }
  }
}
Community
  • 1
  • 1
Becca Dee
  • 1,530
  • 1
  • 24
  • 51
  • The first expand way is for Type/NavigationProperty, so your scenario not working, the second way $expand=..($expand=..) should work, I tested in http://services.odata.org/V4/(S(xohwpieokm4h4n3yiburn4ad))/TripPinServiceRW/People?$expand=Friends($expand=Friends) from odata.org's sample service, it's work, try in-memory data to see is Nhibernate issue or not – Fan Ouyang Aug 26 '15 at 14:29
  • Thanks, @FanOuyang. See my edit above. – Becca Dee Aug 26 '15 at 15:38
  • So, I mistakenly had disabled the code for `ContainsMany`, which I also need, and that was causing the original error. Now I'm only getting the error when using NH. `The 'ObjectContent``1' type failed to serialize the response body for content type 'application/json; odata.metadata=minimal'.` – Becca Dee Aug 26 '15 at 17:50
  • Looking at the "Argument types do not match" at Linq...Expression makes me question the query generation in NH. Can you run a SQL profiler and pick up the query, run it yourself and see if there's any "weirdness" in the data (like null references where there's a one-to-many relation in the Edm model of it)? – Marvin Smit Aug 27 '15 at 20:43
  • @MarvinSmit, I was able to take care of that issue. Now I'm only getting the NullRefrence exception. – Becca Dee Sep 03 '15 at 17:33
  • Have you tried a debug session on it? What is "NHibernate.Linq.Visitors.ExpressionKeyVisitor" doing at the point of the exception? And what's the edm model data it is seeying? – Marvin Smit Sep 04 '15 at 21:16
  • @MarvinSmit, I'm adding the code for the constructor and for `VisitConstantExpression` of `ExpressionKeyVisitor` to my question. Thanks for your help so far. – Becca Dee Sep 11 '15 at 12:54
  • Also, @MarvinSmit, do you want me to post the code where use `ODataModelBuilder`, or do you want me to do something with the debugger to get the information about the EDM model? – Becca Dee Sep 11 '15 at 13:00
  • @MarvinSmit, I must have messed up adding the NH code, because it wasn't there when I checked the question for new activity. When I hit *edit*, though, there it was! I guess I just didn't save my edits. – Becca Dee Sep 14 '15 at 12:48
  • Could you do an SQL profiler run and see the actual T-SQL query it generated? Does it get to? or is the query building failing? I really suggest a "deep dive debug session" (attach to process, symbols libs, 'break on .Net exceptions' and hit the OData endpoint.) – Marvin Smit Sep 16 '15 at 08:30
  • @MarvinSmit, I ended up refactoring my data model for reasons other than this, and I'm now getting http://stackoverflow.com/questions/20582806/error-using-expand-with-nhibernate-and-webapi-odata, which also seems unbeatable. For now, I just am doing `.ToList().AsQueryable` on my result, which also worked on the problem here. It's not an answer, just a workaround. Thank you for the conversation on this. I appreciate it. – Becca Dee Sep 18 '15 at 13:45

0 Answers0