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?
I have the class Cliente
:
public class Cliente
{
public Cliente () { }
public virtual int ClienteId { get; set; }
public IList<Medidor> ListaMedidores { get; set; }
public virtual string NumeroMedidor { get; set; }
}
And class Medidor
public class Medidor
{
public Medidor() { }
public virtual string NumeroMedidor { get; set; }
public virtual string MarcaMedidor { get; set; }
public virtual Cliente Cliente { get; set; }
}
I tried to map like this
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");
}
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.
Regards
EDITMy database is like this:
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) )
Given the sql select * from cliente where core_numero_medidor = '3569371'
:
CORE_ID CORE_NUMERO_MEDIDOR
123 3569371
and the sql select * from MEDIDOR where numero_medidor = '3569371'
:
NUMERO_MEDIDOR MARCA_MEDIDOR
3569371 general_motors
3569371 kia
3569371 FIAT
So I'm suppose to get 3 elements on my IList<Medidor> Lista Medidores
on Cliente
class..
EDIT
I changed to this:
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; }
}
And changed the map of ClienteMap
to:
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:
Expected
NUMERO_MEDIDOR MARCA_MEDIDOR
3569371 general_motors
3569371 kia
3569371 FIAT
My result
NUMERO_MEDIDOR MARCA_MEDIDOR
3569371 general_motors
3569371 general_motors
3569371 general_motors
Any suggestions? I would like to thank @Radim Köhler so far for the help.
ANOTHER EDIT
I found the solution!
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!
So now here's the solution
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
}
}
And here is my query:
Session.Query<CorteReligacao>()
.Fetch(x => x.ListaMedid)
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.
Regards.
After all, with these SQL scripts (adjust for SQL Server in my case)
With these entities (all properties are virtual)
and with only this one mapping in place:
I can confirm, that this query will work:
BTW, this will be (my preferred) generated
xml
mapping:For documentation see:
7.2. Collections of dependent objects
The
one-to-many
andmany-to-one
are always related by one column. This is such column, which contains reference ID (foreign key) to the other table / entity.In our case, it must be column in table of
Medidor
, and its name would be"CORE_NUMERO_MEDIDOR"
. The mapping should look like thisEXTEND
Based on extended question, when we can see this structure of tables
That the DB reference is different then in C#. It seems, like if
It seems that the objects should look like this:
and the mapping should be
ANOTHER EXTEND
Because the second table MEDIDOR is not having its own primary key (column NUMERO_MEDIDOR) but it could contain many same values... coming from CLIENT TABLE... we should use component mapping