2011-11-29 2 views
2

저는 Entity Framework가 새로 도입되어 순수한 t-sql에서 매우 쉬운 문제가 있습니다. 우리는 3 개의 열이있는 테이블을 가지고 있다고 가정합니다. Id (ID, 기본 키), IdKind (int), Number (int)입니다. Column Nubmer는 IdKind 열에 종속됩니다. 이 표의 데이터는 다음과 같아야합니다.다른 필드의 값에 따라 엔티티 프레임 워크에서 증가 필드

Id | IdKind | 넘버

1 | 1 | 1

2 | 1 | 2

3 | 1 | 3

4 | 2 | 1

5 | 2 | 2

6 | 2 | 3

열 번호가 자동으로 증가하는 것을 볼 수 있듯이 IdKind에 따라 다릅니다. t-sql에서 IdKind에 대해 max (Number) + 1을 찾았습니다. 하나의 트랜잭션에서 모든 것이 하나의 저장 프로 시저에 있었기 때문에 Number 값은 IdKind에 고유했습니다.

Entity Framework에서 동일한 작업을 수행하는 방법. Number of Value는 새 객체를 만들거나 IdKind를 변경할 때 계산됩니다.

답변

4

데이터베이스 트리거를 사용하고 StoreGeneratedPattern.Computed으로 EF 매핑의 Number 속성을 구성하여 EF에이 속성이 데이터베이스에 채워져 있고 각 업데이트/삽입 후에 다시로드해야 함을 알립니다.

또한 각 새 번호에 max()를 사용하지 않을 것입니다. 대신 나는 시퀀스를 시뮬레이션하는 별도의 테이블을 유지 관리 할 것이다. 이 테이블에는 시퀀스 당 레코드가 포함되어야합니다. IdKind 당 최대 레코드 수를 기록하십시오. 집계를 선택하는 대신 단일 레코드를 선택하고 새로운 최대 숫자를 포함하도록 업데이트합니다. 이 테이블을 사용하여 작업하는 것은 엔티티에 대한 지속적인 변경 사항과 동일한 트랜잭션에 있어야합니다.

0

나는 동일한 문제가 있었지만 C#으로 해결했습니다.

내가 테이블에 매핑 된 엔티티가 있어야합니다 종류에 따라 사용 된 마지막 번호를 저장하는

public class MyEntity 
{ 
    Kind IdKind{get; set;} 
    int Number{get;set;} 
} 

내가해야 및 보조 기관을.

public class LastNumber 
{ 
    Kind IdKind{get;set;} 
    int LastNumber{get;set;} 
} 

그 다음 테이블의 행 (MyEntity 객체)를 추가하기 전에, I 종류와 LastNumberEntity LastNumber의 필드를 사용하여 적절한 수를 계산한다 내 종류 값과 같다.

두 개의 서로 다른 스레드가 같은 종류의 개체를 동시에 추가 할 수 있으므로이 스레드는 동시성 문제가 있음을 알아야합니다. 스레드는 동일한 LastNumberEntity를 검사하여 LastNumber 값을 가져옵니다. 이 문제는 엔티티 프레임 워크에서 알려진 해결책이 있습니다. 이 코드는 수는 다음과 같습니다

public int GetNumber(Kind idKind) 
    { 
     using (var db = new MyDataContext()) 
     { 
      var lastNumber = db.LastNumbers.Single(x=>x.IdKind == idKind); 
      for (int attemps = 0; attemps < 10;) 
      { 
       try 
       { 
        lastNumber.LastNumber++; 
        db.SaveChanges(); 
        return lastNumber.LastNumber; 
       } 
       catch (DbUpdateConcurrencyException ex) 
       { 
        attemps++; 
       } 
      } 
     } 

     throw new Exception("Many concurrency calls"); 
    } 

이 방법은 특정 종류의 증가 수를 얻고이를 사용하여 동시성 문제를 처리, 우리는 각 MyEntity 개체의 숫자 값을 설정할 수 있습니다.클라이언트 코드는 수 다음과 같습니다

var entity = new MyEntity(); 
var number = GetNumber(entity.IdKind); 
entity.Number = number; 
db.MyEntities.Add(entity); 
db.SaveChanges(); 

이 코드는 항상 GetNumber 방법을 사용하여 DB를 관리하는 저장소를 사용하여 생성 된 엔티티를 보장하기 위해 공장을 만드는 세터 개인 만들기, 리팩토링 할 수있다.

관련 문제