2010-02-22 7 views
2

Ok, j'ai une classe générée lorsque j'ai créé la connexion Linq to SQL.Linq to SQL: Remplissage d'une classe générée étendue dans une requête Linq

Il ressemble fondamentalement ceci:

 

    public partial class Product 
    { 
     public string Name { get; set; } 
     public string Description { get; set; } 
    } 
 

Je tendis en ajoutant une autre propriété, comme celui-ci:


    public partial class Product 
    { 
     public string Category { get; set; }  
    } 

Maintenant, j'ai une requête Linq pour obtenir les détails du produit, comme celui-ci:


    public List GetProducts() 
    { 
     using(MyDataContext dc = new MyDataContext()) 
     { 
      var products = from p in dc.Products 
          select p; 
     } 
    } 

Le nouveau champ que j'ai ajouté (Catégorie) peut être récupéré dans la requête Linq en utilisant "p.Categor y.Description ". Donc, ma question est, qui est la meilleure façon de peupler la classe de produit, y compris la nouvelle propriété de catégorie.

Je préférerais s'il y avait un moyen de remplir automatiquement la partie générée de la classe Product en utilisant les données de la requête Linq "select p".

J'ai aussi pensé à la création d'un constructeur sur ma classe partielle qui accepte le produit (sélectionnez P) et la catégorie (sélectionnez p.Category.Description)

Faire quelque chose comme ceci:


    // Linq query calling the constructor 
    var products = from p in dc.Products 
        select new Product(p, p.Category.Description) 

    // Product Constructor in my extended partial class 
    public Product(Product p, string CategoryDescription) 
    { 
     this = p; // there must be a way to do something like this 
     Category = CategoryDescription; 
    } 

Mais existe-t-il un moyen de le faire sans avoir à lister toutes les propriétés de la classe Product et à les définir individuellement?

+1

Im confused .... pensé Catégorie était une chaîne? Les propriétés d'extension ne sont pas possibles dans C# ... – James

+0

La catégorie est une chaîne dans ma classe étendue. Mais c'est un tableau sur la base de données. Je vais utiliser le champ Description sur la table Category pour remplir ma propriété Category sur ma classe étendue :) – Eoinii

Répondre

2

Si vous voulez réutiliser votre code existant que vous devez créer au lieu de Poco:

var products = from p in dc.Products 
       select new Product 
       { 
        Name = p.Name, 
        Description = p.Description, 
        Category = p.Category.Description 
       } 

Ou pour le rendre encore plus facile, il suffit de faire:

public partial class Product 
{ 
    public string Category 
    { 
     get { return this.Category.Description; } 
     set { this.Category.Description = value; } 
    } 
} 
+0

Le deuxième exemple risque de provoquer un comportement inattendu de chargement paresseux .... –

+0

@marc, ouais bon point, bien que ma première option mentionne déjà Poco (pour éviter cela). Tant que la classe est utilisée dans le bon contexte, ça devrait aller. Juste donner l'OP une autre option. – James

+0

@Marc - Oui j'espérais ne pas avoir à faire votre première réponse - c'est la même chose que d'utiliser un constructeur et de définir toutes les propriétés qu'il contient. Hmmmmm peut-être que ce que j'essaie de faire n'est pas possible :(Je pourrais avoir juste à remplir les objets en réglant chaque propriété individuellement .. – Eoinii

1

LINQ-to SQL joue bien tant que vous le laissez faire son truc par lui-même. IMO, le meilleur meilleur pour gérer ce scénario est de laisser le type généré par DBML à la DAL - seulement retourner ceux-ci si c'est exactement un 100% adapté pour ce que vous voulez retourner. Au lieu de cela, je créerais un nouveau type qui est pas géré par LINQ-to-SQL, et le retourner à la place (vous pouvez faire des projections basées sur l'initialiseur pour les types non-DBML); par exemple:

var products = from p in dc.Products // p is implicitly a Product 
       select new ExtendedProduct // our completely unrelated type 
       { 
        Id = p.Id, 
        Name = p.Name, 
        //... 
        Category = p.Category.Description 
       }; 

Cela devrait vous permettre d'obtenir vos données sur, sans n silencieux + 1 questions, et sans le contexte de données se plaignant. Cela signifie également que vous avez un contrôle complet sur les colonnes qui sont interrogées et comment elles sont mappées. Essentiellement, cela utilise alors LINQ-to-SQL juste pour faire l'intégration de la base de données, en utilisant notre propre type pour l'application principale.

+0

@Marc - En fait, cela fonctionnerait bien avec les procédures stockées, que je suis dans deux esprits à propos de l'utilisation, acclamations :) – Eoinii

0

Il ressemble à ce que vous essayez de faire quelque chose comme ceci:

using(MyDataContext dc = new MyDataContext()) 
{ 
    var products = from p in dc.Products 
        select p; 
    foreach(Product p in products) 
     p.Category = p.Category.Description; 
} 

... qui ne fait pas de sens pour moi. Pour commencer, l'une des «catégories» devra être appelée autre chose.