我正在尝试根据用户聚合大约 200 万行。 一个用户有多个交易,每个交易都有一个平台和一个交易类型。我将平台和交易类型列聚合为 json 并保存为一行。
但是我的代码很慢。 我怎样才能提高性能?
public static void AggregateTransactions()
{
using (var db = new ApplicationDbContext())
{
db.ChangeTracker.AutoDetectChangesEnabled = false;
//Get a list of users who have transactions
var users = db.Transactions
.Select(x => x.User)
.Distinct();
foreach (var user in users.ToList())
{
//Get all transactions for a particular user
var _transactions = db.Transactions
.Include(x => x.Platform)
.Include(x => x.TransactionType)
.Where(x => x.User == user)
.ToList();
//Aggregate Platforms from all transactions for user
Dictionary<string, int> platforms = new Dictionary<string, int>();
foreach (var item in _transactions.Select(x => x.Platform).GroupBy(x => x.Name).ToList())
{
platforms.Add(item.Key, item.Count());
};
//Aggregate TransactionTypes from all transactions for user
Dictionary<string, int> transactionTypes = new Dictionary<string, int>();
foreach (var item in _transactions.Select(x => x.TransactionType).GroupBy(x => x.Name).ToList())
{
transactionTypes.Add(item.Key, item.Count());
};
db.Add<TransactionByDay>(new TransactionByDay
{
User = user,
Platforms = platforms, //The dictionary list is represented as json in table
TransactionTypes = transactionTypes //The dictionary list is represented as json in table
});
db.SaveChanges();
}
}
}
更新
因此数据的基本 View 如下所示:
交易数据:
编号:b11c6b67-6c74-4bbe-f712-08d609af20cf, 用户编号:1, 平台编号:3, TransactionTypeId: 1
编号:4782803f-2f6b-4d99-f717-08d609af20cf, 用户编号:1, 平台编号:3, TransactionTypeId: 4
将数据聚合为 TransactionPerDay:
编号:9df41ef2-2fc8-441b-4a2f-08d609e21559, 用户编号:1, 平台:{“p3”:2}, 交易类型:{"t1":1,"t4":1}
所以在这种情况下,两笔交易合二为一。您可以看到平台和交易类型将聚合为 json。
最佳答案
您可能不应该在循环中调用 db.saveChanges()。将其置于循环之外以将更改持久化一次,可能会有所帮助。
但话说回来,当处理大量数据和性能是关键时,我发现 ADO.NET 可能是更好的选择。这并不意味着您必须停止使用 Entity Framework,但也许对于这种方法您可以使用 ADO.NET。如果你走这条路,你可以:
创建存储过程以返回您需要处理的数据、填充数据表、操作数据并使用 sqlBulkCopy 批量保存所有内容。
使用一个存储过程来完成这个操作。这避免了将数据传送到您的应用程序的需要,并且整个处理过程可以在数据库本身内进行。
关于c# - 如何使用 EF Core 聚合数百万行,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/52009050/