C# 如何映射到NHibernate中的分类列表

C# 如何映射到NHibernate中的分类列表,c#,nhibernate,nhibernate-mapping,C#,Nhibernate,Nhibernate Mapping,我有一个nHibernate父子表关系。父类当前正在将子类拉入列表中,但我想根据表中的排序列将它们放入SortedList中。如何更改NHibernate映射文件以让系统知道我在哪个列上排序 当前的NHibernate映射文件包括: <hibernate-mapping xmlns="urn:nhibernate-mapping-2.2" namespace="Model.Configuration.Pages"

我有一个nHibernate父子表关系。父类当前正在将子类拉入列表中,但我想根据表中的排序列将它们放入SortedList中。如何更改NHibernate映射文件以让系统知道我在哪个列上排序

当前的NHibernate映射文件包括:

<hibernate-mapping xmlns="urn:nhibernate-mapping-2.2"
                   namespace="Model.Configuration.Pages"
                   assembly="Model.Configuration">
  <joined-subclass
            table="PageConfigurations"
            name="PageConfiguration"
            extends="Model.Configuration.Configuration.TargetedConfiguration"
            lazy="false">
    <key column="TargetedConfigurationId" />

    <property name="SchemaVersion" />

    <property name="Template" type="System.String" length="50" />

    <property name="PageKey" type="System.String" length="50" />

    <property name="Percentage" />

    <bag name="Controls" cascade="all-delete-orphan" lazy="false" >
      <key column="PageConfigurationId" />
      <one-to-many class="WidgetConfiguration"/>
    </bag>

  </joined-subclass>
</hibernate-mapping>

对于父表和:

<hibernate-mapping xmlns="urn:nhibernate-mapping-2.2"
                   namespace="Model.Configuration.Pages"
                   assembly="Model.Configuration">
  <class name="WidgetConfiguration" lazy="false" table="PageConfiguration_Widgets" discriminator-value="Default">
    <id name="Id"  unsaved-value="0" type="int" >
      <generator class="identity" />
    </id>
    <discriminator column="ConfigurationType" />

    <property name="Slot" type="System.String" length="100" />
    <property name="WidgetTypeName" type="System.String" length="100"/>
    <property name="ViewName" type="System.String" length="50" />
    <property name="SlotOrder" type="System.Int32" />
  </class>
</hibernate-mapping>

对于子表

在将WidgetConfiguration提取到SortedList中时,我需要向父映射或子映射添加什么,以便让它们知道新的SlotOrder列应该用作键字段

编辑:正在读取数据的类是:

public class PageConfiguration : TargetedConfiguration 
{

    public PageConfiguration()
    {
        // replaced by SortedList
        //Controls = new List<WidgetConfiguration>();
        Controls = new SortedList<int, WidgetConfiguration>();
    }

    public string PageKey { get; set; }
    public string Template { get; set; }
    public int? Percentage { get; set; }
    // replaced by SortedList
    //public IList<WidgetConfiguration> Controls { get; set; }
    public IDictionary<int, WidgetConfiguration> Controls { get; set; }
    public int SchemaVersion { get; set; }
}
公共类页面配置:TargetedConfiguration
{
公共页面配置()
{
//替换为分类列表
//控件=新列表();
控件=新的分类列表();
}
公共字符串PageKey{get;set;}
公共字符串模板{get;set;}
公共整数?百分比{get;set;}
//替换为分类列表
//公共IList控件{get;set;}
公共IDictionary控件{get;set;}
public int SchemaVersion{get;set;}
}

请注意,
列表
已更改为
SortedList
。我如何告诉NHibernate,当一个新项目添加到SortedList时,使用的键值应该是WidgetConfiguration.SlotOrder?

您希望使用
而不是


我注意到您正在将您的收藏映射为
。NHibernate支持三种顺序收集—
Bag
Set
List

正如我猜您知道的,List具有排序语义,但当不需要排序时,您通常会使用
集合

因为
集合
要求每个项目只在一个集合中出现一次,所以在该项目的Id上使用一个delete语句就可以很容易地删除该项目。
袋子
不要求集合的唯一性,所以NHibernate删除项目的唯一方法是删除所有内容,然后重新添加不是已删除项目的所有项目。(相反,将项目添加到
行李
可能比使用
集合
更快,因为不必强制执行唯一性)

Ayende(NHibernate的主要贡献者之一)不久前发布了以下内容:


NHiberante为您想要得到的东西提供了很好的支持。事实上,不止一种方法,还有两种:

1) 使用

使用支持
列的列表映射。这与
列表
对象中使用的C#中的内部索引相同

一个小缺点是,必须将该列保持在0。。。包括所有数字。与底层C#对象相同。但它是有效的

请在此处查看更多信息: 这里是索引集合:

2) 使用orderby=“column\u name asc | desc”

这允许使用一些更为用户友好的列(具有一些可编辑的值),以便在加载期间对列表进行排序

Plase,请参见此处的更多内容:

编辑:按照问题编辑

NHibernate再次支持C#
SortedList
映射。请在这一区转转

映射应该是这样的

<map name="Controls" order-by="SlotOrder" lazy="true" cascade="all-delete-orphan">
    <key column="PageConfigurationId" />
    <index column="SlotOrder" type="System.Int32"/>
    <one-to-many class="WidgetConfiguration"/>
</map>
有了此映射,我们可以将新项添加到
控件中
集合:

WidgetConfiguration config = ...;
PageConfiguration pageConfig = ...;

pageConfig.Controls[config.SlotOrder] = config;
session.Update(pageConfig);
所以

  • 我们已经映射了SortedList(实际上是接口
    IDictionary
  • SlotOrder
    用作键(插入,由NHibernate更新)和
  • 在WidgetConfiguration上可用(只读)
  • 这应该可以回答有关词典排序和键的问题。。。如果我错过了什么,请告诉我

    <class name="WidgetConfiguration" ...>
      ...
      <property name="SlotOrder" type="System.Int32" insert="false" update="false" />
    
    WidgetConfiguration config = ...;
    PageConfiguration pageConfig = ...;
    
    pageConfig.Controls[config.SlotOrder] = config;
    session.Update(pageConfig);