2015-01-07 1 views
0

일부 데이터를 반복하고 데이터베이스에 레코드를 만드는 메서드를 작성 중이므로이 메서드는 리포지토리를 사용합니다.dbset.local 또는 데이터베이스에서 데이터를 가져 오는 리포지토리 패턴

가 원래 이런 식으로 뭔가이었다

///Lets assume that there is a string array called arr somewhere above this. 
var repo = new ItemRepository(); 

for (int i = 0; i<1000; i++) 
{ 
    if (repo.MyItems.Count(x=>x.ID == arr[i]) == 0) 
    { 
     //Doesn't Exist Create 
     repo.MyItems.Add(new Item(arr[i])); 
     repo.Save(); 
    } 
    else 
    { 
     //Here I will get an instance of the entity that already exists and do some updates to it 
    } 
} 

일을하지만 모든 반복으로 DB에 저장했기 때문에 그것은 아주 천천히, 그래서 제가하고 싶은 것은이 같은으로 변경입니다 :

var repo = new ItemRepository(); 

for (int i = 0; i<1000; i++) 
{ 
    if (repo.MyItems.Count(x=>x.ID == arr[i]) == 0) 
    { 
     //Doesn't Exist Create 
     repo.MyItems.Add(new Item(arr[i])); 
    } 
    else 
    { 
     //Here I will get an instance of the entity that already exists and do some updates to it 
    } 

} 

repo.Save(); 

따라서 모든 엔티티가 생성 된 후에 만 ​​저장되므로 수천 개가 아닌 하나의 큰 DB 삽입이 완료됩니다.

문제는 항목이 내 데이터베이스에 다시 저장되지 않았기 때문에 repo.MyItems.Count (x => x.ID == i)가 항목을 다시 가져 오지 않았기 때문입니다. dbset.Local 컬렉션

내 질문에 내 로컬 저장소와 데이터베이스를 쿼리 할 수 ​​있도록 내 리포지토리를 수정할 수있는 방법이 있습니다. 키커이거나 데이터베이스에 있거나 이미있을 수 있기 때문입니다. 저장소에 추가되고 데이터베이스에 삽입되지 않음

위 코드는 의사 코드이지만 일종의 표현은 저장소 방법이

와 같은 것입니다.
public int count(string val) 
{ 
    IQueryable<T> data = _dbSet; 

    return data.Count(x=>x.COLUMNNAME == val); 
} 

다시 이것은 내가 repo에서 가지고있는 것의 표현 일 뿐이지 만 내가 무엇을 할 것인지에 대한 약간의 아이디어를 제공해야합니다. 내가 문제를 정확하게 이해 바랍니다

+0

저장소 패턴이 아닙니다. 그것은 DbSet에 대한 쓸모없는 추상화입니다. 사실,이 코드는 저장소 구현이 무엇보다 유사해야합니다. 하지만 유스 케이스에 저장소가 필요하지 않을 수도 있습니다. – MikeSW

+0

그리고 대부분의 건설적인 코멘트에 대한상은 다음과 같습니다 ... :) 이것은 우리가 UI와 BL 레이어를 영속 계층에 알맞게 유지하지 않고 엔터티 프레임 워크와 직접 상호 작용하지 않기 때문에 dbSet의 추상화입니다. 위의 코드는 제가 수행하려고하는 시스템에서 가져온 것이 아니며, 내가하려고하는 것을 전달하기 위해 단순화 된 의사 코드입니다. 리포지토리 패턴의 구현이 어떻게되어야하는지에 대한 의견이 있으실 것입니다. 임포트가 잘못되어 있다면 그것에 대해 알고 싶습니다!:) – D3vy

+0

UI가 알 수도 있지만 BL은 DbSet 또는 EF [DAO 또는 db를 삽입하십시오]와 관련된 모든 것을 알지 못합니다. 귀하의 '저장소'는 가치를 더하지 않으며 누출됩니다. 'repository.Items.Add/Count'가 없습니다. 그냥 'repository.Add (aLotOfBusinessObjects)'가 있어야합니다. 여기서하고있는 일은 추상화 아래 숨겨진 EF를 사용하는 것입니다. 그러나 사고 방식과 코드는 EF입니다. 빠른 테스트 : 당신이 Azure 테이블로 전환하고있는 것처럼 가장해야하는 유일한 변화는 저장소 구현이 아니라 인터페이스가 아니라 저장소를 호출하는 코드입니다. – MikeSW

답변

0

중 하나에 관심이 있다면, 이것이 내가 구현 및 작동 듯 무엇, 그러나 나는 최대에 제공 끝났다 이것은 시스템의 나머지 부분에 영향을 미친 데이터의 "더티 읽기 (Dirty Reads)"를 허용 할 것이며, 다중 저장의 성능 저하가 시스템의 큰 부분을 재 작업하는 것보다 더 바람직하다는 결론을 얻었습니다. 또는 더티 읽기를 허용하는 repo 구현 ...

참고 : GetSingle은 내가 가지고있는 Count를 대체합니다. 위의 코드.

public T GetSingle(System.Linq.Expressions.Expression<Func<T, bool>> filter = null) 
    { 
     //Check the local collection first 

     IQueryable<T> localEntities = _dbset.Local.AsQueryable(); 

     if (filter != null) 
     { 
      localEntities = localEntities.Where(filter); 
     } 

     if (localEntities.Count() > 0) 
     { 
      return localEntities.FirstOrDefault(); 
     } 
     else 
     { 
      //A local version of this was not found - try the database. 

      IQueryable<T> query = this._dbset; 

      if (filter != null) 
      { 
       query = query.Where(filter); 
      } 

      return query.FirstOrDefault(); 
     }    
    } 

나는 정말 내가 그와 끝까지해야하는 I 아마 다시 발생 하겠어 문제 및 다음 시간으로 알고 싶습니다이 할 수있는 더 좋은 방법이 있다면 !

0

, 이것은 내가 일반적으로 할 것입니다 :

 var repo = new ItemRepository(); 

     Int32 index = 0; 
     Int32 localIndex = 0; 
     while (index < arr.Length) { 
      repo.MyItems.Add(new Item(arr[index])); 
      index++; 
      localIndex++; 
      if (localIndex == 1000) { 
       repo.Save(); 
       localIndex = 0; 
      } 
     } 
     if (localIndex > 0) { 
      repo.Save(); 
     } 
+0

응답 해 주셔서 감사합니다. 새로운 항목을 추가하기 전에 항목의 존재 여부를 확인하지 않았으므로 나중에 처리 한 내용이 아닙니다. 이유는 (위의 코드에서 간략하게하기 위해 생략했습니다) 이유는 'repo.MyItems.Count (x => x.ID == arr [i])'가 둘 이상을 반환하면 해당 엔티티가 업데이트됩니다.이 경우 일부 엔티티 엔티티가 첨부됩니다. – D3vy

+0

업데이트가 발생한 위치를 보여주기 위해 코드를 업데이트했습니다. – D3vy