LINQ to NHibernate:无法解析属性

发布于 2024-10-07 07:29:34 字数 3208 浏览 3 评论 0原文

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

我有一个带有名为 DateOfEvent 的 DateTime 字段的域对象。这是数据库中的实际日期/时间字段。我还添加了 2 个新属性 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();
    }

NHibernate.QueryException:无法解析属性:YearOfEvent of:....Event

FWIW,我已经模糊了项目的名称。 ;)

知道如何让这个查询工作吗?

谢谢! -史蒂夫

编辑: 这是我的映射类:

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>();

也没有工作。

Fluent nHibernate using nHibernate v. 2.1.2.4, nHibernate.Linq v. 1.1.0.1001, and Fluent NHibernate v. 1.1.0.685.

I have a domain object with a DateTime field called DateOfEvent. This is an actual date/time field in the database. I've also added 2 new properties YearOfEvent which grabs the Year from the DateOfEvent field as well as MontOfEvent which grabs the Month from the DateOfEvent field.

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; }
}

However, when running this method:

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: could not resolve property: YearOfEvent of: ....Event

FWIW, I've blurred out the name of the project. ;)

Any idea how to get this query working?

Thanks!
-Steve

EDIT:
Here's my mapping class:

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");
    }
}

...and my config:

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;
    }

I also just tried the Criteria API:

return _session.CreateCriteria(typeof (Event))
            .Add(Expression.Eq("IsActive", true))
            .Add(Expression.Eq("YearOfEvent", year))
            .List<Event>();

No workie either.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(5

滥情哥ㄟ 2024-10-14 07:29:34

以下是如何使用公式解决这个问题。在您的 Event 类中,将这 2 个属性转换为常规属性:

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>();

Here is how you can fix that using the formulas. In your Event class convert those 2 properties into regular properties:

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; }
}

Then in the mapping add formulas to populate their values.. I'm not very positive about the MySQL syntax for retrieving the year & month but you've got an idea (I used this reference):

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");
    }
}

Now you can query them just like any other fields using either LINQ or ICriteria:

return _session.CreateCriteria(typeof (Event))
            .Add(Expression.Eq("IsActive", true))
            .Add(Expression.Eq("YearOfEvent", year))
            .List<Event>();
榆西 2024-10-14 07:29:34

您可以查询数据库中真实存在的属性或映射中引入的属性。由于 YearOfEvent 仅存在于您的实体中,因此您无法在 LINQ-to-NH 或 ICriteria 的查询中使用它。

You can query over properties that really exists in database or introduced in the mappings. As YearOfEvent just exists in your entity, you can not use it in your queries either in LINQ-to-NH or ICriteria.

秉烛思 2024-10-14 07:29:34

我使用的技术是强制执行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()。

The technique that I use is to force execution of NHLinq and then utilize LINQ to finish filtering. This is technically what needs to happen since NH is unaware of non-mapped properties like Event.YearOfEvent. It would look something like this:

_session.Linq<Event>()
.Where(e => e.IsActive)
.ToArray() // force evaluation of expression
.Where(e => e.YearOfEvent == DateTime.Now.Year); // evaluated by LINQ, not NHLinq

Note: You can utilize any of the other methods that force evaluation (e.g., ToList()). This technique is not dependent upon ToArray() specifically.

彼岸花ソ最美的依靠 2024-10-14 07:29:34

你是自动映射这个吗?因为我怀疑它试图映射 YearOfEvent 和 MonthOfEvent,并且它试图从数据库中提取这些列,但它们不存在。

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

Are you auto mapping this? Because I would suspect it's attempted to map YearOfEvent and MonthOfEvent, and it's trying to pull those columns from the database, but they don't exist.

If you're manually mapping them, then this wouldn't be an issue.

握住我的手 2024-10-14 07:29:34

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

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

但是,您的 linq 查询看起来应该可以工作,我不知道该查询如何发生此错误;映射...

Your criteria query is not working, because your "YearOfEvent" property is not listed in your mapping. NHibernate does not know this property, and cannot translate it into a column name.

Try querying on properties that are actually mapped instead of calculated properties, or calculate the property directly in your query...

However, your linq query looks like it should be working, I don't see how this error can occur with that query & mapping...

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文