C# 如何捕获EF异常
我想从实体框架中捕获错误 所以我有下面的代码C# 如何捕获EF异常,c#,asp.net-core,C#,Asp.net Core,我想从实体框架中捕获错误 所以我有下面的代码 return await _context.SaveChangesAsync(cancellationToken); 如果上面的代码出现错误,我希望它在数据库中被捕获为警告,但现在它会自动在数据库中保存为错误,实际上它必须是警告 下面是我得到的错误 保存上下文更改时数据库中发生异常 键入“ValuationReporting.Models.ValuationReportingContext”。 System.InvalidOperationExc
return await _context.SaveChangesAsync(cancellationToken);
如果上面的代码出现错误,我希望它在数据库中被捕获为警告,但现在它会自动在数据库中保存为错误,实际上它必须是警告
下面是我得到的错误
保存上下文更改时数据库中发生异常
键入“ValuationReporting.Models.ValuationReportingContext”。
System.InvalidOperationException:上的属性“TemplateTypeId”
实体类型“ValuationFundTemplate”具有临时值。任何一套
永久值,或确保已配置数据库
为该属性生成值。在
Microsoft.EntityFrameworkCore.Update.Internal.CommandBatchPreparer.ValidateModificationCommand
修改命令位于
Microsoft.EntityFrameworkCore.Update.Internal.CommandBatchPreparer.BatchCommandSiredOnlyList 1
条目+移动下一步
Microsoft.EntityFrameworkCore.Update.Internal.BatchExecutor.ExecuteAsyncDbContext
_,ValueTuple2参数,CancellationToken CancellationToken位于
Microsoft.EntityFrameworkCore.Storage.ExecutionStrategy.ExecuteImplementationAsync[TState,TResult]函数4
操作,Func4验证成功,TState,CancellationToken
取消令牌在
Microsoft.EntityFrameworkCore.Storage.ExecutionStrategy.ExecuteImplementationAsync[TState,TResult]函数4
操作,Func4验证成功,TState,CancellationToken
取消令牌在
Microsoft.EntityFrameworkCore.ChangeTracking.Internal.StateManager.SaveChangesSyncirReadOnlyList`1
entriesToSave,CancellationToken CancellationToken位于
Microsoft.EntityFrameworkCore.ChangeTracking.Internal.StateManager.SaveChangesSyncBoolean
acceptAllChangesOnSuccess,CancellationToken CancellationToken位于
Microsoft.EntityFrameworkCore.DbContext.SaveChangesSyncBoolean
接受更改成功,取消令牌取消令牌
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);
}
同意@PrashantPimpale,您只需使用try-catch即可 但是对于高级方法,我建议您可以使用全局错误处理中间件。 通过它,您可以捕获整个dotnetapi/应用程序中发生的任何错误 以下是公正和详细阐述:
// 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>();
}
}
@PrashantPimpale我已经尝试使用try-catch,但错误仍然记录在数据库中无法取消-错误记录在数据库中?你能解释一下吗?@PrashantPimpale我试过下面的代码试试{return await\u context.savechangessynccancellationtoken;}catchException e{var z1=e.Message;return 0;}不过,在捕获块之前,它会被记录为数据库中的错误。数据库中已发生错误的日志记录。但我不想在数据库中记录一个特定的错误。您也可以分享您的代码吗。这将非常有用。我想您还必须在SaveAsync方法中添加try-catch,然后在异常块中抛出错误。仅供参考:正在生成错误,因为您没有将更新的实体设置为修改状态。entity.EntryUpdateUser.State=EntityState.Modified;我知道这个错误是如何产生的。实际上,我也尝试过将try-catch放在save-async方法中,但在此之前,错误仍然会记录在数据库中。
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.
}
}