ОНОВЛЕННЯ: Останнім часом я отримав кілька оновлень, тому зрозумів, що дам людям поради, які я даю нижче, не найкращий. Оскільки я спочатку почав спілкуватися з тим, щоб робити Entity Framework на старих базах даних без ключів, я зрозумів, що найкраще, що можна зробити BY 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 Code. Потім перейдіть до пошуку на Reverse Code First (що робиться Code First із наявною базою даних). Тоді просто поверніться сюди і знову подивіться на мою ключову пораду. :)
Оригінальний відповідь :
По-перше: як говорили інші, найкращий варіант - додати первинний ключ до таблиці. Повна зупинка. Якщо ви можете це зробити, не читайте більше.
Але якщо ви не можете або просто ненавидите себе, є спосіб зробити це без первинного ключа.
У моєму випадку я працював зі застарілою системою (спочатку плоскі файли на AS400, перенесеному в Access, а потім перенесеному на T-SQL). Тому мені довелося знайти спосіб. Це моє рішення. Наступне працювало для мене за допомогою Entity Framework 6.0 (остання версія NuGet станом на цей час).
Клацніть правою кнопкою миші файл .edmx у Провіднику рішень. Виберіть "Відкрити за допомогою ...", а потім виберіть "XML (Text) Editor". Тут ми будемо редагувати вручну автоматично створений код.
Шукайте такий рядок:
<EntitySet Name="table_name" EntityType="MyModel.Store.table_name" store:Type="Tables" store:Schema="dbo" store:Name="table_nane">
Зніміть store:Name="table_name"
з кінця.
Змінити store:Schema="whatever"
наSchema="whatever"
Подивіться нижче цього рядка і знайдіть <DefiningQuery>
тег. У ньому буде великий оператор select ol 'select. Видаліть тег і його вміст.
Тепер ваша лінія повинна виглядати приблизно так:
<EntitySet Name="table_name" EntityType="MyModel.Store.table_name" store:Type="Tables" Schema="dbo" />
У нас є щось ще змінити. Перегляньте свій файл і знайдіть це:
<EntityType Name="table_name">
Поруч, ймовірно, ви побачите якийсь коментований текст, який попереджає вас про те, що в ньому не був визначений первинний ключ, тому ключ був зроблений із висновку, а визначення - це таблиця / перегляд лише для читання. Ви можете залишити його або видалити. Я її видалив.
Нижче - <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. Тож коли я сказав йому видалити дублікатOrder, те, що було зроблено на задньому плані, було щось на зразок:
DELETE FROM orders
WHERE order_number = (duplicateOrder's order number)
AND customer_name = (duplicateOrder's customer name)
І з цим попередженням ... вам зараз слід добре піти!