0

Url でフィルターを GET として使用すると/api/modalidades?$orderby=Nome&$select=Nome,Id、エラーが表示されます。

パッケージ:

FluentNHibernate 1.3.0.733
NHibernate 3.3.3.4000
Microsoft.AspNet.WebApi 5.0.0-rtm-130624
Microsoft.AspNet.WebApi.Client 5.0.0-rtm-130624
Microsoft.AspNet.WebApi.Core 5.0.0-rtm-130624
Microsoft. AspNet.WebApi.OData 5.0.0-rtm-130624
Microsoft.AspNet.WebApi.Web... 5.0.0-rtm-130624

コード

ドメイン

public class Modalidade : EntityNome
{ }
public abstract class EntityNome : IEntity
{
    public virtual int Id { get; protected internal set; }

    [StringLength(80)]
    [Required]
    public virtual string Nome { get; set; }
}
public interface IEntity : IKeyed<int>
{
}
public interface IKeyed<T> where T : struct
{
    T Id { get; }
}

ウェブ

WebApiConfig.css

public static void Register(HttpConfiguration config)
{
    var modelBuilder = new ODataConventionModelBuilder();

    modelBuilder.EntitySet<Modalidade>("modalidades");
    modelBuilder.Entity<Modalidade>()
        .DerivesFrom<EntityNome>()
        .Property(p => p.Id);

    var model = modelBuilder.GetEdmModel();

    config.Routes.MapODataRoute(routeName: "OData", routePrefix: "api", model: model);

    config.EnableQuerySupport();

    var jsonFormatter = GlobalConfiguration.Configuration.Formatters.JsonFormatter;
    var enumConverter = new StringEnumConverter();
    jsonFormatter.SerializerSettings.Converters.Add(enumConverter);

    config.Formatters.Remove(config.Formatters.XmlFormatter);
    var jqueryFormatter = config.Formatters.FirstOrDefault(x => x.GetType() == typeof(JQueryMvcFormUrlEncodedFormatter));
    config.Formatters.Remove(config.Formatters.XmlFormatter);
    config.Formatters.Remove(config.Formatters.FormUrlEncodedFormatter);
    config.Formatters.Remove(jqueryFormatter);
    config.Formatters.JsonFormatter.SerializerSettings.DateFormatHandling = DateFormatHandling.IsoDateFormat;
}

コントローラー

public class baseApiController<T> : EntitySetController<T, int>
    where T : class, IEntity
{
    public IRepository<T> Repositorio { get; private set; }

    public baseApiController(IRepository<T> repositorio)
    {
        Repositorio = repositorio;
    }

    [Queryable(AllowedQueryOptions = AllowedQueryOptions.All, PageSize = 20)]
    public override IQueryable<T> Get()
    {
        return Repositorio.All();
    }

    [HttpGet, Queryable(AllowedQueryOptions = AllowedQueryOptions.All)]
    protected override T GetEntityByKey(int key)
    {
        return Repositorio.Get(key);
    }
}

[Authorize]
public class modalidadesController : baseApiController<Modalidade>
{
    public modalidadesController(IModalidadeRepository repositorio)
        : base(repositorio)
    { }
}

エラー

フィルターが適用されていない場合、すべてが機能します。しかし、フィルターを適用するとエラーが発生します。

GET /api/modalidades?$orderby=Nome&$select=Nome,Id HTTP/1.1
ホスト: localhost:49971
キャッシュ制御: no-cache

{
    "odata.error": {
        "code": "",
        "message": {
            "lang": "en-US",
            "value": "An error has occurred."
        },
        "innererror": {
            "message": "Exception has been thrown by the target of an invocation.",
            "type": "System.Reflection.TargetInvocationException",
            "stacktrace": "   at System.Web.Http.ApiController.<InvokeActionWithExceptionFilters>d__0.MoveNext()\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.Dispatcher.HttpControllerDispatcher.<SendAsync>d__0.MoveNext()",
            "internalexception": {
                "message": "could not resolve property: class of: CreditoImobiliarioBB.Model.Modalidade [.Take[System.Web.Http.OData.Query.Expressions.SelectExpandWrapper`1[[CreditoImobiliarioBB.Model.Modalidade, CreditoImobiliarioBB.Model, Version=1.0.0.0, Culture=neutral, PublicKeyToken=null]]](.Select[CreditoImobiliarioBB.Model.Modalidade,System.Web.Http.OData.Query.Expressions.SelectExpandWrapper`1[[CreditoImobiliarioBB.Model.Modalidade, CreditoImobiliarioBB.Model, Version=1.0.0.0, Culture=neutral, PublicKeyToken=null]]](.ThenBy[CreditoImobiliarioBB.Model.Modalidade,System.Int32](.OrderBy[CreditoImobiliarioBB.Model.Modalidade,System.String](NHibernate.Linq.NhQueryable`1[CreditoImobiliarioBB.Model.Modalidade], Quote(($it, ) => ($it.Nome)), ), Quote(($it, ) => ($it.Id)), ), Quote((, ) => (new SelectExpandWrapper`1()444fb09a-b4c8-43e1-b1f6-d469f9da76eanew NamedPropertyWithNext`1()IdEqual(, NULL) ? NULL : Convert(.Id)new NamedProperty`1()IsType(, CreditoImobiliarioBB.Model.EntityNome) ? Nome : NULLEqual(, NULL) ? NULL : IsType(, CreditoImobiliarioBB.Model.EntityNome) ? TypeAs().Nome : NULL)), ), p8, )]",
                "type": "NHibernate.QueryException",
                "stacktrace": "   at NHibernate.Persister.Entity.AbstractPropertyMapping.ToType(String propertyName)\r\n   at NHibernate.Persister.Entity.AbstractEntityPersister.ToType(String propertyName)\r\n   at NHibernate.Hql.Ast.ANTLR.Tree.FromElementType.GetPropertyType(String propertyName, String propertyPath)\r\n   at NHibernate.Hql.Ast.ANTLR.Tree.FromElement.GetPropertyType(String propertyName, String propertyPath)\r\n   at NHibernate.Hql.Ast.ANTLR.Tree.DotNode.GetDataType()\r\n   at NHibernate.Hql.Ast.ANTLR.Tree.DotNode.PrepareLhs()\r\n   at NHibernate.Hql.Ast.ANTLR.Tree.DotNode.Resolve(Boolean generateJoin, Boolean implicitJoin, String classAlias, IASTNode parent)\r\n   at NHibernate.Hql.Ast.ANTLR.Tree.FromReferenceNode.Resolve(Boolean generateJoin, Boolean implicitJoin, String classAlias)\r\n   at NHibernate.Hql.Ast.ANTLR.Tree.FromReferenceNode.Resolve(Boolean generateJoin, Boolean implicitJoin)\r\n   at NHibernate.Hql.Ast.ANTLR.HqlSqlWalker.Resolve(IASTNode node)\r\n   at NHibernate.Hql.Ast.ANTLR.HqlSqlWalker.expr()\r\n   at NHibernate.Hql.Ast.ANTLR.HqlSqlWalker.exprOrSubquery()\r\n   at NHibernate.Hql.Ast.ANTLR.HqlSqlWalker.comparisonExpr()\r\n   at NHibernate.Hql.Ast.ANTLR.HqlSqlWalker.logicalExpr()\r\n   at NHibernate.Hql.Ast.ANTLR.HqlSqlWalker.caseExpr()\r\n   at NHibernate.Hql.Ast.ANTLR.HqlSqlWalker.arithmeticExpr()\r\n   at NHibernate.Hql.Ast.ANTLR.HqlSqlWalker.selectExpr()\r\n   at NHibernate.Hql.Ast.ANTLR.HqlSqlWalker.selectExprList()\r\n   at NHibernate.Hql.Ast.ANTLR.HqlSqlWalker.selectClause()\r\n   at NHibernate.Hql.Ast.ANTLR.HqlSqlWalker.unionedQuery()\r\n   at NHibernate.Hql.Ast.ANTLR.HqlSqlWalker.query()\r\n   at NHibernate.Hql.Ast.ANTLR.HqlSqlWalker.selectStatement()\r\n   at NHibernate.Hql.Ast.ANTLR.HqlSqlWalker.statement()\r\n   at NHibernate.Hql.Ast.ANTLR.HqlSqlTranslator.Translate()\r\n   at NHibernate.Hql.Ast.ANTLR.QueryTranslatorImpl.Analyze(String collectionRole)\r\n   at NHibernate.Hql.Ast.ANTLR.QueryTranslatorImpl.DoCompile(IDictionary`2 replacements, Boolean shallow, String collectionRole)\r\n   at NHibernate.Hql.Ast.ANTLR.QueryTranslatorImpl.Compile(IDictionary`2 replacements, Boolean shallow)\r\n   at NHibernate.Hql.Ast.ANTLR.ASTQueryTranslatorFactory.CreateQueryTranslators(IASTNode ast, String queryIdentifier, String collectionRole, Boolean shallow, IDictionary`2 filters, ISessionFactoryImplementor factory)\r\n   at NHibernate.Hql.Ast.ANTLR.ASTQueryTranslatorFactory.CreateQueryTranslators(String queryIdentifier, IQueryExpression queryExpression, String collectionRole, Boolean shallow, IDictionary`2 filters, ISessionFactoryImplementor factory)\r\n   at NHibernate.Engine.Query.HQLExpressionQueryPlan.CreateTranslators(String expressionStr, IQueryExpression queryExpression, String collectionRole, Boolean shallow, IDictionary`2 enabledFilters, ISessionFactoryImplementor factory)\r\n   at NHibernate.Engine.Query.HQLExpressionQueryPlan..ctor(String expressionStr, IQueryExpression queryExpression, String collectionRole, Boolean shallow, IDictionary`2 enabledFilters, ISessionFactoryImplementor factory)\r\n   at NHibernate.Engine.Query.HQLExpressionQueryPlan..ctor(String expressionStr, 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.PrepareQuery(Expression expression, IQuery& query, NhLinqExpression& nhQuery)\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.GetEnumerator()\r\n   at System.Web.Http.OData.Query.ODataQueryOptions.LimitResults[T](IQueryable`1 queryable, Int32 limit, Boolean& resultsLimited)"
            }
        }
    }
}
4

2 に答える 2

0

あなたに追加EnsureStableOrdering = falseしてみてくださいQueryableAttribute

[Queryable(EnsureStableOrdering = false, AllowedQueryOptions = AllowedQueryOptions.All, PageSize = 20)]
public override IQueryable<T> Get()
于 2013-07-03T00:38:46.653 に答える
0

クエリの $select 部分が厄介です。$select と $expand を Linq2Objects と Entityframework 以外で動作させることは試みていません。$select と $expand を動作させ、Entityframework で効率的な方法で生成する式は、自明ではありません。

とはいえ、問題の解決策の 1 つは、ODataQueryOptions を使用してクエリを部分的に適用することです。$filter、$orderby、$skip、$top をデータベースに適用し、最初のステップの後に ToList() を実行して、$select と $expand をインメモリに適用します。

nhibernate をさらに試して、式の生成を改善してこのシナリオを機能させることができるかどうかを確認します。

于 2013-07-02T23:04:53.787 に答える