如何解决实体框架在出错后“丢失”了一行,仍然可以导航到行详细信息
我在工作中处理的一个应用程序有一个有趣的错误,我们无法追踪,我在搜索中找不到任何类似的东西。
我的公司建立了一个帮助台系统来跟踪用户问题,在提交错误后,该票从所有票的列表中“消失”了。它在数据库中仍然可见,并且没有在任何地方被过滤掉。可以通过将 URL 更改为票证 ID 来导航到票证,所有详细信息都与保存错误之前相同。
我们最终通过重新启动网络应用解决了这个问题,但我们想追踪该行从列表中消失的原因。
我继承了这个应用程序,它有很多我们已经意识到的问题,所以我倾向于需要从头开始重建整个事情以使保存方法完全异步而不是一半- 我们目前拥有的一半。
不确定要发布什么代码作为示例,因为它在绝大多数情况下都有效,但显然其中有些不对劲。
[HttpPost]
public async Task<ActionResult> Edit(EditTicketviewmodel ticket)
{
try
{
var tech = (ticket.Technician_ID != null) ? this.UserService.Get(ticket.Technician_ID) : this.UserService.Get(this.User.Identity.GetUserId());
var cust = this.UserService.Get(ticket.Customer_ID);
var ogticket = this.TicketService.Get(ticket.Id);
var dateEdited = DateTime.UtcNow;
var productVersionId = OrganisationService.GetorgProduct(ticket.OrgId,true).First(x => x.ProductID == ticket.ProductID).Product_Version.Id; ;
await this.TicketService.Edit(ticket.Id,ticket.Title,ticket.Description,dateEdited,ticket.Date_Closed,ticket.Customer_ID,ticket.State_Code,ticket.Priority_Code,ticket.Technician_ID,ticket.ProductID,productVersionId,ticket.Ticket_Type_ID);
if (ticket.State_Code == (int)StateCode.Closed)
{
await this.IntegrationService.SendEmailAsync(new EmailProperties()
{
Email = cust.Email,Subject = "Ticket Closed",Body = "Your ticket '{ticket.Title}' has Now been closed.\n\n"//+
//$"Log into the portal to view it Now -> <a href='https://helpdesk.rubixx.co.uk/Ticket/Details/{ticket.Id}'>Ticket {ticket.Id}</a>"
});
await this.IntegrationService.PrepareTeamsMessageAsync(new MessageProperties()
{
Summary = $"{this.UserService.Get(this.User).FullName} has closed a ticket",Ticket_Id = ticket.Id,Note_Id = null,Type = TeamsMessageType.Closed
});
}
else await this.IntegrationService.PrepareTeamsMessageAsync(new MessageProperties()
{
Summary = $"{this.UserService.Get(this.User).FullName} has updated a ticket",Type = TeamsMessageType.Updated
});
this.TicketService.CreateTimelineEvent(ticket.Id,this.User.Identity.GetUserId(),DateTime.UtcNow.ToLocalTime(),"",TimelineEventType.TicketEdited);
this.AddToastMessage("Success","Edited Successfully",ToastType.Success);
return Redirect(ticket.ReturnUrl);
}
catch (Exception ex)
{
this.IntegrationService.LogMessage($"Exception occurred: {ex.Message}");
this.AddToastMessage("Error: ","An internal error has occurred",ToastType.Error);
return this.Redirect("/");
}
}
以及实际保存更改的服务函数:
public async Task Edit(int ID,string Title,string Description,DateTime? dateedited,DateTime? dateclosed,string CustomerId,int StateCode,int Prioritycode,string TechnicianId,int Productid,int? productVersionId,int ticketType = (int)TicketTypeEnum.Support)
{
var originalTicket = Context.Tickets.Find(ID);
originalTicket.Title = Title;
originalTicket.Technician_ID = TechnicianId;
originalTicket.State_Code = ticketType == (int)TicketTypeEnum.FeatureRequest ? (int)Enums.StateCode.FeatureSuggestion : StateCode;
originalTicket.Priority_Code = ticketType == (int)TicketTypeEnum.FeatureRequest ? (int)PriorityCode.FeatureSuggestion : Prioritycode;
originalTicket.Description = Description;
originalTicket.Date_Edited = dateedited;
originalTicket.Date_Closed = dateclosed;
originalTicket.Customer_ID = CustomerId;
originalTicket.ProductID = Productid;
originalTicket.Product_Version_ID = productVersionId;
originalTicket.Ticket_Type_ID = ticketType;
await Context.SaveChangesAsync();
}
这是 CreateTimelineEvent 代码:
public void CreateTimelineEvent(int ticketno,string raisedby,DateTime dateadded,string details,TimelineEventType type,string assignedto = null)
{
try
{
var timelineEvent = new TimelineEvent()
{
Ticket_Number = ticketno,Raised_By = raisedby,DateAdded = dateadded,Details = details,Type = (int)type,Assigned_To = assignedto
};
Context.TimelineEvents.Add(timelineEvent);
Context.SaveChanges();
}
catch (Exception ex)
{
throw ex;
}
}
GetTickets 函数:
public IEnumerable<Ticket> GetTickets(FilterType type,string current_user_id,TicketTypeEnum ticketType = TicketTypeEnum.Support)
{
IEnumerable<Ticket> tickets = null;
switch (ticketType)
{
case TicketTypeEnum.Support:
tickets = Context.Tickets.Include(e => e.Tech).Include(e => e.Customer).SupportTickets();
break;
case TicketTypeEnum.FeatureRequest:
tickets = Context.Tickets.Include(e => e.Tech).Include(e => e.Customer).FeatureRequestTickets();
break;
default:
tickets = Context.Tickets.Include(e => e.Tech).Include(e => e.Customer);
break;
}
switch (type)
{
case FilterType.OpenTickets:
return tickets.OpenTickets();
case FilterType.ClosedTickets:
return tickets.ClosedTickets();
case FilterType.MyOpenTickets:
return tickets.MyOpenTickets(current_user_id);
case FilterType.OpenedToday:
return tickets.OpenedToday();
case FilterType.Duetoday:
return tickets.Duetoday();
default:
return tickets;
}
}
解决方法
很抱歉花了这么长时间才回到这个问题,但在我发布这篇文章后不久,我设法将问题追溯到一个创建 DBContext 静态实例的本土依赖注入系统。
我们决定在 .Net Core 中重写系统以利用内置的依赖注入。
版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。