当数据已经在数据库中时,EF种子不工作 [英] EF Seed not working when data already in database

查看:104
本文介绍了当数据已经在数据库中时,EF种子不工作的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

首次创建数据库并运行 Seed 方法工作正常。当数据已经在数据库中时,它会在第二次运行时抛出错误。

First time creating DB and running Seed method works fine. It throws error on second run when data is already in the database.

我还注意到,当我将属性分配给实体时,它的 PropertyId 不更新并保持为空。

I also noticed that when I assign property to entity, its PropertyId is not updated and stays null.

这是我的代码。

protected override void Seed(StreetStats.Data.StreetStatsDbContext context)
{
    if (System.Diagnostics.Debugger.IsAttached == false)
        System.Diagnostics.Debugger.Launch();

    using (context.Database.BeginTransaction())
    {
        try
        {
            Worker worker = new Worker()
            {
                Name = "Worker 1",
            };

            context.Workers.AddOrUpdate(w => w.Name, worker);
            context.SaveChanges(); //Worker gets Id assigned to the existing worker with the same name in DB

            Job job = new Job()
            {
                Name = "Job 1",                     
                Worker = worker
            };

            context.Jobs.AddOrUpdate(j => j.Name, job);
            context.SaveChanges(); //WorkerId is null for some reason

            MonitoringTask monitoringTask = new MonitoringTask
            {
                Job = job,
                Name = "Task 1"                     
            };

            context.MonitoringTasks.AddOrUpdate(mt => mt.Name, monitoringTask);
            context.SaveChanges(); //Throws exception

            Area area = new Area
            {
                MonitoringTask = monitoringTask,
                Name = "Area 1"                     
            };

            context.Areas.AddOrUpdate(a => a.Name, area);
            context.SaveChanges();

            context.Database.CurrentTransaction.Commit();
        }
        catch (Exception)
        {
            context.Database.CurrentTransaction.Rollback();
            throw;
        }
    }
}

这是第三个异常消息SaveChanges:

This is exception message on third SaveChanges:


UPDATE语句与FOREIGN KEY约束FK_dbo.MonitoringTasks_dbo.Jobs_JobId冲突。冲突发生在数据库StreetStats中,表dbo.Jobs,列Id。

The UPDATE statement conflicted with the FOREIGN KEY constraint "FK_dbo.MonitoringTasks_dbo.Jobs_JobId". The conflict occurred in database "StreetStats", table "dbo.Jobs", column 'Id'.

每个FK关系看起来像/ p>

Every FK relation looks like

Worker Worker { get; set; }
Int64 WorkerId { get; set; }


推荐答案

查看实体状态 job 之后的 AddOrUpdate 调用。你可以这样做:

Look at the entity state of job after its AddOrUpdate call in the second run. You can do this like so:

Debug.WriteLine(context.Entry(job).State);

你会看到它是分离的。但是,如果你这样做...

You'll see that it's Detached. Still, if you do ...

Debug.WriteLine(context.Jobs.Local.First().Name);

...你会看到现实中的工作是附加在上下文中的!

... you'll see that in reality the job is attached to the context!

这是<$ c $中的已知错误 C> AddOrUpdate 。实际上附加到上下文的实例从您的方法范围中隐藏起来,而 job 是EF不知道的第二个实例。

This a known bug in AddOrUpdate. The instance that's actually attached to the context is hidden from your method scope, and job is a second instance that EF doesn't know of.

导致各种苦难。您与 monitoringTask 连接的工作将被视为新实例,EF将尝试插入。我不知道为什么你会得到一个外键异常(我会期望一个唯一的键违规),但我认为这与主键列类型有关,以及它是否具有标识规范。

That causes all kinds of misery. The job you connect with monitoringTask will be seen as a new instance and EF will try to insert it. I'm not sure why you get a foreign key exception (I would have expected a unique key violation) but I think that has to do with primary key column type and whether or not it has an identity specification.

无论如何,解决方法是做...

Anyway, the work-around is to do ...

context.Workers.AddOrUpdate(w => w.Name, worker);
context.SaveChanges();
worker = context.Workers.Local.Single(w => w.Name == worker.Name);

...等等,对于每个 AddOrUpdate 以后打算使用对象的调用。这使得实际附加(但隐藏)的对象与您可见的对象相等。

... and so on, for each AddOrUpdate call of which you intend to use the objects later. This makes the actually attached (but hidden) objects equal to the ones visible to you.

这篇关于当数据已经在数据库中时,EF种子不工作的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆