【问题标题】:Order By nHibernate Causes 'Antlr.Runtime.NoViableAltException'按 nHibernate 排序导致“Antlr.Runtime.NoViableAltException”
【发布时间】:2012-08-31 21:05:18
【问题描述】:

我收到以下错误

引发了“Antlr.Runtime.NoViableAltException”类型的异常。 [.OrderBy[ORM.Entities.Core.Message,System.DateTime](.Where[ORM.Entities.Core.Message](NHibernate.Linq.NhQueryable`1[ORM.Entities.Core.Message], 报价((x,)=> (AndAlso(AndAlso(String.op_Equality(x.ConcerningItemType, p1), 等于(x.ConcerningItemId,p2)),OrElse(等于(x.Sender.Id,p3), .Any[ORM.Entities.Core.MessageRecipient](x.Recipients, (r, ) => (Equal(r.Employee.Id, p4)), ))))), ), Quote((x, ) => (.FirstORM.Entities.Core.AuditGroup.Created)), )]

当我有一个 IQueryable 结果集(刚刚对其应用了一些逻辑),然后我尝试在调用 ToList() 之前按子属性变量对其进行排序

var results = query.Where(x => x.ConcerningItemType == "1422" && x.ConcerningItemId == EnquiryId && //Messages for this Enquiry
                            (x.Sender.Id == EmployeeId || x.Recipients.Any(r => r.Employee.Id == EmployeeId)));

然后我尝试订购导致错误

var results2 = results.OrderBy(x => x.AuditGroup.First().Created).ToList();

如果我改为执行以下操作,则不会出现错误(移动 tolist 以强制它访问数据库)

var results3 = results.ToList().OrderBy(x => x.AuditGroup.First().Created);

询问要求的更多信息

审计组类

    public class AuditGroup : Entity
{
    public virtual string Guid { get; set; }
    public virtual string PageName { get; set; }
    public virtual string ControlId { get; set; }
    public virtual string ItemType { get; set; }
    public virtual int ItemId { get; set; }
    public virtual int EmployeeId { get; set; }
    public virtual string IPAddress { get; set; }
    public virtual string Parameters { get; set; }
    public virtual DateTime Created { get; set; }

}

消息类

    public class Message : Entity
{
    // This class represents the standard address fields, for reuse in other entities
    // 
    public virtual int Id { get; set; }
    public virtual int ConcerningItemId { get; set; }
    public virtual String ConcerningItemType { get; set; }
    public virtual String Subject { get; set; }
    public virtual String Body { get; set; }
    public virtual int RecipientCount { get; set; }
    public virtual String RowStatus { get; set; }

    public virtual Employee Sender { get; set; }
    public virtual ICollection<MessageRecipient> Recipients { get; set; }

    //eww have to do this to be able to access the created date of the message (stored in AuditGroup... Stupidly!)
    public virtual ICollection<AuditGroup> AuditGroup { get; set; }
}

消息映射

        public MessageMapping()
    {
        Id(x => x.Id).Column("MessageId");
        Map(x => x.ConcerningItemId).Nullable().Column("ItemId");
        Map(x => x.ConcerningItemType).Nullable().Column("ItemType");

        Map(x => x.Subject).Nullable();
        Map(x => x.Body);
        Map(x => x.RecipientCount).Column("MessageRecipientCount");
        Map(x => x.RowStatus).Column("MessageRowStatus");

        References(x => x.Sender).Column("EmployeeId");
        HasMany(x => x.Recipients).KeyColumn("MessageId");

        //AuditGroup has ItemId-ItemType Needs to map to MessageId-ItemType
        HasMany(x => x.AuditGroup).KeyColumn("ItemId").Where("ItemType = '1419'");
    }

【问题讨论】:

    标签: c# linq fluent-nhibernate linq-to-nhibernate


    【解决方案1】:

    请提供更多信息(实体和地图)

    我很确定 x.AuditGroup.First().Created 是罪魁祸首。我这样说是因为我试图认为 SQL 查询生成了,但我不能。

    我建议为AuditGroup 创建一个别名并使用它进行排序。这就是我的大致做法。

    AuditGroup auditGroupAlias = null;
    
    query.JoinAlias(p => p.AuditGroup, () => auditGroupAlias)
         .OrderBy(()=>auditGroupAlias.Created)
    

    再次用部分信息我只能给出部分解决方案。

    【讨论】:

    • 按要求提供了映射类和两个实体类
    • 当消息已经知道它的审计组集合时,为什么我需要创建一个别名?
    • 因为你不能在OrderBy里面做First(),所以我知道
    • 另外,在我运行的几个测试中,我在执行此操作时遇到异常(尽管与您不同)
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2010-09-16
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2012-06-28
    相关资源
    最近更新 更多