【发布时间】:2020-06-18 16:17:59
【问题描述】:
我有两个实体,Etf 和 DataPoint。每个Etf 有多个DataPoints。请参阅下面的结构
public class Etf
{
public Etf()
{
DataPoints = new HashSet<DataPoint>();
}
public string Id { get; set; }
public ICollection<DataPoint> DataPoints { get; private set; }
}
public class DataPoint {
public string EtfId { get; set; }
public Etf Etf { get; set; }
public DateTime Date { get; set; }
}
碰巧将具有相同EtfId 和Date 的多个数据点插入到数据库中。我想根据这两个字段删除重复项。
在 SQL 中,我试过这个:
WITH CTE AS
(SELECT Id, ROW_NUMBER() OVER
(PARTITION BY EtfId, Date ORDER BY EtfId, Date DESC)
AS ROW_NUMBER FROM DataPoints)
DELETE FROM CTE WHERE ROW_NUMBER > 1;
这给了我一个错误,即 CTE 不是可更新的表(可能是因为它同时连接到 Etf 和 DataPoint)。然后,我根据this 的答案在 LINQ 中尝试了以下内容:
// Get the duplicate indices
var idxs = await _context.DataPoints
.GroupBy(g => new {g.EtfId, g.Date})
.OrderBy(g => g.Key.EtfId)
.ThenByDescending(g => g.Key.Date)
.SelectMany(g =>
g.Select((i, idx) => new { i.Id, Idx = idx }))
.Where(g => g.Idx > 0)
.Select(g => g.Id)
.ToListAsync(cancellationToken);
// Get the duplicate entities from indices
var duplicates = await _context.DataPoints
.Where(x => idxs.Contains(x.Id))
.ToListAsync(cancellationToken);
// Remove them
_context.DataPoints.RemoveRange(duplicates);
但是,这种方法在Select((i, idx) => ..) 语句中给了我一个System.InvalidOperationException,说它可能是来自 EF Core 的错误或限制。
我可以使用更好的(或只是有效的)方法吗?
【问题讨论】: