1

指定 $filter 时出错{{api}}/Person/Get?$filter=substringof('rid', Name) eq true

错误

{
    "$id": "1",
    "$type": "System.Web.Http.HttpError, System.Web.Http",
    "Message": "An error has occurred.",
    "ExceptionMessage": "Exception has been thrown by the target of an invocation.",
    "ExceptionType": "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()",
    "InnerException": {
        "$id": "2",
        "$type": "System.Web.Http.HttpError, System.Web.Http",
        "Message": "An error has occurred.",
        "ExceptionMessage": "Exception of type 'Antlr.Runtime.NoViableAltException' was thrown. [.Take[BreezeWithNHiberbate.Model.Person](.OrderBy[BreezeWithNHiberbate.Model.Person,System.Int32](.Where[BreezeWithNHiberbate.Model.Person](NHibernate.Linq.NhQueryable`1[BreezeWithNHiberbate.Model.Person], Quote(($it, ) => (Equal(Equal(Or(Equal(Convert($it.Name), NULL), p1) ? NULLp3 : Convert(Convert($it.Name).Contains(p2, )), p4), p5))), ), Quote(($it, ) => ($it.Id)), ), p6, )]",
        "ExceptionType": "NHibernate.Hql.Ast.ANTLR.QuerySyntaxException",
        "StackTrace": "   at NHibernate.Hql.Ast.ANTLR.ErrorCounter.ThrowQueryException()\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)"
    }
}

指定时,过滤器有效!{{api}}/Person/Get?

{
    "$id": "1",
    "$type": "BreezeWithNHiberbate.Model.Person, BreezeWithNHiberbate.Model",
    "Name": "Riderman de Sousa Barbosa",
    "NickName": "ridermansb",
    "Id": 1,
    "CreateAt": "2013-06-21T19:38:27.000",
    "UpdateAt": "2013-06-21T19:38:27.000"
},
{
    "$id": "2",
    "$type": "BreezeWithNHiberbate.Model.Person, BreezeWithNHiberbate.Model",
    "Name": "Felipe de Sousa Barbosa",
    "NickName": "felipegerais",
    "Id": 2,
    "CreateAt": "2013-06-21T19:38:35.000",
    "UpdateAt": "2013-06-21T19:38:35.000"
},
{
    "$id": "3",
    "$type": "BreezeWithNHiberbate.Model.Person, BreezeWithNHiberbate.Model",
    "Name": "Maria Helena de Sousa",
    "NickName": " lelena",
    "Id": 3,
    "CreateAt": "2013-06-21T19:38:41.000",
    "UpdateAt": "2013-06-21T19:38:41.000"
}

源代码

public class Person : Auditable
{
    [Required]
    public virtual string Name { get; set; }
    public virtual string NickName { get; set; }
}

public abstract class Auditable : IAuditable
{
    public virtual int Id { get; protected set; }

    public virtual DateTime CreateAt { get; protected set; }
    public virtual DateTime? UpdateAt { get; protected set; }
}

public interface IAuditable : IEntity
{
    DateTime CreateAt { get; }
    DateTime? UpdateAt { get; }
}

文件夹中的完整代码;BreezeWithNHiberbate

4

1 回答 1

5

我怀疑 NHibernate 的 LINQ 提供程序由于 null 检查而阻塞了过滤器表达式。空值检查将每个过滤器参数包装在 NH LINQ 无法处理的表达式中。

WebApi OData 关闭对 EF、Linq2Sql 和 Linq2Objects 的空值检查,但对其他所有内容打开它。要关闭它,请添加

HandleNullPropagation = HandleNullPropagationOption.False

到您的 Querable 属性。因此,在您的 BaseApiController 中,您将拥有

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

请注意,如果您使用[BreezeNHController](that's Breeze.Nhibernate.WebApi.BreezeNHControllerAttribute) 而不是[BreezeController],它会自动将此选项应用于所有 IQueryable 方法。它还为处理 $expand 和控制序列化期间的延迟加载添加了额外的逻辑。

NHibernate 的官方微风支持即将推出。很高兴看到您已经在使用它。

于 2013-06-24T19:02:45.533 回答