Не могу добавить вид в edmx

При попытке добавить представление в файл edmx ничего не происходит.
Я открыл файл edmx с помощью редактора wxl и заметил следующую ошибку:

предупреждение 6013: для таблицы / представления 'CellularOrders.dbo.V_LINK' не определен первичный ключ, и не может быть выведен действительный первичный ключ. Эта таблица / представление была исключена. Чтобы использовать объект, вам нужно будет просмотреть свою схему, добавить правильные ключи и раскомментировать ее.

(Важная вещь - мне не нужно и не нужно добавлять таблицу, на которой основано представление, в edmx. Более того, представление предназначено только для выполнения операторов выбора данных)

Поэтому в БД я обновил таблицу T_LINK и сделал одно из полей, которое отражает представление в качестве первичного ключа. А потом, когда я снова попытался добавить представление в edmx, ничего больше не происходит.

Как я могу решить это?? Есть ли возможность исправить это, ничего не делая с таблицей? Могу ли я добавить другой вид, который каким-то образом обернет старый вид, но с фиксированными свойствами?

7 ответов

Решение

Каждая таблица или представление, добавляемое в модель объекта, должно иметь некоторый ключ. Это на самом деле не должно быть первичным ключом. Если в таблице не определен первичный ключ, EF попытается вывести ключ, используя простое правило: он возьмет все необнуляемые не вычисляемые недвоичные столбцы и пометит их как ключ сущности. Если такого столбца не существует, сущность не может быть добавлена ​​автоматически, и дизайнер выдаст упомянутое предупреждение. Обходной путь - добавить представление вручную и выбрать ключ самостоятельно, но как только вы это сделаете, вы не сможете использовать обновление из базы данных, потому что оно всегда будет перезаписывать ваши изменения.

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

Просто добавьте столбец в ваше представление. Я добавил Row_Number, чтобы создать такой ключ

SELECT ISNULL(CAST((row_number() OVER (ORDER BY tab.ENTRYDATE)) AS int), 0) 
AS EDMXID,...other columns go on

Выражение табуляции - это псевдоним таблицы, а entrydate - это просто поле, необходимое для row_number, встроенного в функцию sql-server.

Вы можете выбрать различные способы, например,

select newid() as MYEDMXID,....so on

Надежда Помогает

Вы можете установить один из столбцов представления как не допускающий значение Null, используя функцию "ISNULL", как показано ниже.

ALTER VIEW [dbo].[MyView] 
AS
  SELECT 
   ISNULL([StringID],'') AS [Id],
   [Name]
 FROM [Table]

GO

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

Вот пример:

CREATE VIEW dbo.myView
AS
SELECT
 -- This column enables EF-import via designer by enabling PK generation
 Id,
 -- These columns belong to the view
 [Count],
 [Sum]
FROM
(
SELECT
 COUNT(*) AS [Count]
 ,SUM(1) AS [Sum]
FROM
 dbo.myTable
) TheViewItself
-- Grab a primary key of a single row from atable
INNER JOIN (SELECT TOP 1 Id FROM dbo.TableWithPrimaryKey) Id ON 1 = 1

Предикат соединения "ON 1 = 1" выглядит странно. Но мне нужно было это, чтобы убедить EF импортировать представление.

Используйте новую таблицу только для связи с вашими представлениями, если у вас более 100 тыс. Строк, EF6 не лучшее решение;)

CREATE TABLE dbo.TablePrimate(Id int CONSTRAINT PK_TablePrimate PRIMARY KEY (Id))
go
set nocount on;
DECLARE @i int;
set @i=1
WHILE @i<10000
BEGIN
    INSERT dbo.TablePrimate(Id) values(@i)
    SET @i = @i + 1
END
--In fews seconds & 1 MB of storage
GO

Теперь присоединяется к "MyView"

CREATE VIEW dbo.vwTickets
AS
SELECT TP.Id, MyPKView.* FROM (
    SELECT ROW_NUMBER() OVER (ORDER BY Ticket) Line, MyView.*
    FROM (
        select Grupo, App, Ticket, Titulo, FApertura, Estado, Tipo from dbo.vwEvolutivos 
        union 
        select Grupo, App, Ticket, Titulo, FApertura, Estado, Tipo from dbo.vwIncidencias
    ) MyView
) MyPKView
    JOIN dbo.TablePrimate TP ON TP.Id = Line

Для тех, кто использует Oracle, попробуйте добавить ограничение Pk в представление.

Пример

      alter view myView add constraint CONSTRAINT_NAME primary key (column) disable novalidate

Вы можете создать представление в своей базе данных и делать такие запросы в своем коде:

List<users> _users = _context.users.SqlQuery("SELECT * FROM users_v").ToList<users>();

Я долго пытался добавить представления PostgreSQl, но безуспешно.

Другие вопросы по тегам