Fluent NHibernate“无法解析属性" [英] Fluent NHibernate "Could not resolve property"

查看:24
本文介绍了Fluent NHibernate“无法解析属性"的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我已经阅读了很多关于相同错误的问题,但没有一个与我的确切问题相匹配.我正在尝试使用 Fluent NHibernate 访问对象的属性,该对象本身是根对象的一部分.一些答案说我需要使用投影,另一些答案说我需要使用 join,我认为它应该通过延迟加载来工作.

I have read a lot of the questions about that same error but none since to match my exact problem. I'm trying to access the property of an object, itself part of a root object, using Fluent NHibernate. Some answers say I need to use projections, others that I need to use join, and I think it should work through lazy loading.

这是我的两个类以及 Fluent 映射:

Here are my two classes along with the Fluent mappings:

艺术家班

public class Artist
{
    public virtual int Id { get; set; }
    public virtual string Name { get; set; }
    public virtual IList<Album> Albums { get; set; }
    public virtual string MusicBrainzId { get; set; }
    public virtual string TheAudioDbId { get; set; }

    public Artist() { }
}

public class ArtistMap : ClassMap<Artist>
{
    public ArtistMap()
    {
        LazyLoad();
        Id(a => a.Id);
        Map(a => a.Name).Index("Name");
        HasMany(a => a.Albums)
            .Cascade.All();
        Map(a => a.MusicBrainzId);
        Map(a => a.TheAudioDbId);
    }
}

相册类

public class Album
{
    public virtual int Id { get; set; }
    public virtual Artist Artist { get; set; }
    public virtual string Name { get; set; }
    public virtual IList<Track> Tracks { get; set; }
    public virtual DateTime ReleaseDate { get; set; }
    public virtual string TheAudioDbId { get; set; }
    public virtual string MusicBrainzId { get; set; }

    public Album() { }
}

public class AlbumMap : ClassMap<Album>
{
    public AlbumMap()
    {
        LazyLoad();
        Id(a => a.Id);
        References(a => a.Artist)
            .Cascade.All();
        Map(a => a.Name).Index("Name");
        HasMany(a => a.Tracks)
            .Cascade.All();
        Map(a => a.ReleaseDate);
        Map(a => a.TheAudioDbId);
        Map(a => a.MusicBrainzId);
    }
}

在解释这段代码时会发生错误:

And the error happens when this code is interpreted:

var riAlbum = session.QueryOver<Album>()
                .Where(x => x.Name == albumName && x.Artist.Name == artist)
                .List().FirstOrDefault();

当 Fluent NHibernate 尝试解析 x.Artist.Name 值时发生错误:

The error happens when Fluent NHibernate tries to resolve the x.Artist.Name value:

{"无法解析属性:艺术家.名称:专辑"}

{"could not resolve property: Artist.Name of: Album"}

这样做的正确方法是什么?

What would be the correct way of doing this?

推荐答案

您必须将 QueryOver 查询视为(几乎)直接转换为 SQL.考虑到这一点,想象一下这个 SQL 查询:

You have to think of your QueryOver query as (nearly) directly translating into SQL. With this in mind, imagine this SQL query:

select
    Album.*
from
    Album
where
    Album.Name = 'SomeAlbumName' and
    Album.Artist.Name = 'SomeArtistName'

这行不通,因为您无法像在 SQL 语句中那样访问相关表的属性.您需要创建从 AlbumArtist 的连接,然后 then 使用 Where 子句:

This won't work because you can't access a related table's properties like that in a SQL statement. You need to create a join from Album to Artist and then use a Where clause:

var riAlbum = 
    session.QueryOver<Album>()
               .Where(al => al.Name == albumName)
           .JoinQueryOver(al => al.Artist)
               .Where(ar => ar.Name == artistName)
           .List()
           .FirstOrDefault();

此外,由于您使用的是 FirstOrDefault,您可能需要考虑将该逻辑移至数据库端.目前,您正在撤回符合您标准的每条记录,然后获取第一个记录.您可以使用 .Take 将查询限制为 1 个结果:

Also, since you're using FirstOrDefault, you may want to consider moving that logic to the database end. Currently, you're pulling back every record matching your criteria and then taking the first one. You could use .Take to limit the query to 1 result:

var riAlbum = 
    session.QueryOver<Album>()
               .Where(al => al.Name == albumName)
           .JoinQueryOver(al => al.Artist)
               .Where(ar => ar.Name == artistName)
           .Take(1)
           .SingleOrDefault<Album>();

这篇关于Fluent NHibernate“无法解析属性"的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆