我的理解是,当将一个集合映射为列表并给出一个索引列时:
不幸的是,我的经验表明只有(1)有效。 这是映射:
HasMany(x => x.Attachments)
.AsList( index => index.Column("OrderInProduct") )
.Cascade.AllDeleteOrphan() // Handle cascade upserts
;
我对(2)的期望是否错误?我的地图错了吗?
答案 0 :(得分:1)
你可以添加orderby:
HasMany(x => x.Attachments)
.AsList( index => index.Column("OrderInProduct") )
.OrderBy( o => o.Column("OrderInProduct") )
.Cascade.AllDeleteOrphan() // Handle cascade upserts
;
答案 1 :(得分:0)
我刚刚玩过,2)为我工作。您的映射可以。
我相信NHibernate会根据索引列的值对内存中的集合进行排序,而不会发出“ Order By” sql语句。我想到NHibernate可以对内存进行排序here-这将在SQL查询而不是内存中执行排序。
我在NHibernate代码中找不到集合内存排序,因此为了证明内存排序有效,我从子实体表中删除了主键(Id,Index),并保留了2个子实体(索引0和索引1) ),手动-使用手动sql-切换索引值(因此第一条记录的索引为索引1,第二条记录的索引为0),然后我加载了父实体并检查记录是否按预期顺序加载。
答案 2 :(得分:0)
您可能不再在寻找答案,但出于后代的原因,我将在此处发布。 Fluent NHibernate中有一个错误,或者我试图做不允许做的事情,但是当我配置会话工厂以导出.HBM.xml文件时,我发现HasMany映射被指定为包而不是列表,尽管序列号已正确更新。映射是对其他更改(例如.Not.LazyLoad())的响应,但是对于我来说,我一辈子都无法将其映射为列表。
我最终提出了一个骇客,这部分受this链接的启发。在父级中(撇开转录错误:):
private IList<Child> _children;
public virtual IReadOnlyList<Child> Children => _children.OrderBy(la => la.Position).ToList();
protected internal int GetPositionOf(Child child) => _children.ToList().IndexOf(child);
在孩子中:
private int? _position;
protected internal int Position
{
get
{
var position = _position ?? (_position = Parent.GetPositionOf(this));
return position.HasValue ? position.Value : throw new InvalidOperationException("Child position has no value");
}
set { _position = value; }
}
我继续使用.AsList进行地图绘制,以便正确更新位置:
HasMany(x => x.Children).Access.CamelCaseField(Prefix.Underscore).AsList(x => x.Column(ColumnNames.Position));
以防万一,可以导出.hbm文件以查看Fluent Migrator实际生成的内容:
FluentConfiguration configuration = Fluently.Configure()
.Database(dbConfig)
.Mappings(m => m.FluentMappings.AddFromAssembly(Assembly.GetExecutingAssembly())
.ExportTo(@"c:\temp\mappings")
请注意,您必须事先生成文件夹,否则会出现异常。
我很想知道是否有人看到过类似的行为;我正在使用Fluent Migrator 2.1.2和NHibernate 5.2.7。我本来打算提交一个错误报告,但必须先清除一些工作。