将实体oneToMany与流利的NHibernate映射 [英] Mapping entity oneToMany with fluent nhibernate

查看:93
本文介绍了将实体oneToMany与流利的NHibernate映射的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

问题似乎很简单,但是尝试映射此实体时遇到了很多麻烦.我只是看不到我在做什么错.你们可以帮我吗?

The problem appears to be simple however I'm having so much trouble trying to map this entities. I just can't see what am I doing wrong. Can you guys help me?

我有课程Cliente:

public class Cliente
{    
    public Cliente () { }
    public virtual int ClienteId { get; set; }  
    public IList<Medidor> ListaMedidores { get; set; }   
    public virtual string NumeroMedidor { get; set; }       
}

和类Medidor

public class Medidor
{
    public Medidor() { }
    public virtual string NumeroMedidor { get; set; }
    public virtual string MarcaMedidor { get; set; }
    public virtual Cliente Cliente { get; set; }
}

我试图这样映射

public ClienteMap()
{
    Map(x => x.NumeroMedidor).Column("CORE_NUMERO_MEDIDOR");
    HasMany(x => x.ListaMedidores)
        .KeyColumn("NUMERO_MEDIDOR").Inverse().Cascade.All();
}


public MedidorMap()
{
    Table("medidor");
    LazyLoad();

    Id(x => x.NumeroMedidor).Column("NUMERO_MEDIDOR");
    Map(x => x.TipoMedidor).Column("TIPO_MEDIDOR");
    References(x => x.Cliente).Column("CORE_NUMERO_MEDIDOR");
}

目标是根据数据库携带我的Medidor列表. 所以我做到了:

The goal is bring my List of Medidor according to database. So I did:

Session.Query<Cliente>().Fetch(x => x.ListaMedidores).ToList();

我得到的清单总是空的.即使在这些表上有数据,我也将不胜感激.

And i'm getting the list always empty. Even having data on those tables... I would appreciate any kind of help or suggestion.

致谢

我的数据库是这样的:



CREATE TABLE CLIENTE
(
  CORE_ID                      NUMBER           NOT NULL,
  CORE_NUMERO_MEDIDOR          VARCHAR2(50 BYTE)
)

CREATE TABLE MEDIDOR
(
  NUMERO_MEDIDOR  VARCHAR2(50 BYTE),
  MARCA_MEDIDOR   VARCHAR2(50 BYTE)
)

给出sql select * from cliente where core_numero_medidor = '3569371':

CORE_ID CORE_NUMERO_MEDIDOR
123     3569371

和sql select * from MEDIDOR where numero_medidor = '3569371':

NUMERO_MEDIDOR MARCA_MEDIDOR
3569371        general_motors
3569371        kia
3569371        FIAT

所以我想在Cliente类的IList<Medidor> Lista Medidores上获得3个元素.

So I'm suppose to get 3 elements on my IList<Medidor> Lista Medidores on Cliente class..

编辑

我改为:

public class Cliente
{    
    public Cliente () { }
    public virtual int ClienteId { get; set; }  
    public IList<Medidor> ListaMedidores { get; set; }   
    public virtual string NumeroMedidor { get; set; }       
}
public class Medidor
{
    public Medidor() { }
    public virtual string NumeroMedidor { get; set; }
    public virtual string MarcaMedidor { get; set; }
}

并将ClienteMap的地图更改为:

Map(x => x.NumeroMedidor).Column("NUMERO_MEDIDOR");    
HasMany(x => x.ListaMedid)
            .KeyColumns.Add("NUMERO_MEDIDOR")
            .Table("MEDID")
            .PropertyRef("CoreNumeroCliente")
            .Cascade.All();

,现在列表将获得预期的记录数,但所有记录都与第一个记录相同.即:

and now the list gets the expected number of records but all of them its the same as the first one. ie:

预期

NUMERO_MEDIDOR MARCA_MEDIDOR
3569371        general_motors
3569371        kia
3569371        FIAT

我的结果

NUMERO_MEDIDOR MARCA_MEDIDOR
3569371        general_motors
3569371        general_motors
3569371        general_motors

有什么建议吗?到目前为止,我要感谢@RadimKöhler的帮助.

Any suggestions? I would like to thank @Radim Köhler so far for the help.

其他编辑

我找到了解决方法!

我试图将一个非唯一的列映射为主键...我只是将该列更改为一个真正的主键就可以了!

I was trying to map a non-unique column as a primary key... I just changed the column to a real primary key and worked!

所以现在是解决方法

public class Cliente
{    
    public Cliente () { }
    public virtual int ClienteId { get; set; }  
    public IList<Medidor> ListaMedidores { get; set; }   
    public virtual string NumeroMedidor { get; set; }       
}
public class Medidor
{
    public Medidor() { }
    public virtual string NumeroMedidor { get; set; }
    public virtual string MarcaMedidor { get; set; }
}

public class ClienteMap : ClassMap<Cliente>
{
    public ClienteMap()
    {
        Map(x => x.NumeroMedidor).Column("NUMERO_MEDIDOR");    
        HasMany(x => x.ListaMedid)
            .KeyColumns.Add("NUMERO_MEDIDOR")
            .Table("MEDID")
            .PropertyRef("CoreNumeroCliente")
            .Cascade.All();
    }
}

public class MedidorMap : ClassMap<Medidor>
{
    public MedidorMap()
    {
        LazyLoad();

        Id(x => x.NumeroMedidor).Column("NUMERO_MEDIDOR");
        Map(x => x.MarcaMedidor).Column("MARCA_MEDIDOR");
        [...] //Other properties
    }
}

这是我的查询:

Session.Query<CorteReligacao>()
                .Fetch(x => x.ListaMedid)

我真的要感谢RadimKöhler的帮助.他的耐心,专注和乐于帮助解决问题的能力使我缺乏感恩的方式.我只能祝他一生幸福.

I really would like to thanks Radim Köhler for the help. His patience, attention and willingness to helping solve the problem leaves me with lack of way of thanks..I can only wish him all the best in life.

我真的希望这个线程可以对遇到同样问题的人有所帮助.

And I really hope that this thread may help people with the same problem.

致谢.

推荐答案

毕竟,使用这些SQL脚本(根据我的情况调整为SQL Server)

After all, with these SQL scripts (adjust for SQL Server in my case)

CREATE TABLE CLIENTE
(
  CORE_ID                      int           NOT NULL,
  CORE_NUMERO_MEDIDOR          VARCHAR(50)
)

CREATE TABLE MEDIDOR
(
  NUMERO_MEDIDOR  VARCHAR(50),
  MARCA_MEDIDOR   VARCHAR(50)
)

使用这些实体(所有属性都是虚拟的)

public class Cliente
{    
    public virtual int ClienteId { get; set; }  
    public virtual IList<Medidor> ListaMedidores { get; set; }   
    public virtual string NumeroMedidor { get; set; }       
}
public class Medidor
{
    public virtual string NumeroMedidor { get; set; }
    public virtual string MarcaMedidor { get; set; }
    public virtual Cliente Cliente { get; set; }
}

,并且只有仅此一个映射:

public class ClienteMap: ClassMap<Cliente>
{
    public ClienteMap()
    {
        Table("CLIENTE");
        Id(x => x.ClienteId, "CORE_ID");
        Map(x => x.NumeroMedidor).Column("CORE_NUMERO_MEDIDOR");
        HasMany(x => x.ListaMedidores)
            .KeyColumn("NUMERO_MEDIDOR")
            .Component(com =>
            {
                com.ParentReference(y => y.Cliente);
                com.Map(y => y.MarcaMedidor, "MARCA_MEDIDOR");
            })
            .PropertyRef("NumeroMedidor")
            .Table("MEDIDOR")
            // .Inverse() // NO INVERSE, won't work
            .Cascade.All();
    }
}

我可以确认,该查询将起作用:

I can confirm, that this query will work:

var list = session.Query<Cliente>().Fetch(x => x.ListaMedidores).ToList();
var firt = list.First().ListaMedidores.First();
var last = list.First().ListaMedidores.Last();
Assert.IsTrue(firt.MarcaMedidor != last.MarcaMedidor);

顺便说一句,这将是 (我的首选) 生成的xml映射:

BTW, this will be (my preferred) generated xml mapping:

<class xmlns="urn:nhibernate-mapping-2.2" name="Cliente" table="CLIENTE">
    <id name="ClienteId" type="System.Int32">
      <column name="CORE_ID" />
      <generator class="identity" />
    </id>
    <bag cascade="all" name="ListaMedidores" table="MEDIDOR">
      <key property-ref="NumeroMedidor">
        <column name="NUMERO_MEDIDOR" />
      </key>
      <composite-element class="Medidor">
        <parent name="Cliente" />
        <property name="MarcaMedidor" type="System.String">
          <column name="MARCA_MEDIDOR" />
        </property>
      </composite-element>
    </bag>
    <property name="NumeroMedidor" type="System.String">
      <column name="CORE_NUMERO_MEDIDOR" />
    </property>
</class>

有关文档,请参见:

7.2.依赖对象的集合

这篇关于将实体oneToMany与流利的NHibernate映射的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆