2009-10-13 10 views
2

J'ai 2 vues dans SQL mis en place:LINQ to sql Beaucoup-un

  • purchaseOrder
  • PurchaseOrderLineItems

Ceux-ci ont de nombreuses colonnes aliasées (les tables, ils voient/join ne sont pas nommé judicieusement ... c'est un produit de tierce partie)

J'ai 2 classes (simplifiées ci-dessous)

class PurchaseOrder 
    { 
     public string PoNumber { get; set; } 
     public string Vendor { get; set; } 
     public DateTime DateCreated { get; set; } 

     public IEnumerable<PurchaseOrderLineItems> LineItems { get; set; } 
    } 

et

class PurchaseOrderLineItems 
    { 
     public string PoNumber { get; set; } 
     public string Name { get; set; } 
     public double Price { get; set; } 
    } 

J'utilise LINQ to SQL - avec le fichier de mappage XML (créé avec l'aide de SqlMetal.exe)

Ce que je veux faire est effectivly IEnumerable peupler en PurchaseOrder avec Je voulais faire cela en utilisant POCO - sans avoir à ajouter EntitySet <> à ma classe, comme finalement, je vais changer mon ORM à quelque chose comme nHibernate (qui a sac attribut je crois ...?)

Actuellement, j'ai une procédure stockée - sp_getPurchaseOrderLineItems qui prend le PONumber, puis retourne une liste d'objets PurchaseOrderLineItem, que j'ajoute ensuite à mon jeu de résultats (c'est loin, loin de l'idéal)

est-il possible de faire ce dont j'ai besoin? Donc, fondamentalement, une requête sur PurchaseOrder renvoie un IEnumerable de LineItems déjà rempli dans l'instance? Il est à noter que cela ne sera jamais en lecture seule, nous n'insérerons/ne mettrons jamais à jour les données en utilisant ceci.

+0

Cool question, je vais vous trouver une réponse :) – leppie

Répondre

0

C'est le problème n + 1. nHibernate a une solution pour cela, appelée interrogation join-fetch. Ce qu'il fait essentiellement est une requête de jointure externe entre order et order-line, ce qui se traduira par le produit du nombre de lignes des deux tables. Je ne pense pas que Linq2SQL ait une solution pour cela. Mais vous pouvez toujours utiliser votre procédure stockée pour générer la sortie join-fetch, et avoir du code Linq2Objects pour séparer les commandes uniques et les lignes de commande du résultat.

+0

Merci. Est-ce que la solution nHibernates est l'élément que j'ai vu dans les fichiers de mapping avant ...? – Alex

+0

C'est la moitié de la solution.L'autre moitié est de spécifier que nHibernate devrait utiliser la stratégie join-fetch pour obtenir les données (une autre façon qu'un sac prend en charge est la stratégie de chargement paresseux). Vous pouvez spécifier cela dans le xml ou dans le hql (la requête). Voir https://www.hibernate.org/315.html et http://docs.jboss.org/hibernate/core/3.3/reference/en/html/queryhql.html#queryhql-joins – tofi9

2

Vous pouvez étendre votre classe PurchaseOrder pour mettre en œuvre la OnLoadedMethod:

public partial class PurchaseOrder 
{ 
    partial void OnLoaded() 
    { 
     LineItems = FunctionToCall_sp_getPurchaseOrderLineItems_AndBuildSet(); 
    } 
} 

Cela permettra au moins obtenir les éléments de ligne automatiquement lorsque vous recevez votre bon de commande.

+0

Mes entités ne sont pas au courant de la couche de données ... Ils sont dans un projet/assembly "Company.Entities" séparé. – Alex

+1

Si c'est le cas, gardez simplement le code de population de la collection tel quel si cela fonctionne. Lorsque vous passez à NHibernate, des choses comme celles-ci disparaissent avec vos mappages. –