LINQ到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字段获取月份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(
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