流利的NHibernate“无法解决财产问题”

我已经阅读了很多关于同样错误的问题,但没有找到与我的确切问题相符的问题。 我正在尝试使用Fluent NHibernate访问对象的属性,它本身是根对象的一部分。 一些答案说我需要使用投影,其他我需要使用连接,我认为它应该通过延迟加载。

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

艺术家class

public class Artist { public virtual int Id { get; set; } public virtual string Name { get; set; } public virtual IList Albums { get; set; } public virtual string MusicBrainzId { get; set; } public virtual string TheAudioDbId { get; set; } public Artist() { } } public class ArtistMap : ClassMap { 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 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 { 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() .Where(x => x.Name == albumName && x.Artist.Name == artist) .List().FirstOrDefault(); 

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

{“无法解析属性:Artist.Name of:Album”}

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

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

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

这不起作用,因为您无法访问SQL语句中的相关表的属性。 您需要创建从AlbumArtist然后使用Where子句:

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

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

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

另一种解释是您在NHibernateClassMapping定义中缺少此属性或字段的映射。 我来到这里是为什么我基于以下场景得到此错误。

  var query = scheduleRepository.CurrentSession().Query() .Where(x => x.ScheduleInfo.StartDate.Date < dateOfRun.Date); 

这给了我一个StartDate的无法解决属性错误。 这是一个令人头疼的问题,因为我一直使用这种语法。

我的映射文件如下:

 public class ScheduleInfoMapping : NHibernateClassMapping { public ScheduleInfoMapping() { DiscriminateSubClassesOnColumn("Type"); Map(x => x.Detail).MapAsLongText(); } } 

缺少StartDate。 变成:

 public class ScheduleInfoMapping : NHibernateClassMapping { public ScheduleInfoMapping() { DiscriminateSubClassesOnColumn("Type"); Map(x => x.Detail).MapAsLongText(); Map(x => x.StartDate); } } 

哪解决了这个错误。