linq GroupBy with Where

时间:2009-12-07 17:03:49

标签: c# linq

我在此类型的表codelistvalueview中有条目:

我希望按名称空间分组,然后通过tablename分组,找出只出现在两个名称空间(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

在上面的例子中,我只需要第1行中的tableid,因为它同时出现在1和1中。 2排。我需要的值是来自UDP行作为名称空间的行的tableid(本例中为第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      

感谢 苏尼特

1 个答案:

答案 0 :(得分:1)

如果我理解这个问题,我认为这对你有用。我正在使用“codelistvalueview”作为包含表格数据的集合。

var refdatItems = codelistvalueview.Where(x=>x.@namespace == "REFDAT");
var udpItems = codelistvalueview.Where(x=>x.@namespace == "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 ref.@namespace == "REFDAT" &&
          udp.@namespace == "UDP"
    select udp; 

结果varable包含所有“UDP”项目,这些项目也有“REFDAT”项目,其表名相同。

- 编辑 -

我猜你从上次更新中使用LinqPad来找出这个查询。多数民众赞成,因为我也使用它。我已更新查询以使用您选择的名称。尝试在LinqPad中将其作为“C#程序”运行。它选择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;
}