C# 如果实体不存在,则插入该实体
我们一直在使用Dapper和Dapper.Contrib,以便于执行常规数据库操作,这非常好。然而,自从引入Polly为我们的一些操作添加重试策略以来,我一直无法找到保持相同简单性的方法,因为在执行重试之前必须检查记录的存在 下面是我们当前执行插入操作的简化示例:C# 如果实体不存在,则插入该实体,c#,dapper,dapper-contrib,C#,Dapper,Dapper Contrib,我们一直在使用Dapper和Dapper.Contrib,以便于执行常规数据库操作,这非常好。然而,自从引入Polly为我们的一些操作添加重试策略以来,我一直无法找到保持相同简单性的方法,因为在执行重试之前必须检查记录的存在 下面是我们当前执行插入操作的简化示例: public async Task Insert(Payment payment) { var retryPolicy = // Create using Polly. using (var connection =
public async Task Insert(Payment payment)
{
var retryPolicy = // Create using Polly.
using (var connection = new SqlConnection(_connectionString))
{
var dao = MapToDao(payment);
await retryPolicy.ExecuteAsync(() => connection.InsertAsync(dao));
}
}
[Table("Payment")]
public class PaymentDao
{
[ExplicitKey]
public Guid PaymentId { get; set; }
// A whole bunch of properties omitted for brevity
}
其中支付是我们的域模型,PaymentDao是我们的数据访问对象
实际上,我们在调用Insert的服务中有明确检查重复项的逻辑,但重试策略否定了这一点。这意味着,自Polly推出以来,我们看到了少量重复付款
我可以通过执行以下操作来解决此问题:
public async Task Insert(Payment payment)
{
var retryPolicy = // Create using Polly.
using (var connection = new SqlConnection(_connectionString))
{
var dao = MapToDao(payment);
await retryPolicy.ExecuteAsync(() => connection.ExecuteAsync(
@"IF ((SELECT COUNT(*) FROM dbo.Payment WHERE SubscriptionId = @subscriptionId) = 0)
BEGIN
INSERT INTO Payment
(
PaymentId,
SubscriptionId,
// Lots of columns omitted for brevity.
)
VALUES
(
@PaymentId,
@SubscriptionId,
// Lots of values omitted for brevity.
)
END",
new
{
dao.PaymentId,
dao.SubscriptionId,
// Lots of properties omitted for brevity.
}));
}
}
然而,正如你所看到的,它变得相当冗长。有一种更简单的方法吗?< P>您可以考虑首先使用模型检查,然后执行插入,因为搜索使用较少的参数
using (var connection = new SqlConnection(_connectionString)) {
var dao = MapToDao(payment);
var sql = "SELECT COUNT(1) FROM dbo.Payment WHERE SubscriptionId = @subscriptionId";
await retryPolicy.ExecuteAsync(async () => {
var exists = await connection.ExecuteScalarAsync<bool>(sql, new {dao.SubscriptionId});
if(!exists) {
await connection.InsertAsync(dao);
}
});
}
您当前的修复有什么问题?@Nkosi对于一些我们还没有分解的遗留对象,有50多个属性,这导致在内联SQL中大量手动映射值。我只是希望我们能提供一个谓词和dao,它能处理剩下的部分。类似于:connection.InsertIfNotExistsAsyncdao,predicate。非常感谢。祝你晚上愉快。