流利的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
并且在解释此代码时会发生错误:
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语句中的相关表的属性。 您需要创建从Album
到Artist
, 然后使用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); } }
哪解决了这个错误。