2009-12-07 4 views
0

У меня есть записи в таблице codelistvalueview этого типа:LINQ GroupBy с Где

Я хочу, чтобы сгруппировать по пространству имен и, возможно, затем имя_таблицы и выяснить, все записи, которые только встречаются в обоих пространств имен (UPD/REFDAT) а затем перечислите затем те, которые встречаются в UDP, чтобы их можно было удалить.

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 

В случае, описанном выше, мне нужно TABLEID из 1-й строки, так как только что происходит в обоих 1 & 2 ряда. Мне нужно значение tableid из строки с UDP в качестве пространства имен (1-я строка в этом случае)

Я бы подумал, что это (внизу) получит меня, что я хочу, но я получаю несколько нулевых строк между ними ??

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(); 

Это то, что я вижу ...

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

Любые мысли ??

Я, наконец, придумал это, похоже, работает ... не уверен, что это лучший способ сделать это.

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); 

И я получаю это:

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  

благодаря Sunit

+0

Итак, вы спрашиваете здесь два вопроса? – Stu

+0

Я не уверен. Мне нужно перечислить те, которые происходят в UPD, если и только если они также встречаются в REFDAT. – Sunit

+0

Не могли бы вы ответить на вопрос, пожалуйста? Вы хотите найти записи, которые находятся в обоих пространствах имен или находятся в пространстве имен UDP? извините, я не понял ваш вопрос правильно –

ответ

1

Я думаю, что это будет работать для вас, если я понимаю вопрос правильно. Я использую «codelistvalueview» как коллекцию, в которой есть данные таблиц.

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; 

- или -

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

Результат varable имеет все элементы "UDP", которые также имеют "REFDAT" пунктов, где их имена таблиц являются одинаковыми.

- Edit -

Я предполагаю, что с вашего последнего обновления, которые вы используете LINQPad, чтобы выяснить этот вопрос. Это здорово, потому что я тоже использую его. Я обновил запрос, чтобы использовать имена, которые вы выбрали. Попробуйте запустить это как «C# Program» в LinqPad. Он выбирает TableID и отфильтровывает любые дубликаты.

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

Это даст мне несколько записей для строк, которые имеют UDP и одно и то же имя таблицы, но отличаются в других полях. – Sunit

+0

Должен работать, но я получаю 286 записей вместо 5. – Sunit