我有这样的LINQ查询:
from a in _context.tblTradeSpends
orderby a.DealPeriod, a.CustomerNumber, a.LOB, a.VersionDate descending
select new
{
DealPeriod = a.DealPeriod,
CustomerNumber = a.CustomerNumber,
LOB = a.LOB,
PromoID = a.PromoID,
VersionDate = a.VersionDate
}
以下是我的结果集中的一小部分示例(抱歉格式化):
DealPeriod CustomerNumber LOB PromoID VersionDate
2013 10001 PL P0083312 12/04/2013 9:05
2013 10001 PL P0083313 12/04/2013 9:05
2013 10001 PL P0083314 12/04/2013 9:05
2013 10001 PL P0085100 12/04/2013 9:05
2013 10001 PL P0086169 12/04/2013 9:05
2013 10001 PL P0083312 18/01/2013 10:51
2013 10001 PL P0083313 18/01/2013 10:51
2013 10001 PL P0083314 18/01/2013 10:51
2013 10001 PL P0085100 18/01/2013 10:51
2013 10001 PL P0083312 07/07/2013 15:41
2013 10001 PL P0083313 07/07/2013 15:41
2013 10001 PL P0083314 07/07/2013 15:41
2013 10001 SCF P0083308 03/05/2013 11:27
2013 10001 SCF P0083309 03/05/2013 11:27
2013 10001 SCF P0085088 03/05/2013 11:27
2013 10001 SCF P0085380 03/05/2013 11:27
2013 10001 SCF P0085381 03/05/2013 11:27
2013 10213 SCF P0086880 11/07/2013 20:23
2013 10213 SCF P0086881 11/07/2013 20:23
2013 10213 SCF P0086882 11/07/2013 20:23
2013 10213 SCF P0086883 11/07/2013 20:23
2013 10213 SCF P0083630 28/05/2013 13:38
2013 10213 SCF P0083631 28/05/2013 13:38
2013 10213 SCF P0083632 28/05/2013 13:38
2013 10213 SCF P0083633 28/05/2013 13:38
我需要分析这些数据,所以我希望删除某些相关记录以便减少这些数据。我的规则是,我想删除所有具有相同交易期,客户编号和LOB字段的记录,其中没有一个版本日期超过2013年6月1日(2013年6月1日)
因此,在我的结果集中,我希望保留所有以2013|10001|PL
开头的记录,因为某些记录的版本日期为07/17/2013
我会删除以2013|10001|SCF
开头的记录,因为没有包含这些字段值的记录的版本日期超过2013年6月1日
我想保留以2013|10213|SCF
开头的记录,因为其中一些记录的版本日期为11/07/2013。
修改的
我试过King King的代码,我得到了一些不应该在那里的相关记录。以下是我将被过滤掉的两组:
2013 10039 SCF P0083145 05/02/2013 10:22
2013 10039 SCF P0083146 05/02/2013 10:22
2013 10039 SCF P0083147 05/02/2013 10:22
2013 10039 SCF P0085152 05/02/2013 10:22
2013 10039 SCF P0083145 1/22/2013 5:55:00 PM
2013 10039 SCF P0083146 1/22/2013 5:55:00 PM
2013 10039 SCF P0083147 1/22/2013 5:55:00 PM
2013 10039 SCF P0085152 1/22/2013 5:55:00 PM
2013 10039 SCF P0083145 12/05/2012 19:21
2013 10039 SCF P0083146 12/05/2012 19:21
2013 10039 SCF P0083147 12/05/2012 19:21
2013 10040 PL P0084345 1/14/2013 10:27:00 AM
2013 10040 PL P0084346 1/14/2013 10:27:00 AM
2013 10040 PL P0084347 1/14/2013 10:27:00 AM
2013 10040 PL P0084348 1/14/2013 10:27:00 AM
2013 10040 PL P0084345 12/20/2012 10:15:00 PM
2013 10040 PL P0084346 12/20/2012 10:15:00 PM
2013 10040 PL P0084347 12/20/2012 10:15:00 PM
2013 10040 PL P0084348 12/20/2012 10:15:00 PM
答案 0 :(得分:1)
var fixedDate = DateTime.Parse("6/1/2013");
var result = _context.tblTradeSpends.GroupBy(x=>new {x.DealPeriod, x.CustomerNumber, x.LOB})
.Where(g=>g.All(x=>x.VersionDate <= fixedDate) || g.Count()==1)
.SelectMany(g=>g);
我相信这段代码应该有效,所以我尝试创建OP示例中给出的示例列表并测试代码,结果如下:
2013 : 1001 : PL : P0083312 : 4/12/2013 12:00:00 AM
2013 : 1001 : PL : P0083313 : 4/12/2013 12:00:00 AM
2013 : 1001 : PL : P0083314 : 4/12/2013 12:00:00 AM
2013 : 1001 : PL : P0085100 : 4/12/2013 12:00:00 AM
2013 : 1001 : PL : P0086169 : 4/12/2013 12:00:00 AM
2013 : 1001 : PL : P0083312 : 1/18/2013 12:00:00 AM
2013 : 1001 : PL : P0083313 : 1/18/2013 12:00:00 AM
2013 : 1001 : PL : P0083314 : 1/18/2013 12:00:00 AM
2013 : 1001 : PL : P0085100 : 1/18/2013 12:00:00 AM
2013 : 1001 : PL : P0083312 : 12/7/2012 12:00:00 AM
2013 : 1001 : PL : P0083313 : 12/7/2012 12:00:00 AM
2013 : 1001 : PL : P0083314 : 12/7/2012 12:00:00 AM
2013 : 1001 : SCF : P0083308 : 5/3/2013 12:00:00 AM
2013 : 1001 : SCF : P0083309 : 5/3/2013 12:00:00 AM
2013 : 1001 : SCF : P0085088 : 5/3/2013 12:00:00 AM
2013 : 1001 : SCF : P0085380 : 5/3/2013 12:00:00 AM
2013 : 1001 : SCF : P0085381 : 5/3/2013 12:00:00 AM
据我了解OP的要求,此列表应该是OP想要的(删除所有不需要的条目后)。
答案 1 :(得分:0)
只需添加具有这些条件的where子句;
from a in _context.tblTradeSpends
where a.DealPeriod != 2013 && a.CutomerNumber != 10001 && a.LOB != SCF
orderby a.DealPeriod, a.CustomerNumber, a.LOB, a.VersionDate descending
select new
{
DealPeriod = a.DealPeriod,
CustomerNumber = a.CustomerNumber,
LOB = a.LOB,
PromoID = a.PromoID,
VersionDate = a.VersionDate
}
where子句将过滤掉以2013|10001|SCF
开头的所有记录。
答案 2 :(得分:0)
首先,您应该为匿名类型创建一个通用比较器:
public class MyEqualityComparer<T> : IEqualityComparer<T>
{
Func<T, T, bool> _equalsFunction;
Func<T, int> _hashCodeFunction;
public MyEqualityComparer(
Func<T, T, bool> equalsFunction, Func<T, int> hashCodeFunction)
{
if (equalsFunction == null) throw new ArgumentNullException();
if (hashCodeFunction == null) throw new ArgumentNullException();
_equalsFunction = equalsFunction;
_hashCodeFunction = hashCodeFunction;
}
public bool Equals(T x, T y)
{
return _equalsFunction(x, y);
}
public int GetHashCode(T obj)
{
return _hashCodeFunction(obj);
}
}
然后,使用以下查询:
var comp = new MyEqualityComparer<tblTradeSpend>(
(x, y) => x.DealPeriod == y.DealPeriod &&
x.CustomerNumber == y.CustomerNumber &&
x.LOB == y.LOB,
obj => obj.DealPeriod.GetHashCode() ^
obj.CustomerNumber.GetHashCode() ^
obj.LOB.GetHashCode()
);
var q = (from a in _context.tblTradeSpends.AsEnumerable()
where a.VersionDate < DateTime.Parse("6/1/2013")
select new
{
DealPeriod = a.DealPeriod,
CustomerNumber = a.CustomerNumber,
LOB = a.LOB,
PromoID = a.PromoID,
VersionDate = a.VersionDate
}).Distinct(comp).OrderBy(o => o.DealPeriod)
.ThenByDescending(o => o.CustomerNumber)
.ThenByDescending(o => o.LOB)
.ThenByDescending(o => o.PromoID).ToList();