我有一个复杂的大对象图,我希望使用DbContext和SaveChanges方法在数据库中插入。
此对象是使用40k行(大约3MB数据)解析文本文件的结果。此对象中的某些集合包含数千个项目。
我能够正确解析文件并将其添加到上下文中,以便它可以开始跟踪对象。但是当我尝试SaveChanges时,它说:
Microsoft.EntityFrameworkCore.DbUpdateException:更新条目时发生错误。有关详细信息,请参阅内部异常---> System.Data.SqlClient.SqlException:字符串或二进制数据将被截断。
我想知道是否有一种智能且有效的方法来发现哪个对象导致了问题。似乎varchar字段太小而无法存储数据。但是需要手动检查很多表格和字段。
我想以某种方式得到更具体的错误。我已经配置了 ILoggerProvider 并在我的dbContext中添加了 EnableSensitiveDataLogging 选项,以便能够查看正在生成哪些SQL查询。我甚至添加了 MiniProfiler 以查看参数值,因为它们不存在于dbContext生成的日志中。
在Web上的某处读取,我发现在EF6中,在将sql传递给要执行的数据库之前会发生一些验证。但似乎在EF Core中不再可用了。那我怎么解决这个问题呢?
答案 0 :(得分:0)
经过一些研究,我发现解决这个问题的唯一方法是通过重写dbContext的SaveChanges方法来实现一些验证。我已经将这两种方法合并在一起构建我的方法:
Implementing Missing Features in Entity Framework Core - Part 3
结果是......
<强> ApplicationDbContext.cs 强>
public override int SaveChanges(bool acceptAllChangesOnSuccess)
{
ValidateEntities();
return base.SaveChanges(acceptAllChangesOnSuccess);
}
public override async Task<int> SaveChangesAsync(bool acceptAllChangesOnSuccess, CancellationToken cancellationToken = new CancellationToken())
{
ValidateEntities();
return await base.SaveChangesAsync(acceptAllChangesOnSuccess, cancellationToken);
}
private void ValidateEntities()
{
var serviceProvider = this.GetService<IServiceProvider>();
var items = new Dictionary<object, object>();
var entities = from entry in ChangeTracker.Entries()
where entry.State == EntityState.Added || entry.State == EntityState.Modified
select entry.Entity;
foreach (var entity in entities)
{
var context = new ValidationContext(entity, serviceProvider, items);
var results = new List<ValidationResult>();
if (Validator.TryValidateObject(entity, context, results, true)) continue;
foreach (var result in results)
{
if (result == ValidationResult.Success) continue;
var errorMessage = $"{entity.GetType().Name}: {result.ErrorMessage}";
throw new ValidationException(errorMessage);
}
}
}
请注意,没有必要覆盖其他SaveChanges重载,因为他们会调用这两个。
答案 1 :(得分:0)
错误告诉您,您在字段中写入的字符多于它可以容纳的字符数。 例如,当您将给定字段创建为NVARCHAR(4)或CHAR(4)并向其写入“hello”时,将抛出此错误。
因此,您只需检查所读取值的长度即可找到导致问题的值。至少对于一个领域来说太长了。