我想从实体框架中捕获错误。
所以我有以下代码
return await _context.SaveChangesAsync(cancellationToken);
如果上述代码中出现问题,我希望将其捕获为数据库中的警告,但到目前为止,它已自动保存为数据库中的错误,而实际上这是必须警告的。
以下是我得到的错误
在保存上下文更改时数据库中发生异常 键入“ ValuationsReporting.Models.ValuationsReportingContext”。 System.InvalidOperationException:上的属性'TemplateTypeId' 实体类型“ ValuationFundTemplate”具有一个临时值。任一个 明确地指定一个永久值,或确保已配置数据库 为该属性生成值。在 Microsoft.EntityFrameworkCore.Update.Internal.CommandBatchPreparer.Validate(ModificationCommand ificationCommand) Microsoft.EntityFrameworkCore.Update.Internal.CommandBatchPreparer.BatchCommands(IReadOnlyList
1 entries)+MoveNext() at Microsoft.EntityFrameworkCore.Update.Internal.BatchExecutor.ExecuteAsync(DbContext _, ValueTuple
2个参数,CancellationToken cancelledToken)位于 Microsoft.EntityFrameworkCore.Storage.ExecutionStrategy.ExecuteImplementationAsync [TState,TResult](Func4 operation, Func
4验证成功,TState状态,CancellationToken cancelToken) Microsoft.EntityFrameworkCore.Storage.ExecutionStrategy.ExecuteImplementationAsync [TState,TResult](Func4 operation, Func
4验证成功,TState状态,CancellationToken cancelToken) Microsoft.EntityFrameworkCore.ChangeTracking.Internal.StateManager.SaveChangesAsync(IReadOnlyList`1 entryToSave,CancellationToken cancelToken) Microsoft.EntityFrameworkCore.ChangeTracking.Internal.StateManager.SaveChangesAsync(Boolean acceptAllChangesOnSuccess,CancellationToken cancelToken),位于 Microsoft.EntityFrameworkCore.DbContext.SaveChangesAsync(Boolean acceptAllChangesOnSuccess,CancellationToken cancelToken()System.InvalidOperationException
Microsoft.EntityFrameworkCore.Update
我尝试使用try catch,但是一旦转到该行,错误就会记录在数据库中。
实际代码:
try
{
foreach (var template in snapshotDto.SnapshopFundTemplateDtos)
{
if (template.FundId != null)
{
foreach (var fundId in template.FundId)
{
var tempTemplate = allFundTemplates.Where(x => x.ValuationId == valuation.Id && x.FundId == fundId && x.TemplateTypeId == template.TemplateTypeId).FirstOrDefault();
//var tempTemplate = await _valuationFundTemplateRepository.GetOne(valuation.Id, fundId, template.TemplateTypeId, true, cancellationToken);
if (tempTemplate == null)
{
tempTemplate = new ValuationFundTemplate();
tempTemplate.CreatedBy = _userRepository.claimsPrincipal.Identity.Name;
tempTemplate.CreatedOn = DateTime.Now.ToUniversalTime();
isTemplateUpdate = false;
}
//tempTemplate.IsDeleted = false;
//if (template.IsDeleted)
//{
// _valuationFundTemplateRepository.Delete(tempTemplate);
//}
//else
//{
//tempTemplate.IsDeleted = template.IsDeleted;
tempTemplate.IsDeleted = false;
tempTemplate.IsDefaultFundTemplate = template.IsDefault;
tempTemplate.FundId = fundId;
tempTemplate.ValuationId = valuation.Id;
tempTemplate.TemplateTypeId = 0;
tempTemplate.TemplateId = template.TemplateId;
tempTemplate.ModifiedBy = _userRepository.claimsPrincipal.Identity.Name;
tempTemplate.ModifiedOn = DateTime.Now.ToUniversalTime();
tempTemplates.Add(tempTemplate);
if (isTemplateUpdate)
{
_valuationFundTemplateRepository.Update(tempTemplate);
}
else
{
await _valuationFundTemplateRepository.Insert(tempTemplate, cancellationToken);
}
// }
await _valuationFundTemplateRepository.SaveAsync(cancellationToken);//here is where the error occurs which i dont want to capture in database.
if (!isTemplateUpdate)
valuation.ValuationFundTemplate.Add(tempTemplate);
}
}
}
}catch(Exception e)
{
var z = e.Message;
}
public virtual async Task<int> SaveAsync(CancellationToken cancellationToken = default(CancellationToken))
{
return await _context.SaveChangesAsync(cancellationToken);
}
答案 0 :(得分:1)
您同意使用@PrashantPimpale,只需使用try catch
。
但是对于高级方法,我建议您可以使用全局错误处理中间件。
通过它可以捕获整个dotnet
API /应用程序中发生的任何错误。
下面只是细节:
// Extension method used to add the middleware to the HTTP request pipeline.
public static class ErrorHandlingMiddlewareExtensions
{
public static IApplicationBuilder UseErrorHandlingMiddleware(this IApplicationBuilder builder)
{
return builder.UseMiddleware<ErrorHandlingMiddleware>();
}
}
然后在启动公司的app.UseErrorHandlingMiddleware();
方法中添加Configure()
。
您必须首先创建一个ErrorHandlingMiddleware
类。
public class ErrorHandlingMiddleware
{
private readonly RequestDelegate _next;
public ErrorHandlingMiddleware(RequestDelegate next)
{
_next = next;
}
public async Task Invoke(HttpContext httpContext)
{
try
{
await _next(httpContext);
}
catch (Exception ex)
{
await HandleExceptionAsync(httpContext, ex);
}
}
private static async Task HandleExceptionAsync(HttpContext context, Exception exception)
{
// Implement how you want to handle the error.
}
}