Linq2Db跨两表批量删除报错:InvoiceId列重复指定
解决Linq2Db批量删除关联表数据时的重复列报错问题
问题原因
你的代码生成的SQL中,子查询使用了SELECT TOP (@take) *,同时查询了Invoices和InvoiceDetails两张表——这两张表都包含InvoiceId列,导致子查询的结果集t1出现重复列名,触发SQL Server的The column 'InvoiceId' was specified multiple times for 't1'错误。
解决方案
方案1:直接从目标表出发过滤(推荐)
直接查询InvoiceDetails表,通过关联Invoices过滤符合条件的数据,确保只返回InvoiceDetails的列:
var detailsToDelete = ctx.InvoiceDetails .Where(d => d.Invoice.InvoiceDate <= new DateTime(2023, 9, 14)) .ToLinqToDB() .Take(100000); detailsToDelete.Delete();
方案2:明确选择目标表的列
如果坚持使用SelectMany的写法,需要显式选择InvoiceDetails的所有列,避免包含Invoices表的列:
var x = ctx.Invoices .Where(p => p.InvoiceDate <= new DateTime(2023, 9, 14)) .SelectMany(p => p.InvoiceDetails) .Select(d => new { d.InvoiceDetailId, d.InvoiceId, d.Amount, // 替换为你实际的InvoiceDetails列 d.Description }); var y = x.ToLinqToDB().Take(100000); y.Delete();
方案3:使用Linq2Db原生循环批量删除
直接用Linq2Db上下文编写循环删除逻辑,直到没有符合条件的数据,同时避免事务日志溢出:
using var linq2DbCtx = new YourLinq2DbContext(); // 替换为你的LinqToDB上下文类 int deletedCount; do { deletedCount = linq2DbCtx.InvoiceDetails .Where(d => linq2DbCtx.Invoices .Any(i => i.InvoiceId == d.InvoiceId && i.InvoiceDate <= new DateTime(2023, 9, 14))) .Take(100000) .Delete(); } while (deletedCount > 0);
内容的提问来源于stack exchange,提问作者Judge Mental
相关产品推荐
相关产品推荐

