我正在使用LINQ to SQL获取数据集。我需要过滤这个数据集:
如果存在具有null SourceName的字段,并且此字段的至少一个其他记录具有非null SourceName,则应将其删除。
如果它是该“字段”的唯一行,则它应保留在列表中。
以下是一个示例数据:数据由3列组成:'Field','SourceName'和'Rate'
Field | SourceName | Rate
10 | s1 | 9
10 | null | null
11 | null | null
11 | s2 | 5
11 | s3 | 4
12 | null | null
13 | null | null
13 | s4 | 7
13 | s5 | 8
8 | s6 | 2
9 | s7 | 23
9 | s8 | 9
9 | s9 | 3
输出应如下所示:
Field | SourceName | Rate
10 | s1 | 9
11 | s2 | 5
11 | s3 | 4
12 | null | null // <- (remains since there's only
13 | s4 | 7 // 1 record for this 'Field')
13 | s5 | 8
8 | null | null
9 | s8 | 9
9 | s9 | 3
如何过滤它?
答案 0 :(得分:1)
您尝试实现的目标并非无足轻重,只能通过.Where()
子句来解决。您的过滤条件取决于需要分组的条件,因此您必须.GroupBy()
,然后使用.SelectMany()
展平该集合集合。
以下代码使用LINQ to Objects满足您的预期输出,我没有看到任何LINQ to SQL无法将其转换为SQL的原因,没有尝试过那么难。
//Group by the 'Field' field.
yourData.GroupBy(x => x.Field)
//Project the grouping to add a new 'IsUnique' field
.Select(g => new {
SourceAndRate = g,
IsUnique = g.Count() == 1,
})
//Flatten the collection using original items, plus IsUnique
.SelectMany(t => t.SourceAndRate, (t, i) => new {
Field = t.SourceAndRate.Key,
SourceName = i.SourceName,
Rate = i.Rate,
IsUnique = t.IsUnique
})
//Now we can do the business here; filter nulls except unique
.Where(x => x.SourceName != null || x.IsUnique);
答案 1 :(得分:0)
使用Linq内置的'Where'子句和lambda continuation:
使用lambda和一个简单的POCO类将数据存储在像你这样的列表中的简单静态示例:
using System;
using System.Collections.Generic;
using System.Linq;
namespace Simple
{
class Program
{
class Data
{
public string Field { get; set; }
public string SourceName { get; set; }
public string Rate { get; set; }
}
static List<Data> Create()
{
return new List<Data>
{
new Data {Field = "10", SourceName = null, Rate = null},
new Data {Field = "11", SourceName = null, Rate = null},
new Data {Field = "11", SourceName = "s2", Rate = "5"}
};
}
static void Main(string[] args)
{
var ls = Create();
Console.WriteLine("Show me my whole list: \n\n");
// write out everything
ls.ForEach(x => Console.WriteLine(x.Field + "\t" + x.SourceName + "\t" + x.Rate + "\n"));
Console.WriteLine("Show me only non nulls: \n\n");
// exclude some things
ls.Where(l => l.SourceName != null)
.ToList()
.ForEach(x => Console.WriteLine(x.Field + "\t" + x.SourceName + "\t" + x.Rate + "\n"));
Console.ReadLine();
}
}
}