2009-10-27 2 views
1

아래의 방법은 어떤 엔티티와도 작동하지 않기 때문에 사용하지 않아야 함을 알고 있습니다.엔티티에서 SqlBulkCopying하는 동안이 DataTable에 문제가 있습니까?

SqlBulkCopy를 사용하여 데이터를 삽입하는 System.Data.Linq.Table 확장 메서드를 발견했습니다. 엔티티 프레임 워크에 적용하려고하지만 이상한 예외가 발생하지만 원래는 Linq-To-SQL 데이터 클래스에서 작동합니다. 지금까지 결함을 발견 할 수 없었습니다. 모든 SQL 테이블에서 1-1 매핑으로 발생했습니다. 당신이 나를 도울 수?

public static class ObjectQueryExtensions 
{ 
    public static string GetName<TEntity>(
     this ObjectQuery<TEntity> objectQuery) 
     where TEntity : class 
    { 
     var tableNameGroup = new Regex(@"FROM\s([^\s]*)\s" 
      , RegexOptions.IgnoreCase); 
     var sql = objectQuery.ToTraceString(); 
     var tableNameGroupMatch = tableNameGroup.Match(sql); 
     return tableNameGroupMatch.Groups[1].Value; 
    } 

    public static void BulkInsert<TEntity>(
      this ObjectQuery<TEntity> objectQuery 
     , IEnumerable<TEntity> items) 
     where TEntity : class 
    { 
     using (var dt = new DataTable()) 
     { 
      var properties = typeof(TEntity) 
       .GetProperties() 
       .Where(property => property.Name != "EntityKey") 
       .Where(property => property.Name != "EntityState") 
       ; 
      foreach (var property in properties) 
      { 
       dt.Columns.Add(property.Name 
        , Nullable.GetUnderlyingType(property.PropertyType) 
        ?? property.PropertyType); 
      } 

      foreach (var t in items) 
      { 
       DataRow row = dt.NewRow(); 
       foreach (var info in properties) 
       { 
        row[info.Name] = info.GetValue(t, null) ?? DBNull.Value; 
       } 
       dt.Rows.Add(row); 
      } 

      var entityConnection = (EntityConnection)objectQuery 
       .Context.Connection; 
      using (var sqlBulkCopy = new SqlBulkCopy(
       entityConnection.StoreConnection.ConnectionString)) 
      { 
       sqlBulkCopy.DestinationTableName = objectQuery.GetName(); 
       sqlBulkCopy.WriteToServer(dt); 
      } 
     } 
    } 
} 

예외

예외 던져 LinqExtensionsTest.ObjectQueryExtensionsTest.BulkInsertTest

시험 방법 : 지정된 대상 칼럼의 날짜를 입력 변환 될 수있는 데이터 소스로부터 Int64 타입의 주어진 값 : System.InvalidOperationException을 . ---> System.InvalidCastException : 매개 변수 값을 Int64에서 DateTime으로 변환하지 못했습니다. ---> System.InvalidCastException : '날짜 시간'에서 'INT64'에서 잘못된 캐스트 ..

스택 추적

System.Int64.System.IConvertible.ToDateTime (IFormatProvider를 공급자) 시스템 .Convert.ChangeType (개체 값, 형식 변환 유형, IFormatProvider 공급자) System.Data.SqlClient.SqlParameter.CoerceValue (개체 값, MetaType 대상 형식) System.Data.SqlClient.SqlParameter.CoerceValue (개체 값, MetaType 대상 유형) 시스템 .Data.SqlClient.SqlBulkCopy.ConvertValue (개체 값, _SqlMetaData 메타 데이터),System.Data.SqlClient.SqlBulkCopy.ConvertValue (개체 값 _SqlMetaData 메타) System.Data.SqlClient.SqlBulkCopy.WriteToServerInternal() System.Data.SqlClient.SqlBulkCopy.WriteRowSourceToServer (INT32 열 개수)의 System.Data.SQLClient . LinqExtensions에 SqlBulkCopy.WriteToServer (DataTable의 테이블에서는 DataRowState의 RowState) System.Data.SqlClient.SqlBulkCopy.WriteToServer (DataTable의 테이블) LinqExtensions.ObjectQueryExtensions.BulkInsert [TEntity (하여 ObjectQuery 1 objectQuery, IEnumerable 1 항목) \ LinqExtensions ObjectQueryExtensions.cs \ : 라인 (60) LinqExtensionsTest.ObjectQueryExtensionsTest.BulkInsertTest() LinqExtensions \ LinqExtensionsTest \ ObjectQueryExtensionsTest.cs : 줄 88

답변

0

예외가 거의 있습니다. 엔티티 개체에 Int64이라는 속성이 있습니다.이 속성은 데이터베이스에 DateTime으로 정의되어 있으며 암시 적으로 하나에서 다른 것으로 변환 할 수있는 방법이 없습니다. 당신은 정말로 그 데이터베이스 열을 정수로 나타내려고합니까? 어쩌면 그것은 엔터티 클래스의 정의에서 실수 일뿐입니다.

+0

당신의 대답은 가장 확실 합니다만, 저는 Visual Studio Entity Designer를 사용하여 엔티티 클래스를 생성했기 때문에 그것을 믿기가 어려웠습니다. 그런 버그는 없었을 것입니다. –

+0

또한 DataTable과 SQL 프로파일 러의 모든 필드를 다시 확인 했으므로 의심스러운 부분이 확인되지 않았습니다. –

+0

분명히 타입 오류이며, 디자이너에게서 오는 것이 아닙니다. 그럼에도 불구하고 형식 오류입니다. 여기에 표시된 코드는 아니지만 프로젝트에 포함되어 있습니다.따라서 스택을 검색하여 오류를 찾아야합니다. –

3

엔티티에서 DataTable을 만들었지 만 데이터 테이블의 열 순서가 테이블의 열 순서와 일치하는지 (데이터베이스를 변경했는지, 업데이트하지 않았는지 확인하는 것이 좋습니다. 귀하의 모델). 동일하지 않은 경우 데이터 형식이 일치하지 않아 잘못된 캐스트 오류가 발생할 수 있습니다. 나에게 일어났습니다;)

+0

사실, edmx 파일에 미러링되지 않은 데이터베이스를 수정하면 해당 문제가 발생할 것입니다. edmx의 열 순서가 데이터베이스 테이블의 순서와 일치하지 않으면 예외가 발생합니다. –

+0

엔티티와 데이터베이스의 서로 다른 열 순서에 대한 솔루션은 [열 매핑 사용]입니다 (https://stackoverflow.com/a/2340053/12534). –