LINQ到NHibernate:无法解析属性

LINQ到NHibernate:无法解析属性,nhibernate,fluent-nhibernate,linq-to-nhibernate,Nhibernate,Fluent Nhibernate,Linq To Nhibernate,使用nHibernate v。2.1.2.4,nHibernate.Linq v。1.1.0.1001和Fluent NHibernate v。1.1.0.685 我有一个域对象,它有一个名为DateOfEvent的DateTime字段。这是数据库中的实际日期/时间字段。我还添加了两个新属性YearOfEvent,它从DateOfEvent字段获取年份,以及MontOfEvent,它从DateOfEvent字段获取月份 public class Event { public Event(

使用nHibernate v。2.1.2.4,nHibernate.Linq v。1.1.0.1001和Fluent NHibernate v。1.1.0.685

我有一个域对象,它有一个名为DateOfEvent的DateTime字段。这是数据库中的实际日期/时间字段。我还添加了两个新属性YearOfEvent,它从DateOfEvent字段获取年份,以及MontOfEvent,它从DateOfEvent字段获取月份

public class Event
{
    public Event() { }
    public virtual Int32 Id { get; set; }
    public virtual String Title { get; set; }
    public virtual DateTime DateOfEvent { get; set; }
    public virtual Int32 YearOfEvent
    {
        get { return DateOfEvent.Year; }
    }
    public virtual Int32 MonthOfEvent
    {
        get { return DateOfEvent.Month; }
    }
    public virtual String Location { get; set; }
    public virtual String City { get; set; }
    public virtual String State { get; set; }
    public virtual String Zip { get; set; }
    public virtual String Description { get; set; }
    public virtual Boolean HasImage { get; set; }
    public virtual Boolean IsActive { get; set; }
}
但是,在运行此方法时:

public IList<Event> GetActiveEvents(int pageNumber, int pageSize, out int totalItems)
    {
        Int32 skip = Misc.NumberToSkip(pageNumber, pageSize);
        totalItems = (from e in _session.Linq<Event>()
                      where e.IsActive
                      select e).Count();

        return (from e in _session.Linq<Event>()
                where e.IsActive
                select e)
            .Skip(skip)
            .Take(pageSize)
            .ToList();
    }
我还尝试了Criteria API:

return _session.CreateCriteria(typeof (Event))
            .Add(Expression.Eq("IsActive", true))
            .Add(Expression.Eq("YearOfEvent", year))
            .List<Event>();
return\u session.CreateCriteria(typeof(Event))
.Add(表达式.Eq(“IsActive”,真))
.Add(表达式.Eq(“事件年份”,年份))
.List();

也没有工作。

您是否自动映射此项?因为我怀疑它试图映射YearOfEvent和MonthOfEvent,它试图从数据库中提取这些列,但它们不存在


如果您手动映射它们,那么这就不是问题。

您可以查询数据库中实际存在或映射中引入的属性。由于
YearOfEvent
仅存在于实体中,您不能在LINQ to NH或ICriteria中的查询中使用它。

您的条件查询不起作用,因为您的“YearOfEvent”属性未在映射中列出。NHibernate不知道此属性,无法将其转换为列名

尝试查询实际映射的属性而不是计算属性,或者直接在查询中计算属性


但是,您的linq查询看起来应该正常工作,我看不出该查询和映射如何会出现此错误…

下面是如何使用公式解决此问题。在事件类中,将这两个属性转换为常规属性:

public class Event
{
    public Event() { }
    ...
    public virtual DateTime DateOfEvent { get; set; }
    public virtual Int32 YearOfEvent{ get; set; }
    public virtual Int32 MonthOfEvent { get; set; }
    ...
    public virtual Boolean IsActive { get; set; }
}
然后在映射中添加公式以填充其值。。我对用于检索年份和月份的MySQL语法不是很肯定,但您已经有了一个想法(我使用了参考):

公共类事件映射:类映射
{
公共事件地图()
{
表(“tbl_事件”);
Id(x=>x.Id,“eventId”);
Map(x=>x.DateOfEvent,“DateOfEvent”);
Map(x=>x.YearOfEvent)。公式(“选择年份(dateOfEvent)”;
Map(x=>x.MonthOfEvent).Formula(“选择月(dateOfEvent)”);
...
Map(x=>x.IsActive,“IsActive”);
}
}
现在,您可以像使用LINQ或ICriteria查询任何其他字段一样查询它们:

return _session.CreateCriteria(typeof (Event))
            .Add(Expression.Eq("IsActive", true))
            .Add(Expression.Eq("YearOfEvent", year))
            .List<Event>();
return\u session.CreateCriteria(typeof(Event))
.Add(表达式.Eq(“IsActive”,真))
.Add(表达式.Eq(“事件年份”,年份))
.List();

我使用的技术是强制执行NHLinq,然后利用LINQ完成过滤。这在技术上是需要发生的,因为NH不知道诸如Event.YearOfEvent之类的未映射属性。它看起来像这样:

_session.Linq<Event>()
.Where(e => e.IsActive)
.ToArray() // force evaluation of expression
.Where(e => e.YearOfEvent == DateTime.Now.Year); // evaluated by LINQ, not NHLinq
\u session.Linq()
.其中(e=>e.IsActive)
.ToArray()//强制计算表达式
.Where(e=>e.YearOfEvent==DateTime.Now.Year);//由LINQ而非NHLinq评估

注意:您可以使用任何其他强制求值的方法(例如,ToList())。这项技术并不具体依赖于ToArray()。

Phill,我正在手动映射它们。我已经发布了我的配置以及它的映射。奇怪。在我看来不错,我想可能是LINQ提供商试图对这些属性做一些花哨的事情。您是否尝试过在没有LINQ的情况下运行相同的查询?Phill,只是尝试(发布了查询)使用CriteriaAPI。同样的例外。奇怪,我不能说我以前遇到过这样的问题。请尝试从这两个属性中删除虚拟属性。我怀疑这会有帮助,但值得一试。除此之外,我现在没有主意了对不起:(奇怪,我不能说我以前有过这样的问题。你能尝试从两个属性中删除虚拟。不确定是否有用,值得一试。除此之外,我没有主意。我唯一的其他建议是尝试从Fluent网站上创建最新的稳定版本。已经尝试过了。获得此例外:以下类型不能用作代理:…事件:方法get_YearOfEvent应为“public/protected virtual”或“protected internal virtual”…事件:方法get_MonthOfEvent应为“public/protected virtual”或“protected internal virtual”
public class EventMap : ClassMap<Event>
{
    public EventMap()
    {
        Table("tbl_event");
        Id(x => x.Id, "eventId");
        Map(x => x.DateOfEvent, "dateOfEvent");
        Map(x => x.YearOfEvent).Formula("SELECT YEAR(dateOfEvent)");
        Map(x => x.MonthOfEvent).Formula("SELECT MONTH(dateOfEvent)");            
        ...
        Map(x => x.IsActive, "isActive");
    }
}
return _session.CreateCriteria(typeof (Event))
            .Add(Expression.Eq("IsActive", true))
            .Add(Expression.Eq("YearOfEvent", year))
            .List<Event>();
_session.Linq<Event>()
.Where(e => e.IsActive)
.ToArray() // force evaluation of expression
.Where(e => e.YearOfEvent == DateTime.Now.Year); // evaluated by LINQ, not NHLinq