2017-03-03 1 views
0

간단한 SQL Server 테이블에 파일 이름 목록을 삽입하려고합니다..NET 문자열 []을 FastMember 객체에 매핑하려고했지만 오류가 있거나 매핑되지 않았습니다.

다른 SO 답변에서 제안한대로 SqlBulkCopy 및 @markgravell's FastMember 라이브러리를 활용하려고합니다. 이 매핑 문제처럼

public async Task AddFileNamesAsync(string[] fileNames) 
{ 
    fileNames.ShouldNotBeNull(); 

    using (var bulkCopy = new SqlBulkCopy(ConnectionString)) 
    { 
     using (var reader = ObjectReader.Create(fileNames)) 
     { 
      bulkCopy.DestinationTableName = "FileNames"; 
      bulkCopy.ColumnMappings.Add("value", "FileName"); 
      await bulkCopy.WriteToServerAsync(reader) 
          .ConfigureAwait(false); 
     } 
    } 
} 

CREATE TABLE [dbo].[FileNames](
[FileNameId] [int] IDENTITY(1,1) NOT NULL, 
[FileName] [varchar](500) NOT NULL 

그래서 내가 느끼는 중 하나에 : - 일부 내부 기가되는 콜렉션 에 매핑 할 FastMember 수 없습니다 - FastMember의 기가되는 콜렉션이 같은 이름이없는 DB 컬럼으로는 할 수 있습니다 지도가 없습니다.

아무도 도와 줄 수 있습니까?

+0

당신은 IDataReader의 독자적인 구현을 작성할 수 있습니다. SqlBulkCopy는 판독기에서 GetValue, Read 및 FieldCount 구현을 호출하기 때문에 사용자 지정 판독기를 작성하는 것이 상대적으로 쉽습니다. 그냥 생각. – TnTinMn

답변

1

GitHub 소스 코드를 검토하기 전에이 라이브러리를 사용한 적이 한번도 없었습니다. 소스에서 쿼리하는 속성이 필요합니다. 이제 문자열에는 속성이 없습니다 value 실제로 사용해야하는 것은 모두 Length 속성입니다. Length을 사용하십시오. 이제는 FastMember 라이브러리에서 문제가 될 수 있습니다. FastMember 라이브러리에서는 대상 객체에서 Property를 캡처하기 위해 CallSite 접근 자 함수를 만듭니다.

Source here

는 지금은 연극이 있고 작동 재산에 액세스 할 수 없습니다. 언뜻보기에는 TypeAccessor 결과에 Chars 속성이 반환되지만 작동하지 않는 것으로 보입니다.

내 제안은 실제로 질문에 대한 답변이 아니라 작동하도록하는 방법입니다. 문자열의 속성이있는 유형을 만든 경우 효과적으로이 문제를 해결할 수 있습니다. 우리는 각각의 파일 이름입니다 value의 특성을 가진 새로운 유형의 생성 된

public async Task AddFileNamesAsync(string[] fileNames) 
{ 
    fileNames.ShouldNotBeNull(); 

    var list = fileNames.Select(f => new { value = f }); 

    using (var bulkCopy = new SqlBulkCopy(ConnectionString)) 
    { 
     using (var reader = ObjectReader.Create(list)) 
     { 
      bulkCopy.DestinationTableName = "FileNames"; 
      bulkCopy.ColumnMappings.Add("value", "FileName"); 

      try 
      { 
       await bulkCopy.WriteToServerAsync(reader) 
           .ConfigureAwait(false); 

      } 
      catch(Exception ex) 
      { 

      } 
     } 
    } 
} 

지금이 작동합니다. 이제 실행은 예상대로 작동합니다. ( try..catch...은 테스트 용이었습니다.)

+0

나는이 제안 된 답을 두려워했다. 왜냐하면 나는 데이터의 두 복사본을 가지기 때문이다. 물론, 우리는 bazillion (소스) 문자열을 말하는 것이 아닙니다 ... 그러나 그것은 요점입니다. 이것이 제가 OP에서 언급 한 것을 피한 이유였습니다. 흠 ....... 버머. 하지만 그래 ... 나는이 대답과 같은 줄을 따라 생각하고 있었다. –

+0

@ Pure.Krome 죄송합니다. FastMember의 소스 코드를 실제로 변경하거나 다시 컴파일하지 않고도 해킹 할 수있는 방법이 없습니다. 나는 메소드에 접근하는 방법을 시도했다. (즉, 문자열에서'ToString() '을 호출했다.)하지만 속성에만 고정되었다. – Nico

+0

문제가 없습니다. :) 정말 고마워! –

관련 문제