我已经阅读了很多关于同样错误的问题,但没有找到与我的确切问题相符的问题 . 我正在尝试使用Fluent NHibernate访问对象的属性,该对象本身是根对象的一部分 . 一些答案说我需要使用投影,其他我需要使用连接,我认为它应该通过延迟加载 .
这是我的两个类以及Fluent映射:
Artist class
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);
}
}
Album class
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);
}
}
并且在解释此代码时会发生错误:
var riAlbum = session.QueryOver<Album>()
.Where(x => x.Name == albumName && x.Artist.Name == artist)
.List().FirstOrDefault();
当Fluent NHibernate尝试解析x.Artist.Name值时,会发生错误:
{“无法解析属性:Artist.Name of:Album”}
这样做的正确方法是什么?
2 回答
您必须将QueryOver查询视为(几乎)直接转换为SQL . 考虑到这一点,想象一下这个SQL查询:
这样就可以访问SQL语句中的相关表的属性 . 您需要创建从
Album
到Artist
的连接,然后使用Where
子句:此外,由于您正在使用
FirstOrDefault
,您可能需要考虑将该逻辑移动到数据库端 . 目前,您正在撤回符合条件的每条记录,然后选择第一条记录 . 您可以使用.Take
将查询限制为1个结果:另一种解释是您缺少NHibernateClassMapping定义中此属性或字段的映射 . 我来到这里是为什么我基于以下场景得到此错误 .
这给了我一个StartDate的无法解决属性错误 . 这是一个令人头疼的问题,因为我一直使用这种语法 .
我的映射文件如下:
缺少StartDate . 变成:
哪解决了这个错误 .