Entité de cartographie oneToMany avec nhibernate fluide

Le problème semble être simple, mais j’ai beaucoup de difficulté à mapper ces entités. Je ne vois tout simplement pas ce que je fais mal. Pouvez-vous m’aider?

J’ai la classe Cliente :

 public class Cliente { public Cliente () { } public virtual int ClienteId { get; set; } public IList ListaMedidores { get; set; } public virtual ssortingng NumeroMedidor { get; set; } } 

Et la classe Medidor

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

J’ai essayé de cartographier comme ça

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

L’objective est d’apporter ma liste de Medidor selon la firebase database. Alors j’ai fait:

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

Et la liste est toujours vide. Même en disposant de données sur ces tables … j’apprécierais toute aide ou suggestion.

Cordialement

MODIFIER

Ma firebase database est comme ceci:


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

 CREER TABLE MEDIDOR
 (
   NUMERO_MEDIDOR VARCHAR2 (50 octets),
   MARCA_MEDIDOR VARCHAR2 (50 BYTE)
 )

Étant donné le sql select * from cliente where core_numero_medidor = '3569371' :

 CORE_ID CORE_NUMERO_MEDIDOR 123 3569371 

et le sql select * from MEDIDOR where numero_medidor = '3569371' :

 NUMERO_MEDIDOR MARCA_MEDIDOR 3569371 general_motors 3569371 kia 3569371 FIAT 

Donc je suis IList Lista Medidores avoir 3 éléments sur mon IList Lista Medidores sur la classe Cliente ..

MODIFIER

J’ai changé pour ceci:

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

Et changé la carte de ClienteMap à:

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

et maintenant la liste obtient le nombre attendu d’enregistrements mais tous sont identiques au premier. c’est à dire:

Attendu

 NUMERO_MEDIDOR MARCA_MEDIDOR 3569371 general_motors 3569371 kia 3569371 FIAT 

Mon résultat

 NUMERO_MEDIDOR MARCA_MEDIDOR 3569371 general_motors 3569371 general_motors 3569371 general_motors 

Aucune suggestion? Je tiens à remercier @Radim Köhler jusqu’à présent pour l’aide.

UN AUTRE ÉDIT

J’ai trouvé la solution!

J’essayais de mapper une colonne non unique en tant que clé primaire … Je viens de changer la colonne en une vraie clé primaire et j’ai travaillé!

Alors maintenant, voici la solution

 public class Cliente { public Cliente () { } public virtual int ClienteId { get; set; } public IList ListaMedidores { get; set; } public virtual ssortingng NumeroMedidor { get; set; } } public class Medidor { public Medidor() { } public virtual ssortingng NumeroMedidor { get; set; } public virtual ssortingng MarcaMedidor { get; set; } } public class ClienteMap : ClassMap { 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 { public MedidorMap() { LazyLoad(); Id(x => x.NumeroMedidor).Column("NUMERO_MEDIDOR"); Map(x => x.MarcaMedidor).Column("MARCA_MEDIDOR"); [...] //Other properties } } 

Et voici ma requête:

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

Je voudrais vraiment remercier Radim Köhler pour son aide. Sa patience, son attention et sa volonté d’aider à résoudre le problème me laissent un manque de gratitude. Je ne peux que lui souhaiter le meilleur dans la vie.

Et j’espère vraiment que ce fil pourra aider les gens avec le même problème.

Cordialement.

Après tout, avec ces scripts SQL (ajuster pour SQL Server dans mon cas)

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

Avec ces entités (toutes les propriétés sont virtuelles)

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

et avec seulement cette cartographie en place:

 public class ClienteMap: ClassMap { 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(); } } 

Je peux confirmer que cette requête fonctionnera:

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

BTW, ce sera (mon préféré) mappage xml généré:

                     

Pour la documentation voir:

7.2. Collections d’objects dépendants

Le one-to-many et le many-to-one sont toujours liés par une colonne. C’est cette colonne qui contient l’ID de référence (clé étrangère) de l’autre table / entité.

Dans notre cas, il doit s’agir d’une colonne dans la table de Medidor et son nom serait "CORE_NUMERO_MEDIDOR" . La cartographie devrait ressembler à ceci

 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 } 

ÉTENDRE

Basé sur une question étendue, quand on peut voir cette structure de tables

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

Que la référence à la firebase database est différente de celle en C # Il semble que si

La table CLIENTE fait référence à un seul MEDIDOR, alors que MEDIDOR compte de nombreux CLIENTE.

Il semble que les objects devraient ressembler à ceci:

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

et la cartographie devrait être

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

Un autre prolonger

Parce que la deuxième table MEDIDOR ne possède pas sa propre clé primaire (colonne NUMERO_MEDIDOR) mais qu’elle pourrait contenir beaucoup de valeurs identiques … provenant de CLIENT TABLE … nous devrions utiliser le mappage de composant

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