C# 发生了参照完整性约束违规

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/16128664/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-10 00:05:48  来源:igfitidea点击:

A referential integrity constraint violation occurred

c#asp.net-mvcentity-framework-4

提问by Elad Benda

I'm trying to update an existing entity.

我正在尝试更新现有实体。

I have the following code:

我有以下代码:

public MamConfiguration_V1 Save(MamConfiguration_V1 item)
{
    mMaMDBEntities.MamConfiguration_V1.Attach(item);
    mMaMDBEntities.ObjectStateManager.ChangeObjectState(item, System.Data.EntityState.Modified);
    mMaMDBEntities.SaveChanges();
    return item;
}

But the Attachmethods throws an exception:

但是这些Attach方法会引发异常:

A referential integrity constraint violation occurred: The property values that define the referential constraints are not consistent between principal and dependent objects in the relationship.

发生参照完整性约束冲突:定义参照约束的属性值在关系中的主体和从属对象之间不一致。

How can I fix this?

我怎样才能解决这个问题?

采纳答案by álvaro García

What is the definition of the item object? It seems that in some of its collections that set the realionship with other entities exist some type of conflict. You could try to clear all the collections to see if the problem persists, but in this case you lost the foreign key assignment. But perhaps it could help you to locate the problem.

item 对象的定义是什么?似乎在它的一些与其他实体建立关系的集合中存在某种类型的冲突。您可以尝试清除所有集合以查看问题是否仍然存在,但在这种情况下您丢失了外键分配。但也许它可以帮助您定位问题。

This could be a tip. When I try to attach an existing entity to the context, I use to do the following:

这可能是一个提示。当我尝试将现有实体附加到上下文时,我会执行以下操作:

mMaMDBEntities.Entry<MamConfiguration>(item).State = System.Data.EntityState.Modified;

You can add the using of System.Data to avoid the needed to write it all the time.

您可以添加 System.Data 的使用,以避免需要一直编写它。

This attach the entity in the state that you want, modified in this case and track the changes. This is one line instead of two.

这会附加处于您想要的状态的实体,在这种情况下进行修改并跟踪更改。这是一行而不是两行。

回答by Mat J

Seems like you have some relationship with foreign key field and a navigation property in the item, and those fields have conflicting values. This occurs when you load an entity and its related entities, change the relationship at one end, mark only that end as Modifiedand attempt to save. Make sure you modify relationship at both ends and mark all the affected entities as Modifiedbefore calling SaveChanges.

似乎您与 中的外键字段和导航属性有某种关系item,并且这些字段具有冲突的值。当您加载实体及其相关实体、更改一端的关系、仅将该端标记为Modified并尝试保存时,就会发生这种情况。确保修改两端的关系并像Modified调用SaveChanges.

回答by drf

I encountered this exception under a different set of circumstances, and am posting here since this question comes up when the error message is searched.

我在不同的情况下遇到了这个异常,我在这里发帖是因为在搜索错误消息时出现了这个问题。

The exception was thrown when calling IObjectContextAdapter.ObjectContext.AttachTo(entitySetName, entity)with a partially-loaded entity. The foreign keys on the entity were defined, but the navigational properties were not loaded. (That is, O.ItemIDhad a value, but O.Itemwas null). The specific circumstances did not allow O.Itemto be loaded.

IObjectContextAdapter.ObjectContext.AttachTo(entitySetName, entity)使用部分加载的实体调用时抛出异常。实体上的外键已定义,但未加载导航属性。(也就是说,O.ItemID有一个值,但O.Item为空)。具体情况不允许O.Item加载。

The problem turned out to be that the Object State Manager had loaded the object in a separate method and was already tracking the object defined with the same keys. Since the separate method did not need to track the object state, the issue was resolved by calling IQueryable.AsNoTracking()within that method.

问题原来是对象状态管理器已经在一个单独的方法中加载了对象,并且已经在跟踪使用相同键定义的对象。由于单独的方法不需要跟踪对象状态,因此通过IQueryable.AsNoTracking()在该方法内调用解决了该问题。

回答by Snicklefritz

The issue for me was that entity framework had loaded my object in multiple places, so when I updated a foreign key, there were now two references to the same object, one with a foreign key pointing to record a and one with a foreign key pointing to record b, which caused an error since my relationship is one to one. To resolve it, I used context.Entry(Object).State = EntityState.Detached, reloaded the object, made the foreign key change and then saved my changes

我的问题是实体框架在多个地方加载了我的对象,所以当我更新一个外键时,现在有两个对同一个对象的引用,一个外键指向记录 a,一个外键指向记录 b,这导致了错误,因为我的关系是一对一的。为了解决这个问题,我使用了 context.Entry(Object).State = EntityState.Detached,重新加载了对象,进行了外键更改,然后保存了我的更改

回答by Migit

Lets say you have the following schema: schema

假设您有以下架构: 模式

If you want to edit the CurrentLocationId in Person, you also need to edit the CurrentLocation object embedded in the Person object. EF will automatically populate the CurrentLocation object because CurrentLocationId has a foreign key in the CurrentLocation's table. When you edit the CurrentLocationId without updating the CurrentLocation object as well, they become out of sync. This is what causes the exception in this case.

如果要编辑Person 中的CurrentLocationId,还需要编辑Person 对象中嵌入的CurrentLocation 对象。EF 将自动填充 CurrentLocation 对象,因为 CurrentLocationId 在 CurrentLocation 的表中有一个外键。当您编辑 CurrentLocationId 而不更新 CurrentLocation 对象时,它们会变得不同步。这就是在这种情况下导致异常的原因。

So let's say you needed to update the Person object's CurrentLocationId. We'll assume you pre-fetched the Person data and the Location data.

因此,假设您需要更新 Person 对象的 CurrentLocationId。我们假设您预取了 Person 数据和 Location 数据。

public class DbData 
{
    List<Person> PersonList;
    List<Location> LocationList;
    public DbData()
    {
        using (var context = new MyContext())
        {
             PersonList = context.Persons.ToList();
             LocationList = context.Locations.ToList();
        }
    }

    public void UpdatePersonLocation(Person person, int newLocationId)
    {
        using (var context = new MyContext())
        {
            var location = LocationList.Where(l=>l.id==newLocationId).Single();
            //you need to update both the id and the location for this to not throw the exception
            person.CurrentLocationId == newLocationId;
            person.CurrentLocation == location;  
            context.Entry(person).State = System.Data.Entity.EntityState.Modified;
            context.SaveChanges();
        }
    }
    //or if you're giving it the location object...
    public void UpdatePersonLocation(Person person, Location location)
    {
        using (var context = new MyContext())
        {
            //you need to update both the id and the location for this to not throw the exception
            person.CurrentLocationId == location.id;
            person.CurrentLocation == location;  
            context.Entry(person).State = System.Data.Entity.EntityState.Modified;
            context.SaveChanges();
        }
    }
}

回答by Maro

This might be an old post but the following worked for me

这可能是一个旧帖子,但以下内容对我有用

set the SaveOptions optionto SaveOptions.DetectChangesBeforeSave

设置SaveOptions optionSaveOptions.DetectChangesBeforeSave