我正在将EF Core与.NET Core 3.0一起使用。我面临一个非常奇怪的案件。我正在将数据从SQLite传输到SQL Server。
using (var context1 = new Context1())
using (var context2 = new Context2())
{
foreach(var tran in context1.Transactions.Distinct())
{
var trans = new Model{
PersonID = tran.PersonID,
CreatedDate = tran.TranDate,
TranDate = tran.TranDate,
CreatedBy = tran.CreatedBy
};
context2.Transactions.Add(trans);
}
int cc = context2.SaveChanges();
int count1 = context1.Transactions.Count();
int count2 = context2.Transactions.Count();
}
问题是,当插入少量数据(1,000行)时,数据完整性很好,但是一次插入200,000条记录时,数据将重复,但应插入的记录数正确。
我还注意到重复项是在不同的周期发生的,因为它们的ID并不是按顺序排列的,插入是随机发生的!
ID TranDate PersonID CreatedBy CreatedDate
-------------------------------------------------------------------------------
513842 2019-06-17 10:29:11.3368419 93596 NULL 2019-06-17 10:29:11.3368419
516055 2019-06-17 10:29:11.3368419 93596 NULL 2019-06-17 10:29:11.3368419
516342 2019-06-17 10:29:11.3368419 93596 NULL 2019-06-17 10:29:11.3368419
更新: 只是为了确认重复
SQLite数据
SqlServer:
Update2:
Console.WriteLine(context1.Transactions.OrderBy(t => t.TranDate).GroupBy(t => t.TranDate).Count());
194735
但是;
foreach(var tran in context1.Transactions.OrderBy(t => t.TranDate).AsEnumerable().GroupBy( x => x.TranDate).Select(g => g.First()))
传输到SqlServer的总数为
答案 0 :(得分:0)
我认为问题是Distinct()
并没有按照您的想象做。
我怀疑原始表具有带有不同ID的“重复项”。
我建议您使用GroupBy
代替Distinct
:
context1.Transactions
.GroupBy( x =>
new { x.PersonID,
x.TranDate,
x.CreatedBy} )
.Select( g=> g.First());
答案 1 :(得分:0)
我认为问题可能与数据库上下文的重复有关。由于两个数据库结构几乎相同,因此我复制了现有的数据库上下文并更改了连接字符串。一定是里面的东西还在互相参照吗?!我不知道。该问题仅在输入三千次后出现。
但是,我要解决的问题是我删除了所有与数据库上下文相关的文件,包括模型,并使用scaffold
命令为每个数据库重新生成了新文件
dotnet ef dbcontext scaffold "Data Source=data.db" Microsoft.EntityFrameworkCore.Sqlite --output-dir Models
dotnet ef dbcontext scaffold "connectionstring" Microsoft.EntityFrameworkCore.SqlServer --output-dir Models
结果是我没有重复数据,但是没有按顺序插入它们,这似乎是EF的正常行为。
答案 2 :(得分:-1)
当行数在200,000范围内时,批量插入更适合。
如果您不关心事务完整性,可以一次将它们插入1,000或5,000行的块中。