【问题标题】:nhibernate mapping by code, mapping entity with list of value objects通过代码进行休眠映射,用值对象列表映射实体
【发布时间】:2015-01-17 13:29:45
【问题描述】:

我的实体有很多数据源。

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>();
   }
}

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

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

我正在使用 nhibernate orm 及其通过代码映射的方法。 所以我使用这个链接作为参考映射了值对象。 //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

{"关联引用未映射的类:My.Model.DataSource"}

【问题讨论】:

  • 但是这个异常不是很清楚吗?您也只需映射DataSource。就是这样
  • 我在上面映射了DataSource,public static Action> Mapping()
  • 能否请您作为答案发布您将如何映射实体以及值对象列表
  • 我通过代码提供了一些映射草稿和亚当柱映射的一些基本链接。这应该有点启发这个问题......
  • 感谢您的努力,但我做出了设计选择,将 DataSource 作为值对象(而不是实体)。你对这种方式有什么建议吗?

标签: c# .net nhibernate


【解决方案1】:

复合元素

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

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

对于值的集合,我们使用标签。

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

...

组件列表(在下一章讨论):

<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; }
}

那么该类的映射可能是:

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();}
    );
}

【讨论】:

  • 是的,但我不希望 DataSource 成为一个实体。它应该代表这个上下文中的值对象。
  • 好的,那么你应该使用OneToMany - 6.3. Collections of Values and Many-To-Many Associations对于值的集合,我们使用''标签。 或 组件列表(在下一章讨论):&lt;composite-element&gt;
  • 我用所有细节扩展了答案。 NHibernate 可以将IList&lt;string&gt;&lt;element&gt; 映射,也可以将虚拟实体与&lt;composite-element&gt; 映射...希望这会有所帮助
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2019-12-03
  • 2020-12-18
  • 2014-04-27
  • 1970-01-01
  • 2023-03-14
  • 2021-11-11
相关资源
最近更新 更多