2009-12-07 6 views
0

j'avoir des entrées dans le tableau codelistvalueview de ce type:LINQ GroupBy avec Où

Je veux groupe par espace de nom et peut-être alors par tablename et découvrez toutes les entrées qui ne se produisent que dans les deux espaces de noms (UPD/REFDAT) et ensuite liste ceux qui se produisent dans UDP afin qu'ils puissent être supprimés.

namespace tableid tablename count 
UDP 1C06F2EF-5371-4A3F-A07C-226DB7242053 WeldingProcedureSpecification 34 
REFDAT 42D225CA-A96B-4806-9C5C-86D2B3B3AFEE WeldingProcedureSpecification 2 
REFDAT EA0F846C-59B4-4F6D-91D1-B00698C98349 WeldClass 5 
REFDAT E8516DFC-9980-4CBC-B62C-D2C11618424E WasherType 14 

Dans le cas ci-dessus, j'ai besoin tableid de la 1ère ligne que depuis cela se produit à la fois la ligne 1 & 2. La valeur dont j'ai besoin est, le tableid de la ligne avec UDP comme l'espace de nom (1ère rangée dans ce cas)

Je penserais que ceci (ci-dessous) m'obtiendrait ce que je veux mais j'obtiens quelques rangées nulles entre ??

var grp = CodelistValueView.Where(x=>x.Namespace=="UDP" || x.Namespace=="REFDAT") 
      .GroupBy(x=>new {x.Namespace, x.TableID, x.TableName}, 
     x=>new {x.Namespace, x.TableID, x.TableName, x.ShortStringValue}) 
      .OrderByDescending(g=>g.Key.TableName) 
      .Select(g=>g.Where(x=>x.Namespace=="UDP").First()); 

grp.Dump(); 

Voilà ce que je vois ...

null 
null 
UDP 1c06f2ef-5371-4a3f-a07c-226db7242053 WeldingProcedureSpecification GTAW, SA-789 
null 

Toutes les pensées ??

J'ai finalement trouvé ce qui semble fonctionner ... je ne sais pas si c'est la meilleure façon de le faire.

var grp = CodelistValueView.Where(x=>x.Namespace=="UDP" || x.Namespace=="REFDAT") 
      .Select(x=>new {NS=x.Namespace, Tablename=x.TableName, TableId=x.TableID}) 
     .GroupBy(g=> new {g.NS, g.Tablename, g.TableId}, (g,x)=>g) 
     .GroupBy(x=>x.Tablename, x=>x) 
     .Where(x=>x.Count() > 1) 
     .Select(x=>x.Where(a=>a.NS=="UDP").First())    
     .OrderBy(x=>x.Tablename); 

Et je reçois ceci:

NS Tablename TableId 
UDP ValveFlowPattern 64bd5be2-0ddb-495a-a0db-28476ebe858d 
UDP ValveOperatorPartDataBasis dcdb1f66-83f1-4738-8587-49a72c63801d 
UDP ValvePortOption 99b1797c-4712-410a-8578-d4a6a01e8968 
UDP WeldingProcedurePractice 682bcc0b-db7a-4b10-80ba-1f969b96abfe 
UDP WeldingProcedureSpecification 1c06f2ef-5371-4a3f-a07c-226db7242053  

grâce sUnit

+0

Vous demandez donc deux requêtes ici? – Stu

+0

Je ne suis pas sûr. J'ai besoin d'énumérer ceux qui se produisent dans UPD si et seulement si elles se produisent également dans REFDAT. – Sunit

+0

Pourriez-vous être plus clair sur la question s'il vous plaît? Voulez-vous rechercher les enregistrements qui se trouvent dans les espaces de noms ou dans l'espace de noms UDP uniquement? désolé je n'ai pas bien compris votre question –

Répondre

1

Je pense que cela fonctionnera pour vous si je comprends bien la question. J'utilise "codelistvalueview" comme la collection qui contient les données des tables.

var refdatItems = codelistvalueview.Where(x=>[email protected] == "REFDAT"); 
var udpItems = codelistvalueview.Where(x=>[email protected] == "UDP"); 

var result = 
    from refItem in refdatItems 
    join udpItem in udpItems on refItem.tablename equals udpItem.tablename 
    select udpItem; 

- ou -

var result = 
    from ref in codelistvalueview 
    join udp in codelistvalueview 
     on ref.tablename = udp.tablename 
    where [email protected] == "REFDAT" && 
      [email protected] == "UDP" 
    select udp; 

Le résultat varable a tous les éléments "UDP" qui ont également des éléments "de REFDAT" où sont les mêmes leurs noms de table.

- Edition -

Je devine que de votre dernière mise à jour que vous utilisez LINQPad pour comprendre cette requête. C'est génial, parce que je l'utilise aussi. J'ai mis à jour la requête pour utiliser les noms que vous avez choisis. Essayez d'exécuter ceci comme un "programme C#" dans LinqPad. Il sélectionne le TableID et filtre les doublons.

void Main() 
{ 
    var CodelistValueView = new data[] { 
     new data() {TableName = "1", Namespace="UDP", TableID=1}, 
     new data() {TableName = "1", Namespace="REFDAT", TableID=1}, 
     new data() {TableName = "2", Namespace="UDP", TableID=3}, 
     new data() {TableName = "3", Namespace="REFDAT", TableID=4}, 
     new data() {TableName = "4", Namespace="UDP", TableID=1}, 
     new data() {TableName = "4", Namespace="REFDAT", TableID=1}, 
     new data() {TableName = "5", Namespace="other", TableID=5}, 
     new data() {TableName = "6", Namespace="UDP", TableID=2}, 
     new data() {TableName = "6", Namespace="REFDAT", TableID=2} 
    }; 

    var result = 
     from Ref in CodelistValueView 
     join udp in CodelistValueView 
     on Ref.TableName equals udp.TableName 
     where Ref.Namespace == "REFDAT" && 
       udp.Namespace == "UDP" 
     select udp.TableID; 

    result.Distinct().Dump(); 
} 

// Define other methods and classes here 
class data 
{ 
    public string TableName; 
    public string Namespace; 
    public int TableID; 
} 
+0

Cela me donnera plusieurs entrées pour les lignes qui ont UDP et même nom de table mais diffèrent sur les autres champs. – Sunit

+0

Devrait fonctionner mais j'obtiens 286 entrées au lieu de 5. – Sunit