Использование представления без первичного ключа с сущностью

Я только что начал проект преобразования приложения из 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 });

Я надеюсь, что это кому - то поможет-ответ для меня был анализ набора данных, который вид денормализует и ищет составной ключ.

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