По нескольким причинам, о которых я не имею права говорить, мы определяем представление о нашей базе данных Sql Server 2005 следующим образом:
CREATE VIEW [dbo].[MeterProvingStatisticsPoint]
AS
SELECT
CAST(0 AS BIGINT) AS 'RowNumber',
CAST(0 AS BIGINT) AS 'ProverTicketId',
CAST(0 AS INT) AS 'ReportNumber',
GETDATE() AS 'CompletedDateTime',
CAST(1.1 AS float) AS 'MeterFactor',
CAST(1.1 AS float) AS 'Density',
CAST(1.1 AS float) AS 'FlowRate',
CAST(1.1 AS float) AS 'Average',
CAST(1.1 AS float) AS 'StandardDeviation',
CAST(1.1 AS float) AS 'MeanPlus2XStandardDeviation',
CAST(1.1 AS float) AS 'MeanMinus2XStandardDeviation'
WHERE 0 = 1
Идея состоит в том, что Entity Framework создаст объект на основе этого запроса, что он и делает, но генерирует его с ошибкой, которая гласит следующее:
Предупреждение 6002: для таблицы / представления «Keystone_Local.dbo.MeterProvingStatisticsPoint» не определен первичный ключ. Ключ был выведен, и определение было создано как таблица / представление только для чтения.
И он решает, что поле CompletedDateTime будет первичным ключом этой сущности.
Мы используем EdmGen для генерации модели. Есть ли способ, чтобы структура сущностей не включала какое-либо поле этого представления в качестве первичного ключа?
источник
Я смог решить эту проблему с помощью дизайнера.
Мне не нужно было менять свое мнение, чтобы использовать обходные пути ISNULL, NULLIF или COALESCE. Если вы обновите свою модель из базы данных, предупреждения снова появятся, но исчезнут, если вы закроете и снова откроете VS. Изменения, сделанные в конструкторе, будут сохранены и не будут затронуты обновлением.
источник
Согласитесь с @Tillito, однако в большинстве случаев это приведет к загрязнению оптимизатора SQL и не будет использовать правильные индексы.
Это может быть очевидно для кого-то, но я потратил часы на решение проблем с производительностью, используя решение Tillito. Допустим, у вас есть таблица:
и ваш взгляд примерно такой
Оптимизатор Sql не будет использовать индекс ix_customer и будет выполнять сканирование таблицы по первичному индексу, но если вместо:
ты используешь
это заставит MS SQL (по крайней мере, в 2008 году) включить правильный план в план.
Если
источник
Этот метод хорошо работает для меня. Я использую ISNULL () для поля первичного ключа и COALESCE (), если поле не должно быть первичным ключом, но также должно иметь ненулевое значение. В этом примере возвращается поле идентификатора с необнуляемым первичным ключом. Другие поля не являются ключами и имеют (Нет) в качестве атрибута Nullable.
если у вас действительно нет первичного ключа, вы можете подделать его, используя ROW_NUMBER, чтобы сгенерировать псевдоключ, который игнорируется вашим кодом. Например:
источник
NEWID() as id
, но это та же идея. И есть законные варианты использования - если у вас есть представление только для чтения, например. Гадкий, ЭФТекущий генератор EDM Entity Framework создаст составной ключ из всех необнуляемых полей в вашем представлении. Чтобы получить контроль над этим, вам нужно изменить представление и столбцы базовой таблицы, установив для столбцов значение NULL, если вы не хотите, чтобы они были частью первичного ключа. Также верно и обратное, как я обнаружил, ключ, сгенерированный EDM, вызывал проблемы с дублированием данных, поэтому мне пришлось определить столбец, который можно обнулять как необнуляемый, чтобы составной ключ в EDM включал этот столбец.
источник
Context.Entity.ToList()
дубликаты записей, но если вы выполняете SQL-запрос, сгенерированный EF напрямую (полученный с помощью LINQPad), дублирование записей не происходит. Кажется, это проблема сопоставления записей базы данных с возвращаемыми объектными объектами (POCO), поскольку PK выводится с использованием объясненной логики (столбцы, не имеющие значения NULL).Похоже, это известная проблема с EdmGen: http://social.msdn.microsoft.com/forums/en-US/adodotnetentityframework/thread/12aaac4d-2be8-44f3-9448-d7c659585945/
источник
Чтобы получить представление, мне нужно было показать только один столбец первичного ключа. Я создал второе представление, которое указывало на первое, и использовал NULLIF, чтобы типы могли обнуляться. Это помогло мне заставить EF думать, что в представлении был только один первичный ключ.
Не уверен, поможет ли это вам, хотя я не верю, что EF примет объект без первичного ключа.
источник
Если вы не хотите связываться с тем, что должно быть первичным ключом, я рекомендую:
ROW_NUMBER
в свой выбористочник
Из-за вышеупомянутых проблем я предпочитаю функции табличных значений.
Если у вас есть это:
создать это:
Затем вы просто импортируете функцию, а не представление.
источник