使用 Fluent nhibernate 映射实体 oneToMany

2024-02-13

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

我有课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根据数据库。 所以我做了:

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

我得到的列表总是空的。即使在这些表上有数据......我将不胜感激任何类型的帮助或建议。

Regards

EDIT

我的数据库是这样的:




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)
)

  

给定sqlselect * from cliente where core_numero_medidor = '3569371':

CORE_ID CORE_NUMERO_MEDIDOR
123     3569371

和 SQLselect * from MEDIDOR where numero_medidor = '3569371':

NUMERO_MEDIDOR MARCA_MEDIDOR
3569371        general_motors
3569371        kia
3569371        FIAT

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

EDIT

我改成这样:

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 to:

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

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

Expected

NUMERO_MEDIDOR MARCA_MEDIDOR
3569371        general_motors
3569371        kia
3569371        FIAT

我的结果

NUMERO_MEDIDOR MARCA_MEDIDOR
3569371        general_motors
3569371        general_motors
3569371        general_motors

有什么建议么?我要感谢@Radim Köhler 迄今为止提供的帮助。

另一个编辑

我找到了解决方案!

我试图将非唯一列映射为主键...我刚刚将该列更改为真正的主键并且成功了!

所以现在这是解决方案

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)

我真的要感谢 Radim Köhler 的帮助。他的耐心、关注和帮助解决问题的意愿让我无以言表的感谢……我只能祝他生活一切顺利。

我真的希望这个帖子可以帮助有同样问题的人。

Regards.


The one-to-many and many-to-one总是通过一列相关。就是这样的列,其中包含其他表/实体的引用 ID(外键)。

在我们的例子中,它必须是表中的列Medidor,它的名字是"CORE_NUMERO_MEDIDOR"。映射应该是这样的

public ClienteMap()
{
    ...
    HasMany(x => x.ListaMedidores)
       //.KeyColumn("NUMERO_MEDIDOR")
       .KeyColumn("CORE_NUMERO_MEDIDOR") // column in other table
       .Inverse().Cascade.All();
}


public MedidorMap()
{
    ...
    References(x => x.Cliente)
        .Column("CORE_NUMERO_MEDIDOR");  // column in this table
}

EXTEND

基于扩展问题,当我们可以看到这种表结构时

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)
)

DB 引用与 C# 中的不同。看起来,好像如果

表 CLIENTE 仅引用oneMEDIDOR,而MEDIDOR 有很多客户。

看起来这些对象应该是这样的:

public class Cliente
{    
    ...
    //public IList<Medidor> ListaMedidores { get; set; }    
    //public Medidor Medidor { get; set; }    
}

public class Medidor
{
    ...
    //public virtual Cliente Cliente { get; set; }
    public virtual IList<Cliente> Clientes { get; set; }
}

并且映射应该是

public ClienteMap()
{
    ...
    References(x => x.Medidor, "CORE_NUMERO_MEDIDOR");
}


public MedidorMap()
{
    ...
    Id(x => x.NumeroMedidor).Column("NUMERO_MEDIDOR")
                               // column in this table to be compared
    HasMany(x => x.Clientes)
       .KeyColumn("CORE_NUMERO_MEDIDOR") // with column in other table
       .Inverse().Cascade.All();
}

另一个延伸

因为第二个表 MEDIDOR 没有自己的主键(NUMERO_MEDIDOR 列),但它可能包含许多相同的值...来自 CLIENT TABLE...我们应该使用组件映射

public ClienteMap()
{
    ...
    Map(x => x.NumeroMedidor).Column("CORE_NUMERO_MEDIDOR");
    HasMany(x => x.ListaMedidores)
        .Component(com =>
        {
            com.Parent(y => y.Cliente, "NUMERO_MEDIDOR")
               .PropertyRef("NumeroMedidor")
               ;
            com.Map(y => y.MarcaMedidor, "MARCA_MEDIDOR");
        })
        .PropertyRef("NumeroMedidor")
        .Table("MEDIDOR")
       // .Inverse() // NO INVERSE, won't work
       .Cascade.All();

}
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

使用 Fluent nhibernate 映射实体 oneToMany 的相关文章

随机推荐