简体   繁体   English

如何删除 Entity Framework Core 中指定日期之前的记录,不包括最新的?

[英]How do I delete records before a specified date in Entity Framework Core excluding the latest?

How can I delete all but the latest stock records, that were created before a specific date, in Entity Framework Core.如何在 Entity Framework Core 中删除除最新股票记录之外的所有在特定日期之前创建的记录。 I am unable to figure out the required LINQ query but have managed to put together SQL that should do the job:我无法弄清楚所需的 LINQ 查询,但已经设法将 SQL 放在一起应该可以完成这项工作:

--
-- Parameters. 
--
DECLARE @PurgeDate DATETIME = DATEADD(day, -7, GETDATE());
DECLARE @RegionId INT = 28;

DECLARE @StockCodes TABLE(
    StockCode NVARCHAR(10)
);

-- Could be a significant number
INSERT INTO @StockCodes VALUES ('ABC123'), ('DEF123') /* etc... */;

--
-- Get stock records that are newer than the purge date or the latest record if not. 
-- This ensures there is always at least one stock record for a stock code.
--
WITH LatestStockRecords
AS
(
    SELECT s.*, [RowNumber] = ROW_NUMBER() OVER (PARTITION BY s.[StockCode] ORDER BY s.[CreatedAt] DESC)
    FROM StockRecords AS s
        INNER JOIN Locations AS l
            ON s.[LocationId] = l.[Id]
    WHERE l.[RegionId] = @RegionId
        AND s.[StockCode] IN (SELECT * FROM @StockCodes)
)
SELECT *.[Id]
INTO #_STOCK_RECORD_IDS
FROM LatestStockRecords
WHERE [CreatedAt] >= @PurgeDate
    OR [RowNumber] = 1;
    
--
-- Delete the stock records that do not appear in the latest stock records temporary table.
--
DELETE s
FROM StockRecords AS s
    INNER JOIN Locations AS l
        ON s.[LocationId] = l.[Id]
WHERE l.[RegionId] = @RegionId
    AND s.[StockCode] IN (SELECT * FROM @StockCodes)
    AND s.[Id] NOT IN (SELECT * FROM #_STOCK_RECORD_IDS);

There could be a significant number of records to delete so performance needs to be a consideration.可能有大量记录要删除,因此需要考虑性能。

EDIT: Removed DbContext and entities as I don't think they're relevant to the question.编辑:删除 DbContext 和实体,因为我认为它们与问题无关。

This is how I eventually solved the problem.这就是我最终解决问题的方法。 I had to force the evaluation of the grouping query as Entity Framework Core doesn't seem to support the neccessary query at this point.我不得不强制评估分组查询,因为此时 Entity Framework Core 似乎不支持必要的查询。

var regionId = 28;
var stockCodes = new string[] { "ABC123", "DEF123" /* etc... */ };
var purgeDate = DateTime.UtcNow.AddDays(-NumberOfDaysToPurge);

bool IsPurgeable(StockRecord stockRecord)
{
    return stockRecord.CreatedAt >= purgeDate;
}

var latestStockRecordIds = context.StockRecords
    .Where(stockRecord =>
        stockRecord.Location.RegionId == regionId
        && stockCodes.Contains(stockRecord.StockCode))
    .AsEnumerable() // <-- force execution
    .GroupBy(stockRecord => stockRecord.StockCode)
    .SelectMany(group =>
    {
        var orderedStockRecords = group.OrderByDescending(stockRecord => stockRecord.CreatedAt);

        var stockRecords = orderedStockRecords.Count(IsPurgeable) > 0
            ? orderedStockRecords.Where(IsPurgeable)
            : orderedStockRecords.Take(1);

        return stockRecords.Select(stockRecord => stockRecord.Id);
    });

var stockRecordsToRemove = await context.StockRecords
    .Where(stockRecord =>
        stockRecord.Location.RegionId == regionId
        && StockCodeCodes.Contains(stockRecord.StockCode)
        && stockRecord.CreatedAt <= purgeDate
        && !latestStockRecordIds.Contains(stockRecord.Id))
    .ToListAsync();

context.ChangeTracker.AutoDetectChangesEnabled = false;
context.StockRecords.RemoveRange(stockRecordsToRemove);

await context.SaveChangesAsync();

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

相关问题 如何删除 Entity Framework.Core 中的一组记录? - How do I delete a set of records in Entity Framework .Core? 如何在实体框架中循环创建和删除记录 - How do I create and delete records in Entity Framework in a loop 如何删除 Entity Framework Core 中的多行? - How do I delete multiple rows in Entity Framework Core? 实体框架核心:如何通过仅选择最新创建的记录在“ IQueryable”上执行联接? - Entity Framework Core: How to perform a Join on `IQueryable` by selecting only the latest created records? 如何使用 ExecuteSqlCommand 删除实体框架中的记录? - How can I delete records in Entity Framework using ExecuteSqlCommand? 如何使用 EF Core 删除数据库中的多条记录? - How do I delete multiple records in database using EF Core? 如何使用Entity Framework按创建日期升序删除1000条记录? - How to delete 1000 records based upon created date ascending using Entity Framework? 如何在 Azure Functions 中使用 Entity Framework Core - How do I use Entity Framework Core in Azure Functions 实体框架核心运行缓慢-如何使其更快? - Entity Framework Core is slow - how do I make it faster? 如何更改Entity Framework Core 2.2中的ILazyLoader实现? - How do I change the ILazyLoader implementation in Entity Framework Core 2.2?
 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM