[entity-framework] 엔터티 프레임 워크 및 SQL Server보기

내가 말할 자유가없는 몇 가지 이유로, 우리는 다음과 같이 Sql Server 2005 데이터베이스에 대한 견해를 정의하고 있습니다.

CREATE VIEW [dbo].[MeterProvingStatisticsPoint]
AS
SELECT
    CAST(0 AS BIGINT) AS 'RowNumber',
    CAST(0 AS BIGINT) AS 'ProverTicketId',
    CAST(0 AS INT) AS 'ReportNumber',
    GETDATE() AS 'CompletedDateTime',
    CAST(1.1 AS float) AS 'MeterFactor',
    CAST(1.1 AS float) AS 'Density',
    CAST(1.1 AS float) AS 'FlowRate',
    CAST(1.1 AS float) AS 'Average',
    CAST(1.1 AS float) AS 'StandardDeviation',
    CAST(1.1 AS float) AS 'MeanPlus2XStandardDeviation',
    CAST(1.1 AS float) AS 'MeanMinus2XStandardDeviation'
WHERE 0 = 1

아이디어는 Entity Framework 가이 쿼리를 기반으로 엔티티를 작성하지만 다음과 같은 오류로 생성합니다.

경고 6002 : 테이블 / 뷰 ‘Keystone_Local.dbo.MeterProvingStatisticsPoint’에 기본 키가 정의되어 있지 않습니다. 키가 유추되었으며 정의가 읽기 전용 테이블 / 뷰로 작성되었습니다.

그리고 CompletedDateTime 필드가이 엔티티 기본 키가되도록 결정합니다.

우리는 EdmGen을 사용하여 모델을 생성하고 있습니다. 엔터티 프레임 워크에이 뷰의 필드를 기본 키로 포함시키지 않는 방법이 있습니까?



답변

우리는 같은 문제가 있었고 이것이 해결책입니다.

엔티티 프레임 워크가 열을 기본 키로 사용하도록하려면 ISNULL을 사용하십시오.

엔티티 프레임 워크가 열을 기본 키로 사용하지 않도록하려면 NULLIF를 사용하십시오.

이것을 적용하는 쉬운 방법은 뷰의 select 문을 다른 select로 감싸는 것입니다.

예:

SELECT
  ISNULL(MyPrimaryID,-999) MyPrimaryID,
  NULLIF(AnotherProperty,'') AnotherProperty
  FROM ( ... ) AS temp


답변

디자이너를 사용하여이 문제를 해결할 수있었습니다.

  1. 모델 브라우저를 엽니 다.
  2. 다이어그램에서보기를 찾으십시오.
  3. 기본 키를 마우스 오른쪽 버튼으로 클릭하고 “엔터티 키”가 선택되어 있는지 확인하십시오.
  4. 기본이 아닌 모든 키를 여러 개 선택하십시오. Ctrl 또는 Shift 키를 사용하십시오.
  5. 속성 창에서 (필요한 경우 F4 키를 누름) “엔터티 키”드롭 다운을 False로 변경하십시오.
  6. 변경 사항을 저장하다.
  7. Visual Studio를 닫았다가 다시여십시오. EF 6과 함께 Visual Studio 2013을 사용하고 있으며 경고를 없애기 위해이 작업을 수행해야했습니다.

ISNULL, NULLIF 또는 COALESCE 해결 방법을 사용하기 위해 뷰를 변경할 필요가 없었습니다. 데이터베이스에서 모델을 업데이트하면 경고가 다시 나타나지만 VS를 닫았다가 다시 열면 사라집니다. 디자이너에서 변경 한 내용은 유지되며 새로 고침의 영향을받지 않습니다.


답변

@Tillito에 동의하지만 대부분의 경우 SQL 최적화 프로그램을 손상시키고 올바른 인덱스를 사용하지 않습니다.

누군가에게는 분명 할 수 있지만 Tillito 솔루션을 사용하여 성능 문제를 해결하는 데 몇 시간을 소비했습니다. 테이블이 있다고 가정 해 봅시다.

 Create table OrderDetail
    (
       Id int primary key,
       CustomerId int references Customer(Id),
       Amount decimal default(0)
    );
 Create index ix_customer on OrderDetail(CustomerId);

당신의 관점은 다음과 같습니다

 Create view CustomerView
    As
      Select
          IsNull(CustomerId, -1) as CustomerId, -- forcing EF to use it as key
          Sum(Amount) as Amount
      From OrderDetail
      Group by CustomerId

SQL Optimizer는 인덱스 ix_customer를 사용하지 않고 기본 인덱스에서 테이블 스캔을 수행하지만 다음과 같은 경우에 수행합니다.

Group by CustomerId

너는 사용한다

Group by IsNull(CustomerId, -1)

MS SQL (적어도 2008 년)은 올바른 인덱스를 계획에 포함시킵니다.

만약


답변

이 방법은 저에게 효과적입니다. 1 차 키 필드에 ISNULL ()을 사용하고 필드가 1 차 키가 아니어야하지만 널값이 아닌 값을 가져야하는 경우 COALESCE ()를 사용합니다. 이 예에서는 널 입력 불가능 기본 키가있는 ID 필드를 생성합니다. 다른 필드는 키가 아니며 Nullable 속성으로 (없음)을 갖습니다.

SELECT
ISNULL(P.ID, - 1) AS ID,
COALESCE (P.PurchaseAgent, U.[User Nickname]) AS PurchaseAgent,
COALESCE (P.PurchaseAuthority, 0) AS PurchaseAuthority,
COALESCE (P.AgencyCode, '') AS AgencyCode,
COALESCE (P.UserID, U.ID) AS UserID,
COALESCE (P.AssignPOs, 'false') AS AssignPOs,
COALESCE (P.AuthString, '') AS AuthString,
COALESCE (P.AssignVendors, 'false') AS AssignVendors
FROM Users AS U
INNER JOIN Users AS AU ON U.Login = AU.UserName
LEFT OUTER JOIN PurchaseAgents AS P ON U.ID = P.UserID

기본 키가없는 경우 ROW_NUMBER를 사용하여 스푸핑하여 코드에서 무시되는 의사 키를 생성 할 수 있습니다. 예를 들면 다음과 같습니다.

SELECT
ROW_NUMBER() OVER(ORDER BY A,B) AS Id,
A, B
FROM SOMETABLE


답변

현재 Entity Framework EDM 생성기는보기의 널 입력 불가능 필드에서 복합 키를 작성합니다. 이를 제어하려면 기본 키의 일부로 원하지 않는 경우 열을 널 입력 가능으로 설정하는보기 및 기본 테이블 열을 수정해야합니다. EDM에서 생성 된 키로 인해 데이터 중복 문제가 발생했기 때문에 그 반대도 마찬가지입니다. 따라서 EDM의 복합 키가 해당 열을 포함하도록 nullable 열을 null이 아닌 열로 정의해야했습니다.


답변


답변

난 단지 보여주기 위해했던보기 얻으려면 하나 내가 처음과 사용 NULLIF에 대한 지적이 유형이 널 만들 수있는 두 번째보기를 생성 기본 키 열을. 이것은 EF가 뷰에 단 하나의 기본 키가 있다고 생각하게 만들었습니다.

EF가 기본 키가없는 엔터티를 수락 할 것이라고 믿지 않기 때문에 이것이 도움이되는지 확실하지 않습니다.