Breeze错误抛出了类型'Antlr.Runtime.NoViableAltException'的异常

时间:2013-06-24 13:24:22

标签: nhibernate asp.net-mvc-4 fluent-nhibernate asp.net-web-api breeze

指定$ 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文件夹中的完整code here;

1 个答案:

答案 0 :(得分:5)

我怀疑NHibernate的LINQ提供程序由于空检查而阻塞了过滤器表达式。空检查将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](即Breeze.Nhibernate.WebApi.BreezeNHControllerAttribute)而不是[BreezeController],则会自动将此选项应用于所有IQueryable方法。它还为处理$ expand和控制序列化期间的延迟加载添加了额外的逻辑。

NHibernate的官方Breeze支持即将推出。很高兴看到你已经在使用它了。