2009-02-05 21 views
3

Est-il possible de joindre deux classes sans mappage spécifié entre elles (à l'aide de l'API Criteria)?NHibernate - joindre sans mappage

Je dois joindre deux classes et récupérer des données des deux mais je ne peux pas les mapper. Je connais seulement la clé étrangère SomeID dans la première classe et la clé primaire ID dans la seconde.

Comment créer des critères pour les joindre? Est-ce possible sans cartographie?

S'il vous plaît, aidez, j'en ai vraiment besoin mais je suis coincé. :/

PS

Je sais que 'toute' la cartographie, mais je 10 domaines comme SomeID. La création de mappages pour 10 champs uniquement pour la création de jointures est excessive. S'il n'y a pas d'autre résolution, je le ferai mais je ne veux pas.

Répondre

6

Je ne sais pas la version des critères, mais HQL vous pouvez le faire comme ceci:

select customer, order from Customer customer, Order order 
    where order.CustomerID = customer.Id 
    and customer.Id = 42 

Le jeu de résultats sera alors une liste d'objets [] où le client sera fois répété le nombre de commandes qu'il a passées (en supposant bien sûr qu'il y a un client pour plusieurs commandes).

Veuillez noter que le résultat sera vide s'il n'y a pas d'ordes.

+0

Yeap. Je l'utilise par critères. Je suis à la recherche de la possibilité de créer quelque chose comme ceci: clientèle sélecte, commande du client à la clientèle, premiere commande, l'utilisateur, l'utilisateur où order.SomeID_1 = customer.Id order.SomeID_2 = user.Id I Je ne sais pas au moment du design quel champ contient SomeID_xxx. :/ – dariol

+0

OK, je l'ai. HQL est seulement une option. – dariol

+0

avez-vous pu créer la requête de critères pour cela? si oui pls post..sadly im dans la même situation :( – Illuminati

1

Si vous ne voulez pas ou ne pouvez pas définir les propriétés d'association dans vos entités (comme dans les applications modulaires qui prennent en charge le chargement dynamique des plugins), vous pouvez créer des associations "fausses" avec l'API Fluent.

Voir le code source Orchard, classe "ContentItemAlteration". Dans Orchard, l'entité ContentItem doit être jointe aux enregistrements ContentPart stockés dans des tables différentes. Chaque type ContentPart est fourni par des modules, ce qui signifie qu'il est difficile (et probablement pas préférable) de changer la source de ContentItem et d'ajouter une association pour chaque nouvel enregistrement de pièce.

Voici le code exact que je suis arrivé à partir de sources Orchard:

/// <summary> 
    /// Add a "fake" column to the automapping record so that the column can be 
    /// referenced when building joins accross content item record tables. 
    /// <typeparam name="TItemRecord">Either ContentItemRecord or ContentItemVersionRecord</typeparam> 
    /// <typeparam name="TPartRecord">A part record (deriving from TItemRecord)</typeparam> 
    /// </summary> 
    class Alteration<TItemRecord, TPartRecord> : IAlteration<TItemRecord> { 
     public void Override(AutoMapping<TItemRecord> mapping) { 

      // public TPartRecord TPartRecord {get;set;} 
      var name = typeof(TPartRecord).Name; 
      var dynamicMethod = new DynamicMethod(name, typeof(TPartRecord), null, typeof(TItemRecord)); 
      var syntheticMethod = new SyntheticMethodInfo(dynamicMethod, typeof(TItemRecord)); 
      var syntheticProperty = new SyntheticPropertyInfo(syntheticMethod); 

      // record => record.TPartRecord 
      var parameter = Expression.Parameter(typeof(TItemRecord), "record"); 
      var syntheticExpression = (Expression<Func<TItemRecord, TPartRecord>>)Expression.Lambda(
       typeof(Func<TItemRecord, TPartRecord>), 
       Expression.Property(parameter, syntheticProperty), 
       parameter); 

      mapping.References(syntheticExpression) 
       .Access.NoOp() 
       .Column("Id") 
       .ForeignKey("none") // prevent foreign key constraint from ContentItem(Version)Record to TPartRecord 
       .Unique() 
       .Not.Insert() 
       .Not.Update() 
       .Cascade.All(); 
     } 
    } 

Ce code ajoute simplement une association « partie » à ContentItem qui vous permet d'utiliser vos critères dans les jointures. Si, par exemple, vous avez une partie nommée "ProductPart" qui est stockée dans une table nommée "ProductPartRecord", vous pouvez rejoindre votre ContentItem sur la fausse propriété "ProductPartRecord". Par ailleurs, il semble que cette tactique peut également être appliquée au côté HasMany de la fausse relation, mais vous devez personnaliser les sources Fluent, je suppose.