2013-05-06 4 views
-1

dbs를 만들거나 dbs 또는 테이블 등에서 일부 레코드를 복사하는 등 많은 db 작업을위한 서비스를 작성했습니다. 그러나 메모리 문제를 다루고 있습니다. 그 중 하나 :저장 프로 시저를 사용할 때 "메모리 부족"오류가 발생했습니다.

Im 저장 프로 시저로 레코드를 가져오고 엔티티 목록을 채 웁니다.

public List<FpBatteryEntity> LoadFPBattery() 
    { 
     List<FpBatteryEntity> retVal = new List<FpBatteryEntity>(); 

     DataSet dataSet = _dataAccessProvider.ExecuteSPDataSet("sp_fp_battery", null); 
     if (dataSet != null && dataSet.HasData()) 
     { 
      DataTable requestsTable = dataSet.Tables[0]; 
      if (requestsTable != null && requestsTable.HasData()) 
      { 
       foreach (DataRow row in requestsTable.Rows) 
       { 
        FpBatteryEntity entity = new FpBatteryEntity() 
        { 
         Faceplate = row["tf_faceplate"], 
         Battery = row["tf_battery"] 
        }; 
        retVal.Add(entity); 
       } 
      } 
     } 
     return retVal; 
    } 

그런 다음 목록의 각 엔터티에 대해 새 sp를 실행합니다.

public bool LoadFPBattery(List<FpBatteryEntity> entityList) 
    { 
     foreach (var entity in entityList) 
     { 
      DBParameterCollection parameters = new DBParameterCollection 
      { 
       new DBParameter("@faceplate", SqlDbType.VarChar, entity.Faceplate), 
       new DBParameter("@battery", SqlDbType.VarChar, entity.Battery) 
      }; 

      _dataAccessProvider.ExecuteSPNonQuery("sp_ins_fp_battery", parameters); 
     } 

     return true; 
    } 

불행하게도 30 개 이상의 연산이 있으며 그 중 일부는 수천 개의 레코드를 처리합니다.

같은 단계를 호출합니다.

 ..... 

     List<MapColorEntity> mapColor = _dbRepository.LoadMapColor(marketId); 
     if (!_otherDbRepository.LoadMapColor(mapColor)) 
      return false; 

     List<AttributesEntity> attributes = _dbRepository.LoadOptionAttrib(marketId); 
     if (!_otherDbRepository.LoadOptionAttrib(OptionAttributes)) 
      return false; 

     List<FpBatteryEntity> fpBattery = _dbRepository.LoadFPBattery(); 
     if (!_otherDbRepository.DelFPBattery()) 
      return false; 
     if (!_otherDbRepository.LoadFPBattery(fpBattery)) 
      return false; 

     ..... 

5-6 후 단계 작업은 오류 "메모리 부족"으로 손상된다. 이러한 모든 작업을 단계적으로 수행해야합니다. 이러한 작업을보다 유익하고 원활하게 만들 수있는 제안이 있다면 궁금합니다. 이 메모리 문제를 어떻게 풀 수 있습니까? 뒤에서는 어떻게됩니까?

사용법;

윈도우 7 운영 체제, 3GB의 사용 가능한 램, 사이베이스 ASE, ODBC 드라이버

+1

실제로 모든 쿼리를 하나씩 메모리에로드해야합니까? 결과를 스트리밍 할 수 없으므로 한 번에 메모리의 일부만 보유 할 수 있습니까? 또한 전체 응용 프로그램에 대해 하나의 DB 컨텍스트를 사용하지 마십시오. 당신이 만드는 각각의 거래에 대해 새로운 것을 만드십시오; 메모리 사용 공간을 줄이는 데 도움이됩니다. – Servy

+0

@servy, 결과를 스트리밍하는 것이 목적에 도움이 될 수 있으므로 시도해 보겠습니다. 하지만 내 코드는 더 복잡해질 것입니다. – htcdmrl

+0

당신이하고있는 일에 따라 크게 다르지 않습니다. 'List'보다는'IEnumerable'을 사용하고 메소드를 반복자 블록으로 바꾸십시오 (솔직히 간단하게 해주 며 복잡하지 않습니다). – Servy

답변

1

내가 대신 DataTable에의 DataReader을 사용하는 것이 좋습니다 것입니다. 이 작업을 수행하는 방식으로 데이터 사본 2 개가 메모리에 저장됩니다.

+0

고마워 frres, 어쩌면 DataReader 내 문제를 해결할 수 있지만 "_dataAccessProvider.ExecuteSPDataSet"제공하는 DLL을 사용해야합니다. 왜 dll 메서드를 DataReader 함께 반환합니다 :(어쩌면 나는 3GB 이상의 것보다 더 쓸모있는 코드 위의 올바르게 실행됩니다 .DLL 쓴 사람이 무제한 숫양 또는 다른 것을 :) 생각하십니까 :) 다른 생각이야? 나를 기능적으로 만듭니다. – htcdmrl

+0

일단 읽은 후에는 DataTable에서 레코드를 제거 할 수 있습니다. –

관련 문제