在表上引入 FOREIGN KEY 约束可能会导致循环或多个级联路径导致 Database.SetInitializer 不起作用? [英] Introducing FOREIGN KEY constraint on table may cause cycles or multiple cascade paths causing Database.SetInitializer to not work?

查看:25
本文介绍了在表上引入 FOREIGN KEY 约束可能会导致循环或多个级联路径导致 Database.SetInitializer 不起作用?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我的代码优先数据库运行良好.如果我对数据库上下文进行了更改,则下次启动应用程序时数据库将更新.但是后来我向数据库中添加了一些模型,并在重新启动应用程序时出现此错误:

My code-first database was working great. If I made a change to my database context the database would be updated the next time I started the application. But then I added some models to the database and got this error when I restarted my application:

在表 'OrderDetails' 上引入 FOREIGN KEY 约束 'FK_OrderDetails_Orders_OrderId' 可能会导致循环或多个级联路径.指定 ON DELETE NO ACTION 或 ON UPDATE NO ACTION,或修改其他 FOREIGN KEY 约束.无法创建约束.查看以前的错误.

一件奇怪的事情是,如果我在不更改任何内容的情况下再次启动应用程序,则会收到此错误:

One of the weird things is that if I start the application up again without changing anything, I then get this error:

无法检查模型兼容性,因为数据库不包含模型元数据.只能检查使用 Code First 或 Code First Migrations 创建的数据库的模型兼容性.

为了让第一个错误再次发生,我必须删除我的 .mdf 和 .ldf 文件(数据库),并只用我的修订历史记录中的副本替换 .mdf 文件.

To get the first error to happen again, I have to delete my .mdf and .ldf files (the database) and replace just the .mdf file with a copy from my revision history.

为什么会发生这种情况?

供参考:

我的 Global.asax.cs 文件在 Application_Start() 方法中有这个:

My Global.asax.cs file has this within the Application_Start() method:

Database.SetInitializer(new EfDbContextInitializer());

看起来像这样:

public class EfDbContextInitializer : DropCreateDatabaseIfModelChanges<EfDbContext>
{
    protected override void Seed(EfDbContext context)
    {
        var orders = new List<Order>
            {
                . . .
            };
        orders.ForEach(s => context.Orders.Add(s));
         . . . etc. . .
        context.SaveChanges();
    }
}

我来自 Web.config 的连接字符串:

My connection string from Web.config:

<add name="EFDbContext" connectionString="data source=.SQLEXPRESS;Integrated Security=SSPI;database=pos;AttachDBFilename=|DataDirectory|pos.mdf;MultipleActiveResultSets=true;User Instance=true" providerName="System.Data.SqlClient"/>

最后,我的 Order 和 OrderDetails 模型(第一个错误是直接引用的):

And, finally, my Order and OrderDetails models (what the first error is directly referencing):

public class Order
{
    public int OrderId { get; set; }

    public List<OrderDetail> OrderDetails { get; set; }

    public int EstablishmentId { get; set; }

    public virtual Establishment Establishment { get; set; }
}

public class OrderDetail
{
    public int OrderDetailId { get; set; }

    public int OrderId { get; set; }

    public int ProductId { get; set; }

    public int Quantity { get; set; }

    public decimal UnitPrice { get; set; }

    public virtual Product Product { get; set; }

    public virtual Order Order { get; set; }
}

更新/注意:如果我注释掉 public int OrderId { get;放;} 在我的 OrderDetail 类中,项目启动良好(尽管我没有获得添加 OrderId 的所需能力(当然).

Update / Note: If I comment out public int OrderId { get; set; } in my OrderDetail class, the project starts up fine (although I do not get the desired ability to add an OrderId (of course).

推荐答案

此问题是由可能的循环级联删除引起的.这可能以多种形式发生,但归结为一次被两个或多个级联删除规则删除的记录.

This problem is caused by a possible cyclic cascading delete. This can happen in many forms, but it comes down to a record being deleted by two or more cascading delete rules in one time.

例如,假设您有父表和两个子表.然后你还有另一个表链接到两个子表:

For example, lets say you have Parent table and two Child tables. Then you also have another table which is linked to both Child tables:

Parent
------
ParentId
Name

ChildOne
--------
ChildOneId
ParentId
Name

ChildTwo
--------
ChildTwoId
ParentId
Name

SharedChild
-----------
SharedChildId
ChildOneId
ChildTwoId
Name

当您从父表中删除记录时,此删除操作可能会级联到 ChildOne ChildTwo.这两个删除可以进一步级联到 SharedChild,这里我们遇到了问题:两条路径试图从 SharedChild 中删除相同的记录.

When you delete a record from the Parent table, it is possible this delete will cascade to both ChildOne and ChildTwo. These two deletes can then further cascade to SharedChild and here we get the problem: two paths trying to delete the same record from SharedChild.

我并不是说您的情况完全相同,但无论如何,您都会遇到类似的情况.为了解决这个问题,您可以决定让一个分支在链中进一步向下级联,并在另一条链中阻止它.

I'm not saying your situation is exactly the same, but one way or another, you have something similar going on. To solve this, you can decide to let one branch be allowed to cascade further down the chain and prevent it in the other chain.

您仅在第一次运行应用程序时出现此错误的原因,然后每次删除数据库时,是因为(我相信)实体框架在发生错误时停止生成数据库,并且您留下不完整的数据库.这就是您在其他情况下遇到其他错误的原因.

The reason you get this error only the first time you run your app and then every time you delete the database, is because (I believe) Entity Framework stops generating the database at the point the error occurs and you are left with an incomplete database. That's why you're getting the other error in the other situations.

如果您需要更多帮助来解决循环级联删除问题,您可能需要展示整个数据模型及其关系.

If you need more help resolving the cyclic cascading delete, you will probably need to show your entire datamodel and its relations.

这篇关于在表上引入 FOREIGN KEY 约束可能会导致循环或多个级联路径导致 Database.SetInitializer 不起作用?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

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