2014-10-29 3 views
1

현재 Entity Framework를 사용하고 있으며 정기적으로 여러 항목을 업데이트해야합니다.SQL Compact Edition 일괄 업데이트

내가해야 할 일은 몇 가지 다른 테이블을 기반으로 한 저널링 번호를 추가하는 것입니다. SQL Server를 사용하면 내부 및 외부 조인 GROUP BY 및 ROW_NUMBER와 함께 스토어드 프로 시저를 사용할 수 있습니다.이 프로 시저는 저를 위해 무거운 작업을 수행하며 매우 효율적입니다.

CREATE PROCEDURE [dbo].[sp_UpdateNumber] 
    @RefId int 
AS 
BEGIN 
    UPDATE TableWithNumber 
    SET Nmr = other.Nmr 
    FROM (
     SELECT MIN(C.Nmr) as Nmr, Z_ID 
     FROM 
     (
      SELECT 
       ROW_NUMBER() OVER (ORDER BY D.TicksCreatedOn, D.Z_Id, D.B_ID) as Nmr, D.* 
       FROM (
        SELECT 
          S.Id as S_ID, 
          Z.Id as Z_ID, 
          B.Id as B_ID, 
          S.TicksCreatedOn 
        FROM 
          ChildTable as B 
          INNER JOIN TableWithNumber Z on Z.ChildTableRefA_Id = B.Id 
          INNER JOIN ParentTable S on Z.ParentTable_Id = S.Id 
        WHERE S.Ref_Id = @RefId 
       UNION 
        SELECT 
          S.Id as S_ID, 
          Z.Id as Z_ID, 
          B.Id as B_ID, 
          S.TicksCreatedOn 
        FROM 
          ChildTable as B 
          INNER JOIN TableWithNumber Z on Z.ChildTableRefB_Id = B.Id 
          INNER JOIN ParentTable S on Z.ParentTable_Id = S.Id 
        WHERE S.Ref_Id = @RefId) as D 
     ) as C 
    GROUP BY C.Z_ID) as other 
    WHERE other.Z_ID = Id AND Ref_Id = @RefId 
END 

때문에 저장 프로 시저가 SQL 세륨에서 사용할 수있는, 당신은 하위 선택에 GROUP BY를 사용하는 방법에 대한 자세한 제한하지, 난 이제 저널링 수를 계산해야 다음과 같이

는 프로 시저 코드를 참조하십시오 코드에서. 컨텍스트에서 SqlQuery를 사용하여 최소 필수 데이터 세트를 검색하고 그룹화 한 다음 엔티티 당 업데이트를 시작합니다.

SELECT ZID 
FROM 
    (SELECT S.Id as [SID], Z.Id as [ZID], B.Id as [BID], S.TicksCreatedOn 
    FROM ChildTable AS B 
     INNER JOIN TableWithNumber as Z on Z.ChildTableRefA_Id = B.Id 
     INNER JOIN ParentTable as S on Z.ParentTable_Id = S.Id 
    WHERE S.Ref_Id = @RefId 
    UNION 
    SELECT S.Id as [SID], Z.Id as [ZID], B.Id as [BID], S.TicksCreatedOn 
    FROM ChildTable AS B 
     INNER JOIN TableWithNumber as Z on Z.ChildTableRefB_Id = B.Id 
     INNER JOIN ParentTable as S on Z.ParentTable_Id = S.Id 
     WHERE S.Ref_Id = @RefId) AS D 
ORDER BY TicksCreatedOn, ZID, BID 


     var result = Database.SqlQuery<NumberUpdate>(QUERY, new SqlCeParameter("@RefId", 1)).ToList(); 

응용 프로그램의 코드는 foreach 문에 ExecuteSqlCommand를 호출하는 것보다 SQL의 CE에서 개체의 목록을 업데이트 할 수있는 더 빠르거나 더 효율적인 방법이 있는지 궁금 해서요이

var grouped = result 
     .Select((x,y) => new NumberUpdate { ZID = x.ZID, Number = ++y }) 
     .GroupBy(x => x.ZID); 

    foreach (var group in grouped) 
    { 
     Database.ExecuteSqlCommand("UPDATE TableWithNumber SET Number = @Nr WHERE Id = @Id", 
      new SqlCeParameter("@Nr", group.Min(x => x.Number)), 
      new SqlCeParameter("@Id", group.Key)); 
    } 

처럼 약간 보인다 고리?

+0

내가 찾을 수있는 유일한 개선점은 'foreach' 루프 전에 SqlCeCommand를 준비한 다음 루프 내에서 기존 매개 변수의 값만 변경하는 것입니다. 그러나 UPDATE는 SQL CE 내에서 매우 제한적입니다. –

+0

내장 데이터베이스에서 저장 프로 시저 및 트리거가 필요한 경우 [LocalDB] (http://blogs.msdn.com/b/sqlexpress/archive/2011/07/12/introducing-localdb-a-better-sql- express.aspx). –

+0

LocalDB는 좋았을 것이고 그것을 사용하는 것을 좋아했을 것입니다. 그러나 응용 프로그램의 중요한 요구 사항 중 하나는 배포/복사가 가능해야하며 설치 루틴이 필요하지 않아야한다는 것입니다. LocalDB는 클라이언트에서 설정이 필요하기 때문에 불행히도 옵션이 아닙니다. 다시 한번, 나는 그것을 사용하는 것을 좋아했을 것이다. – UrbanEsc

답변

0

비즈니스 논리를 사용하면 복잡한 SQL 명령이 아닌 여러 행의 데이터를 "행 단위"로 업데이트 할 수 있으므로 "테이블 직접"방식을 시도 할 수 있습니다. 여기에는 다음 단계가 포함됩니다.

만들기 SqlCeConnection SDF 파일을 가리키는 연결 문자열을 가진 개체입니다. 이 연결에 대한 SqlCeCommand 개체를 만듭니다. CommandType.TableDirect입니다. SqlCeResultSetResultSetOptions.UpdatableResultSetOptions.Scrollable을 만듭니다.

이제, 읽기업데이트 방법을 탐색 를 사용하여 테이블 행을 업데이트 할 수 있습니다. 이 접근법은 가능한 가장 빠른 방법입니다. 그러나 전통적인 EF 방식보다 훨씬 많은 코드를 작성해야합니다.

관련 문제