Подтвердить что ты не робот

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

Я только начал работать над проектом, конвертирующим приложение из необработанного 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 является pk для таблицы aip.slbtransinsured, rsn является pk для aip.slbtransinsurer и aip.slblinecodes.

Можно ли вообще добавить представление к модели Entity без уникального идентификатора? Или есть простой способ добавить уникальный уникальный идентификатор строки в представление? Представление читается только, никогда не записывается в.

4b9b3361

Ответ 1

Можно ли вообще добавить представление к модели Entity без уникальный идентификатор?

Если без первичного ключа, нет. Это приведет к ошибке :

Во время генерации модели были обнаружены одна или несколько ошибок проверки:

System.Data.Edm.EdmEntityType:: EntityType 'SalesOnEachCountry' имеет ключ не определен. Определите ключ для этого EntityType. System.Data.Edm.EdmEntitySet: EntityType: EntitySet SalesOnEachCountryList основан на типе SalesOnEachCountry, который не имеет Определены ключи.

Если без уникального идентификатора, да, хотя он имеет нежелательный вывод. Записи с одним и тем же идентификатором будут ссылаться на один и тот же объект, это называется шаблон карты идентификации

Пример, даже если ваше представление создает эти две строки:

Country     Year TotalSales
Philippines 2010 20.000000
Philippines 2011 40.000000

Если вы просто скопируете первичный ключ только в поле Страна, например.

public class SalesOnEachCountry
{        
    [Key]
    public int CountryId { get; set; }
    public string CountryName { get; set; }        
    public int OrYear { get; set; }
    public long SalesCount { get; set; }
    public decimal TotalSales { get; set; }
}

даже ваше представление создает две вышеуказанные строки в редакторе запросов Oracle, Entity Framework производит этот неправильный вывод:

Country     Year TotalSales
Philippines 2010 20.000000
Philippines 2010 20.000000

Entity Framework будет считать, что вторая строка - это тот же самый объект, что и первая строка.

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

public class SalesOnEachCountry
{        
    [Key, Column(Order=0)] public int CountryId { get; set; }
    public string CountryName { get; set; }
    [Key, Column(Order=1)] public int OrYear { get; set; }

    public long SalesCount { get; set; }      
    public decimal TotalSales { get; set; }
}

Сделайте свой первичный ключ похожим на приведенные выше атрибуты, Entity Framework может правильно сопоставить каждую строку представления с собственными объектами. Следовательно, Entity Framework теперь может отображать те же строки, что и ваш вид.

Country     Year TotalSales
Philippines 2010 20.000000
Philippines 2011 40.000000

Полная информация здесь: http://www.ienablemuch.com/2011/06/mapping-class-to-database-view-with.html


Затем, в отношении ваших представлений, которые не имеют столбцов, чтобы сделать уникальную строку, самым простым способом гарантировать, что Entity Framework может сопоставить каждую из строк вашего представления с их собственными объектами, является создание отдельного столбца для вашего первичного ключа вида, хорошим кандидатом является просто создать столбец номера строки в каждой строке. например.

create view RowNumberedView as

select 
    row_number() over(order by <columns of your view sorting>) as RN
    , *
from your_existing_view

Затем назначьте атрибут [Key] в свойстве RN вашего class RowNumberedView

Ответ 2

Расширение ответа Майкла Буэна: Я обнаружил, что добавление номера строки в представление с помощью ISNULL() позволит инфраструктуре сущности вывести представление и автоматически создать необходимые данные EntitySet.

create view RowNumberedView as

select 
    ISNULL(ROW_NUMBER() OVER (ORDER BY <column>), 0) AS RN
    , *
from your_existing_view

Ответ 3

Можно ли вообще добавить представление к модели Entity без уникального идентификатора?

Возможно иметь представления, в которых нет ни одного столбца или набора столбцов, которые создают первичный ключ; таким образом, вы оказываетесь в ложных отношениях. Таблицы хранилища данных иногда следуют этой форме. Короче говоря, нормализация иногда не соблюдается ни по причинам производительности, ни по причинам отчетности.

Теперь к вашему второму пункту:

Или есть простой способ добавить уникальный уникальный идентификатор строки в представление?

Я предлагаю вам выбрать все столбцы из 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;

Ответ 4

Поле счетчика строк может быть добавлено в представление для использования в качестве ключа.

См. ссылку .