通过代码进行 nhibernate 映射,使用值对象列表映射实体

nhibernate mapping by code, mapping entity with list of value objects

我的实体有很多数据源。

public class MyData
{
   public virtual int Id { get; set; }
   public virtual string Name { get; set; }
   public virtual IList<DataSource> Sources { get; set; }
   public MyData(){
       Sources = new List<DataSource>();
   }
}

我有 DataSource class 代表 MyData 实体的值对象

public class DataSource
{
   public enum SourceEnum { dataOneSrc = 1, dataTwoSrc = 2}
   public virtual SourceEnum Source { get; set; }
   public virtual string InternalRefNr { get; set; }
}

我正在使用 nhibernate orm 及其通过代码映射的方法。 所以我使用这个 link 作为参考映射值对象。 //http://lycog.com/programming/nhibernate-32-mapping-code-component-mapping/

public static Action<IComponentMapper<DataSource>> Mapping()
{
    return c =>{
                c.Property(p => p.Source);
                c.Property(p => p.InternalRefNr, m =>
                {
                    m.Length(255);
                });                    
            };
    }

和使用

的实体映射
public MyData()
{
    ...
    Bag<DataSource>(x => x.Sources,
        c => { },
        r =>{ r.OneToMany();}
    );
}

我得到 Nhibernate.MappingException

{"Association references unmapped class: My.Model.DataSource"}

复合元素

如果我们不想映射分离的实体,我们不能使用one-to-many。我们需要:

6.3. Collections of Values and Many-To-Many Associations(小引用)

For a collection of values, we use the tag.

<element
        column="column_name"                (1)
        type="typename"                     (2)
/>

...

A list of components (discussed in the next chapter):

<list name="CarComponents" table="car_components">
    <key column="car_id"/>
    <index column="posn"/>
    <composite-element class="Eg.Car.CarComponent">
            <property name="Price" type="float"/>
            <property name="Type" type="Eg.Car.ComponentType, Eg"/>
            <property name="SerialNumber" column="serial_no" type="String"/>
    </composite-element>
</list>

所以在我们的例子中,我们不能使用一对多,但是 Component:

// instead of this
r =>{ r.OneToMany();}
// we need this for IList<string>
r.Element(e => { });
// this for DataSource as in the above question
r.Component(c => { });

一对多:

代码映射应该是这样的:Hibernate's Mapping by Code。 任何实体都应该有代理键(Id)。那应该是数据源:

public class DataSource
{
   public virtual int Id { get; set; }
   public virtual string InternalRefNr { get; set; }
   public virtual MyDataMyData{ get; set; }
}

class 的映射可能是:

public class DataSourceMap : DataSourceMapping<DataSource>
{
    public DataSourceMap()
    {
        Id(x => x.Id, m => m.Generator(Generators.Identity));
        Property(x => x.InternalRefNr);
        ManyToOne(x => x.MyData);
    }
}

现在我们可以根据 Mapping-by-Code - Set and Bag

映射 MyData
public MyData()
{
    ...
    Bag<DataSource>(x => x.Sources,
        c => { c.Inverse(true); },
        r =>{ r.OneToMany();}
    );
}