首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >崩溃时EF6缓存本地数据

崩溃时EF6缓存本地数据
EN

Stack Overflow用户
提问于 2016-01-06 19:29:34
回答 1查看 102关注 0票数 0

我试图找出究竟是什么导致了这个错误:

INSERT语句与外键约束"FK_dbo.Draft_dbo.GameEvent_GameEventId“冲突。冲突发生在数据库"Azularis“、表"dbo.GameEvent”、列'Id‘中。声明已被终止。

现在的问题是,在我的数据库中,当我运行select语句时,表GameEvent是空的。下面是导致错误的代码

代码语言:javascript
复制
for (var i = 0; i < totalTeams / 2; i++)
{
    var game = new GameEvent
    {
        GameOrderNo = i + 1,
        EventId = eventId,
        RoundNo = 1
    };
    Db.GameEvents.Add(game);
}
if (await Db.SaveChangesAsync() > 0) //It crashes here
{
    Db.Drafts.Add(CreateDraft(teamIds.First(), game.Id, -1, 1));
    await Db.SaveChangesAsync() > 0
}

上面的逻辑是不完整的,因为我还在开发它,但是崩溃发生在if (await Db.SaveChangesAsync() > 0)上。

现在,如果我删除数据库并运行它,它没有问题,记录被保存并且没有错误。如果由于任何原因,代码崩溃,而我去删除记录并再次运行,我将得到上面的错误。

我注意到的是,如果我在Db.Draft上悬停,然后查看,它仍然有记录,它没有从缓存中转储它们,而且我假设它试图编写相同的PK两次,这样它就崩溃了。

这是我的理论,我不明白,任何帮助都是非常感谢的。

编辑:我的另一种理论(我认为比第一种理论更有可能)是草稿被缓存,并且它试图写入这些记录,而且由于GameEvent是空的,所以它不能插入,因为没有要引用的主键。

因此,如何在代码崩溃时强制它转储这个缓存?在生产环境中,如果无论出于什么原因,没有人能够插入更多的数据。

对于我来说,克服上述错误的唯一方法是删除并重新创建数据库。

编辑2:

下面是我复制的方式:我从新数据库开始,运行一次。代码将在Db.Drafts.Add上起草,因为teamId将为null。然后我回到数据库,截断草案表,然后从GameEvent表中删除所有记录。

我再次运行代码,这次它在这个简单的测试场景中失败了:

代码语言:javascript
复制
var test = new GameEvent
{
   GameOrderNo = 1,
   EventId = new Guid("1e48bd5b-58ab-e511-a551-e03f497d18e0"),
   RoundNo = 1
};

Db.GameEvents.Add(test);
await Db.SaveChangesAsync();

编辑3:

架构由以下代码生成:

代码语言:javascript
复制
public class GameEvent
{
    [Key, DatabaseGenerated(DatabaseGeneratedOption.Identity)]
    public Guid Id { get; set; }
    public Guid EventId { get; set; }
    public int GameOrderNo { get; set; }
    public int RoundNo { get; set; }
}

public class Draft
{
    [Key, DatabaseGenerated(DatabaseGeneratedOption.Identity)]
    public Guid Id { get; set; }
    public Guid TeamId { get; set; }
    public Guid GameEventId { get; set; }
    public double Score { get; set; }
    public int Placement { get; set; }
    public virtual Team Team { get; set; }
    public virtual GameEvent GameEvent { get; set; }
}
EN

回答 1

Stack Overflow用户

回答已采纳

发布于 2016-01-06 21:18:41

这是因为Db的寿命太长了。,您应该使用,从不使用静态上下文

当您第一次创建DraftGameEvent时,EF首先将新对象作为Added保存在缓存中,在保存它们之后,它们就是Unchanged

现在,您从数据库中删除所有内容,并再次执行相同的操作。您将创建将标记为Added但与仍处于缓存中的实体关联为Unchanged的新实体。现在EF只为Added实体发出Added语句,而不是为Unchanged实体发出Unchanged语句。但是插入的记录确实有FK指向您刚刚手动删除的记录。

从您的描述来看,很难了解到底发生了什么,但是我相信,如果您为每个数据库交互使用一个新的上下文,那么您就不会有麻烦了。

票数 1
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/34641230

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档