Не удалось обновить EntitySet - поскольку он содержит элемент DefiningQuery и no <UpdateFunction>


416

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

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

var RoomDetails = context.Rooms.ToList(); 

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

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

context.SaveChanges(); 

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

Unable to update the EntitySet - because it has a DefiningQuery and no <UpdateFunction> element exists in the <ModificationFunctionMapping> element to support the current operation.

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

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

+40

Я допустил ошибку, на столе не было первичного ключа, спасибо за ваше время! Извините за неудобства! 28 сен. 112011-09-28 15:49:43

+1

Просто случилось со мной - возможно, создано 1000 таблиц с первичными ключами, и забыли одно - сообщение об исключении не очень помогает 05 авг. 122012-08-05 13:25:38

+1

отлично. я действительно забыл добавить первичный ключ в таблицу. Попробуем быть осторожным) 01 ноя. 122012-11-01 14:12:07

822

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

  • Entity Set сопоставлен с точки зрения базы данных
  • Пользовательская база данных запросов
  • Таблица базы данных не имеет первичного ключа

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

+2

Обязательно также измените хранилище: схема для простой схемы для этого EntitySet, если у вас все еще есть проблемы. 04 окт. 122012-10-04 14:33:04

  0

Итак, решение состоит в том, чтобы добавить первичный ключ? 19 ноя. 122012-11-19 22:11:04

+2

@ DanielAllenLangdon: Да. 20 ноя. 122012-11-20 09:53:49

+46

Затем удалите и заново создайте объект, потому что обновление не работает правильно в дизайнере EF. 28 фев. 132013-02-28 13:22:08

+28

PK был ответом. Благодаря! 03 апр. 132013-04-03 10:05:48

+1

Обновление в дизайнере EF отлично работало для меня после добавления Первичного ключа в базу данных. Использование EF 5.0 и .net 4.0 29 июл. 132013-07-29 14:47:32

+1

То же самое! Thx ... пришлось удалить таблицу и добавить в EF, чтобы получить ее, хотя 20 мар. 142014-03-20 18:52:14

  0

Что делать, если вы не можете добавить первичный ключ 21 мар. 142014-03-21 15:33:57

  0

PK. Кто бы мог подумать. 26 ноя. 142014-11-26 18:05:58

  0

Перенос данных в antoher DB. И забыл сохранить ключ. Этот ответ был решением (создал скрипт для воспроизведения ключа) 10 апр. 152015-04-10 08:04:01

  0

Я использую представление и вместо него запускаю его. есть ли в любом случае я могу использовать представление через EF для вставки, обновления и удаления? <br/> Редактировать: Я использовал [этот] (http://stackoverflow.com/questions/11974384/ef-code-first-and-database-views) ответ вашего. @LadislavMrnka 19 май. 152015-05-19 13:04:34

  0

Мой стол отсутствовал Первичный ключ. Я обновил таблицу и начал работать 26 окт. 152015-10-26 17:23:15

  0

У меня была такая же проблема. У меня не было столбца PK в базе данных, и когда я добавил модель, он установил два столбца в качестве ключа сущности. Позже я установил PK, но забыл обновить модель.Я просто обновляю модель, и все было хорошо. 26 авг. 162016-08-26 19:51:18

  0

Добавление ПК помогло мне !!! 30 сен. 162016-09-30 22:56:49

  0

Добавлен PK в SSMS, открытая модель в VS, обновленная из базы данных, запускает собственный инструмент для файлов .tt, перестраивает решение, работает сейчас - вот шаги, которые я выполнил для успеха. 18 ноя. 162016-11-18 22:59:52

  0

PK был проблемой здесь, он был добавлен в БД, но не был в модели. Обновление не сработало, но удаление и чтение объекта выполнялось, как было предложено выше. 17 янв. 172017-01-17 14:05:54

  0

В моем случае первичного ключа не было. Спасибо 04 дек. 172017-12-04 05:36:04

  0

Добавьте первичный ключ и не забудьте обновить модель Entity Framework после этого 15 янв. 182018-01-15 16:09:35


18

Это также может случиться, если модель данных устарела.

Надеюсь, это сэкономит кому-то разочарование :)


71

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

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

и не забудьте нажать «Обновить модель из базы данных» в вашем .edmx-файле. 20 окт. 152015-10-20 07:22:29


36

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


6

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

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

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

  0

. Разве это так, как работает EDMX? Я привык работать с Code First, который не требует PK на чистой таблице соединений. 30 окт. 142014-10-30 16:46:21


26

ОБНОВЛЕНИЕ: В последнее время у меня есть несколько оборотов, поэтому я решил, что знаю людей, совет, который я даю ниже, не самый лучший. Поскольку я изначально начал работать с Entity Framework на старых базарах без ключа, я понял, что лучшее, что вы можете сделать, FAR - это сделать это с помощью обратного кода.Есть несколько хороших статей о том, как это сделать. Просто следуйте им, а затем, когда вы хотите добавить к нему ключ, используйте аннотации данных, чтобы «подделать» ключ.

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

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

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

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

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

Оригинал ответа:

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

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

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

  1. Щелкните правой кнопкой мыши по файлу .edmx в Обозревателе решений. Выберите «Открыть с ...», а затем выберите «XML (Text) Editor». Мы собираемся вручную редактировать автоматически сгенерированный код здесь.

  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> тег. В нем будет большой ол-выбор. Удалите тег и его содержимое.

  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> 

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

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

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

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

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

  0

Нашел этот ответ после нахождения того же решения проблемы. Определенно правильный ответ! Только определение первичного ключа, как упомянуто в других ответах, во многих случаях не поможет. 18 ноя. 142014-11-18 09:44:03


3

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

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

  0

Я чувствую себя глупо - неправильно DB Connection 07 янв. 152015-01-07 20:57:43


1

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

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

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


40

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

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

Большое спасибо - это именно то, что исправила мою проблему. Довольно беспокоя, что это не было зафиксировано в EF. И, довольно удивительно, что вы поняли это! 02 апр. 162016-04-02 01:12:21

  0

Я попытался удалить объект и повторно добавить его. Перекомпиляция. Очистка. Ничего не сработало для меня, кроме этого. 12 май. 162016-05-12 16:21:09

+1

Это решило мою проблему, но я не знаю, как вы пришли к ответам и почему ваше предложение решило проблему. 28 дек. 162016-12-28 23:03:13

  0

Что произойдет, если вам нужно обновить модель базы данных? Я сделал «Обновить модель из базы данных», и она оставила мою модель совершенно непригодной для использования. Я должен был отменить и начать заново. Если есть способ обойти это? 13 сен. 172017-09-13 20:02:40

  0

Это действительно странная проблема. Есть ли какая-либо информация о том, как эта проблема возникает, чтобы избежать ее? Тем не менее - это помогло 24 янв. 182018-01-24 09:56:23


4

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


2

У меня была такая же проблема. Как сказал этот поток, в моей таблице не было ПК, поэтому я установил ПК и запустил код.Но, к сожалению, ошибка пришла снова. То, что я сделал дальше, было удалено из соединения DB (удалить .edmx файл в папке Model Solution Solution) и воссоздать его. Ошибка исчезла после этого. Спасибо всем за то, что поделились своими впечатлениями. Это экономит много времени.


0

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

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

Щелкните правой кнопкой мыши на странице конструктора EDMX Entity и "Обновить модель из базы данных.


0

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

  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.

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


0

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


0

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


0

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