使用nHibernate v.2.1.2.4,nHibernate.Linq v.1.1.0.1001和Fluent NHibernate v.1.1.0.685进行流利的nHibernate。
我有一个名为DateOfEvent的DateTime字段的域对象。这是数据库中的实际日期/时间字段。我还添加了2个新属性YearOfEvent,它从DateOfEvent字段获取Year,以及从DateOfEvent字段获取Month的MontOfEvent。
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();
}
NHibernate.QueryException:无法解析属性:YearOfEvent:.... Event
FWIW,我已经模糊了项目的名称。 ;)
知道如何使这个查询有效吗?
谢谢! -Steve
编辑: 这是我的映射类:
public class EventMap : ClassMap<Event>
{
public EventMap()
{
Table("tbl_event");
Id(x => x.Id, "eventId");
Map(x => x.DateOfEvent, "dateOfEvent");
Map(x => x.Description, "description");
Map(x => x.Title, "title");
Map(x => x.Location, "location");
Map(x => x.State, "state");
Map(x => x.City, "city");
Map(x => x.Zip, "zip");
Map(x => x.HasImage, "hasImage");
Map(x => x.IsActive, "isActive");
}
}
...和我的配置:
public Configuration GetConfiguration()
{
Configuration configuration;
var assembly = Assembly.Load(".....Data");
var fluentConfig = Fluently.Configure()
.Database(MySQLConfiguration.Standard.ConnectionString(
c => c.FromConnectionStringWithKey("......")
))
.Mappings(m => m.FluentMappings.AddFromAssembly(assembly));
configuration = fluentConfig.BuildConfiguration();
configuration.Properties.Add("hbm2ddl.keywords", "none");
return configuration;
}
我也尝试了Criteria API:
return _session.CreateCriteria(typeof (Event))
.Add(Expression.Eq("IsActive", true))
.Add(Expression.Eq("YearOfEvent", year))
.List<Event>();
也没有工作。
答案 0 :(得分:4)
以下是使用公式解决问题的方法。在Event类中,将这两个属性转换为常规属性:
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语法不是很积极。一个月,但你有一个想法(我使用this参考):
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");
}
}
现在您可以像使用LINQ或ICriteria的任何其他字段一样查询它们:
return _session.CreateCriteria(typeof (Event))
.Add(Expression.Eq("IsActive", true))
.Add(Expression.Eq("YearOfEvent", year))
.List<Event>();
答案 1 :(得分:2)
您可以查询真正存在于数据库中或在映射中引入的属性。由于YearOfEvent
只存在于您的实体中,因此无法在LINQ-to-NH或ICriteria的查询中使用它。
答案 2 :(得分:2)
我使用的技术是强制执行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
注意:您可以使用强制评估的任何其他方法(例如,ToList())。该技术不依赖于ToArray()。
答案 3 :(得分:1)
你是自动映射吗?因为我怀疑它试图映射YearOfEvent和MonthOfEvent,并且它试图从数据库中提取这些列,但它们不存在。
如果你手动映射它们,那么这不是问题。
答案 4 :(得分:0)
您的条件查询无效,因为您的“YearOfEvent”属性未在您的映射中列出。 NHibernate不知道这个属性,也不能将它转换为列名。
尝试查询实际映射的属性而不是计算属性,或直接在查询中计算属性...
然而,您的linq查询看起来应该正常工作,我不知道该查询&amp;映射...