调用"保存更改"时收到'Database operation expected to affect 1 row(s) but actually affected 0 row(s).'错误



我一直在尝试让一个EntityFramework解决方案为即将到来的连接到Postgres数据库的项目工作,并且大部分工作已经完成。但是,在尝试批量添加/更新实体时,我遇到了一些问题,我不确定下面的错误是否掩盖了我流程的实际错误:

Database operation expected to affect 1 row(s) but actually affected 0 row(s).
Data may have been modified or deleted since entities were loaded. 
See http://go.microsoft.com/fwlink/?LinkId=527962 for information on understanding and handling optimistic concurrency exceptions.

我正在使用设计时上下文工厂模式来允许我的 Azure 函数应用调用它,这是我当前的实现:

public class ContextFactory : IDesignTimeDbContextFactory<Context>
{
public Context CreateDbContext(string[] args)
{
var optionsBuilder = new DbContextOptionsBuilder<Context>();
optionsBuilder.UseNpgsql("{ConnectionString}");
optionsBuilder.EnableDetailedErrors();
optionsBuilder.EnableSensitiveDataLogging();
return new Context(optionsBuilder.Options);
}
}

我目前通过Startup.cs添加到函数应用程序的服务中:

builder.Services.AddDbContext<ESRContext>(options => 
options.UseNpgsql(Environment.GetEnvironmentVariable("PostgreDBConnectionString")));

当前,在尝试调用context.SaveChanges()方法时,表中没有任何内容可供我尝试使用。下面是我一直使用的实体模型:

public class Record
{
public int UserId { get; set; }
public int CourseID { get; set; }
[ConcurrencyCheck]
public int CourseSessionID { get; set; }
public string Code { get; set; }
[ConcurrencyCheck]
public DateTime DateFrom { get; set; }
[ConcurrencyCheck]
public DateTime DateTo { get; set; }
}

(请原谅格式,无法完全使其对齐!

我正在处理一个按行映射到此实体的文件,并根据该行是否存在于上下文中进行添加/更新。例如:

如果同一文件中的行首先使用Context.Records.Add()course的完成添加到上下文中,然后后续行旨在通过首先从上下文中获取实体,使用新属性修改该实体,然后使用Context.Records.Update(record)将其保存回来,为文件中的用户/课程组合更新它。首先,这是正确的做法吗?我将在我实现的基本流程之后添加一段代码:

try
{
//File rows based through as Records
foreach (var record in fileRecords)
{
var existingRecord = GetRecord(int.Parse(record.UserId), int.Parse(record.CourseId));
if (existingRecord != null)
{
if (existingRecord.DateFrom < DateTime.ParseExact(record.DateFrom, "yyyyMMdd", CultureInfo.InvariantCulture))
{
UpdateRecord(existingRecord, record);
}
}
else
{
_logger.LogInformation(
"User with userId of {userId} on competence {courseId} could not be found in reference store. Adding.",
record.userId, record.courseId
);
var addedRecord = new Data.Entities.Record
{
UserId = int.Parse(record.UserId),
CourseSessionId = int.Parse(record.CourseSessionId),
Code = code,
CourseId = int.Parse(record.CourseId),
DateFrom = string.IsNullOrWhiteSpace(record.DateFrom) ? DateTime.MinValue : DateTime.ParseExact(record.DateFrom, "yyyyMMdd", CultureInfo.InvariantCulture),
DateTo = string.IsNullOrWhiteSpace(record.DateTo) ? DateTime.MinValue : DateTime.ParseExact(record.DateTo, "yyyyMMdd", CultureInfo.InvariantCulture)
};
_context.Records.Add(addedRecord);
}
}
_context.SaveChanges();
}
catch (DbUpdateConcurrencyException ex)
{
foreach (var entry in ex.Entries)
{
var record = (Data.Entities.Record)entry.Entity;
_logger.LogInformation("Concurrency issue found: n" +
"UserId {userId} n" +
"CourseId {courseId} n" +
"CourseSessionId {courseSessionId} n" +
"DateFrom: {dateFrom} n" +
"DateTo: {dateTo}",
record.UserId,
record.CourseId,
record.CourseSessionId,
record.DateFrom,
record.DateTo
);
}
}
private void UpdateRecord(Data.Entities.Record existingRecord, FileRecord updatedRecord)
{
existingRecord.CourseSessionId = int.Parse(updatedRecord.CourseSessionId);
existingRecord.DateFrom = string.IsNullOrWhiteSpace(updatedRecord.DateFrom) ? DateTime.MinValue : DateTime.ParseExact(updatedRecord.DateFrom, "yyyyMMdd", CultureInfo.InvariantCulture);
existingRecord.DateTo = string.IsNullOrWhiteSpace(updatedRecord.DateTo) ? DateTime.MinValue : DateTime.ParseExact(updatedRecord.DateTo, "yyyyMMdd", CultureInfo.InvariantCulture);
_context.Records.Update(existingRecord);
}
private Data.Entities.Record GetRecord(int userId, int courseId)
{
var returnedObject = _context.Records.SingleOrDefault(er => er.UserId == userId && er.CourseId == courseId);
return returnedObject;
}

这个问题可能已经随着我想问的问题而到处都是,所以很抱歉!从本质上讲,我收到了上面提到的此错误,我不确定我是否缺少任何最佳实践或其他内容,因为该错误似乎非常通用,并且在捕获时不包含InnerException

我将根据收到的评论监测和更新这个问题。希望你们能帮助解决这个问题!

很高兴@JakeRoper能够解决这个问题。感谢您@jdweng的建议,这些建议有助于操作解决问题。代表您的讨论发布此内容,以便可以帮助其他社区成员。

收到以下错误消息,因为您同时使用 update() 和 savechanges(),这会导致并发冲突。您可以使用可以更新记录的函数之一。

Database operation expected to affect 1 row(s) but actually affected 0 row(s).
Data may have been modified or deleted since entities were loaded. 
See http://go.microsoft.com/fwlink/?LinkId=527962 for information on >understanding and handling optimistic concurrency exceptions. 

如果错误仍然存在,另一种方法是在保存更改期间捕获DbUpdateConcurrencyException。有关并发异常的详细信息,可以参考处理并发冲突。

相关内容

最新更新