实体框架声称保存更改但有时不保存

时间:2018-01-04 17:07:46

标签: c# asp.net-mvc entity-framework

我有一个非常奇怪的问题 - 有时我的数据库无法填充计划和存储桶,然后在尝试将任务保存到数据库时抛出最后显示的异常。其他时候代码完美无缺。我很感激任何有关为什么这样做的见解。这可能是删除命令的计时问题吗?

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();

最后一行是发生错误的地方。

  

SqlException:INSERT语句与FOREIGN KEY约束“FK_PlanTask”冲突。冲突发生在数据库“Dashboard-dev”,表“dbo.Plans”,列“Id”中。声明已经终止。

奇怪的是,它并不总是扔!任何帮助将不胜感激。

更新:你说得对 - 看起来代码同时运行了两次。为什么?我没有(故意)意味着这样做......

public class DBController : Controller
{
    public ActionResult Index()
    {
        DBAccess.UpdateData();
        return View();
    }
}

上面发布的代码段是此方法UpdateData()的开头。

2 个答案:

答案 0 :(得分:2)

由于它抱怨外键PlanId(我猜),我会说GetTasks以某种方式返回错误的PlanId。

要了解它的底部,我将设置一个探查器会话,并在出现错误时检查SQL语句。或者只是在异常发生时检查调试器中的对象,我猜。属性的值应该给出了发生了什么的线索。

编辑:我刚注意到你的第一行说'有时它没有填充计划和任务',错过了。我不明白如果它无法保存计划会如何继续,但SQL分析器会话可能能够回答这个问题。

事后编辑:当然最简单的答案可能是并发,特别是如果这是一个Web应用程序,两个请求可能同时进入并重叠。

答案 1 :(得分:0)

任务是否可以为空PlanID(为什么它有时会起作用)?顶部的删除看起来很可疑,您是否应该将PlanID设置为新创建的planRecord?无论哪种方式,您都将其设置为不再存在的计划,因此级联可能无法在某处工作(例如,它应该将死计划作为TaskBucket的外键取消。 / p>