Не могу добавить вид в 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, но безуспешно.