Невозможно определить действительный порядок для зависимых операций - программирование
Подтвердить что ты не робот

Невозможно определить действительный порядок для зависимых операций

Это моя модель

public string Content { get; set; }

public Faq Reply { set; get; }

public int? ReplyId { get; set; }

public ICollection<Faq> Children { get; set; }

[ForeignKey("WriterId")]
public virtual UserProfile Writer { get; set; }

public virtual int? WriterId { get; set; }

public Status Status { get; set; }

[ForeignKey("DepartmentId")]
public virtual Department Department { get; set; }

public virtual int? DepartmentId { get; set; }

И это моя ошибка

Невозможно определить действительное упорядочение для зависимых операций. Зависимости могут существовать из-за ограничений внешнего ключа, требований к модели или сохраненных в магазине значений.

4b9b3361

Ответ 1

Другой возможной причиной этого является неправильное задание свойства внешнего ключа.

Например, это может произойти в следующем сценарии:

  • DepartmentId установлен в ноль или любое другое значение, которое не является допустимым внешним ключом.
  • Департамент имеет значение null или это объект отдела, который содержит нулевое значение для собственного свойства DepartmentId.
  • Эта конфигурация приведет к сбою Entity Framework, поскольку она пытается найти отдел с первичным ключом нуля, который, вероятно, не будет существовать.

Я столкнулся с этим исключением один раз, когда я сопоставил один объект с другим, и я неправильно установил внешний ключ в ноль, вместо того чтобы установить его на нуль.

Я не могу сказать, что эта конфигурация является тем, что вызывает ваше исключение, не видя фактических значений свойств, но это одна из возможностей.

Ответ 2

FWIW, я просто потратил утреннюю отладку аналогичной проблемы в EF 6.1. В моем случае это произошло из-за случайного смешивания объектов, принадлежащих различным контекстам: установка значения свойства навигации в объекте, принадлежащем одному контексту, с объектом, принадлежащим другому контексту.

Ответ 3

В моем случае это было вызвано вложением нового зависимого объекта внутри другого нового объекта во время создания чего-то вроде этого:

var mySecondaryObject = new MyClass1 { ... };
var myPrimaryObject = new MyClass2 { Child = mySecondaryObject, ... };
dbContext.MyClass2Collection.Add(mySecondNewOject);
dbContext.SaveChanges();

Удаление вложенной ссылки и назначение дочернего элемента после создания первичного объекта разрешило проблему.

Ответ 4

Простым способом избежать этой ошибки является создание первичного объекта сначала, SaveChanges, а затем создание зависимого объекта перед вызовом SaveChanges снова.

В этом случае создайте объект, который вы показываете выше, SaveChanges, затем создайте дочерний объект Faq, добавьте его в коллекцию и снова установите в качестве ответа, а затем SaveChanges.

Ответ 5

Вот как мы решили эту проблему. У нас есть объект, который определил sql-запрос для заполнения объектов. Этот объект имел один столбец, помеченный как ключ, и имел методы вставки, обновления и удаления CRUD. Ключ-столбец был автоматически заполнен хранимой процедурой Oracle и возвращен обратно в курсор. Мы получили эту ошибку при вставке новой строки.

После исследования и исследования мы обнаружили, что проблема заключалась в том, что вставка хранимой процедуры передавалась в качестве столбца ключа в качестве значения параметра, а также была заполнена, когда хранимая процедура возвращала обратно автоматически генерируемое значение столбца ключа.

Мы удалили параметр ключевого столбца из SP вставки и проблема была решена.

Ответ 6

Я создал проект образец, который имитирует ошибку, когда у вас есть два отношения. По сути, идея состоит в том, что у вас есть клиент со списком заказов. Затем на клиенте вы хотите сохранить дополнительное свойство, чтобы отметить текущий порядок. Это приводит к "двум" отношениям, которые структура элемента имеет проблемы с хранением и удалением в одной транзакции.

Лучше создать флаг bool "IsCurrent" для заказов и фильтровать для этого. Также возможно создать свойство или расширение для Клиента, который автоматически выполняет фильтрацию. Об этом уже говорилось в сообщении this.

Я думаю, что нет другого способа, кроме использования двух вызовов SaveChanges, что плохо, потому что тогда вы выбрасываете идею UnitOfWork.

Ответ 7

Возможно, поздно, но у меня была такая же проблема, и я решил это сделать. в случае, если есть родитель, добавьте свойство child к родительским дочерним элементам, если не просто сохраните объект.

            using (var context = new MyEntities())
            {
                child.CreatedOn = DateTime.Now;

                if (child.ParentId == null)
                {
                    context.Things.Add(child);
                }
                else
                {
                    var parent = context.Things.Where(x => x.Id == child.ParentId).SingleOrDefault();

                    if(parent == null)
                    {
                        return false;
                    }

                    parent.Things.Add(child);
                }

                context.SaveChanges();

                return true;
            }

Ответ 8

Итак, я столкнулся с этой проблемой, и хочу поделиться тем, как я ее решил, это не так просто, как дважды вызвать изменения смены, но имеет некоторые преимущества перед этим методом.

У меня была ситуация, когда я хотел, чтобы все записи были успешными или неудачными, частичные вставки детей были неприемлемыми. Я также не хотел писать код для удаления родителя, если ребенок терпит неудачу (что, если в этом коде была ошибка, что если этот код не удался и т.д.).

Во-вторых, было возможно иметь группу записей, и я хотел, чтобы все эти записи были успешными или не выполнялись в одной транзакции. По сути, я очень подробно разбираюсь в EF (моя версия EF - 6.1.3). Также я шел только на один уровень в родительском отношении, а не на произвольное количество уровней.

int tempId = -1;
int parentTempId = -1;
foreach(var record in recordsToSave)
{
    var childRecords = record.ChildRecords.ToList();

    record.ChildRecords.Clear();

    record.RecId = tempId;
    parentTempId = tempId;
    tempId--;

    _db.Records.Add(record);

    foreach(var childRecord in childRecords)
    {
        childRecord.RecId = tempId;
        childRecord.ParentRecId = parentTempId;
        tempId--;
        _db.Records.Add(childRecord);
    }
}

using (TransactionScope tran = new TransactionScope())
{
    _db.SaveChanges();
    tran.Complete();
}
  • Сначала я очистил дочернюю коллекцию и скопировал ее во временный список. У EF были проблемы с моими отношениями.
  • Я создал временный идентификатор и назначил его родительской записи и сохранил его для последующего использования с дочерними элементами.
  • Я вручную связал ребенка с родителем - через мои временные идентификаторы.

Он работал, и он также вставлял мои данные визуально привлекательным способом (по крайней мере для меня) введите описание изображения здесь

Ответ 9

Это случилось со мной. EF 6.1/MVC

IN: public ActionResult Create (OfficeRecordModel officeData)

Имеем:

Office newOffice = new Office();
newOffice.Parent = officeData.Parent;
newOffice.Level = officeData.Level != null ? officeData.Level.Value : -1;
newOffice.ShortName = officeData.ShortName.Trim();
newOffice.LongName = officeData.LongName.Trim();
newOffice.IsActive = officeData.IsActive;                        
dbCtxt.Office.Add(newOffice);
dbCtxt.SaveChanges();

Бум я получаю: { "Невозможно определить допустимый порядок для зависимых операций. Зависимости могут существовать из-за ограничений внешнего ключа, требований к модели или значений, созданных магазином".}

Офис:

public int ID { get; set; }
public Nullable<int> Parent { get; set; }
public int Level { get; set; }
public string ShortName { get; set; }
public string LongName { get; set; }
public bool IsActive { get; set; }

В таблице Office указан идентификатор личности, который мы не задаем. Итак, EF использует 0. Ну, у нас есть запись ID = 0 в таблице Office (корневой офис для нас в этой рекурсивной таблице саморекламы).

Чтобы устранить это, мы устанавливаем идентификатор Identity равным -1. Так что больше не конфликт в существующем ключе. -1 в конечном счете игнорируется и устанавливается личность.

Добавление: newOffice.ID = -1; сделал трюк.

Ответ 10

У меня был класс сущности с самореферентным свойством навигации. Если свойство внешнего ключа было установлено равным нулю, оно завершилось ошибкой.

Если я установлю для него другое недопустимое значение, например -1, или другое значение, которое не существует в базе данных, эта ошибка НЕ будет получена. Если я изменил свойство навигации, чтобы ссылаться на неправильный объект (чтобы он не был самоссылкой), он НЕ получил эту ошибку, даже используя ноль.

Так что, по-видимому, EF делает что-то особенное с нулями для ссылок на свойства навигации. Я знаю, что отношение было определено правильно, потому что мой запрос, который использует его, вывел правильные данные.

Я смог решить мою проблему, используя ноль вместо нуля. Во всяком случае, это было действительно правильное значение для меня.