엔티티에 기본 키가 없는 보기 사용
저는 방금 원시 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
idiredid는 aip.slb transinsured 테이블의 pk이고, rsn은 aip.slb transinsurer 및 aip.slbline 코드의 pk입니다.
고유 식별자 없이 도면요소 모델에 뷰를 추가할 수 있습니까?아니면 보기에 고유한 행 식별자를 쉽게 추가할 수 있는 방법이 있습니까?보기는 읽기만 하고 쓰기는 하지 않습니다.
고유 식별자 없이 도면요소 모델에 뷰를 추가할 수 있습니까?
기본 키가 없으면 아니요.그러면 다음과 같은 오류가 발생합니다.
모델을 생성하는 동안 하나 이상의 유효성 검사 오류가 감지되었습니다.
시스템. 데이터.Edm.EdmEntity유형: 엔티티'각 국가별 영업' 유형에 정의된 키가 없습니다.이 엔터티 유형에 대한 키를 정의합니다.시스템.데이터. 에드먼.에드먼티집합: 엔티티유형: EntitySetSalesOn각 국가 목록은 키가 정의되지 않은 각 국가의 유형 SalesOn각 국가를 기준으로 합니다.
고유 식별자가 없는 경우, 예, 바람직하지 않은 출력을 가지고 있습니다.동일한 식별자를 가진 레코드는 동일한 개체를 참조합니다. 이를 ID 맵 패턴이라고 합니다.
보기가 다음 두 행을 생성하는 경우에도 예제:
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는 두 번째 행이 첫 번째 행과 동일한 개체라고 간주합니다.
고유성을 보장하려면 각 행을 고유하게 만드는 열을 식별해야 합니다.위의 예에서는 기본 키가 고유하도록 Year를 포함해야 합니다.
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]
의 class RowNumberedView
Michael Buen의 답변 확장: ISNULL()을 사용하여 뷰에 행 번호를 추가하면 엔티티 프레임워크가 뷰를 가져와서 필요한 EntitySet 데이터를 자동으로 생성할 수 있다는 것을 발견했습니다.
create view RowNumberedView as
select
ISNULL(ROW_NUMBER() OVER (ORDER BY <column>), 0) AS RN
, *
from your_existing_view
저는 최근에 직장에서 같은 문제에 부딪혔습니다.제가 조사한 결과, PK 없이 EF6 CodeFirst에 뷰를 첨부하는 방법에 대한 답을 찾을 수 없었습니다.대부분은 이주와 관련된 것으로 보이며 상당히 혼란스러웠습니다.더 잘 합니다.SQL VIEWS
.
저는 소개하려고 노력했습니다.window function
는 EF6를 행 (으)로 표시되는 PK는 EF6입니다.하지만 이것은 제 질문을 전반적으로 더 비싸게 만들었기 때문에 저는 이 아이디어를 포기해야만 했습니다.
결국, 비즈니스 애플리케이션이 작동하는 데 필요한 모든 시나리오를 다루는 복합 키를 도입할 수 있는지 알아보기 위해 데이터 세트를 신중하게 분석해야 했습니다.사해야함을 사용하는 것을 하세요.IsNull(ColumnName,0)
당신이 만족할 수 있도록 보장하기에는 너무..IsRequired()
코드퍼스트 유창한 방법으로.
예
HasKey(x => new { x.KfiId, x.ApplicationNumber, x.CustomerId });
저는 이것이 누군가에게 도움이 되기를 바랍니다 - 저의 대답은 보기가 정규화되지 않는 데이터 세트를 분석하고 복합 키를 찾는 것이었습니다.
마크 칼스가 제안한 또 다른 멋진 아이디어를 시도해 볼 수 있습니다.
ASP.NET에서 MVC와 함께 Entity Framework를 사용하는 경우
앞에서 말한 것처럼 자동 증분 또는 ROW_NUMBER가 있는 열로 뷰를 생성합니다.만약 당신이 그 칼럼을 가지고 있고 그것의 이름은.rowNumber
.
go file (콘텍스트 파일로 이동)yourDatabaseNameContext
) 에 Models
프로그램의 MVC 응용 .
modelBuilder.Entity<yourView>(entity =>
{
entity.HasNoKey();
다음으로 변경:
modelBuilder.Entity<yourView>(entity =>
{
entity.HasKey(e => e.rowNumber);
고유 식별자 없이 도면요소 모델에 뷰를 추가할 수 있습니까?
기본 키를 생성하는 열 또는 열 집합이 하나도 없는 보기를 가질 수 있으므로, 가상 관계가 발생할 수 있습니다.데이터 웨어하우스 테이블이 해당 양식을 따르는 경우도 있습니다.즉, 성능이나 보고의 이유로 정규화가 지켜지지 않는 경우가 있습니다.
이제 두 번째 요점을 말씀드리겠습니다.
아니면 보기에 고유한 행 식별자를 쉽게 추가할 수 있는 방법이 있습니까?
제가 제안하는 것은 slb transinsured에서 모든 열을 선택하고 각 레코드를 고유하게 식별하는 하나의 열을 찾을 수 있는지 확인하는 것입니다.제가 보기에 데이터는 slbline 코드에 당신이 선택해야 하는 코드 유형이 있어야 합니다. 마치 조회와 같습니다.
재미로, 이것을 실행해 보고 무엇을 얻을 수 있는지 말해 보십시오.
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;
둘다요.NEWID()
그리고.ROW_NUMBER() OVER(...)
는 다른 답변에 언급된 대로 고유한 값을 생성하지만 보기 결과에 null로 표시됩니다(값이 null이 아닐 것임을 알고 있음에도 불구하고).이렇게 하면 엔티티 프레임워크에서 키로 선택할 수 없습니다.
수정 사항은 다음과 같이 'ISNULL()'로 묶는 것입니다.
CREATE VIEW MyView
AS
SELECT
ISNULL(NEWID(), 0x0) as RowId,
...
FROM ...
또는
-- *** See performance note below ***
CREATE VIEW MyView
AS
SELECT
ISNULL(ROW_NUMBER() OVER(ORDER BY (SELECT NULL)), 0) as RowNum,
...
FROM ...
그 결과RowId
그리고.RowNum
이제 열이 뷰 결과에서 분할할 수 없는 유형으로 보고됩니다.할당된 값은 반복할 수 없으며 읽기 전용 사용 사례에만 사용할 수 있습니다.
중요 참고:그ROW_NUMBER()
바람직하지 않은 성능 문제가 발생할 수 있습니다.결과를 계산하기 위해 SQL Server는 참조 쿼리에 의해 정의될 수 있는 필터를 적용하기 전에 행 번호 값을 검색하여 전체 뷰 행 집합에 할당하는 것으로 나타납니다.예를 들어, 쿼리SELECT * FROM MyView V WHERE V.ActivityDate >= @StartDate AND V.ActivityDate < @EndDate
날짜 범위 필터가 적용되기 전에 항상 데이터를 검색하고 행 번호를 할당할 수 있습니다.이는 다음과 같은 경우에 문제가 되지 않습니다.NEWID()
사용됩니다.
다양한 양식을 보여주는 이 db<>fidle을 참조하십시오.
보기를 사용할 때 AsNoTracking()을 사용하는 것이 좋습니다.그러면 EF 추적을 위한 키 필드의 사용이 비활성화됩니다.그런 다음 Null이 아닌 필드를 EF 키로 수동으로 정의할 수 있습니다(반복하더라도).
대부분의 행 카운터는 결국 엔진이 뷰의 전체 도메인을 스캔하여 적절한 카운터 값을 생성하도록 요구하기 때문에 추가 행 카운터 필드를 만들지 않는 것이 좋습니다(where 절).
링크를 참조하십시오.
언급URL : https://stackoverflow.com/questions/11370245/using-a-view-with-no-primary-key-with-entity
'bestsource' 카테고리의 다른 글
Mongodb에서 필드 값 곱셈 (0) | 2023.07.03 |
---|---|
Java의 여러 데이터 소스(오라클, Excel, SQL 서버)에 액세스하기 위한 단일 SQL 쿼리 (0) | 2023.07.03 |
Oracle jdbc에서 문 준비 및 타임스탬프 설정 (0) | 2023.07.03 |
문자열 벡터에서 숫자 추출 (0) | 2023.06.28 |
쿼츠 스케줄러의 각 테이블은 무엇을 의미합니까? (0) | 2023.06.28 |