Entity Framework: таблица без первичного ключа
У меня есть существующая БД, с которой я хотел бы построить новое приложение с помощью EF4. 0
в некоторых таблицах не определены первичные ключи, поэтому при создании новой модели данных сущности я получаю следующее сообщение: "в таблице/представлении TABLE_NAME не определен первичный ключ, и не может быть выведен допустимый первичный ключ. Эта таблица / представление была исключена. Чтобы использовать сущность, вам нужно будет просмотреть свою схему, добавить правильные ключи и раскомментировать ее".
Если я хочу используйте их и изменяйте данные, должен ли я обязательно добавить PK в эти таблицы или есть обходной путь, чтобы мне не пришлось?
15 ответов:
ошибка означает именно то, что он говорит.
даже если вы могли бы обойти это, поверьте мне, вы не хотите. Количество запутанных ошибок, которые могут быть введены, ошеломляет и пугает, не говоря уже о том, что ваша производительность, скорее всего, пойдет по трубам.
Не работайте вокруг этого. Исправьте свою модель данных.
EDIT: Я видел, что многие люди опускают этот вопрос. Это нормально, я полагаю, но имейте в виду, что ОП спросил о сопоставлении a таблица без первичного ключа, а не view. Ответ все тот же. Работа над необходимостью EF иметь ПК на таблицах-плохая идея с точки зрения управляемости, целостности данных и производительности.
некоторые из них отметили, что у них нет возможности исправить базовую модель данных, потому что они сопоставляются с сторонним приложением. Это не очень хорошая идея, так как модель может измениться из - под вас. Возможно, в этом случае вы захотите сопоставить вид, который, опять же, не является тем, что просил OP.
Я думаю, что это решается Tillito:
Entity Framework и SQL Server View
Я процитирую его запись ниже:
у нас была такая же проблема и это решение:
чтобы заставить Entity framework использовать столбец в качестве первичного ключа, используйте ISNULL.
чтобы заставить Entity framework не использовать столбец в качестве первичного ключа, используйте NULLIF.
простой способ применить это-обернуть оператор select вашего представления в другой выберите.
пример:
SELECT ISNULL(MyPrimaryID,-999) MyPrimaryID, NULLIF(AnotherProperty,'') AnotherProperty FROM ( ... ) AS tempответил 26 апреля ' 10 в 17: 00 по Tillito
составные ключи также могут быть выполнены с помощью Entity Framework Fluent API
public class MyModelConfiguration : EntityTypeConfiguration<MyModel> { public MyModelConfiguration() { ToTable("MY_MODEL_TABLE"); HasKey(x => new { x.SourceId, x.StartDate, x.EndDate, x.GmsDate }); ... } }
в моем случае мне пришлось сопоставить сущность с тем, что не имеют первичного ключа. Более того, мне не разрешили изменить это представление. К счастью, это представление имело столбец, который был уникальной строкой. Мое решение состояло в том, чтобы пометить этот столбец как первичный ключ:
[Key] [DatabaseGenerated(DatabaseGeneratedOption.None)] [StringLength(255)] public string UserSID { get; set; }обманули эф. Работал отлично, никто не заметил... :)
ЭТО РЕШЕНИЕ РАБОТАЕТ
вам не нужно карту вручную, даже если у вас нет ПК. Вам просто нужно сказать EF, что один из ваших столбцов является индексом, а столбец индекса не может быть обнулен.
для этого вы можете добавить номер строки в свой вид с помощью функции isNull, как показано ниже
select ISNULL(ROW_NUMBER() OVER (ORDER BY xxx), - 9999) AS id from a
ISNULL(id, number)является ключевым моментом здесь, потому что он говорит EF, что этот столбец может быть первичным ключом
EF не требует первичного ключа в базе данных. Если бы это было так, вы не могли бы привязать сущности к представлениям.
вы можете изменить SSDL (и CSDL), чтобы указать уникальное поле в качестве первичного ключа. Если у вас нет уникального поля, то я считаю, что вы обливаетесь. Но у вас действительно должно быть уникальное поле (и ПК), иначе вы столкнетесь с проблемами позже.
Эрик
если я хочу использовать их и изменять данные, я должен обязательно добавить PK в эти таблицы, или есть обходной путь, так что мне не нужно?
для тех, кто достигает этого вопроса и использует ядро Entity Framework, вам больше не нужно обязательно добавлять PK в таблицы thoses или делать какие-либо обходные пути. С EF Core 2.1 у нас появилась новая функция Типы Запросов
типы запросов должны использоваться для:
- служит в качестве возвращаемого типа для специальных запросов FromSql ().
- сопоставление с представлениями базы данных.
- сопоставление с таблицами, в которых не определен первичный ключ.
- сопоставление с запросами, определенными в модели.
поэтому в вашем DbContext просто добавьте следующее свойство типа
DbQuery<T>вместоDbSet<T>, как показано ниже. Предполагая, что ваше имя таблицыMyTable:public DbQuery<MyTable> MyTables { get; set; }
приведенные выше ответы верны, если у вас действительно нет ПК.
но если есть один, но он просто не указан с индексом в БД, и вы не можете изменить БД (да, я работаю в мире Дилберта), вы можете вручную отобразить поле(ы) в качестве ключа.
наличие бесполезного идентификационного ключа иногда бессмысленно. Я нахожу, что если идентификатор не используется, зачем его добавлять? Однако Entity не так прощает об этом, поэтому лучше всего добавить поле ID. Даже в том случае, если он не используется, это лучше, чем иметь дело с инцессивными ошибками сущности об отсутствующем ключе идентификации.
Это просто дополнение к ответу @Erick T. Если нет ни одного столбца с уникальными значениями, обходным путем является использование составного ключа следующим образом:
[Key] [Column("LAST_NAME", Order = 1)] public string LastName { get; set; } [Key] [Column("FIRST_NAME", Order = 2)] public string FirstName { get; set; }опять же, это просто обходной путь. Реальное решение состоит в том, чтобы исправить модель данных.
- измените структуру таблицы и добавьте основной столбец. Обновите модель
- изменить .EDMX файл в Редакторе XML и попробуйте добавить новый столбец под тегом для этой конкретной таблицы (не будет работать)
- вместо того, чтобы создавать новый Основной столбец для выхода из таблицы, я буду создайте составной ключ, используя все существующие столбцы (работала)
Entity Framework: добавление DataTable без первичного ключа к сущности Модель.
Это может быть поздно, чтобы ответить...однако...
Если таблица не имеет первичного ключа, то есть несколько сценариев, которые должны быть проанализированы для того, чтобы сделать эф работает должным образом. Правило таково: EF будет работать с таблицами/классами с первичным ключом. Вот как он делает отслеживание...
скажем, ваш стол 1. Записи уникальны: уникальность создается одним столбцом внешнего ключа: 2. Записи уникальны: уникальность создается комбинацией нескольких столбцов. 3. Записи не являются уникальными (по большей части*).
для сценариев #1 и #2 Вы можете добавить следующую строку в DbContext модуль OnModelCreating метод: modelBuilder.Сущность.)(HasKey (x => new { x.column_a, x.column_b }); // столько столбцов, сколько требуется, чтобы сделать записи уникальными.
для сценария #3 Вы все еще можете использовать вышеупомянутое решение (#1 + #2) после изучения таблицы (*что делает все записи уникальными в любом случае). Если необходимо включить все столбцы, чтобы сделать все записи уникальными затем вы можете добавить столбец первичного ключа в таблице. Если эта таблица от стороннего поставщика, чем клонировать эту таблицу в локальную базу данных (на ночь или столько раз, сколько вам нужно) с первичным ключевым столбцом, добавленным произвольно через ваш сценарий клонирования.
с практической точки зрения, каждая таблица-даже денормализованная таблица, такая как таблица склада-должна иметь первичный ключ. Или, если это невозможно, нужно хотя бы иметь уникальный индекс.
без какого-либо уникального ключа дубликаты записей могут (и будут) появляться в таблице, что очень проблематично как для слоев ORM, так и для базового понимания данных. Таблица с повторяющимися записями, вероятно, является признаком плохого дизайна.
в по крайней мере, таблица должна иметь хотя бы столбец идентификаторов. Добавление столбца автоматического создания идентификатора занимает около 2 минут в SQL Server и 5 минут в Oracle. Для этого дополнительного усилия, многие,много проблем удастся избежать.
мы также столкнулись с этой проблемой, и хотя у нас был столбец с нулями, важно было то, что у нас был зависимый столбец, который не имел нулей, и что комбинация этих двух столбцов была уникальной.
Итак, чтобы процитировать ответ, данный Пратапом Редди, он отлично работал для нас.
Comments