Не удается обновить EntitySet-потому что он имеет DefiningQuery и не существует элемента



Я использую Entity Framework 1 с .net 3.5.



Я делаю что-то простое, вроде этого:



var RoomDetails = context.Rooms.ToList();

foreach (var Room in Rooms)
{
Room.LastUpdated = DateTime.Now;
}


Я получаю эту ошибку, когда я пытаюсь сделать:



 context.SaveChanges();


Я получаю ошибку:




не удалось обновить EntitySet-потому что он имеет DefiningQuery и нет элемент существует в элемент для поддержки текущей операции.




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



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

637   18  

18 ответов:

обычно это происходит по одной из следующих причин:

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

после этого вам все равно может потребоваться обновить конструктор Entity Framework (или удалить объект, а затем добавить его), прежде чем вы перестанете получать ошибку.

просто добавьте первичный ключ в таблицу. Вот и все. Проблема решена.

ALTER TABLE <TABLE_NAME>
ADD CONSTRAINT <CONSTRAINT_NAME> PRIMARY KEY(<COLUMN_NAME>)

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

  1. щелкните правой кнопкой мыши на файле edmx, выберите Открыть с помощью, XML editor
  2. найдите объект в элементе edmx:StorageModels
  3. удалить DefiningQuery
  4. переименовать store:Schema="dbo" до Schema="dbo" (в противном случае, код будет генерировать ошибку, говоря, что имя является недопустимым)

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

обновление: в последнее время я получил несколько комментариев по этому поводу, поэтому я решил, что дам людям знать, что совет, который я даю ниже, не самый лучший. Поскольку я изначально начал заниматься созданием Entity Framework на старых базах данных без ключей, я понял, что лучшее, что вы можете сделать,-это сделать это с помощью обратного кода. Есть несколько хороших статей, о том, как это сделать. Просто следуйте им, а затем, когда вы хотите добавить ключ к нему, используйте аннотации данных, чтобы "подделать" ключ.

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

    [Key, Column(Order = 0)]
    public Int32? OrderNumber { get; set; }

    [Key, Column(Order = 1)]
    public String Customer { get; set; }

делая это, вы в основном подделали EF, полагая, что есть кластерный ключ, состоящий из OrderNumber и Customer. Это позволит вам делать вставки, обновления и т. д на вашем keyless стол.

если вы не слишком знакомы с выполнением обратного кода, сначала найдите хороший учебник по коду Entity Framework. Затем сначала найдите его на обратном коде (который сначала выполняет код с существующей базой данных). Тогда просто вернитесь сюда и посмотрите на мой ключевой совет еще раз. :)

Оригинальный Ответ:

во-первых: как уже сказали, лучшим вариантом будет добавление первичного ключа в таблицу. Точка. Если вы можете это сделать, прочитайте нет дальше.

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

в моем случае я работал с устаревшей системой (первоначально плоские файлы на as400 портировались для доступа, а затем портировались на T-SQL). Поэтому я должен был найти способ. Это мое решение. Следующее работало для меня с использованием Entity Framework 6.0 (последний на NuGet на момент написания этой статьи).

  1. Правой Кнопкой Мыши на вашем .файл edmx в обозревателе решений. Выберите "Открыть С Помощью..."а затем выберите "XML (текстовый) редактор". Мы собираемся вручную редактировать автоматически сгенерированный код здесь.

  2. посмотрите на такую строку:
    <EntitySet Name="table_name" EntityType="MyModel.Store.table_name" store:Type="Tables" store:Schema="dbo" store:Name="table_nane">

  3. удалить store:Name="table_name" из конец.

  4. изменить store:Schema="whatever" до Schema="whatever"

  5. посмотрите ниже этой строки и найдите <DefiningQuery> тег. В нем будет большой оператор select. Удалите тег, и это содержание.

  6. теперь ваша строка должна выглядеть примерно так:
    <EntitySet Name="table_name" EntityType="MyModel.Store.table_name" store:Type="Tables" Schema="dbo" />

  7. нам нужно еще кое-что изменить. Просмотрите свой файл и найдите следующее:
    <EntityType Name="table_name">

  8. рядом вы, вероятно, увидите какой-то прокомментированный текст, предупреждающий вас, что у него не было идентифицированного первичного ключа, поэтому ключ был выведен, и определение является таблицей/представлением только для чтения. Вы можете оставить его или удалить. Я удалил оно.

  9. ниже <Key> тег. Это то, что Entity Framework будет использовать для вставки/обновления/удаления. ПОЭТОМУ УБЕДИТЕСЬ, ЧТО ВЫ ДЕЛАЕТЕ ЭТО ПРАВИЛЬНО. Свойство (или свойства) в этом теге нужно указывать однозначно идентифицировать строку. Например, допустим, я знаю свою таблицу orders, в то время как он не имеет первичного ключа, гарантируется только один номер заказа на одного клиента.

так мой выглядит например:

<EntityType Name="table_name">
              <Key>
                <PropertyRef Name="order_numbers" />
                <PropertyRef Name="customer_name" />
              </Key>

серьезно, не делайте это неправильно. Предположим, что даже если никогда не должно быть дубликатов, каким-то образом две строки попадают в мою систему с одним и тем же номером заказа и именем клиента. Упс! Вот что я получаю за то, что не использую ключ! Поэтому я использую Entity Framework для удаления одного. Потому что я знаю, что дубликат-это только сегодня, я делаю так:

var duplicateOrder = myModel.orders.First(x => x.order_date == DateTime.Today);
myModel.orders.Remove(duplicateOrder);

угадайте, что? Я просто удалил как дубликат, так и оригинал! Это потому, что я сказал сущности Фреймворк, который order_number / cutomer_name был моим первичным ключом. Поэтому, когда я сказал ему удалить duplicateOrder, то, что он сделал в фоновом режиме, было что-то вроде:

DELETE FROM orders
WHERE order_number = (duplicateOrder's order number)
AND customer_name = (duplicateOrder's customer name)

и с этим предупреждением... теперь вы должны быть хорошо идти!

Это также может произойти, если данные модели устарели.

надеюсь, это спасет кого-то еще разочарование :)

Я получал то же сообщение об ошибке, но в моем сценарии я пытался обновить сущности, полученные из отношения "многие ко многим", используя PJT (Pure Join Table).

из чтения других сообщений я подумал, что могу исправить это, добавив дополнительное поле PK в таблицу соединений... Однако если вы добавляете столбец PK в объединенную таблицу, он больше не является PJT, и вы теряете все преимущества Entity framework, такие как автоматическое сопоставление отношений между сущности.

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

может произойти ошибка, если ваша таблица не имеет первичного ключа, в этом случае таблица "только для чтения" и БД.Команда SaveChanges () всегда будет приводить к ошибке

Так что это правда, просто добавьте первичный ключ

Примечание: убедитесь, что при обновлении диаграммы EF из базы данных, на которую вы указываете право база данных, в моем случае строка подключения указывала на локальную БД вместо обновленной БД Dev, ошибку schoolboy я знаю, но я хотел опубликовать это, потому что это может быть очень неприятно, если вы уверены, что добавили первичный ключ, и вы все еще получаете ту же ошибку

У меня была та же проблема. Как сказал этот поток, в моей таблице не было PK, поэтому я установил PK и запустил код. Но к сожалению ошибка пришла снова. Затем я удалил соединение с БД (delete .edmx-файл в папке модели обозревателя решений) и воссоздал его. Ошибка ушла после этого. Спасибо всем за обмен опытом. Это экономит много времени.

Я получал эту проблему, потому что я генерировал свой EDMX из существующей базы данных (разработанный кем-то другим, и я использую термин "разработанный" свободно здесь).

оказалось, что у стола вообще не было ключей. EF создавал модель со многими несколькими ключами. Мне пришлось добавить первичный ключ в таблицу БД в SQL, а затем обновить мою модель в VS.

это исправило это для меня.

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

добавление первичного ключа сработало и для меня !

Как только это будет сделано, вот как обновить модель данных без ее удаления -

щелкните правой кнопкой мыши на странице edmx Entity designer и "обновить модель из базы данных".

у меня была точно такая же проблема, к сожалению, добавление первичного ключа не решает проблему. Так вот как я решаю мои:

  1. убедитесь, что у вас есть primary key на столе, поэтому я изменяю свою таблицу и добавляю первичный ключ.
  2. Delete the ADO.NET Entity Data Model (edmx-файл), где я использую для сопоставления и подключения к моей базе данных.
  3. Add again a new file of ADO.NET Entity Data Model для подключения к моей базе данных и для сопоставления свойств моей модели.
  4. Clean and rebuild the solution.

проблема решена.

просто добавьте первичный ключ в таблицу, а затем воссоздайте EF

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

У меня возникла эта проблема и считаю, что это было вызвано тем, что я удалил индекс на моем первичном ключе таблиц и заменил его индексом на некоторые другие поля в таблице.

после того, как я удалил индекс первичного ключа и обновил edmx, вставки перестали работать.

я обновил таблицу до более старой версии, обновил edmx, и все снова работает.

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

Открыть Свой .edmx файл в Редакторе XML, а затем удалить тег из тега, а также изменить магазин:Schema="dbo" в Schema="dbo" и перестроить решение теперь ошибка будет решена, и вы сможете сохранить данные.

Comments

    Ничего не найдено.