我是小型企业的唯一开发人员,我在asp.net mvc应用程序中继承了一些遗留代码,基本上将一个实体从一个业务部门“重新路由”到另一个业务部门。主实体具有“步骤”对象的集合,并且为了实现期望的“重新路由”功能,该动作向该集合添加了几个步骤并设置了其他步骤的属性。这是代码:
[HttpPost]
[ValidateAntiForgeryToken]
public async Task<ActionResult> Re_Route_TIR(int tir_id, double this_step, int group_id, string routing_reason, int re_route_group_id, int selected_opportunity_code, string opportunity_code_comment)
{
TIR_OV_Helper helper = new TIR_OV_Helper();
tir_departments department = db.tir_departments.FirstOrDefault(x => x.department_id == group_id);
tir_tir_steps currentStep = db.tir_tir_steps.Where(x => x.tir_id == tir_id).OrderBy(x => x.tir_step).FirstOrDefault(x => x.tir_step_date == null);
try
{
var user_id = System.Web.HttpContext.Current.User.Identity.GetUserId();
tir_tirs tir = db.tir_tirs.FirstOrDefault(x => x.tir_id == tir_id);
var original_step = tir.steps.OrderBy(x => x.tir_step).FirstOrDefault(o => o.tir_step_date == null);
original_step.tir_step_date = DateTime.Now;
original_step.assignedUserId = user_id;
original_step.tir_step_state_id = 4;
List<tir_tir_steps> steps = db.tir_tir_steps.Where(x => x.tir_id == tir_id).ToList();
foreach (tir_tir_steps step in steps)
{
if (step.tir_step > original_step.tir_step)
{
step.tir_step += 20;
}
}
tir_tir_steps newstep = new tir_tir_steps();
tir_tir_steps routedstep = new tir_tir_steps();
newstep.tir_step = original_step.tir_step + 10;
newstep.tir_department_id = re_route_group_id;
newstep.tir_operation_id = 33;
newstep.tir_step_state_id = 8;
newstep.tir_id = tir_id;
newstep.tir_department = db.tir_departments.FirstOrDefault(x => x.department_id == re_route_group_id);
tir.steps.Add(newstep);
routedstep.tir_step = newstep.tir_step + 10;
routedstep.tir_id = tir_id;
routedstep.tir_department_id = original_step.tir_department_id;
routedstep.tir_operation_id = original_step.tir_operation_id;
routedstep.tir_department = db.tir_departments.FirstOrDefault(x => x.department_id == original_step.tir_department_id);
tir.steps.Add(routedstep);
helper.SetNextStep(8, tir_id); // if no resource then 8 = "waiting"
var previously_with_dept_id = re_route_group_id;
var currently_with_dept_id = helper.GetCurrentStepGroupId(tir_id); //GetCurrentStepDepartmentId(tir_id);
tir.current_operation_id = 33; // db.tir_operations.Find(operation_id);
tir.current_dept_group_id = re_route_group_id;
tir.currently_with = "Open";
////
tir_tir_opportunity opportunity_code_data = new tir_tir_opportunity
{
tir_id = tir_id,
tir_oppt_id = selected_opportunity_code,
opptUserId = User.Identity.GetUserId(),
oppt_report_date = DateTime.Now,
oppt_report_group_id = department.department_id,
opp_code_reason = opportunity_code_comment,
operation = "Re-Route"
};
tir_comments dcomment = new tir_comments();
dcomment.comment_date = DateTime.Now;
dcomment.comment_user_name = User.Identity.GetFullName();
dcomment.comment_text = opportunity_code_comment;
dcomment.department_id = group_id;
dcomment.department_name = db.tir_departments.SingleOrDefault(x => x.department_id == group_id).department_name;
dcomment.tir_id = tir_id;
tir.department_comments.Add(dcomment);
db.tir_tir_opportunity.Add(opportunity_code_data);
await db.SaveChangesAsync();
return RedirectToAction("Index", "Dashboard", new { id = tir_id });
}
catch (Exception ex)
{
//...
}
}
我知道这是一个非常丑陋且漫长的动作,需要重构,但是当我在我的机器上运行它时,它会正常工作。但是,一些测试此代码的用户遇到了空引用异常。这是错误消息:
Error Message - at System.Data.Entity.Core.Objects.DataClasses.RelatedEnd.GetOtherEndOfRelationship(IEntityWrapper wrappedEntity) at System.Data.Entity.Core.Objects.EntityEntry.AddRelationshipDetectedByForeignKey(Dictionary`2 relationships, Dictionary`2 principalRelationships, EntityKey relatedKey, EntityEntry relatedEntry, RelatedEnd relatedEndFrom) at System.Data.Entity.Core.Objects.EntityEntry.DetectChangesInForeignKeys() at System.Data.Entity.Core.Objects.ObjectStateManager.DetectChangesInForeignKeys(IList`1 entries) at System.Data.Entity.Core.Objects.ObjectStateManager.DetectChanges() at System.Data.Entity.Internal.InternalContext.GetStateEntries(Func`2 predicate) at System.Data.Entity.DbContext.GetValidationErrors() at System.Data.Entity.Internal.InternalContext.SaveChangesAsync(CancellationToken cancellationToken) at System.Data.Entity.Internal.LazyInternalContext.SaveChangesAsync(CancellationToken cancellationToken) at System.Data.Entity.DbContext.SaveChangesAsync() at TIR_Sandbox_New.Controllers.LevelCompleteController.<Re_Route_TIR>d__6.MoveNext()
我假设这是Entity Framework中的某种竞争条件,但我对Entity Framework相当新。我认为实体框架中的某些线程没有足够快地完成这些测试人员,这就是为什么它会破坏它们。如何解决问题并使其适用于所有用户?另外,我如何在将来避免类似的问题?任何帮助将不胜感激!
我猜测tirs和步骤之间的关系也可能是相关的,所以我也发布了这些关系。
public class tir_tirs
{
public tir_tirs()
{
this.steps = new HashSet<tir_tir_steps>();
...
}
public virtual ICollection<tir_tir_steps> steps { get; set; }
}
public class tir_tir_steps
{
[Key]
public int tir_steps_id { get; set; }
public int tir_id { get; set; }
[ForeignKey("tir_id")]
public virtual tir_tirs tir { get; set; }
public Nullable<double> tir_step { get; set; }
public Nullable<System.DateTime> tir_step_date { get; set; }
public int? tir_step_state_id { get; set; }
[ForeignKey("tir_step_state_id")]
public virtual tir_steps_status tir_step_state { get; set; }
}