一对值的C#SQL筛选器?
我正在使用一个数据表,其中有一些行被复制作为备份。我试图过滤掉已复制的数据,但遇到了一些问题,因为我需要过滤一对列。每一行都有一个名称和一个日期,一个标志表示它是副本还是其他一些东西(有两个以上的值,但这些是我感兴趣的值)和一些其他信息。我正在尝试获取所有未显示为备份的行,例如:一对值的C#SQL筛选器?,c#,sql,linq,C#,Sql,Linq,我正在使用一个数据表,其中有一些行被复制作为备份。我试图过滤掉已复制的数据,但遇到了一些问题,因为我需要过滤一对列。每一行都有一个名称和一个日期,一个标志表示它是副本还是其他一些东西(有两个以上的值,但这些是我感兴趣的值)和一些其他信息。我正在尝试获取所有未显示为备份的行,例如: ABC 1/1/2001 dataSet ... | ABC 1/1/2001 backupSet ... DEF 2/2/2002 dataSet ... | DEF 2/2/2002
ABC 1/1/2001 dataSet ... | ABC 1/1/2001 backupSet ...
DEF 2/2/2002 dataSet ... | DEF 2/2/2002 backupSet ...
GHI 3/3/2003 dataSet ... | ABC 4/4/2004 backupSet ...
ABC 4/4/2004 dataSet ... |
DEF 5/5/2005 dataSet ... |
ABC 6/6/2006 dataSet ... |
将导致:
GHI 3/3/2003 dataSet ...
DEF 5/5/2005 dataSet ...
ABC 6/6/2006 dataSet ...
我可以对一列进行筛选,但我不知道如何同时对两列进行筛选
var result = from a in db.table
where a.type == "dataSet"
let backupData = (from b in db.table where b.type == "backupSet" select b.name)
where !backupData.Contains(a.type)
select new DataObject
{
...
};
就我所知
我还试图将其保留为一个查询,因为结果集可能非常大,所以我不想只在内存中创建一对集合,然后尝试将它们过滤掉。可能吗?仍然对SQL有点缺乏经验,非常感谢您的帮助。根据您正在尝试做什么(以及您可以做什么),您可能希望使用
分组方式
,假设名称
是将backupSet和dataSet链接在一起的关键:
var result = db.Table
.GroupBy(x => new { x.name, x.type }) // Composite key
.Select(g => new {
Name = g.Key.name, // ABC, DEF, etc
Type = g.Key.type, // "backupSet", "dataSet"
LastRecord = g.OrderByDescending(x => x.date).FirstOrDefault() // Last record for either backupSet or dataSet
})
.ToList() // Materialize... query can be very complex
.GroupBy(x => x.Name)
.Select(g => new {
Name = g.Key,
LastBackupSet = g.First(x => x.Type == "backupSet").LastRecord,
LastDataSet = g.First(x => x.Type == "dataSet").LastRecord
})
.ToList();
但是要小心,在最后一个表达式中,g.First can throw Sequence不包含元素且。LastRecord
can throw Object reference未设置为对象的实例您可以使用以下任一选项(使用!
):
或者(看起来有点复杂,但通常效率更高)(使用null
右侧实现):
var result =
from a in db.table
where a.type == "dataSet"
&& !db.table.Any(b => b.type == "backupSet"
&& b.name == a.name && b.date == a.date)
select new DataObject
{
...
};
var result =
from a in db.table.Where(x => x.type == "dataSet")
join b in db.table.Where(x => x.type == "backupSet")
on new { a.name, a.date } equals new { b.name, b.date } into bGroup
from b in bGroup.DefaultIfEmpty()
where b == null
select new DataObject
{
...
};