Что не так с этим DataTable при SqlBulkCopy-от Entity? - PullRequest
1 голос
/ 27 октября 2009

Я знаю, что приведенный ниже метод не предназначен для работы с какой-либо сущностью, и его использование не должно быть принудительным.

Я нашел метод расширения System.Data.Linq.Table, который использует SqlBulkCopy для вставки данных. Я пытаюсь адаптировать его к Entity Framework, но он выдает странное исключение, в то время как оригинал работает для классов данных 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 вызвал исключение: System.InvalidOperationException: данное значение типа Int64 из источника данных нельзя преобразовать в тип datetime указанного целевого столбца. ---> System.InvalidCastException: не удалось преобразовать значение параметра из Int64 в DateTime. ---> System.InvalidCastException: недопустимое приведение от 'Int64' к 'DateTime' ..

трассировка стека

System.Int64.System.IConvertible.ToDateTime (поставщик IFormatProvider) System.Convert.ChangeType (значение объекта, тип преобразования типа, поставщик IFormatProvider) System.Data.SqlClient.SqlParameter.CoerceValue (значение объекта, MetaType destinationType) System.Data.SqlClient.SqlParameter.CoerceValue (значение объекта, MetaType destinationType) System.Data.SqlClient.SqlBulkCopy.ConvertValue (значение объекта, метаданные _SqlMetaData) System.Data.SqlClient.SqlBulkCopy.ConvertValue (значение объекта, метаданные _SqlMetaData) System.Data.SqlClient.SqlBulkCopy.WriteToServerInternal () System.Data.SqlClient.SqlBulkCopy.WriteRowSourceToServer (Int32 columnCount) System.Data.SqlClient.SqlBulkCopy.WriteToServer (таблица DataTable, DataRowState rowState) System.Data.SqlClient.SqlBulkCopy.WriteToServer (таблица DataTable) LinqExtensions.ObjectQueryExtensions.BulkInsert [TEntity] (ObjectQuery 1 objectQuery, IEnumerable 1 элементов) в LinqExtensions \ LinqExtensions \ ObjectQueryExtensions.cs: строка 60 LinqExtensionsTest.ObjectQueryExtensionsTest.BulkInsertTest () в LinqExtensions \ LinqExtensionsTest \ ObjectQueryExtensionsTest.cs: строка 88

Ответы [ 2 ]

3 голосов
/ 17 декабря 2013

Я знаю, что вы создали свой DataTable из своих сущностей, но я предлагаю проверить, совпадает ли порядок столбцов в DataTable со столбцами в таблице (возможно, вы изменили свою базу данных и не обновили свой модель). Если это не то же самое, вы можете иметь несоответствующий тип данных и столкнуться с недопустимой ошибкой приведения. Это случилось со мной;)

0 голосов
/ 27 октября 2009

Исключение, которое вы получили, в значительной степени говорит обо всем: в вашем объектном объекте у вас есть свойство типа Int64, которое в базе данных определено как DateTime, и нет способа неявного преобразования одного в другое. Вы действительно намереваетесь представить этот столбец базы данных как целое число? Может быть, это просто ошибка в определении класса сущности.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...