diff --git a/EntityFramework.Utilities/EntityFramework.Utilities/EFBatchOperation.cs b/EntityFramework.Utilities/EntityFramework.Utilities/EFBatchOperation.cs index 72fa98c..6120997 100644 --- a/EntityFramework.Utilities/EntityFramework.Utilities/EFBatchOperation.cs +++ b/EntityFramework.Utilities/EntityFramework.Utilities/EFBatchOperation.cs @@ -21,7 +21,8 @@ public interface IEFBatchOperationBase where T : class /// The items to insert /// The DbConnection to use for the insert. Only needed when for example a profiler wraps the connection. Then you need to provide a connection of the type the provider use. /// The size of each batch. Default depends on the provider. SqlProvider uses 15000 as default - void InsertAll(IEnumerable items, DbConnection connection = null, int? batchSize = null) where TEntity : class, T; + void InsertAll(IEnumerable items, DbConnection connection = null, int? batchSize = null, int? executeTimeout = null) where TEntity : class, T; + IEFBatchOperationFiltered Where(Expression> predicate); @@ -66,7 +67,7 @@ public static IEFBatchOperationBase For(TContext conte return EFBatchOperation.For(context, set); } } - public class EFBatchOperation : IEFBatchOperationBase, IEFBatchOperationFiltered + public class EFBatchOperation : IEFBatchOperationBase, IEFBatchOperationFiltered where T : class where TContext : DbContext { @@ -95,7 +96,7 @@ public static IEFBatchOperationBase For(TContext conte /// The items to insert /// The DbConnection to use for the insert. Only needed when for example a profiler wraps the connection. Then you need to provide a connection of the type the provider use. /// The size of each batch. Default depends on the provider. SqlProvider uses 15000 as default - public void InsertAll(IEnumerable items, DbConnection connection = null, int? batchSize = null) where TEntity : class, T + public void InsertAll(IEnumerable items, DbConnection connection = null, int? batchSize = null, int? executeTimeout = null) where TEntity : class, T { var con = context.Connection as EntityConnection; if (con == null && connection == null) @@ -117,6 +118,7 @@ public void InsertAll(IEnumerable items, DbConnection connecti var properties = tableMapping.PropertyMappings .Where(p => currentType.IsSubclassOf(p.ForEntityType) || p.ForEntityType == currentType) .Select(p => new ColumnMapping { NameInDatabase = p.ColumnName, NameOnObject = p.PropertyName }).ToList(); + if (tableMapping.TPHConfiguration != null) { properties.Add(new ColumnMapping @@ -157,12 +159,13 @@ public void UpdateAll(IEnumerable items, Action currentType.IsSubclassOf(p.ForEntityType) || p.ForEntityType == currentType) - .Select(p => new ColumnMapping { - NameInDatabase = p.ColumnName, - NameOnObject = p.PropertyName, + .Select(p => new ColumnMapping + { + NameInDatabase = p.ColumnName, + NameOnObject = p.PropertyName, DataType = p.DataTypeFull, IsPrimaryKey = p.IsPrimaryKey - }).ToList(); + }).ToList(); var spec = new UpdateSpecification(); updateSpecification(spec); @@ -203,7 +206,7 @@ public int Delete() } else { - Configuration.Log("Found provider: " + (provider == null ? "[]" : provider.GetType().Name ) + " for " + con.StoreConnection.GetType().Name); + Configuration.Log("Found provider: " + (provider == null ? "[]" : provider.GetType().Name) + " for " + con.StoreConnection.GetType().Name); return Fallbacks.DefaultDelete(context, this.predicate); } } @@ -231,7 +234,7 @@ public int Update(Expression> prop, Expression> modi var mqueryInfo = provider.GetQueryInformation(mquery); var update = provider.GetUpdateQuery(queryInformation, mqueryInfo); - + var parameters = query.Parameters .Concat(mquery.Parameters) .Select(p => new SqlParameter { Value = p.Value, ParameterName = p.Name }) @@ -247,6 +250,6 @@ public int Update(Expression> prop, Expression> modi } - + } } diff --git a/EntityFramework.Utilities/EntityFramework.Utilities/EFDataReader.cs b/EntityFramework.Utilities/EntityFramework.Utilities/EFDataReader.cs index 432373c..00e4222 100644 --- a/EntityFramework.Utilities/EntityFramework.Utilities/EFDataReader.cs +++ b/EntityFramework.Utilities/EntityFramework.Utilities/EFDataReader.cs @@ -36,17 +36,24 @@ public EFDataReader(IEnumerable items, IEnumerable properties) var temp = info; foreach (var part in parts.Skip(1)) { - var i = temp.PropertyType.GetProperty(part); - var g = i.GetGetMethod(); - - var old = getter; - getter = x => g.Invoke(old(x), null); - - temp = i; + try + { + var i = temp.PropertyType.GetProperty(part); + var g = i.GetGetMethod(); + + var old = getter; + getter = x => g.Invoke(old(x), null); + + temp = i; + } + catch (Exception ex) + { + throw ex; + } } - - + return getter; + }).ToList(); Items = items; Enumerator = items.GetEnumerator(); diff --git a/EntityFramework.Utilities/EntityFramework.Utilities/EntityFramework.Utilities.csproj b/EntityFramework.Utilities/EntityFramework.Utilities/EntityFramework.Utilities.csproj index 75bd2c5..1b6ad35 100644 --- a/EntityFramework.Utilities/EntityFramework.Utilities/EntityFramework.Utilities.csproj +++ b/EntityFramework.Utilities/EntityFramework.Utilities/EntityFramework.Utilities.csproj @@ -31,12 +31,10 @@ - False - ..\packages\EntityFramework.6.1.3\lib\net40\EntityFramework.dll + ..\..\..\herbalife.bi\src\packages\EntityFramework.6.1.3\lib\net40\EntityFramework.dll - False - ..\packages\EntityFramework.6.1.3\lib\net40\EntityFramework.SqlServer.dll + ..\..\..\herbalife.bi\src\packages\EntityFramework.6.1.3\lib\net40\EntityFramework.SqlServer.dll diff --git a/EntityFramework.Utilities/EntityFramework.Utilities/IQueryProvider.cs b/EntityFramework.Utilities/EntityFramework.Utilities/IQueryProvider.cs index e0af4d9..8f83335 100644 --- a/EntityFramework.Utilities/EntityFramework.Utilities/IQueryProvider.cs +++ b/EntityFramework.Utilities/EntityFramework.Utilities/IQueryProvider.cs @@ -15,14 +15,11 @@ public interface IQueryProvider string GetDeleteQuery(QueryInformation queryInformation); string GetUpdateQuery(QueryInformation predicateQueryInfo, QueryInformation modificationQueryInfo); - void InsertItems(IEnumerable items, string schema, string tableName, IList properties, DbConnection storeConnection, int? batchSize); - void UpdateItems(IEnumerable items, string schema, string tableName, IList properties, DbConnection storeConnection, int? batchSize, UpdateSpecification updateSpecification); + void InsertItems(IEnumerable items, string schema, string tableName, IList properties, DbConnection storeConnection, int? batchSize, int? executeTimeout = null); + void UpdateItems(IEnumerable items, string schema, string tableName, IList properties, DbConnection storeConnection, int? batchSize, UpdateSpecification updateSpecification, int? executeTimeout = null); bool CanHandle(DbConnection storeConnection); - QueryInformation GetQueryInformation(System.Data.Entity.Core.Objects.ObjectQuery query); - - } } diff --git a/EntityFramework.Utilities/EntityFramework.Utilities/MappingHelper.cs b/EntityFramework.Utilities/EntityFramework.Utilities/MappingHelper.cs index 1100b1a..dcaee9e 100644 --- a/EntityFramework.Utilities/EntityFramework.Utilities/MappingHelper.cs +++ b/EntityFramework.Utilities/EntityFramework.Utilities/MappingHelper.cs @@ -227,7 +227,10 @@ public EfMapping(DbContext db) private string GetFullTypeName(ScalarPropertyMapping scalar) { - if (scalar.Column.TypeName == "nvarchar" || scalar.Column.TypeName == "varchar") + if (scalar.Column.TypeName == "nvarchar" || + scalar.Column.TypeName == "varchar" || + scalar.Column.TypeName == "nchar" || + scalar.Column.TypeName == "char") { return string.Format("{0}({1})", scalar.Column.TypeName, scalar.Column.MaxLength); } diff --git a/EntityFramework.Utilities/EntityFramework.Utilities/SqlQueryProvider.cs b/EntityFramework.Utilities/EntityFramework.Utilities/SqlQueryProvider.cs index ca85d23..d3234e8 100644 --- a/EntityFramework.Utilities/EntityFramework.Utilities/SqlQueryProvider.cs +++ b/EntityFramework.Utilities/EntityFramework.Utilities/SqlQueryProvider.cs @@ -40,14 +40,14 @@ public string GetUpdateQuery(QueryInformation predicateQueryInfo, QueryInformati } else { - updateSql = string.Join(" = ", update.Split(new string[]{" = "}, StringSplitOptions.RemoveEmptyEntries).Reverse()); + updateSql = string.Join(" = ", update.Split(new string[] { " = " }, StringSplitOptions.RemoveEmptyEntries).Reverse()); } - + return string.Format("UPDATE [{0}].[{1}] SET {2} {3}", predicateQueryInfo.Schema, predicateQueryInfo.Table, updateSql, predicateQueryInfo.WhereSql); } - public void InsertItems(IEnumerable items, string schema, string tableName, IList properties, DbConnection storeConnection, int? batchSize) + public void InsertItems(IEnumerable items, string schema, string tableName, IList properties, DbConnection storeConnection, int? batchSize, int? executeTimeout = null) { using (var reader = new EFDataReader(items, properties)) { @@ -56,9 +56,12 @@ public void InsertItems(IEnumerable items, string schema, string tableName { con.Open(); } - using (SqlBulkCopy copy = new SqlBulkCopy(con)) + + using (SqlBulkCopy copy = new SqlBulkCopy(con, SqlBulkCopyOptions.TableLock, null)) { + copy.BulkCopyTimeout = executeTimeout ?? 600; copy.BatchSize = Math.Min(reader.RecordsAffected, batchSize ?? 15000); //default batch size + if (!string.IsNullOrWhiteSpace(schema)) { copy.DestinationTableName = string.Format("[{0}].[{1}]", schema, tableName); @@ -67,7 +70,7 @@ public void InsertItems(IEnumerable items, string schema, string tableName { copy.DestinationTableName = "[" + tableName + "]"; } - + copy.NotifyAfter = 0; foreach (var i in Enumerable.Range(0, reader.FieldCount)) @@ -81,7 +84,7 @@ public void InsertItems(IEnumerable items, string schema, string tableName } - public void UpdateItems(IEnumerable items, string schema, string tableName, IList properties, DbConnection storeConnection, int? batchSize, UpdateSpecification updateSpecification) + public void UpdateItems(IEnumerable items, string schema, string tableName, IList properties, DbConnection storeConnection, int? batchSize, UpdateSpecification updateSpecification, int? executeTimeout = null) { var tempTableName = "temp_" + tableName + "_" + DateTime.Now.Ticks; var columnsToUpdate = updateSpecification.Properties.Select(p => p.GetPropertyName()).ToDictionary(x => x); @@ -99,8 +102,8 @@ public void UpdateItems(IEnumerable items, string schema, string tableName var setters = string.Join(",", filtered.Where(c => !c.IsPrimaryKey).Select(c => "[" + c.NameInDatabase + "] = TEMP.[" + c.NameInDatabase + "]")); var pks = properties.Where(p => p.IsPrimaryKey).Select(x => "ORIG.[" + x.NameInDatabase + "] = TEMP.[" + x.NameInDatabase + "]"); - var filter = string.Join(" and ", pks); - var mergeCommand = string.Format(@"UPDATE [{0}] + var filter = string.Join(" and ", pks); + var mergeCommand = string.Format(@"UPDATE [{0}] SET {3} FROM @@ -114,13 +117,16 @@ INNER JOIN using (var mCommand = new SqlCommand(mergeCommand, con)) using (var dCommand = new SqlCommand(string.Format("DROP table {0}.[{1}]", schema, tempTableName), con)) { + createCommand.CommandTimeout = executeTimeout ?? 600; + mCommand.CommandTimeout = executeTimeout ?? 600; + createCommand.ExecuteNonQuery(); InsertItems(items, schema, tempTableName, filtered, storeConnection, batchSize); mCommand.ExecuteNonQuery(); dCommand.ExecuteNonQuery(); } - + }