Использование представления без первичного ключа с сущностью
Я только что начал проект преобразования приложения из raw ADO.NET и встроенный SQL в Entity. Я столкнулся с проблемой с одним из представлений, используемых приложением. Представление не имеет первичного ключа и столбца (или комбинации столбцов), однозначно идентифицирующих строку. Вот выбор представления создается с помощью:
SELECT
filingmonth,
CEIL(filingmonth / 3),
licnum,
filingyear,
DECODE(GROUPING(insurername), '1', '- All Insured -', insurername),
insurername,
policylinecode,
linedescription,
SUM(NVL(grosspremium, 0)),
SUM(DECODE(taxexempt, 1, grosspremium, 0)),
TRUNC(
CASE
WHEN
(
b.rsn IS NOT NULL
OR A.zeroreport = 1
)
AND b.datereceived IS NULL
THEN A.datereceived
ELSE b.datereceived
END),
SUM(aip.iscompanyadmitted(b.naiccocode, b.naicalienid)),
A.insuredid
FROM
aip.slbtransinsured A
LEFT OUTER JOIN aip.slbtransinsurer b
ON
A.insuredid = b.insuredid
LEFT OUTER JOIN aip.slblinecodes C
ON
b.policylinecode = C.linecode
WHERE
A.submitted = 1
AND A.entryincomplete = 0
GROUP BY
licnum,
filingmonth,
filingyear,
TRUNC(
CASE
WHEN
(
b.rsn IS NOT NULL
OR A.zeroreport = 1
)
AND b.datereceived IS NULL
THEN A.datereceived
ELSE b.datereceived
END),
ROLLUP(insurername, aip.iscompanyadmitted(b.naiccocode, b.naicalienid),
policylinecode, linedescription), A.insuredid;
и вот некоторые примеры данных, показывающие, что есть некоторые строки, которые полностью дублируются (строки 3 и 4):
FILINGMONTH CEIL(FILINGMONTH/3) LICNUM FILINGYEAR DECODE(GROUPING(INSURERNAME),'1','-ALLINSURED-',INSURERNAME) INSURERNAME POLICYLINECODE LINEDESCRIPTION SUM(NVL(GROSSPREMIUM,0)) SUM(DECODE(TAXEXEMPT,1,GROSSPREMIUM,0)) TRUNC(CASEWHEN(B.RSNISNOTNULLORA.ZEROREPORT=1)ANDB.DATERECEIVEDISNULLTHENA.DATERECEIVEDELSEB.DATERECEIVEDEND) SUM(AIP.ISCOMPANYADMITTED(B.NAICCOCODE,B.NAICALIENID)) INSUREDID
6 2 8150 2007 SAVERS PROPERTY AND CASUALTY INSURANCE CO SAVERS PROPERTY AND CASUALTY INSURANCE CO 17 OTHER LIABILITY 721.25 0 18-JUL-07 0 81
6 2 8150 2007 SAVERS PROPERTY AND CASUALTY INSURANCE CO SAVERS PROPERTY AND CASUALTY INSURANCE CO 17 721.25 0 18-JUL-07 0 81
6 2 8150 2007 SAVERS PROPERTY AND CASUALTY INSURANCE CO SAVERS PROPERTY AND CASUALTY INSURANCE CO 721.25 0 18-JUL-07 0 81
6 2 8150 2007 SAVERS PROPERTY AND CASUALTY INSURANCE CO SAVERS PROPERTY AND CASUALTY INSURANCE CO 721.25 0 18-JUL-07 0 81
insuredid-это ПК для aip.slbtransinsured таблица, rsn ПК для aip.slbtransinsurer и aip.slblinecodes.
можно ли вообще добавить представление в модель сущности без уникального идентификатора? Или есть простой способ добавить уникальный идентификатор строки в представление? Вид только читается, но никогда не записывается.
5 ответов
можно ли вообще добавить представление в модель сущности без уникальный идентификатор?
если без первичного ключа, нет. Это приведет к такому виду :
при создании модели была обнаружена одна или несколько ошибок проверки:
присвоить[Key]
атрибут на свойстве RN вашегоclass RowNumberedView
расширение ответа от Майкла Буэна: Я обнаружил, что добавление номера строки в представление с помощью ISNULL () позволит Entity framework автоматически извлекать представление и создавать необходимые данные EntitySet.
create view RowNumberedView as
select
ISNULL(ROW_NUMBER() OVER (ORDER BY <column>), 0) AS RN
, *
from your_existing_view
можно ли вообще добавить представление в модель сущности без уникального идентификатора?
можно иметь представления, в которых нет ни одного столбца или набора столбцов, которые создают первичный ключ; таким образом, вы заканчиваете с ложными отношениями. Таблицы хранилища данных иногда следуют этой форме. Короче говоря, нормализация иногда не соблюдается ни по причинам производительности, ни по причинам отчетности.
теперь второй точка:
или есть простой способ, чтобы добавить уникальный идентификатор строки в представление?
Я предлагаю вам выбрать все столбцы из slbtransinsured и посмотреть, сможете ли вы найти один столбец, который однозначно идентифицирует каждую запись. Мне кажется, что данные должны быть типом кода в slblinecodes, который вам нужно выбрать, что-то вроде поиска.
для пинки, попробуйте запустить это и скажите мне, что вы получить:
SELECT filingmonth,
CEIL (filingmonth / 3),
licnum,
filingyear,
DECODE (GROUPING (insurername), '1', '- All Insured -', insurername),
insurername,
policylinecode,
linedescription,
SUM (NVL (grosspremium, 0)),
SUM (DECODE (taxexempt, 1, grosspremium, 0)),
TRUNC (
CASE
WHEN (b.rsn IS NOT NULL OR a.zeroreport = 1)
AND b.datereceived IS NULL
THEN
a.datereceived
ELSE
b.datereceived
END),
SUM (aip.iscompanyadmitted (b.naiccocode, b.naicalienid)),
a.insuredid
FROM aip.slbtransinsured a
LEFT OUTER JOIN aip.slbtransinsurer b
ON a.insuredid = b.insuredid
LEFT OUTER JOIN aip.slblinecodes c
ON b.policylinecode = c.linecode
WHERE a.submitted = 1 AND a.entryincomplete = 0
GROUP BY filingmonth,
licnum,
filingyear,
DECODE (GROUPING (insurername), '1', '- All Insured -', insurername),
insurername,
policylinecode,
linedescription,
TRUNC (
CASE
WHEN (b.rsn IS NOT NULL OR a.zeroreport = 1)
AND b.datereceived IS NULL
THEN
a.datereceived
ELSE
b.datereceived
END),
a.insuredid;
поле счетчика строк может быть добавлено в представление для использования в качестве ключа.
см. ссылке.
на работе недавно я столкнулся с этой же проблемой. Основываясь на моих исследованиях, я не мог найти ответов о том, как прикрепить представление к EF6 CodeFirst без ПК. Большинство из них, по-видимому, связаны с миграцией и были довольно запутанными. Я считаю, что DB first имеет лучшую поддержку для работы SQL VIEWS
.
Я пытался представить window function
(RowNumber) с идеей, чтобы использовать идентификатор строки в качестве ПК, чтобы сохранить EF6 счастливым. Но это сделало мой запрос более дорогим в целом, поэтому мне пришлось отказаться от этой идеи.
в конце концов, я должен был тщательно проанализировать свой набор данных, чтобы увидеть, могу ли я ввести составной ключ - тот, который охватывает все сценарии, необходимые моему бизнес-приложению для обеспечения работы. Не забудьте использовать IsNull(ColumnName,0)
тоже, чтобы убедиться, что вы можете удовлетворить .IsRequired()
в CodeFirst свободно методы.
Я.е
HasKey(x => new { x.KfiId, x.ApplicationNumber, x.CustomerId });
Я надеюсь, что это кому - то поможет-ответ для меня был анализ набора данных, который вид денормализует и ищет составной ключ.
другой классная идея, вы можете попробовать предложенные Марк Лицензий.