2013-05-23 8 views
0

J'essaie de trouver une manière plus élégante d'extraire des informations de ma base de données vers mon application Web. Actuellement, je tire toutes les données de ma table et n'utilise que les données de deux colonnes. Il a été suggéré que je cherche à utiliser SelectMany() pour accomplir cela en étant capable de sélectionner uniquement les colonnes dont j'ai besoin.linq-to-sql Problèmes SelectMany()

Je ne suis pas entièrement sûr de savoir comment traduire l'exemple msdn en une instruction linq en utilisant une base de données linq-to-sql.

Ma déclaration actuelle est la suivante:

return db.document_library_sitefiles 
     .Where(item => item.SiteID == siteId) 
     .Select(item => item.document_library) 
     .GroupBy(item => item.Filename) 
     .Select(group => group.OrderByDescending(p=>p.Version).First()) 
     .Where(item => !item.Filename.Contains("*")).ToList(); 

Ma tentative actuelle, que je sais est faux, ressemble à ceci:

return db.document_library_sitefiles 
     .Where(item => item.SiteID == siteId) 
     .SelectMany(item => item.document_library, (filename, filesize) 
      => new { filename, filesize }) 
     .Select(item => new { filename = item.document_library.filename, 
           filesize = item.document_library.filesize }) 
     .ToList(); 

Suis-je à distance près d'obtenir mes résultats escomptés?

Fondamentalement, je veux obtenir les données dans mes filename et filesize colonnes sans tirer le reste des données qui comprend file content (pas ma conception ou une idée), donc je ne suis pas inonder mon serveur avec des informations inutiles juste pour montrer simple tableau de données des fichiers actuellement dans ce DB.

Répondre

1

Je pense que vous allez dans la bonne direction. Il semble que vous modifiez simplement la deuxième requête de manière indésirable. Essayez ceci.

return db.document_library_sitefiles 
     .Where(item => item.SiteID == siteId) 
     .Select(item => item.document_library) 
     .GroupBy(item => item.Filename) 
     .Select(group => group.OrderByDescending(p=>p.Version).First()) 
     .Where(item => !item.Filename.Contains("*")) 
     .Select(item => new { filename = item.document_library.filename, 
           filesize = item.document_library.filesize }).ToList(); 

Fondamentalement, vous voulez garder toute la logique exactement le même que dans la première requête puis juste virer de bord sur un plus où vous sélectionnez l'objet anonyme initialisez pour revenir.

Lors de votre tentative d'interrogation, vous avez modifié une partie de la logique sous-jacente. Vous voulez que toutes les opérations précoces restent exactement les mêmes (sinon les résultats que vous retournez proviendront d'un ensemble différent), vous voulez seulement transformer les objets dans l'ensemble résultant, c'est pourquoi vous ajoutez un select après la finale où.

+0

Cela a beaucoup de sens. Mes compétences SQL sont novices, au mieux. Je rencontre quand même le problème de mon type de retour. Ceci est stocké dans une fonction qui a le type de retour de liste statique publique et quand j'utilise le .ToList() dans l'instruction select finale, je me retrouve avec une erreur. J'essaye de convertir implicitement le type ''System.Collections.Generic.List '' '' System.Collections.Generic.List <~. ~ .document_library> ''. J'essayais de comprendre le type de liste pour mon type de retour, mais j'ai été incorrect en utilisant la chaîne – MacSalty

+0

@Anonymity si le rendre 'var docs = LINQ result' cela fonctionnera. Ou, une autre option consiste à définir un type et à changer le nouveau dans select pour être 'new ObjectType {\\ assignment here}' ou vous pouvez aussi faire un constructeur pour prendre ces deux champs afin qu'il soit juste new ObjectType (nom, taille) Comme vous pouvez le voir, le compilateur C# génère une définition pour votre type anonyme, donc vous ne pouvez pas essayer de l'assigner à un autre type que vous avez défini ou cela provoquera l'erreur ci-dessus. – evanmcdonnal

+0

Génial, merci @evanmcdonnal. Maintenant, je dois juste comprendre l'erreur qu'il génère et je devrais être tout ensemble. 'System.Data.SqlClient.SqlException: nom de colonne non valide 'Filename'. Nom de colonne invalide 'Nom de fichier' .' est l'erreur de l'enregistrement. J'ai stocké l'information dans un constructeur dans mon ViewModel. – MacSalty

1

Vous pouvez simplement ajouter une première déclaration à votre première déclaration?

....Where(item => !item.Filename.Contains("*")) 
    .Select(item => new { 
          item.Filename, 
          item.Filesize 
         }).ToList();