C# 实体框架声称保存更改,但有时不保存';T
我有一个非常奇怪的问题-有时我的数据库无法填充计划和存储桶,然后在试图将任务保存到数据库时抛出最后显示的异常。其他时候,代码可以完美地工作。如果能深入了解为什么会这样,我将不胜感激。这可能是delete命令的时间问题吗C# 实体框架声称保存更改,但有时不保存';T,c#,asp.net-mvc,entity-framework,C#,Asp.net Mvc,Entity Framework,我有一个非常奇怪的问题-有时我的数据库无法填充计划和存储桶,然后在试图将任务保存到数据库时抛出最后显示的异常。其他时候,代码可以完美地工作。如果能深入了解为什么会这样,我将不胜感激。这可能是delete命令的时间问题吗 EntitiesModelContainer db = new EntitiesModelContainer(); List<Plan> ignoredPlans = db.Plans.Where(p => p.Ignore).ToList(); // De
EntitiesModelContainer db = new EntitiesModelContainer();
List<Plan> ignoredPlans = db.Plans.Where(p => p.Ignore).ToList();
// Delete old data completely
// foreign keys will cascade delete some tables such as buckets and tasks
db.Database.ExecuteSqlCommand("DELETE FROM Plans");
db.Database.ExecuteSqlCommand("DELETE FROM Assignees");
PlansResponse plans = GraphAPI.GetPlans();
foreach (PlanResponse plan in plans.Plans)
{
Plan planRecord = new Plan()
{
Id = plan.ID,
Title = plan.Title,
Ignore = ignoredPlans.Find(p => p.Id == plan.ID) != null
};
db.Plans.Add(planRecord);
bool changes = db.ChangeTracker.HasChanges();
int result = db.SaveChanges();
if (!planRecord.Ignore)
{
BucketsResponse buckets = GraphAPI.GetBuckets(plan);
foreach (BucketResponse bucket in buckets.Buckets)
{
Bucket bucketRecord = new Bucket()
{
Id = bucket.ID,
Name = bucket.Name,
PlanId = bucket.PlanID
};
db.Buckets.Add(bucketRecord);
db.SaveChanges();
}
TasksResponse tasks = GraphAPI.GetTasks(plan);
foreach (TaskResponse task in tasks.Tasks)
{
Task taskRecord = new Task()
{
Id = task.ID,
Title = task.Title,
Progress = task.PercentComplete,
Description = task.HasDescription ? GraphAPI.GetTaskDetails(task).Description : null,
CreatedDateTime = task.CreatedDateTime,
DueDateTime = task.DueDateTime,
CompletedDateTime = task.CompletedDateTime,
PlanId = task.PlanID,
BucketId = task.BucketID
};
db.Tasks.Add(taskRecord);
db.SaveChanges();
上面发布的代码片段是这个方法的开始,因为它抱怨外键PlanId(我猜是这样),所以我认为gettask以某种方式返回了一个不正确的PlanId 为了弄清真相,我设置了一个探查器会话,并在出现错误时检查SQL语句。或者在异常发生时只检查调试器中的对象。这些属性的值应该提供一个关于发生了什么的线索 编辑:我刚刚注意到你的第一行写着“有时它无法填充计划和任务”,但没有注意到。我不明白如果无法保存计划,它将如何继续,但SQL profiler会话可能能够回答这个问题
事后编辑:当然,最简单的答案可能是并发,特别是如果这是一个web应用程序,两个请求可能会同时传入并重叠。任务是否可以有空的
PlanID
(为什么有时可能会工作)?顶部的删除看起来可疑,您是否应该将PlanID
设置为新创建的planRecord
?无论哪种方式,您都将其设置为一个不再存在的计划,以便级联可能在某个地方不起作用(例如,假设它将失效的计划作为任务
和存储桶
)的外键作废)代码>在删除现有记录之前看起来可疑,因为现有实体实例仍将被上下文跟踪(尽管在这种情况下db.Plans.Add(planRecord);
应引发异常)。尝试使用无跟踪查询,例如db.Plans.AsNoTracking().Where(p=>p.Ignore.ToList()代码>是的,这就是让我如此困惑的原因。通过调试,我可以看到整数结果
返回1
,表示应该添加计划。但是,只有在出现异常时,计划才会保留在db.Plans.Local中-有时这会起作用,当我设置断点尝试调试时,它似乎会起作用。请注意,不会引发异常,代码会继续,就好像它已经成功一样。也许删除会覆盖它?我想不出有哪种情况下删除会在添加之后执行。而且看起来您并不是在手动处理连接详细信息或事务,所以也不可能是这样。可能应用程序的多个线程或实例同时执行此操作,并且它们重叠?不管怎样,我想它一定是这个代码之外的东西。嘿,我发布了我的问题的更新。问题已经解决了,但如果你能告诉我原因,我将不胜感激!啊,我知道这毕竟是一个并发问题。如果这是一个web应用程序,那么它很简单,同时有两个请求:)计划将始终具有有效的ID-它们来自Microsoft的Graph API,即Planner部分。
public class DBController : Controller
{
public ActionResult Index()
{
DBAccess.UpdateData();
return View();
}
}