From 912ed92a889999da581bdaeeeb073b3b4ce4c8e4 Mon Sep 17 00:00:00 2001 From: NorthernLight1 <49600465+NorthernLight1@users.noreply.github.com> Date: Fri, 7 Jun 2024 22:56:20 -0400 Subject: [PATCH 1/4] Added Support For Proxy Types --- .../Data/ProductWithTrigger.cs | 27 +++++++++++++++++++ .../Data/TestDbContext.cs | 2 ++ .../DbContextExtensions/BulkInsert.cs | 22 +++++++++++++++ .../DbContextExtensions/BulkInsertAsync.cs | 22 +++++++++++++++ ...EntityFrameworkCore.Extensions.Test.csproj | 11 ++++---- 5 files changed, 79 insertions(+), 5 deletions(-) create mode 100644 N.EntityFrameworkCore.Extensions.Test/Data/ProductWithTrigger.cs diff --git a/N.EntityFrameworkCore.Extensions.Test/Data/ProductWithTrigger.cs b/N.EntityFrameworkCore.Extensions.Test/Data/ProductWithTrigger.cs new file mode 100644 index 0000000..b5b6f2b --- /dev/null +++ b/N.EntityFrameworkCore.Extensions.Test/Data/ProductWithTrigger.cs @@ -0,0 +1,27 @@ +using System; +using System.Collections.Generic; +using System.ComponentModel.DataAnnotations; +using System.ComponentModel.DataAnnotations.Schema; +using System.Text; +using N.EntityFrameworkCore.Extensions.Test.Data.Enums; + +namespace N.EntityFrameworkCore.Extensions.Test.Data +{ + public class ProductWithTrigger + { + [Key] + [DatabaseGenerated(DatabaseGeneratedOption.None)] + public string Id { get; set; } + [StringLength(50)] + public string Name { get; set; } + public decimal Price { get; set; } + public bool OutOfStock { get; set; } + [Column("Status")] + [StringLength(25)] + public string StatusString { get; set; } + public ProductWithTrigger() + { + + } + } +} \ No newline at end of file diff --git a/N.EntityFrameworkCore.Extensions.Test/Data/TestDbContext.cs b/N.EntityFrameworkCore.Extensions.Test/Data/TestDbContext.cs index 86d9433..91fc88a 100644 --- a/N.EntityFrameworkCore.Extensions.Test/Data/TestDbContext.cs +++ b/N.EntityFrameworkCore.Extensions.Test/Data/TestDbContext.cs @@ -27,6 +27,7 @@ protected override void OnConfiguring(DbContextOptionsBuilder optionsBuilder) { optionsBuilder.UseSqlServer(Config.GetConnectionString("TestDatabase")); optionsBuilder.SetupEfCoreExtensions(); + optionsBuilder.UseLazyLoadingProxies(); } protected override void OnModelCreating(ModelBuilder modelBuilder) { @@ -50,6 +51,7 @@ protected override void OnModelCreating(ModelBuilder modelBuilder) t.ComplexProperty(p => p.Position).IsRequired(); t.Property(p => p.Color).HasConversion(x => x.ToArgb(), x => Color.FromArgb(x)); }); + } } } \ No newline at end of file diff --git a/N.EntityFrameworkCore.Extensions.Test/DbContextExtensions/BulkInsert.cs b/N.EntityFrameworkCore.Extensions.Test/DbContextExtensions/BulkInsert.cs index d0b7a81..db3d9e5 100644 --- a/N.EntityFrameworkCore.Extensions.Test/DbContextExtensions/BulkInsert.cs +++ b/N.EntityFrameworkCore.Extensions.Test/DbContextExtensions/BulkInsert.cs @@ -2,6 +2,7 @@ using System.Collections.Generic; using System.Linq; using Microsoft.Data.SqlClient; +using Microsoft.EntityFrameworkCore; using Microsoft.VisualStudio.TestTools.UnitTesting; using N.EntityFrameworkCore.Extensions.Test.Data; @@ -348,6 +349,27 @@ public void With_Options_InsertIfNotExists() Assert.IsTrue(newTotal - oldTotal == expectedRowsInserted, "The new count minus the old count should match the number of rows inserted."); } [TestMethod] + public void With_Proxy_Type() + { + var dbContext = SetupDbContext(false); + int oldTotalCount = dbContext.Products.Where(o => o.Price == 10.57M).Count(); + + var products = new List(); + for (int i = 0; i < 2000; i++) + { + var product = dbContext.Products.CreateProxy(); + product.Id = (-i).ToString(); + product.Price = 10.57M; + products.Add(product); + } + int oldTotal = dbContext.Products.Where(o => o.Price == 10.57M).Count(); + int rowsInserted = dbContext.BulkInsert(products); + int newTotal = dbContext.Products.Where(o => o.Price == 10.57M).Count(); + + Assert.IsTrue(rowsInserted == products.Count, "The number of rows inserted must match the count of products list"); + Assert.IsTrue(newTotal - oldTotal == rowsInserted, "The new count minus the old count should match the number of rows inserted."); + } + [TestMethod] public void With_ValueGenerated_Default() { var dbContext = SetupDbContext(false); diff --git a/N.EntityFrameworkCore.Extensions.Test/DbContextExtensions/BulkInsertAsync.cs b/N.EntityFrameworkCore.Extensions.Test/DbContextExtensions/BulkInsertAsync.cs index 2fd0a34..5da3955 100644 --- a/N.EntityFrameworkCore.Extensions.Test/DbContextExtensions/BulkInsertAsync.cs +++ b/N.EntityFrameworkCore.Extensions.Test/DbContextExtensions/BulkInsertAsync.cs @@ -3,6 +3,7 @@ using System.Linq; using System.Threading.Tasks; using Microsoft.Data.SqlClient; +using Microsoft.EntityFrameworkCore; using Microsoft.VisualStudio.TestTools.UnitTesting; using N.EntityFrameworkCore.Extensions.Test.Data; @@ -301,6 +302,27 @@ public async Task With_KeepIdentity() Assert.IsTrue(allIdentityFieldsMatch, "The identities between the source and the database should match."); } [TestMethod] + public async Task With_Proxy_Type() + { + var dbContext = SetupDbContext(false); + int oldTotalCount = dbContext.Products.Where(o => o.Price == 10.57M).Count(); + + var products = new List(); + for (int i = 0; i < 2000; i++) + { + var product = dbContext.Products.CreateProxy(); + product.Id = (-i).ToString(); + product.Price = 10.57M; + products.Add(product); + } + int oldTotal = dbContext.Products.Where(o => o.Price == 10.57M).Count(); + int rowsInserted = await dbContext.BulkInsertAsync(products); + int newTotal = dbContext.Products.Where(o => o.Price == 10.57M).Count(); + + Assert.IsTrue(rowsInserted == products.Count, "The number of rows inserted must match the count of products list"); + Assert.IsTrue(newTotal - oldTotal == rowsInserted, "The new count minus the old count should match the number of rows inserted."); + } + [TestMethod] public async Task With_Schema() { var dbContext = SetupDbContext(false); diff --git a/N.EntityFrameworkCore.Extensions.Test/N.EntityFrameworkCore.Extensions.Test.csproj b/N.EntityFrameworkCore.Extensions.Test/N.EntityFrameworkCore.Extensions.Test.csproj index bd6be52..fd4ccaf 100644 --- a/N.EntityFrameworkCore.Extensions.Test/N.EntityFrameworkCore.Extensions.Test.csproj +++ b/N.EntityFrameworkCore.Extensions.Test/N.EntityFrameworkCore.Extensions.Test.csproj @@ -6,15 +6,16 @@ - - + + + - - - + + + From d2eae709968cd4f525cdff70960371cb9bfa1ebd Mon Sep 17 00:00:00 2001 From: Rikard Andersson Date: Tue, 11 Jun 2024 20:53:57 +0200 Subject: [PATCH 2/4] Use file scoped namespace declaration --- .../Common/Config.cs | 9 +- .../Data/Enums/ProductStatus.cs | 11 +- .../Data/Order.cs | 51 +- .../Data/Position.cs | 13 +- .../Data/Product.cs | 43 +- .../Data/ProductCategory.cs | 13 +- .../Data/ProductWithComplexKey.cs | 33 +- .../Data/ProductWithCustomSchema.cs | 19 +- .../Data/ProductWithTrigger.cs | 29 +- .../Data/TestDbContext.cs | 85 +-- .../Data/TpcCustomer.cs | 13 +- .../Data/TpcPerson.cs | 15 +- .../Data/TpcVendor.cs | 13 +- .../Data/TphCustomer.cs | 13 +- .../Data/TphPerson.cs | 15 +- .../Data/TphVendor.cs | 13 +- .../Data/TptCustomer.cs | 13 +- .../Data/TptPerson.cs | 15 +- .../Data/TptVendor.cs | 13 +- .../DatabaseExtensionsBase.cs | 9 +- .../DatabaseExtensions/SqlQueryToCsvFile.cs | 19 +- .../SqlQueryToCsvFileAsync.cs | 19 +- .../DatabaseExtensions/SqlQuery_Count.cs | 19 +- .../DatabaseExtensions/SqlQuery_CountAsync.cs | 19 +- .../DatabaseExtensions/TableExists.cs | 13 +- .../DatabaseExtensions/TruncateTable.cs | 25 +- .../DatabaseExtensions/TruncateTableAsync.cs | 25 +- .../DbContextExtensions/BulkDelete.cs | 151 ++-- .../DbContextExtensions/BulkDeleteAsync.cs | 151 ++-- .../DbContextExtensions/BulkFetch.cs | 185 +++-- .../DbContextExtensions/BulkInsert.cs | 683 +++++++++-------- .../DbContextExtensions/BulkInsertAsync.cs | 717 +++++++++--------- .../DbContextExtensions/BulkMerge.cs | 591 +++++++-------- .../DbContextExtensions/BulkMergeAsync.cs | 619 ++++++++------- .../DbContextExtensions/BulkSaveChanges.cs | 433 ++++++----- .../BulkSaveChangesAsync.cs | 433 ++++++----- .../DbContextExtensions/BulkSync.cs | 415 +++++----- .../DbContextExtensions/BulkSyncAsync.cs | 415 +++++----- .../DbContextExtensions/BulkUpdate.cs | 417 +++++----- .../DbContextExtensions/BulkUpdateAsync.cs | 415 +++++----- .../DbContextExtensionsBase.cs | 447 ++++++----- .../DbContextExtensions/DeleteFromQuery.cs | 257 ++++--- .../DeleteFromQueryAsync.cs | 257 ++++--- .../DbContextExtensions/Fetch.cs | 299 ++++---- .../DbContextExtensions/FetchAsync.cs | 327 ++++---- .../DbContextExtensions/InsertFromQuery.cs | 115 ++- .../InsertFromQueryAsync.cs | 145 ++-- .../DbContextExtensions/QueryToCsvFile.cs | 73 +- .../QueryToCsvFileAsync.cs | 73 +- .../DbContextExtensions/UpdateFromQuery.cs | 475 ++++++------ .../UpdateFromQueryAsync.cs | 475 ++++++------ .../DbSetExtensions/Clear.cs | 25 +- .../DbSetExtensions/ClearAsync.cs | 25 +- .../DbSetExtensions/Truncate.cs | 25 +- .../DbSetExtensions/TruncateAsync.cs | 25 +- .../Common/Constants.cs | 9 +- .../Data/BulkDeleteOptions.cs | 9 +- .../Data/BulkFetchOptions.cs | 17 +- .../Data/BulkInsertOptions.cs | 43 +- .../Data/BulkInsertResult.cs | 11 +- .../Data/BulkMergeOption.cs | 35 +- .../Data/BulkMergeOutputRow.cs | 13 +- .../Data/BulkMergeResult.cs | 17 +- .../Data/BulkOperation.cs | 79 +- .../Data/BulkOperationAsync.cs | 19 +- .../Data/BulkOptions.cs | 31 +- .../Data/BulkQueryResult.cs | 13 +- .../Data/BulkSyncOptions.cs | 9 +- .../Data/BulkSyncResult.cs | 11 +- .../Data/BulkUpdateOptions.cs | 13 +- .../Data/DatabaseFacadeExtensions.cs | 61 +- .../Data/DatabaseFacadeExtensionsAsync.cs | 37 +- .../Data/DbContextExtensions.cs | 225 +++--- .../Data/DbContextExtensionsAsync.cs | 199 +++-- .../Data/DbTransactionContext.cs | 43 +- .../Data/EfExtensionsCommand.cs | 19 +- .../Data/EfExtensionsCommandInterceptor.cs | 15 +- .../Data/EntityDataReader.cs | 157 ++-- .../Data/FetchOptions.cs | 13 +- .../Data/FetchResult.cs | 11 +- .../Data/QueryToFileOptions.cs | 21 +- .../Data/QueryToFileResult.cs | 13 +- .../Data/SqlMergeAction.cs | 13 +- .../Data/SqlQuery.cs | 29 +- .../Data/TableMapping.cs | 93 ++- .../Enums/ConnectionBehavior.cs | 11 +- .../Enums/EfExtensionsCommandType.cs | 9 +- .../Extensions/CommonExtensions.cs | 9 +- .../Extensions/IPropertyExtensions.cs | 9 +- .../Extensions/LinqExtensions.cs | 67 +- .../Extensions/ObjectExtensions.cs | 9 +- .../Extensions/SqlStatementExtensions.cs | 9 +- .../Sql/SqlBuilder.cs | 71 +- .../Sql/SqlClause.cs | 25 +- .../Sql/SqlExpression.cs | 45 +- .../Sql/SqlExpressionType.cs | 15 +- .../Sql/SqlKeyword.cs | 55 +- .../Sql/SqlPart.cs | 19 +- .../Sql/SqlStatement.cs | 65 +- .../Util/CommonUtil.cs | 45 +- .../Util/SqlUtil.cs | 11 +- 101 files changed, 5448 insertions(+), 5549 deletions(-) diff --git a/N.EntityFrameworkCore.Extensions.Test/Common/Config.cs b/N.EntityFrameworkCore.Extensions.Test/Common/Config.cs index 9cd853c..9c35b08 100644 --- a/N.EntityFrameworkCore.Extensions.Test/Common/Config.cs +++ b/N.EntityFrameworkCore.Extensions.Test/Common/Config.cs @@ -3,16 +3,15 @@ using System.Text; using Microsoft.Extensions.Configuration; -namespace N.EntityFrameworkCore.Extensions.Test.Common +namespace N.EntityFrameworkCore.Extensions.Test.Common; + +public class Config { - public class Config + public static string GetConnectionString(string name) { - public static string GetConnectionString(string name) - { var builder = new ConfigurationBuilder() .AddJsonFile("appsettings.json", optional: true, reloadOnChange: true); return builder.Build().GetConnectionString(name); } - } } \ No newline at end of file diff --git a/N.EntityFrameworkCore.Extensions.Test/Data/Enums/ProductStatus.cs b/N.EntityFrameworkCore.Extensions.Test/Data/Enums/ProductStatus.cs index 0e19e97..e3b5c8c 100644 --- a/N.EntityFrameworkCore.Extensions.Test/Data/Enums/ProductStatus.cs +++ b/N.EntityFrameworkCore.Extensions.Test/Data/Enums/ProductStatus.cs @@ -4,11 +4,10 @@ using System.Text; using System.Threading.Tasks; -namespace N.EntityFrameworkCore.Extensions.Test.Data.Enums +namespace N.EntityFrameworkCore.Extensions.Test.Data.Enums; + +public enum ProductStatus { - public enum ProductStatus - { - InStock, - OutOfStock, - } + InStock, + OutOfStock, } \ No newline at end of file diff --git a/N.EntityFrameworkCore.Extensions.Test/Data/Order.cs b/N.EntityFrameworkCore.Extensions.Test/Data/Order.cs index f82ab52..8e50f11 100644 --- a/N.EntityFrameworkCore.Extensions.Test/Data/Order.cs +++ b/N.EntityFrameworkCore.Extensions.Test/Data/Order.cs @@ -1,34 +1,33 @@ using System; using System.ComponentModel.DataAnnotations; -namespace N.EntityFrameworkCore.Extensions.Test.Data +namespace N.EntityFrameworkCore.Extensions.Test.Data; + +public class Order { - public class Order + [Key] + public long Id { get; set; } + public string ExternalId { get; set; } + public Guid? GlobalId { get; set; } + public decimal Price { get; set; } + public DateTime AddedDateTime { get; set; } + public DateTime? ModifiedDateTime { get; set; } + public DateTimeOffset? ModifiedDateTimeOffset { get; set; } + public DateTime DbAddedDateTime { get; set; } + public DateTime DbModifiedDateTime { get; set; } + public bool? Trigger { get; set; } + public bool Active { get; set; } + public OrderStatus Status { get; set; } + public Order() { - [Key] - public long Id { get; set; } - public string ExternalId { get; set; } - public Guid? GlobalId { get; set; } - public decimal Price { get; set; } - public DateTime AddedDateTime { get; set; } - public DateTime? ModifiedDateTime { get; set; } - public DateTimeOffset? ModifiedDateTimeOffset { get; set; } - public DateTime DbAddedDateTime { get; set; } - public DateTime DbModifiedDateTime { get; set; } - public bool? Trigger { get; set; } - public bool Active { get; set; } - public OrderStatus Status { get; set; } - public Order() - { - AddedDateTime = DateTime.UtcNow; - Active = true; - } + AddedDateTime = DateTime.UtcNow; + Active = true; } +} - public enum OrderStatus - { - Unknown, - Completed, - Error - } +public enum OrderStatus +{ + Unknown, + Completed, + Error } \ No newline at end of file diff --git a/N.EntityFrameworkCore.Extensions.Test/Data/Position.cs b/N.EntityFrameworkCore.Extensions.Test/Data/Position.cs index 0fe3b65..d4c162c 100644 --- a/N.EntityFrameworkCore.Extensions.Test/Data/Position.cs +++ b/N.EntityFrameworkCore.Extensions.Test/Data/Position.cs @@ -4,12 +4,11 @@ using System.Text; using System.Threading.Tasks; -namespace N.EntityFrameworkCore.Extensions.Test.Data +namespace N.EntityFrameworkCore.Extensions.Test.Data; + +public class Position { - public class Position - { - public int Building; - public int Aisle; - public int Bay; - } + public int Building; + public int Aisle; + public int Bay; } \ No newline at end of file diff --git a/N.EntityFrameworkCore.Extensions.Test/Data/Product.cs b/N.EntityFrameworkCore.Extensions.Test/Data/Product.cs index da60e06..384d185 100644 --- a/N.EntityFrameworkCore.Extensions.Test/Data/Product.cs +++ b/N.EntityFrameworkCore.Extensions.Test/Data/Product.cs @@ -5,31 +5,30 @@ using System.Text; using N.EntityFrameworkCore.Extensions.Test.Data.Enums; -namespace N.EntityFrameworkCore.Extensions.Test.Data +namespace N.EntityFrameworkCore.Extensions.Test.Data; + +public class Product { - public class Product - { - [Key] - [DatabaseGenerated(DatabaseGeneratedOption.None)] - public string Id { get; set; } - [StringLength(50)] - public string Name { get; set; } - public decimal Price { get; set; } - public bool OutOfStock { get; set; } - [Column("Status")] - [StringLength(25)] - public string StatusString { get; set; } - public int? ProductCategoryId { get; set; } - public System.Drawing.Color Color { get; set; } - public ProductStatus? StatusEnum { get; set; } - public DateTime? UpdatedDateTime { get; set; } + [Key] + [DatabaseGenerated(DatabaseGeneratedOption.None)] + public string Id { get; set; } + [StringLength(50)] + public string Name { get; set; } + public decimal Price { get; set; } + public bool OutOfStock { get; set; } + [Column("Status")] + [StringLength(25)] + public string StatusString { get; set; } + public int? ProductCategoryId { get; set; } + public System.Drawing.Color Color { get; set; } + public ProductStatus? StatusEnum { get; set; } + public DateTime? UpdatedDateTime { get; set; } - public Position Position { get; set; } + public Position Position { get; set; } - public virtual ProductCategory ProductCategory { get; set; } - public Product() - { + public virtual ProductCategory ProductCategory { get; set; } + public Product() + { - } } } \ No newline at end of file diff --git a/N.EntityFrameworkCore.Extensions.Test/Data/ProductCategory.cs b/N.EntityFrameworkCore.Extensions.Test/Data/ProductCategory.cs index 7ff35e9..83bd84d 100644 --- a/N.EntityFrameworkCore.Extensions.Test/Data/ProductCategory.cs +++ b/N.EntityFrameworkCore.Extensions.Test/Data/ProductCategory.cs @@ -6,12 +6,11 @@ using Microsoft.VisualStudio.TestTools.UnitTesting; using N.EntityFrameworkCore.Extensions.Test.Data.Enums; -namespace N.EntityFrameworkCore.Extensions.Test.Data +namespace N.EntityFrameworkCore.Extensions.Test.Data; + +public class ProductCategory { - public class ProductCategory - { - public int Id { get; set; } - public string Name { get; set; } - public bool Active { get; internal set; } - } + public int Id { get; set; } + public string Name { get; set; } + public bool Active { get; internal set; } } \ No newline at end of file diff --git a/N.EntityFrameworkCore.Extensions.Test/Data/ProductWithComplexKey.cs b/N.EntityFrameworkCore.Extensions.Test/Data/ProductWithComplexKey.cs index 3e495f5..12ef54b 100644 --- a/N.EntityFrameworkCore.Extensions.Test/Data/ProductWithComplexKey.cs +++ b/N.EntityFrameworkCore.Extensions.Test/Data/ProductWithComplexKey.cs @@ -6,24 +6,23 @@ using System.Text; using System.Threading.Tasks; -namespace N.EntityFrameworkCore.Extensions.Test.Data +namespace N.EntityFrameworkCore.Extensions.Test.Data; + +public class ProductWithComplexKey { - public class ProductWithComplexKey + public Guid Key1 { get; set; } + public Guid Key2 { get; set; } + public Guid Key3 { get; set; } + public decimal Price { get; set; } + public bool OutOfStock { get; set; } + [Column("Status")] + [StringLength(25)] + public string StatusString { get; set; } + public DateTime? UpdatedDateTime { get; set; } + public ProductWithComplexKey() { - public Guid Key1 { get; set; } - public Guid Key2 { get; set; } - public Guid Key3 { get; set; } - public decimal Price { get; set; } - public bool OutOfStock { get; set; } - [Column("Status")] - [StringLength(25)] - public string StatusString { get; set; } - public DateTime? UpdatedDateTime { get; set; } - public ProductWithComplexKey() - { - //Key1 = Guid.NewGuid(); - //Key2 = Guid.NewGuid(); - //Key3 = Guid.NewGuid(); - } + //Key1 = Guid.NewGuid(); + //Key2 = Guid.NewGuid(); + //Key3 = Guid.NewGuid(); } } \ No newline at end of file diff --git a/N.EntityFrameworkCore.Extensions.Test/Data/ProductWithCustomSchema.cs b/N.EntityFrameworkCore.Extensions.Test/Data/ProductWithCustomSchema.cs index 71d314e..a9306a5 100644 --- a/N.EntityFrameworkCore.Extensions.Test/Data/ProductWithCustomSchema.cs +++ b/N.EntityFrameworkCore.Extensions.Test/Data/ProductWithCustomSchema.cs @@ -5,15 +5,14 @@ using System.Text; using N.EntityFrameworkCore.Extensions.Test.Data.Enums; -namespace N.EntityFrameworkCore.Extensions.Test.Data +namespace N.EntityFrameworkCore.Extensions.Test.Data; + +public class ProductWithCustomSchema { - public class ProductWithCustomSchema - { - [Key] - [DatabaseGenerated(DatabaseGeneratedOption.None)] - public string Id { get; set; } - [StringLength(50)] - public string Name { get; set; } - public decimal Price { get; set; } - } + [Key] + [DatabaseGenerated(DatabaseGeneratedOption.None)] + public string Id { get; set; } + [StringLength(50)] + public string Name { get; set; } + public decimal Price { get; set; } } \ No newline at end of file diff --git a/N.EntityFrameworkCore.Extensions.Test/Data/ProductWithTrigger.cs b/N.EntityFrameworkCore.Extensions.Test/Data/ProductWithTrigger.cs index b5b6f2b..137b8b9 100644 --- a/N.EntityFrameworkCore.Extensions.Test/Data/ProductWithTrigger.cs +++ b/N.EntityFrameworkCore.Extensions.Test/Data/ProductWithTrigger.cs @@ -5,23 +5,22 @@ using System.Text; using N.EntityFrameworkCore.Extensions.Test.Data.Enums; -namespace N.EntityFrameworkCore.Extensions.Test.Data +namespace N.EntityFrameworkCore.Extensions.Test.Data; + +public class ProductWithTrigger { - public class ProductWithTrigger + [Key] + [DatabaseGenerated(DatabaseGeneratedOption.None)] + public string Id { get; set; } + [StringLength(50)] + public string Name { get; set; } + public decimal Price { get; set; } + public bool OutOfStock { get; set; } + [Column("Status")] + [StringLength(25)] + public string StatusString { get; set; } + public ProductWithTrigger() { - [Key] - [DatabaseGenerated(DatabaseGeneratedOption.None)] - public string Id { get; set; } - [StringLength(50)] - public string Name { get; set; } - public decimal Price { get; set; } - public bool OutOfStock { get; set; } - [Column("Status")] - [StringLength(25)] - public string StatusString { get; set; } - public ProductWithTrigger() - { - } } } \ No newline at end of file diff --git a/N.EntityFrameworkCore.Extensions.Test/Data/TestDbContext.cs b/N.EntityFrameworkCore.Extensions.Test/Data/TestDbContext.cs index 91fc88a..4299def 100644 --- a/N.EntityFrameworkCore.Extensions.Test/Data/TestDbContext.cs +++ b/N.EntityFrameworkCore.Extensions.Test/Data/TestDbContext.cs @@ -6,52 +6,51 @@ using Microsoft.EntityFrameworkCore; using N.EntityFrameworkCore.Extensions.Test.Common; -namespace N.EntityFrameworkCore.Extensions.Test.Data +namespace N.EntityFrameworkCore.Extensions.Test.Data; + +public class TestDbContext : DbContext { - public class TestDbContext : DbContext - { - public virtual DbSet Products { get; set; } - public virtual DbSet ProductCategories { get; set; } - public virtual DbSet ProductsWithCustomSchema { get; set; } - public virtual DbSet ProductsWithComplexKey { get; set; } - public virtual DbSet Orders { get; set; } - public virtual DbSet TpcPeople { get; set; } - public virtual DbSet TphPeople { get; set; } - public virtual DbSet TphCustomers { get; set; } - public virtual DbSet TphVendors { get; set; } - public virtual DbSet TptPeople { get; set; } - public virtual DbSet TptCustomers { get; set; } - public virtual DbSet TptVendors { get; set; } + public virtual DbSet Products { get; set; } + public virtual DbSet ProductCategories { get; set; } + public virtual DbSet ProductsWithCustomSchema { get; set; } + public virtual DbSet ProductsWithComplexKey { get; set; } + public virtual DbSet Orders { get; set; } + public virtual DbSet TpcPeople { get; set; } + public virtual DbSet TphPeople { get; set; } + public virtual DbSet TphCustomers { get; set; } + public virtual DbSet TphVendors { get; set; } + public virtual DbSet TptPeople { get; set; } + public virtual DbSet TptCustomers { get; set; } + public virtual DbSet TptVendors { get; set; } - protected override void OnConfiguring(DbContextOptionsBuilder optionsBuilder) - { - optionsBuilder.UseSqlServer(Config.GetConnectionString("TestDatabase")); - optionsBuilder.SetupEfCoreExtensions(); - optionsBuilder.UseLazyLoadingProxies(); - } - protected override void OnModelCreating(ModelBuilder modelBuilder) + protected override void OnConfiguring(DbContextOptionsBuilder optionsBuilder) + { + optionsBuilder.UseSqlServer(Config.GetConnectionString("TestDatabase")); + optionsBuilder.SetupEfCoreExtensions(); + optionsBuilder.UseLazyLoadingProxies(); + } + protected override void OnModelCreating(ModelBuilder modelBuilder) + { + modelBuilder.Entity().ToTable("Product", "top"); + modelBuilder.Entity().HasKey(c => new { c.Key1 }); + modelBuilder.Entity().Property("Key1").HasDefaultValueSql("newsequentialid()"); + modelBuilder.Entity().Property("Key2").HasDefaultValueSql("newsequentialid()"); + modelBuilder.Entity().Property("Key3").HasDefaultValueSql("newsequentialid()"); + modelBuilder.Entity().Property("DbAddedDateTime").HasDefaultValueSql("getdate()"); + modelBuilder.Entity().Property("DbModifiedDateTime").HasComputedColumnSql("getdate()"); + modelBuilder.Entity().Property(p => p.Status).HasConversion(); + modelBuilder.Entity().UseTpcMappingStrategy(); + modelBuilder.Entity().ToTable("TpcCustomer"); + modelBuilder.Entity().ToTable("TpcVendor"); + modelBuilder.Entity().Property("CreatedDate"); + modelBuilder.Entity().ToTable("TptPeople"); + modelBuilder.Entity().ToTable("TptCustomer"); + modelBuilder.Entity().ToTable("TptVendor"); + modelBuilder.Entity(t => { - modelBuilder.Entity().ToTable("Product", "top"); - modelBuilder.Entity().HasKey(c => new { c.Key1 }); - modelBuilder.Entity().Property("Key1").HasDefaultValueSql("newsequentialid()"); - modelBuilder.Entity().Property("Key2").HasDefaultValueSql("newsequentialid()"); - modelBuilder.Entity().Property("Key3").HasDefaultValueSql("newsequentialid()"); - modelBuilder.Entity().Property("DbAddedDateTime").HasDefaultValueSql("getdate()"); - modelBuilder.Entity().Property("DbModifiedDateTime").HasComputedColumnSql("getdate()"); - modelBuilder.Entity().Property(p => p.Status).HasConversion(); - modelBuilder.Entity().UseTpcMappingStrategy(); - modelBuilder.Entity().ToTable("TpcCustomer"); - modelBuilder.Entity().ToTable("TpcVendor"); - modelBuilder.Entity().Property("CreatedDate"); - modelBuilder.Entity().ToTable("TptPeople"); - modelBuilder.Entity().ToTable("TptCustomer"); - modelBuilder.Entity().ToTable("TptVendor"); - modelBuilder.Entity(t => - { - t.ComplexProperty(p => p.Position).IsRequired(); - t.Property(p => p.Color).HasConversion(x => x.ToArgb(), x => Color.FromArgb(x)); - }); + t.ComplexProperty(p => p.Position).IsRequired(); + t.Property(p => p.Color).HasConversion(x => x.ToArgb(), x => Color.FromArgb(x)); + }); - } } } \ No newline at end of file diff --git a/N.EntityFrameworkCore.Extensions.Test/Data/TpcCustomer.cs b/N.EntityFrameworkCore.Extensions.Test/Data/TpcCustomer.cs index 983cd25..c67f4dc 100644 --- a/N.EntityFrameworkCore.Extensions.Test/Data/TpcCustomer.cs +++ b/N.EntityFrameworkCore.Extensions.Test/Data/TpcCustomer.cs @@ -1,11 +1,10 @@ using System; -namespace N.EntityFrameworkCore.Extensions.Test.Data +namespace N.EntityFrameworkCore.Extensions.Test.Data; + +public class TpcCustomer : TpcPerson { - public class TpcCustomer : TpcPerson - { - public string Email { get; set; } - public string Phone { get; set; } - public DateTime AddedDate { get; set; } - } + public string Email { get; set; } + public string Phone { get; set; } + public DateTime AddedDate { get; set; } } \ No newline at end of file diff --git a/N.EntityFrameworkCore.Extensions.Test/Data/TpcPerson.cs b/N.EntityFrameworkCore.Extensions.Test/Data/TpcPerson.cs index 1659a4f..c3823e5 100644 --- a/N.EntityFrameworkCore.Extensions.Test/Data/TpcPerson.cs +++ b/N.EntityFrameworkCore.Extensions.Test/Data/TpcPerson.cs @@ -1,12 +1,11 @@ using System.ComponentModel.DataAnnotations.Schema; -namespace N.EntityFrameworkCore.Extensions.Test.Data +namespace N.EntityFrameworkCore.Extensions.Test.Data; + +public abstract class TpcPerson { - public abstract class TpcPerson - { - [DatabaseGenerated(DatabaseGeneratedOption.None)] - public long Id { get; set; } - public string FirstName { get; set; } - public string LastName { get; set; } - } + [DatabaseGenerated(DatabaseGeneratedOption.None)] + public long Id { get; set; } + public string FirstName { get; set; } + public string LastName { get; set; } } \ No newline at end of file diff --git a/N.EntityFrameworkCore.Extensions.Test/Data/TpcVendor.cs b/N.EntityFrameworkCore.Extensions.Test/Data/TpcVendor.cs index f1df475..7c32100 100644 --- a/N.EntityFrameworkCore.Extensions.Test/Data/TpcVendor.cs +++ b/N.EntityFrameworkCore.Extensions.Test/Data/TpcVendor.cs @@ -1,10 +1,9 @@  -namespace N.EntityFrameworkCore.Extensions.Test.Data +namespace N.EntityFrameworkCore.Extensions.Test.Data; + +public class TpcVendor : TpcPerson { - public class TpcVendor : TpcPerson - { - public string Email { get; set; } - public string Phone { get; set; } - public string Url { get; set; } - } + public string Email { get; set; } + public string Phone { get; set; } + public string Url { get; set; } } \ No newline at end of file diff --git a/N.EntityFrameworkCore.Extensions.Test/Data/TphCustomer.cs b/N.EntityFrameworkCore.Extensions.Test/Data/TphCustomer.cs index 28cdf15..5325781 100644 --- a/N.EntityFrameworkCore.Extensions.Test/Data/TphCustomer.cs +++ b/N.EntityFrameworkCore.Extensions.Test/Data/TphCustomer.cs @@ -1,11 +1,10 @@ using System; -namespace N.EntityFrameworkCore.Extensions.Test.Data +namespace N.EntityFrameworkCore.Extensions.Test.Data; + +public class TphCustomer : TphPerson { - public class TphCustomer : TphPerson - { - public string Email { get; set; } - public string Phone { get; set; } - public DateTime AddedDate { get; set; } - } + public string Email { get; set; } + public string Phone { get; set; } + public DateTime AddedDate { get; set; } } \ No newline at end of file diff --git a/N.EntityFrameworkCore.Extensions.Test/Data/TphPerson.cs b/N.EntityFrameworkCore.Extensions.Test/Data/TphPerson.cs index 2ffc21a..37f090b 100644 --- a/N.EntityFrameworkCore.Extensions.Test/Data/TphPerson.cs +++ b/N.EntityFrameworkCore.Extensions.Test/Data/TphPerson.cs @@ -1,12 +1,11 @@ using System.ComponentModel.DataAnnotations.Schema; -namespace N.EntityFrameworkCore.Extensions.Test.Data +namespace N.EntityFrameworkCore.Extensions.Test.Data; + +[Table("TphPeople")] +public abstract class TphPerson { - [Table("TphPeople")] - public abstract class TphPerson - { - public long Id { get; set; } - public string FirstName { get; set; } - public string LastName { get; set; } - } + public long Id { get; set; } + public string FirstName { get; set; } + public string LastName { get; set; } } \ No newline at end of file diff --git a/N.EntityFrameworkCore.Extensions.Test/Data/TphVendor.cs b/N.EntityFrameworkCore.Extensions.Test/Data/TphVendor.cs index 5d0fdb2..2effa1d 100644 --- a/N.EntityFrameworkCore.Extensions.Test/Data/TphVendor.cs +++ b/N.EntityFrameworkCore.Extensions.Test/Data/TphVendor.cs @@ -1,10 +1,9 @@  -namespace N.EntityFrameworkCore.Extensions.Test.Data +namespace N.EntityFrameworkCore.Extensions.Test.Data; + +public class TphVendor : TphPerson { - public class TphVendor : TphPerson - { - public string Email { get; set; } - public string Phone { get; set; } - public string Url { get; set; } - } + public string Email { get; set; } + public string Phone { get; set; } + public string Url { get; set; } } \ No newline at end of file diff --git a/N.EntityFrameworkCore.Extensions.Test/Data/TptCustomer.cs b/N.EntityFrameworkCore.Extensions.Test/Data/TptCustomer.cs index 2256f2b..ec17284 100644 --- a/N.EntityFrameworkCore.Extensions.Test/Data/TptCustomer.cs +++ b/N.EntityFrameworkCore.Extensions.Test/Data/TptCustomer.cs @@ -1,11 +1,10 @@ using System; -namespace N.EntityFrameworkCore.Extensions.Test.Data +namespace N.EntityFrameworkCore.Extensions.Test.Data; + +public class TptCustomer : TptPerson { - public class TptCustomer : TptPerson - { - public string Email { get; set; } - public string Phone { get; set; } - public DateTime AddedDate { get; set; } - } + public string Email { get; set; } + public string Phone { get; set; } + public DateTime AddedDate { get; set; } } \ No newline at end of file diff --git a/N.EntityFrameworkCore.Extensions.Test/Data/TptPerson.cs b/N.EntityFrameworkCore.Extensions.Test/Data/TptPerson.cs index 20ef993..4c23db2 100644 --- a/N.EntityFrameworkCore.Extensions.Test/Data/TptPerson.cs +++ b/N.EntityFrameworkCore.Extensions.Test/Data/TptPerson.cs @@ -1,12 +1,11 @@ using System.ComponentModel.DataAnnotations.Schema; -namespace N.EntityFrameworkCore.Extensions.Test.Data +namespace N.EntityFrameworkCore.Extensions.Test.Data; + +public class TptPerson { - public class TptPerson - { - [DatabaseGenerated(DatabaseGeneratedOption.None)] - public long Id { get; set; } - public string FirstName { get; set; } - public string LastName { get; set; } - } + [DatabaseGenerated(DatabaseGeneratedOption.None)] + public long Id { get; set; } + public string FirstName { get; set; } + public string LastName { get; set; } } \ No newline at end of file diff --git a/N.EntityFrameworkCore.Extensions.Test/Data/TptVendor.cs b/N.EntityFrameworkCore.Extensions.Test/Data/TptVendor.cs index 1098cf9..ca9eb25 100644 --- a/N.EntityFrameworkCore.Extensions.Test/Data/TptVendor.cs +++ b/N.EntityFrameworkCore.Extensions.Test/Data/TptVendor.cs @@ -1,10 +1,9 @@  -namespace N.EntityFrameworkCore.Extensions.Test.Data +namespace N.EntityFrameworkCore.Extensions.Test.Data; + +public class TptVendor : TptPerson { - public class TptVendor : TptPerson - { - public string Email { get; set; } - public string Phone { get; set; } - public string Url { get; set; } - } + public string Email { get; set; } + public string Phone { get; set; } + public string Url { get; set; } } \ No newline at end of file diff --git a/N.EntityFrameworkCore.Extensions.Test/DatabaseExtensions/DatabaseExtensionsBase.cs b/N.EntityFrameworkCore.Extensions.Test/DatabaseExtensions/DatabaseExtensionsBase.cs index e974880..9831c8e 100644 --- a/N.EntityFrameworkCore.Extensions.Test/DatabaseExtensions/DatabaseExtensionsBase.cs +++ b/N.EntityFrameworkCore.Extensions.Test/DatabaseExtensions/DatabaseExtensionsBase.cs @@ -6,12 +6,12 @@ using System.Threading.Tasks; using N.EntityFrameworkCore.Extensions.Test.Data; -namespace N.EntityFrameworkCore.Extensions.Test.DatabaseExtensions +namespace N.EntityFrameworkCore.Extensions.Test.DatabaseExtensions; + +public class DatabaseExtensionsBase { - public class DatabaseExtensionsBase + protected TestDbContext SetupDbContext(bool populateData) { - protected TestDbContext SetupDbContext(bool populateData) - { TestDbContext dbContext = new TestDbContext(); dbContext.Database.EnsureCreated(); dbContext.Orders.Truncate(); @@ -58,5 +58,4 @@ protected TestDbContext SetupDbContext(bool populateData) } return dbContext; } - } } \ No newline at end of file diff --git a/N.EntityFrameworkCore.Extensions.Test/DatabaseExtensions/SqlQueryToCsvFile.cs b/N.EntityFrameworkCore.Extensions.Test/DatabaseExtensions/SqlQueryToCsvFile.cs index 1df2c8a..2817d71 100644 --- a/N.EntityFrameworkCore.Extensions.Test/DatabaseExtensions/SqlQueryToCsvFile.cs +++ b/N.EntityFrameworkCore.Extensions.Test/DatabaseExtensions/SqlQueryToCsvFile.cs @@ -6,14 +6,14 @@ using Microsoft.Data.SqlClient; using Microsoft.VisualStudio.TestTools.UnitTesting; -namespace N.EntityFrameworkCore.Extensions.Test.DatabaseExtensions +namespace N.EntityFrameworkCore.Extensions.Test.DatabaseExtensions; + +[TestClass] +public class SqlQueryToCsvFile : DatabaseExtensionsBase { - [TestClass] - public class SqlQueryToCsvFile : DatabaseExtensionsBase + [TestMethod] + public void With_Default_Options() { - [TestMethod] - public void With_Default_Options() - { var dbContext = SetupDbContext(true); int count = dbContext.Orders.Where(o => o.Price > 5M).Count(); var queryToCsvFileResult = dbContext.Database.SqlQueryToCsvFile("SqlQueryToCsvFile-Test.csv", "SELECT * FROM Orders WHERE Price > @Price", new SqlParameter("@Price", 5M)); @@ -22,9 +22,9 @@ public void With_Default_Options() Assert.IsTrue(queryToCsvFileResult.DataRowCount == count, "The number of data rows written to the file should match the count from the database"); Assert.IsTrue(queryToCsvFileResult.TotalRowCount == count + 1, "The total number of rows written to the file should match the count from the database plus the header row"); } - [TestMethod] - public void With_Options_ColumnDelimiter_TextQualifer() - { + [TestMethod] + public void With_Options_ColumnDelimiter_TextQualifer() + { var dbContext = SetupDbContext(true); string filePath = "SqlQueryToCsvFile_Options_ColumnDelimiter_TextQualifer-Test.csv"; int count = dbContext.Orders.Where(o => o.Price > 5M).Count(); @@ -35,5 +35,4 @@ public void With_Options_ColumnDelimiter_TextQualifer() Assert.IsTrue(queryToCsvFileResult.DataRowCount == count, "The number of data rows written to the file should match the count from the database"); Assert.IsTrue(queryToCsvFileResult.TotalRowCount == count + 1, "The total number of rows written to the file should match the count from the database plus the header row"); } - } } \ No newline at end of file diff --git a/N.EntityFrameworkCore.Extensions.Test/DatabaseExtensions/SqlQueryToCsvFileAsync.cs b/N.EntityFrameworkCore.Extensions.Test/DatabaseExtensions/SqlQueryToCsvFileAsync.cs index 3d57c38..faf8dac 100644 --- a/N.EntityFrameworkCore.Extensions.Test/DatabaseExtensions/SqlQueryToCsvFileAsync.cs +++ b/N.EntityFrameworkCore.Extensions.Test/DatabaseExtensions/SqlQueryToCsvFileAsync.cs @@ -6,14 +6,14 @@ using Microsoft.Data.SqlClient; using Microsoft.VisualStudio.TestTools.UnitTesting; -namespace N.EntityFrameworkCore.Extensions.Test.DatabaseExtensions +namespace N.EntityFrameworkCore.Extensions.Test.DatabaseExtensions; + +[TestClass] +public class SqlQueryToCsvFileAsync : DatabaseExtensionsBase { - [TestClass] - public class SqlQueryToCsvFileAsync : DatabaseExtensionsBase + [TestMethod] + public async Task With_Default_Options() { - [TestMethod] - public async Task With_Default_Options() - { var dbContext = SetupDbContext(true); int count = dbContext.Orders.Where(o => o.Price > 5M).Count(); var queryToCsvFileResult = await dbContext.Database.SqlQueryToCsvFileAsync("SqlQueryToCsvFile-Test.csv", "SELECT * FROM Orders WHERE Price > @Price", new object[] { new SqlParameter("@Price", 5M) }); @@ -22,9 +22,9 @@ public async Task With_Default_Options() Assert.IsTrue(queryToCsvFileResult.DataRowCount == count, "The number of data rows written to the file should match the count from the database"); Assert.IsTrue(queryToCsvFileResult.TotalRowCount == count + 1, "The total number of rows written to the file should match the count from the database plus the header row"); } - [TestMethod] - public async Task With_Options_ColumnDelimiter_TextQualifer() - { + [TestMethod] + public async Task With_Options_ColumnDelimiter_TextQualifer() + { var dbContext = SetupDbContext(true); string filePath = "SqlQueryToCsvFile_Options_ColumnDelimiter_TextQualifer-Test.csv"; int count = dbContext.Orders.Where(o => o.Price > 5M).Count(); @@ -35,5 +35,4 @@ public async Task With_Options_ColumnDelimiter_TextQualifer() Assert.IsTrue(queryToCsvFileResult.DataRowCount == count, "The number of data rows written to the file should match the count from the database"); Assert.IsTrue(queryToCsvFileResult.TotalRowCount == count + 1, "The total number of rows written to the file should match the count from the database plus the header row"); } - } } \ No newline at end of file diff --git a/N.EntityFrameworkCore.Extensions.Test/DatabaseExtensions/SqlQuery_Count.cs b/N.EntityFrameworkCore.Extensions.Test/DatabaseExtensions/SqlQuery_Count.cs index ec87927..61b9908 100644 --- a/N.EntityFrameworkCore.Extensions.Test/DatabaseExtensions/SqlQuery_Count.cs +++ b/N.EntityFrameworkCore.Extensions.Test/DatabaseExtensions/SqlQuery_Count.cs @@ -2,14 +2,14 @@ using Microsoft.Data.SqlClient; using Microsoft.VisualStudio.TestTools.UnitTesting; -namespace N.EntityFrameworkCore.Extensions.Test.DatabaseExtensions +namespace N.EntityFrameworkCore.Extensions.Test.DatabaseExtensions; + +[TestClass] +public class SqlQuery_Count : DatabaseExtensionsBase { - [TestClass] - public class SqlQuery_Count : DatabaseExtensionsBase + [TestMethod] + public void With_Decimal_Value() { - [TestMethod] - public void With_Decimal_Value() - { var dbContext = SetupDbContext(true); int efCount = dbContext.Orders.Where(o => o.Price > 5M).Count(); var sqlCount = dbContext.Database.FromSqlQuery("SELECT * FROM Orders WHERE Price > @Price", new SqlParameter("@Price", 5M)).Count(); @@ -18,9 +18,9 @@ public void With_Decimal_Value() Assert.IsTrue(efCount > 0, "Count from SQL should be greater than zero"); Assert.IsTrue(efCount == sqlCount, "Count from EF should match the count from the SqlQuery"); } - [TestMethod] - public void With_OrderBy() - { + [TestMethod] + public void With_OrderBy() + { var dbContext = SetupDbContext(true); int efCount = dbContext.Orders.Where(o => o.Price > 5M).Count(); var sqlCount = dbContext.Database.FromSqlQuery("SELECT * FROM Orders WHERE Price > @Price ORDER BY Id", new SqlParameter("@Price", 5M)).Count(); @@ -29,5 +29,4 @@ public void With_OrderBy() Assert.IsTrue(efCount > 0, "Count from SQL should be greater than zero"); Assert.IsTrue(efCount == sqlCount, "Count from EF should match the count from the SqlQuery"); } - } } \ No newline at end of file diff --git a/N.EntityFrameworkCore.Extensions.Test/DatabaseExtensions/SqlQuery_CountAsync.cs b/N.EntityFrameworkCore.Extensions.Test/DatabaseExtensions/SqlQuery_CountAsync.cs index 4d837ee..676f50a 100644 --- a/N.EntityFrameworkCore.Extensions.Test/DatabaseExtensions/SqlQuery_CountAsync.cs +++ b/N.EntityFrameworkCore.Extensions.Test/DatabaseExtensions/SqlQuery_CountAsync.cs @@ -3,14 +3,14 @@ using Microsoft.Data.SqlClient; using Microsoft.VisualStudio.TestTools.UnitTesting; -namespace N.EntityFrameworkCore.Extensions.Test.DatabaseExtensions +namespace N.EntityFrameworkCore.Extensions.Test.DatabaseExtensions; + +[TestClass] +public class SqlQuery_CountAsync : DatabaseExtensionsBase { - [TestClass] - public class SqlQuery_CountAsync : DatabaseExtensionsBase + [TestMethod] + public async Task With_Decimal_Value() { - [TestMethod] - public async Task With_Decimal_Value() - { var dbContext = SetupDbContext(true); int efCount = dbContext.Orders.Where(o => o.Price > 5M).Count(); var sqlCount = await dbContext.Database.FromSqlQuery("SELECT * FROM Orders WHERE Price > @Price", new SqlParameter("@Price", 5M)).CountAsync(); @@ -19,9 +19,9 @@ public async Task With_Decimal_Value() Assert.IsTrue(efCount > 0, "Count from SQL should be greater than zero"); Assert.IsTrue(efCount == sqlCount, "Count from EF should match the count from the SqlQuery"); } - [TestMethod] - public async Task With_OrderBy() - { + [TestMethod] + public async Task With_OrderBy() + { var dbContext = SetupDbContext(true); int efCount = dbContext.Orders.Where(o => o.Price > 5M).Count(); var sqlCount = await dbContext.Database.FromSqlQuery("SELECT * FROM Orders WHERE Price > @Price ORDER BY Id", new SqlParameter("@Price", 5M)).CountAsync(); @@ -30,5 +30,4 @@ public async Task With_OrderBy() Assert.IsTrue(efCount > 0, "Count from SQL should be greater than zero"); Assert.IsTrue(efCount == sqlCount, "Count from EF should match the count from the SqlQuery"); } - } } \ No newline at end of file diff --git a/N.EntityFrameworkCore.Extensions.Test/DatabaseExtensions/TableExists.cs b/N.EntityFrameworkCore.Extensions.Test/DatabaseExtensions/TableExists.cs index dfe2d9f..878b142 100644 --- a/N.EntityFrameworkCore.Extensions.Test/DatabaseExtensions/TableExists.cs +++ b/N.EntityFrameworkCore.Extensions.Test/DatabaseExtensions/TableExists.cs @@ -5,14 +5,14 @@ using System.Threading.Tasks; using Microsoft.VisualStudio.TestTools.UnitTesting; -namespace N.EntityFrameworkCore.Extensions.Test.DatabaseExtensions +namespace N.EntityFrameworkCore.Extensions.Test.DatabaseExtensions; + +[TestClass] +public class TableExists : DatabaseExtensionsBase { - [TestClass] - public class TableExists : DatabaseExtensionsBase + [TestMethod] + public void With_Orders_Table() { - [TestMethod] - public void With_Orders_Table() - { var dbContext = SetupDbContext(true); int efCount = dbContext.Orders.Where(o => o.Price > 5M).Count(); bool ordersTableExists = dbContext.Database.TableExists("Orders"); @@ -21,5 +21,4 @@ public void With_Orders_Table() Assert.IsTrue(ordersTableExists, "Orders table should exist"); Assert.IsTrue(!orderNewTableExists, "Orders_New table should not exist"); } - } } \ No newline at end of file diff --git a/N.EntityFrameworkCore.Extensions.Test/DatabaseExtensions/TruncateTable.cs b/N.EntityFrameworkCore.Extensions.Test/DatabaseExtensions/TruncateTable.cs index 9028dfa..c9cdcd7 100644 --- a/N.EntityFrameworkCore.Extensions.Test/DatabaseExtensions/TruncateTable.cs +++ b/N.EntityFrameworkCore.Extensions.Test/DatabaseExtensions/TruncateTable.cs @@ -5,21 +5,20 @@ using System.Threading.Tasks; using Microsoft.VisualStudio.TestTools.UnitTesting; -namespace N.EntityFrameworkCore.Extensions.Test.DatabaseExtensions +namespace N.EntityFrameworkCore.Extensions.Test.DatabaseExtensions; + +[TestClass] +public class TruncateTable : DatabaseExtensionsBase { - [TestClass] - public class TruncateTable : DatabaseExtensionsBase + [TestMethod] + public void With_Orders_Table() { - [TestMethod] - public void With_Orders_Table() - { - var dbContext = SetupDbContext(true); - int oldOrdersCount = dbContext.Orders.Count(); - dbContext.Database.TruncateTable("Orders"); - int newOrdersCount = dbContext.Orders.Count(); + var dbContext = SetupDbContext(true); + int oldOrdersCount = dbContext.Orders.Count(); + dbContext.Database.TruncateTable("Orders"); + int newOrdersCount = dbContext.Orders.Count(); - Assert.IsTrue(oldOrdersCount > 0, "Orders table should have data"); - Assert.IsTrue(newOrdersCount == 0, "Order table should be empty after truncating"); - } + Assert.IsTrue(oldOrdersCount > 0, "Orders table should have data"); + Assert.IsTrue(newOrdersCount == 0, "Order table should be empty after truncating"); } } \ No newline at end of file diff --git a/N.EntityFrameworkCore.Extensions.Test/DatabaseExtensions/TruncateTableAsync.cs b/N.EntityFrameworkCore.Extensions.Test/DatabaseExtensions/TruncateTableAsync.cs index 5dcc1ac..3e9d674 100644 --- a/N.EntityFrameworkCore.Extensions.Test/DatabaseExtensions/TruncateTableAsync.cs +++ b/N.EntityFrameworkCore.Extensions.Test/DatabaseExtensions/TruncateTableAsync.cs @@ -5,21 +5,20 @@ using System.Threading.Tasks; using Microsoft.VisualStudio.TestTools.UnitTesting; -namespace N.EntityFrameworkCore.Extensions.Test.DatabaseExtensions +namespace N.EntityFrameworkCore.Extensions.Test.DatabaseExtensions; + +[TestClass] +public class TruncateTableAsync : DatabaseExtensionsBase { - [TestClass] - public class TruncateTableAsync : DatabaseExtensionsBase + [TestMethod] + public async Task With_Orders_Table() { - [TestMethod] - public async Task With_Orders_Table() - { - var dbContext = SetupDbContext(true); - int oldOrdersCount = dbContext.Orders.Count(); - await dbContext.Database.TruncateTableAsync("Orders"); - int newOrdersCount = dbContext.Orders.Count(); + var dbContext = SetupDbContext(true); + int oldOrdersCount = dbContext.Orders.Count(); + await dbContext.Database.TruncateTableAsync("Orders"); + int newOrdersCount = dbContext.Orders.Count(); - Assert.IsTrue(oldOrdersCount > 0, "Orders table should have data"); - Assert.IsTrue(newOrdersCount == 0, "Order table should be empty after truncating"); - } + Assert.IsTrue(oldOrdersCount > 0, "Orders table should have data"); + Assert.IsTrue(newOrdersCount == 0, "Order table should be empty after truncating"); } } \ No newline at end of file diff --git a/N.EntityFrameworkCore.Extensions.Test/DbContextExtensions/BulkDelete.cs b/N.EntityFrameworkCore.Extensions.Test/DbContextExtensions/BulkDelete.cs index b2eafa5..82412dc 100644 --- a/N.EntityFrameworkCore.Extensions.Test/DbContextExtensions/BulkDelete.cs +++ b/N.EntityFrameworkCore.Extensions.Test/DbContextExtensions/BulkDelete.cs @@ -3,90 +3,89 @@ using Microsoft.VisualStudio.TestTools.UnitTesting; using N.EntityFrameworkCore.Extensions.Test.Data; -namespace N.EntityFrameworkCore.Extensions.Test.DbContextExtensions +namespace N.EntityFrameworkCore.Extensions.Test.DbContextExtensions; + +[TestClass] +public class BulkDelete : DbContextExtensionsBase { - [TestClass] - public class BulkDelete : DbContextExtensionsBase + [TestMethod] + public void With_Default_Options() { - [TestMethod] - public void With_Default_Options() - { - var dbContext = SetupDbContext(true); - var orders = dbContext.Orders.Where(o => o.Price == 1.25M).ToList(); - int rowsDeleted = dbContext.BulkDelete(orders); - int newTotal = dbContext.Orders.Where(o => o.Price == 1.25M).Count(); + var dbContext = SetupDbContext(true); + var orders = dbContext.Orders.Where(o => o.Price == 1.25M).ToList(); + int rowsDeleted = dbContext.BulkDelete(orders); + int newTotal = dbContext.Orders.Where(o => o.Price == 1.25M).Count(); - Assert.IsTrue(orders.Count > 0, "There must be orders in database that match this condition (Price = $1.25)"); - Assert.IsTrue(rowsDeleted == orders.Count, "The number of rows deleted must match the count of existing rows in database"); - Assert.IsTrue(newTotal == 0, "Must be 0 to indicate all records were deleted"); - } - [TestMethod] - public void With_Inheritance_Tpc() - { - var dbContext = SetupDbContext(true, PopulateDataMode.Tpc); - var customers = dbContext.TpcPeople.OfType().ToList(); - int rowsDeleted = dbContext.BulkDelete(customers); - var newCustomers = dbContext.TpcPeople.OfType().Count(); + Assert.IsTrue(orders.Count > 0, "There must be orders in database that match this condition (Price = $1.25)"); + Assert.IsTrue(rowsDeleted == orders.Count, "The number of rows deleted must match the count of existing rows in database"); + Assert.IsTrue(newTotal == 0, "Must be 0 to indicate all records were deleted"); + } + [TestMethod] + public void With_Inheritance_Tpc() + { + var dbContext = SetupDbContext(true, PopulateDataMode.Tpc); + var customers = dbContext.TpcPeople.OfType().ToList(); + int rowsDeleted = dbContext.BulkDelete(customers); + var newCustomers = dbContext.TpcPeople.OfType().Count(); - Assert.IsTrue(customers.Count > 0, "There must be tphCustomer records in database"); - Assert.IsTrue(rowsDeleted == customers.Count, "The number of rows deleted must match the count of existing rows in database"); - Assert.IsTrue(newCustomers == 0, "Must be 0 to indicate all records were deleted"); - } - [TestMethod] - public void With_Inheritance_Tph() - { - var dbContext = SetupDbContext(true, PopulateDataMode.Tph); - var customers = dbContext.TphPeople.OfType().ToList(); - int rowsDeleted = dbContext.BulkDelete(customers); - var newCustomers = dbContext.TphPeople.OfType().Count(); + Assert.IsTrue(customers.Count > 0, "There must be tphCustomer records in database"); + Assert.IsTrue(rowsDeleted == customers.Count, "The number of rows deleted must match the count of existing rows in database"); + Assert.IsTrue(newCustomers == 0, "Must be 0 to indicate all records were deleted"); + } + [TestMethod] + public void With_Inheritance_Tph() + { + var dbContext = SetupDbContext(true, PopulateDataMode.Tph); + var customers = dbContext.TphPeople.OfType().ToList(); + int rowsDeleted = dbContext.BulkDelete(customers); + var newCustomers = dbContext.TphPeople.OfType().Count(); - Assert.IsTrue(customers.Count > 0, "There must be tphCustomer records in database"); - Assert.IsTrue(rowsDeleted == customers.Count, "The number of rows deleted must match the count of existing rows in database"); - Assert.IsTrue(newCustomers == 0, "Must be 0 to indicate all records were deleted"); - } - [TestMethod] - public void With_Inheritance_Tpt() - { - var dbContext = SetupDbContext(true, PopulateDataMode.Tpt); - var customers = dbContext.TptCustomers.ToList(); - int rowsDeleted = dbContext.BulkDelete(customers); - var newCustomers = dbContext.TptCustomers.Count(); + Assert.IsTrue(customers.Count > 0, "There must be tphCustomer records in database"); + Assert.IsTrue(rowsDeleted == customers.Count, "The number of rows deleted must match the count of existing rows in database"); + Assert.IsTrue(newCustomers == 0, "Must be 0 to indicate all records were deleted"); + } + [TestMethod] + public void With_Inheritance_Tpt() + { + var dbContext = SetupDbContext(true, PopulateDataMode.Tpt); + var customers = dbContext.TptCustomers.ToList(); + int rowsDeleted = dbContext.BulkDelete(customers); + var newCustomers = dbContext.TptCustomers.Count(); - Assert.IsTrue(customers.Count > 0, "There must be tphCustomer records in database"); - Assert.IsTrue(rowsDeleted == customers.Count, "The number of rows deleted must match the count of existing rows in database"); - Assert.IsTrue(newCustomers == 0, "Must be 0 to indicate all records were deleted"); - } - [TestMethod] - public void With_Options_DeleteOnCondition() - { - var dbContext = SetupDbContext(true); - int oldTotal = dbContext.Orders.Where(o => o.Price == 1.25M).Count(); - var orders = dbContext.Orders.Where(o => o.Price == 1.25M && o.ExternalId != null).ToList(); - int rowsDeleted = dbContext.BulkDelete(orders, options => { options.DeleteOnCondition = (s, t) => s.ExternalId == t.ExternalId; options.UsePermanentTable = true; }); - int newTotal = dbContext.Orders.Where(o => o.Price == 1.25M).Count(); + Assert.IsTrue(customers.Count > 0, "There must be tphCustomer records in database"); + Assert.IsTrue(rowsDeleted == customers.Count, "The number of rows deleted must match the count of existing rows in database"); + Assert.IsTrue(newCustomers == 0, "Must be 0 to indicate all records were deleted"); + } + [TestMethod] + public void With_Options_DeleteOnCondition() + { + var dbContext = SetupDbContext(true); + int oldTotal = dbContext.Orders.Where(o => o.Price == 1.25M).Count(); + var orders = dbContext.Orders.Where(o => o.Price == 1.25M && o.ExternalId != null).ToList(); + int rowsDeleted = dbContext.BulkDelete(orders, options => { options.DeleteOnCondition = (s, t) => s.ExternalId == t.ExternalId; options.UsePermanentTable = true; }); + int newTotal = dbContext.Orders.Where(o => o.Price == 1.25M).Count(); - Assert.IsTrue(orders.Count > 0, "There must be orders in database that match this condition (Price < $2)"); - Assert.IsTrue(rowsDeleted == orders.Count, "The number of rows deleted must match the count of existing rows in database"); - Assert.IsTrue(newTotal == oldTotal - rowsDeleted, "Must be 0 to indicate all records were deleted"); - } - [TestMethod] - public void With_Transaction() + Assert.IsTrue(orders.Count > 0, "There must be orders in database that match this condition (Price < $2)"); + Assert.IsTrue(rowsDeleted == orders.Count, "The number of rows deleted must match the count of existing rows in database"); + Assert.IsTrue(newTotal == oldTotal - rowsDeleted, "Must be 0 to indicate all records were deleted"); + } + [TestMethod] + public void With_Transaction() + { + var dbContext = SetupDbContext(true); + var orders = dbContext.Orders.Where(o => o.Price == 1.25M).ToList(); + int rowsDeleted, newTotal = 0; + using (var transaction = dbContext.Database.BeginTransaction()) { - var dbContext = SetupDbContext(true); - var orders = dbContext.Orders.Where(o => o.Price == 1.25M).ToList(); - int rowsDeleted, newTotal = 0; - using (var transaction = dbContext.Database.BeginTransaction()) - { - rowsDeleted = dbContext.BulkDelete(orders); - newTotal = dbContext.Orders.Where(o => o.Price == 1.25M).Count(); - transaction.Rollback(); - } - var rollbackTotal = dbContext.Orders.Count(o => o.Price == 1.25M); - - Assert.IsTrue(orders.Count > 0, "There must be orders in database that match this condition (Price < $2)"); - Assert.IsTrue(rowsDeleted == orders.Count, "The number of rows deleted must match the count of existing rows in database"); - Assert.IsTrue(newTotal == 0, "Must be 0 to indicate all records were deleted"); - Assert.IsTrue(rollbackTotal == orders.Count, "The number of rows after the transacation has been rollbacked should match the original count"); + rowsDeleted = dbContext.BulkDelete(orders); + newTotal = dbContext.Orders.Where(o => o.Price == 1.25M).Count(); + transaction.Rollback(); } + var rollbackTotal = dbContext.Orders.Count(o => o.Price == 1.25M); + + Assert.IsTrue(orders.Count > 0, "There must be orders in database that match this condition (Price < $2)"); + Assert.IsTrue(rowsDeleted == orders.Count, "The number of rows deleted must match the count of existing rows in database"); + Assert.IsTrue(newTotal == 0, "Must be 0 to indicate all records were deleted"); + Assert.IsTrue(rollbackTotal == orders.Count, "The number of rows after the transacation has been rollbacked should match the original count"); } } \ No newline at end of file diff --git a/N.EntityFrameworkCore.Extensions.Test/DbContextExtensions/BulkDeleteAsync.cs b/N.EntityFrameworkCore.Extensions.Test/DbContextExtensions/BulkDeleteAsync.cs index bcaa87e..32028ee 100644 --- a/N.EntityFrameworkCore.Extensions.Test/DbContextExtensions/BulkDeleteAsync.cs +++ b/N.EntityFrameworkCore.Extensions.Test/DbContextExtensions/BulkDeleteAsync.cs @@ -3,90 +3,89 @@ using Microsoft.VisualStudio.TestTools.UnitTesting; using N.EntityFrameworkCore.Extensions.Test.Data; -namespace N.EntityFrameworkCore.Extensions.Test.DbContextExtensions +namespace N.EntityFrameworkCore.Extensions.Test.DbContextExtensions; + +[TestClass] +public class BulkDeleteAsync : DbContextExtensionsBase { - [TestClass] - public class BulkDeleteAsync : DbContextExtensionsBase + [TestMethod] + public async Task With_Default_Options() { - [TestMethod] - public async Task With_Default_Options() - { - var dbContext = SetupDbContext(true); - var orders = dbContext.Orders.Where(o => o.Price == 1.25M).ToList(); - int rowsDeleted = await dbContext.BulkDeleteAsync(orders); - int newTotal = dbContext.Orders.Where(o => o.Price == 1.25M).Count(); + var dbContext = SetupDbContext(true); + var orders = dbContext.Orders.Where(o => o.Price == 1.25M).ToList(); + int rowsDeleted = await dbContext.BulkDeleteAsync(orders); + int newTotal = dbContext.Orders.Where(o => o.Price == 1.25M).Count(); - Assert.IsTrue(orders.Count > 0, "There must be orders in database that match this condition (Price = $1.25)"); - Assert.IsTrue(rowsDeleted == orders.Count, "The number of rows deleted must match the count of existing rows in database"); - Assert.IsTrue(newTotal == 0, "Must be 0 to indicate all records were deleted"); - } - [TestMethod] - public async Task With_Inheritance_Tpc() - { - var dbContext = SetupDbContext(true, PopulateDataMode.Tpc); - var customers = dbContext.TpcPeople.OfType().ToList(); - int rowsDeleted = await dbContext.BulkDeleteAsync(customers); - var newCustomers = dbContext.TpcPeople.OfType().Count(); + Assert.IsTrue(orders.Count > 0, "There must be orders in database that match this condition (Price = $1.25)"); + Assert.IsTrue(rowsDeleted == orders.Count, "The number of rows deleted must match the count of existing rows in database"); + Assert.IsTrue(newTotal == 0, "Must be 0 to indicate all records were deleted"); + } + [TestMethod] + public async Task With_Inheritance_Tpc() + { + var dbContext = SetupDbContext(true, PopulateDataMode.Tpc); + var customers = dbContext.TpcPeople.OfType().ToList(); + int rowsDeleted = await dbContext.BulkDeleteAsync(customers); + var newCustomers = dbContext.TpcPeople.OfType().Count(); - Assert.IsTrue(customers.Count > 0, "There must be tphCustomer records in database"); - Assert.IsTrue(rowsDeleted == customers.Count, "The number of rows deleted must match the count of existing rows in database"); - Assert.IsTrue(newCustomers == 0, "Must be 0 to indicate all records were deleted"); - } - [TestMethod] - public async Task With_Inheritance_Tph() - { - var dbContext = SetupDbContext(true, PopulateDataMode.Tph); - var customers = dbContext.TphPeople.OfType().ToList(); - int rowsDeleted = await dbContext.BulkDeleteAsync(customers); - var newCustomers = dbContext.TphPeople.OfType().Count(); + Assert.IsTrue(customers.Count > 0, "There must be tphCustomer records in database"); + Assert.IsTrue(rowsDeleted == customers.Count, "The number of rows deleted must match the count of existing rows in database"); + Assert.IsTrue(newCustomers == 0, "Must be 0 to indicate all records were deleted"); + } + [TestMethod] + public async Task With_Inheritance_Tph() + { + var dbContext = SetupDbContext(true, PopulateDataMode.Tph); + var customers = dbContext.TphPeople.OfType().ToList(); + int rowsDeleted = await dbContext.BulkDeleteAsync(customers); + var newCustomers = dbContext.TphPeople.OfType().Count(); - Assert.IsTrue(customers.Count > 0, "There must be tphCustomer records in database"); - Assert.IsTrue(rowsDeleted == customers.Count, "The number of rows deleted must match the count of existing rows in database"); - Assert.IsTrue(newCustomers == 0, "Must be 0 to indicate all records were deleted"); - } - [TestMethod] - public async Task With_Inheritance_Tpt() - { - var dbContext = SetupDbContext(true, PopulateDataMode.Tpt); - var customers = dbContext.TptCustomers.ToList(); - int rowsDeleted = await dbContext.BulkDeleteAsync(customers); - var newCustomers = dbContext.TptCustomers.Count(); + Assert.IsTrue(customers.Count > 0, "There must be tphCustomer records in database"); + Assert.IsTrue(rowsDeleted == customers.Count, "The number of rows deleted must match the count of existing rows in database"); + Assert.IsTrue(newCustomers == 0, "Must be 0 to indicate all records were deleted"); + } + [TestMethod] + public async Task With_Inheritance_Tpt() + { + var dbContext = SetupDbContext(true, PopulateDataMode.Tpt); + var customers = dbContext.TptCustomers.ToList(); + int rowsDeleted = await dbContext.BulkDeleteAsync(customers); + var newCustomers = dbContext.TptCustomers.Count(); - Assert.IsTrue(customers.Count > 0, "There must be tphCustomer records in database"); - Assert.IsTrue(rowsDeleted == customers.Count, "The number of rows deleted must match the count of existing rows in database"); - Assert.IsTrue(newCustomers == 0, "Must be 0 to indicate all records were deleted"); - } - [TestMethod] - public async Task With_Options_DeleteOnCondition() - { - var dbContext = SetupDbContext(true); - int oldTotal = dbContext.Orders.Where(o => o.Price == 1.25M).Count(); - var orders = dbContext.Orders.Where(o => o.Price == 1.25M && o.ExternalId != null).ToList(); - int rowsDeleted = await dbContext.BulkDeleteAsync(orders, options => { options.DeleteOnCondition = (s, t) => s.ExternalId == t.ExternalId; options.UsePermanentTable = true; }); - int newTotal = dbContext.Orders.Where(o => o.Price == 1.25M).Count(); + Assert.IsTrue(customers.Count > 0, "There must be tphCustomer records in database"); + Assert.IsTrue(rowsDeleted == customers.Count, "The number of rows deleted must match the count of existing rows in database"); + Assert.IsTrue(newCustomers == 0, "Must be 0 to indicate all records were deleted"); + } + [TestMethod] + public async Task With_Options_DeleteOnCondition() + { + var dbContext = SetupDbContext(true); + int oldTotal = dbContext.Orders.Where(o => o.Price == 1.25M).Count(); + var orders = dbContext.Orders.Where(o => o.Price == 1.25M && o.ExternalId != null).ToList(); + int rowsDeleted = await dbContext.BulkDeleteAsync(orders, options => { options.DeleteOnCondition = (s, t) => s.ExternalId == t.ExternalId; options.UsePermanentTable = true; }); + int newTotal = dbContext.Orders.Where(o => o.Price == 1.25M).Count(); - Assert.IsTrue(orders.Count > 0, "There must be orders in database that match this condition (Price < $2)"); - Assert.IsTrue(rowsDeleted == orders.Count, "The number of rows deleted must match the count of existing rows in database"); - Assert.IsTrue(newTotal == oldTotal - rowsDeleted, "Must be 0 to indicate all records were deleted"); - } - [TestMethod] - public async Task With_Transaction() + Assert.IsTrue(orders.Count > 0, "There must be orders in database that match this condition (Price < $2)"); + Assert.IsTrue(rowsDeleted == orders.Count, "The number of rows deleted must match the count of existing rows in database"); + Assert.IsTrue(newTotal == oldTotal - rowsDeleted, "Must be 0 to indicate all records were deleted"); + } + [TestMethod] + public async Task With_Transaction() + { + var dbContext = SetupDbContext(true); + var orders = dbContext.Orders.Where(o => o.Price == 1.25M).ToList(); + int rowsDeleted, newTotal = 0; + using (var transaction = dbContext.Database.BeginTransaction()) { - var dbContext = SetupDbContext(true); - var orders = dbContext.Orders.Where(o => o.Price == 1.25M).ToList(); - int rowsDeleted, newTotal = 0; - using (var transaction = dbContext.Database.BeginTransaction()) - { - rowsDeleted = await dbContext.BulkDeleteAsync(orders); - newTotal = dbContext.Orders.Where(o => o.Price == 1.25M).Count(); - transaction.Rollback(); - } - var rollbackTotal = dbContext.Orders.Count(o => o.Price == 1.25M); - - Assert.IsTrue(orders.Count > 0, "There must be orders in database that match this condition (Price < $2)"); - Assert.IsTrue(rowsDeleted == orders.Count, "The number of rows deleted must match the count of existing rows in database"); - Assert.IsTrue(newTotal == 0, "Must be 0 to indicate all records were deleted"); - Assert.IsTrue(rollbackTotal == orders.Count, "The number of rows after the transacation has been rollbacked should match the original count"); + rowsDeleted = await dbContext.BulkDeleteAsync(orders); + newTotal = dbContext.Orders.Where(o => o.Price == 1.25M).Count(); + transaction.Rollback(); } + var rollbackTotal = dbContext.Orders.Count(o => o.Price == 1.25M); + + Assert.IsTrue(orders.Count > 0, "There must be orders in database that match this condition (Price < $2)"); + Assert.IsTrue(rowsDeleted == orders.Count, "The number of rows deleted must match the count of existing rows in database"); + Assert.IsTrue(newTotal == 0, "Must be 0 to indicate all records were deleted"); + Assert.IsTrue(rollbackTotal == orders.Count, "The number of rows after the transacation has been rollbacked should match the original count"); } } \ No newline at end of file diff --git a/N.EntityFrameworkCore.Extensions.Test/DbContextExtensions/BulkFetch.cs b/N.EntityFrameworkCore.Extensions.Test/DbContextExtensions/BulkFetch.cs index de7f31b..9b4d300 100644 --- a/N.EntityFrameworkCore.Extensions.Test/DbContextExtensions/BulkFetch.cs +++ b/N.EntityFrameworkCore.Extensions.Test/DbContextExtensions/BulkFetch.cs @@ -5,115 +5,114 @@ using System.Threading.Tasks; using Microsoft.VisualStudio.TestTools.UnitTesting; -namespace N.EntityFrameworkCore.Extensions.Test.DbContextExtensions +namespace N.EntityFrameworkCore.Extensions.Test.DbContextExtensions; + +[TestClass] +public class BulkFetch : DbContextExtensionsBase { - [TestClass] - public class BulkFetch : DbContextExtensionsBase + [TestMethod] + public void With_Complex_Property() { - [TestMethod] - public void With_Complex_Property() - { - var dbContext = SetupDbContext(true); - var products = dbContext.Products.Where(o => o.Price == 1.25m).ToList(); - var fetchedProducts = dbContext.Products.BulkFetch(products); - bool foundNullPositionProperty = fetchedProducts.Any(o => o.Position == null); + var dbContext = SetupDbContext(true); + var products = dbContext.Products.Where(o => o.Price == 1.25m).ToList(); + var fetchedProducts = dbContext.Products.BulkFetch(products); + bool foundNullPositionProperty = fetchedProducts.Any(o => o.Position == null); - Assert.IsTrue(products.Count > 0, "There must be orders in database that match this condition (Price = $1.25)"); - Assert.IsTrue(products.Count == fetchedProducts.Count(), "The number of rows deleted must match the count of existing rows in database"); - Assert.IsFalse(foundNullPositionProperty, "The Position complex property should be populated when using BulkFetch()"); - } - [TestMethod] - public void With_Default_Options() - { - var dbContext = SetupDbContext(true); - var orders = dbContext.Orders.Where(o => o.Price == 1.25M).ToList(); - var fetchedOrders = dbContext.Orders.BulkFetch(orders); - bool ordersAreMatched = true; + Assert.IsTrue(products.Count > 0, "There must be orders in database that match this condition (Price = $1.25)"); + Assert.IsTrue(products.Count == fetchedProducts.Count(), "The number of rows deleted must match the count of existing rows in database"); + Assert.IsFalse(foundNullPositionProperty, "The Position complex property should be populated when using BulkFetch()"); + } + [TestMethod] + public void With_Default_Options() + { + var dbContext = SetupDbContext(true); + var orders = dbContext.Orders.Where(o => o.Price == 1.25M).ToList(); + var fetchedOrders = dbContext.Orders.BulkFetch(orders); + bool ordersAreMatched = true; - foreach (var fetchedOrder in fetchedOrders) + foreach (var fetchedOrder in fetchedOrders) + { + var order = orders.First(o => o.Id == fetchedOrder.Id); + if (order.ExternalId != fetchedOrder.ExternalId || order.AddedDateTime != fetchedOrder.AddedDateTime || order.ModifiedDateTime != fetchedOrder.ModifiedDateTime) { - var order = orders.First(o => o.Id == fetchedOrder.Id); - if (order.ExternalId != fetchedOrder.ExternalId || order.AddedDateTime != fetchedOrder.AddedDateTime || order.ModifiedDateTime != fetchedOrder.ModifiedDateTime) - { - ordersAreMatched = false; - break; - } + ordersAreMatched = false; + break; } - - Assert.IsTrue(orders.Count > 0, "There must be orders in database that match this condition (Price = $1.25)"); - Assert.IsTrue(orders.Count == fetchedOrders.Count(), "The number of rows deleted must match the count of existing rows in database"); - Assert.IsTrue(ordersAreMatched, "The orders from BulkFetch() should match what is retrieved from DbContext"); } - [TestMethod] - public void With_Enum() - { - var dbContext = SetupDbContext(true); - var products = dbContext.Products.Where(o => o.Price == 1.25m).ToList(); - var fetchedProducts = dbContext.Products.BulkFetch(products); - bool productsAreMatched = true; - foreach (var fetchedProduct in fetchedProducts) + Assert.IsTrue(orders.Count > 0, "There must be orders in database that match this condition (Price = $1.25)"); + Assert.IsTrue(orders.Count == fetchedOrders.Count(), "The number of rows deleted must match the count of existing rows in database"); + Assert.IsTrue(ordersAreMatched, "The orders from BulkFetch() should match what is retrieved from DbContext"); + } + [TestMethod] + public void With_Enum() + { + var dbContext = SetupDbContext(true); + var products = dbContext.Products.Where(o => o.Price == 1.25m).ToList(); + var fetchedProducts = dbContext.Products.BulkFetch(products); + bool productsAreMatched = true; + + foreach (var fetchedProduct in fetchedProducts) + { + var product = products.First(o => o.Id == fetchedProduct.Id); + if (product.Id != fetchedProduct.Id || product.Name != fetchedProduct.Name || product.StatusEnum != fetchedProduct.StatusEnum) { - var product = products.First(o => o.Id == fetchedProduct.Id); - if (product.Id != fetchedProduct.Id || product.Name != fetchedProduct.Name || product.StatusEnum != fetchedProduct.StatusEnum) - { - productsAreMatched = false; - break; - } + productsAreMatched = false; + break; } - - Assert.IsTrue(products.Count > 0, "There must be orders in database that match this condition (Price = $1.25)"); - Assert.IsTrue(products.Count == fetchedProducts.Count(), "The number of rows deleted must match the count of existing rows in database"); - Assert.IsTrue(productsAreMatched, "The products from BulkFetch() should match what is retrieved from DbContext"); } - [TestMethod] - public void With_IQueryable() - { - var dbContext = SetupDbContext(true); - var orders = dbContext.Orders.Where(o => o.Price <= 10 && o.ExternalId != null); - var fetchedOrders = dbContext.Orders.BulkFetch(orders, options => { options.IgnoreColumns = o => new { o.ExternalId }; }).ToList(); - int newTotal = dbContext.Orders.Where(o => o.Price <= 10 && o.ExternalId == null).Count(); - bool foundNullExternalId = fetchedOrders.Where(o => o.ExternalId != null).Any(); - Assert.IsTrue(orders.Count() > 0, "There must be orders in the database that match condition (Price <= 10 And ExternalId != null)"); - Assert.IsTrue(orders.Count() == fetchedOrders.Count(), "The number of orders must match the number of fetched orders"); - Assert.IsTrue(!foundNullExternalId, "Fetched orders should not contain any items where ExternalId is null."); - } - [TestMethod] - public void With_Options_IgnoreColumns() - { - var dbContext = SetupDbContext(true); - var orders = dbContext.Orders.Where(o => o.Price <= 10 && o.ExternalId != null).ToList(); - var fetchedOrders = dbContext.Orders.BulkFetch(orders, options => { options.IgnoreColumns = o => new { o.ExternalId }; }).ToList(); - int newTotal = dbContext.Orders.Where(o => o.Price <= 10 && o.ExternalId == null).Count(); - bool foundNullExternalId = fetchedOrders.Where(o => o.ExternalId != null).Any(); + Assert.IsTrue(products.Count > 0, "There must be orders in database that match this condition (Price = $1.25)"); + Assert.IsTrue(products.Count == fetchedProducts.Count(), "The number of rows deleted must match the count of existing rows in database"); + Assert.IsTrue(productsAreMatched, "The products from BulkFetch() should match what is retrieved from DbContext"); + } + [TestMethod] + public void With_IQueryable() + { + var dbContext = SetupDbContext(true); + var orders = dbContext.Orders.Where(o => o.Price <= 10 && o.ExternalId != null); + var fetchedOrders = dbContext.Orders.BulkFetch(orders, options => { options.IgnoreColumns = o => new { o.ExternalId }; }).ToList(); + int newTotal = dbContext.Orders.Where(o => o.Price <= 10 && o.ExternalId == null).Count(); + bool foundNullExternalId = fetchedOrders.Where(o => o.ExternalId != null).Any(); - Assert.IsTrue(orders.Count() > 0, "There must be orders in the database that match condition (Price <= 10 And ExternalId != null)"); - Assert.IsTrue(orders.Count() == fetchedOrders.Count(), "The number of orders must match the number of fetched orders"); - Assert.IsTrue(!foundNullExternalId, "Fetched orders should not contain any items where ExternalId is null."); - } - [TestMethod] - public void With_ValueConverter() - { - var dbContext = SetupDbContext(true); - var products = dbContext.Products.Where(o => o.Price == 1.25M).ToList(); - var fetchedProducts = dbContext.Products.BulkFetch(products); - bool areMatched = true; + Assert.IsTrue(orders.Count() > 0, "There must be orders in the database that match condition (Price <= 10 And ExternalId != null)"); + Assert.IsTrue(orders.Count() == fetchedOrders.Count(), "The number of orders must match the number of fetched orders"); + Assert.IsTrue(!foundNullExternalId, "Fetched orders should not contain any items where ExternalId is null."); + } + [TestMethod] + public void With_Options_IgnoreColumns() + { + var dbContext = SetupDbContext(true); + var orders = dbContext.Orders.Where(o => o.Price <= 10 && o.ExternalId != null).ToList(); + var fetchedOrders = dbContext.Orders.BulkFetch(orders, options => { options.IgnoreColumns = o => new { o.ExternalId }; }).ToList(); + int newTotal = dbContext.Orders.Where(o => o.Price <= 10 && o.ExternalId == null).Count(); + bool foundNullExternalId = fetchedOrders.Where(o => o.ExternalId != null).Any(); + + Assert.IsTrue(orders.Count() > 0, "There must be orders in the database that match condition (Price <= 10 And ExternalId != null)"); + Assert.IsTrue(orders.Count() == fetchedOrders.Count(), "The number of orders must match the number of fetched orders"); + Assert.IsTrue(!foundNullExternalId, "Fetched orders should not contain any items where ExternalId is null."); + } + [TestMethod] + public void With_ValueConverter() + { + var dbContext = SetupDbContext(true); + var products = dbContext.Products.Where(o => o.Price == 1.25M).ToList(); + var fetchedProducts = dbContext.Products.BulkFetch(products); + bool areMatched = true; - foreach (var fetchedProduct in fetchedProducts) + foreach (var fetchedProduct in fetchedProducts) + { + var product = products.First(o => o.Id == fetchedProduct.Id); + if (product.Name != fetchedProduct.Name || product.Price != fetchedProduct.Price + || product.Color != fetchedProduct.Color) { - var product = products.First(o => o.Id == fetchedProduct.Id); - if (product.Name != fetchedProduct.Name || product.Price != fetchedProduct.Price - || product.Color != fetchedProduct.Color) - { - areMatched = false; - break; - } + areMatched = false; + break; } - - Assert.IsTrue(products.Count > 0, "There must be orders in database that match this condition (Price = $1.25)"); - Assert.IsTrue(products.Count == fetchedProducts.Count(), "The number of rows deleted must match the count of existing rows in database"); - Assert.IsTrue(areMatched, "The products from BulkFetch() should match what is retrieved from DbContext"); } + + Assert.IsTrue(products.Count > 0, "There must be orders in database that match this condition (Price = $1.25)"); + Assert.IsTrue(products.Count == fetchedProducts.Count(), "The number of rows deleted must match the count of existing rows in database"); + Assert.IsTrue(areMatched, "The products from BulkFetch() should match what is retrieved from DbContext"); } } \ No newline at end of file diff --git a/N.EntityFrameworkCore.Extensions.Test/DbContextExtensions/BulkInsert.cs b/N.EntityFrameworkCore.Extensions.Test/DbContextExtensions/BulkInsert.cs index db3d9e5..b0be457 100644 --- a/N.EntityFrameworkCore.Extensions.Test/DbContextExtensions/BulkInsert.cs +++ b/N.EntityFrameworkCore.Extensions.Test/DbContextExtensions/BulkInsert.cs @@ -6,402 +6,401 @@ using Microsoft.VisualStudio.TestTools.UnitTesting; using N.EntityFrameworkCore.Extensions.Test.Data; -namespace N.EntityFrameworkCore.Extensions.Test.DbContextExtensions +namespace N.EntityFrameworkCore.Extensions.Test.DbContextExtensions; + +[TestClass] +public class BulkInsert : DbContextExtensionsBase { - [TestClass] - public class BulkInsert : DbContextExtensionsBase + [TestMethod] + public void With_Complex_Key() { - [TestMethod] - public void With_Complex_Key() + var dbContext = SetupDbContext(true); + var products = new List(); + for (int i = 50000; i < 60000; i++) { - var dbContext = SetupDbContext(true); - var products = new List(); - for (int i = 50000; i < 60000; i++) - { - var key = i.ToString(); - products.Add(new ProductWithComplexKey { Price = 1.57M }); - } - int oldTotal = dbContext.ProductsWithComplexKey.Where(o => o.Price <= 10).Count(); - int rowsInserted = dbContext.BulkInsert(products); - int newTotal = dbContext.ProductsWithComplexKey.Where(o => o.Price <= 10).Count(); + var key = i.ToString(); + products.Add(new ProductWithComplexKey { Price = 1.57M }); + } + int oldTotal = dbContext.ProductsWithComplexKey.Where(o => o.Price <= 10).Count(); + int rowsInserted = dbContext.BulkInsert(products); + int newTotal = dbContext.ProductsWithComplexKey.Where(o => o.Price <= 10).Count(); - Assert.IsTrue(rowsInserted == products.Count, "The number of rows inserted must match the count of order list"); - Assert.IsTrue(newTotal - oldTotal == rowsInserted, "The new count minus the old count should match the number of rows inserted."); + Assert.IsTrue(rowsInserted == products.Count, "The number of rows inserted must match the count of order list"); + Assert.IsTrue(newTotal - oldTotal == rowsInserted, "The new count minus the old count should match the number of rows inserted."); + } + [TestMethod] + public void With_Default_Options() + { + var dbContext = SetupDbContext(false); + var orders = new List(); + for (int i = 0; i < 20000; i++) + { + orders.Add(new Order { Id = i, Price = 1.57M }); } - [TestMethod] - public void With_Default_Options() + int oldTotal = dbContext.Orders.Where(o => o.Price <= 10).Count(); + int rowsInserted = dbContext.BulkInsert(orders); + int newTotal = dbContext.Orders.Where(o => o.Price <= 10).Count(); + + Assert.IsTrue(rowsInserted == orders.Count, "The number of rows inserted must match the count of order list"); + Assert.IsTrue(newTotal - oldTotal == rowsInserted, "The new count minus the old count should match the number of rows inserted."); + } + [TestMethod] + public void With_Inheritance_Tpc() + { + var dbContext = SetupDbContext(false); + var customers = new List(); + var vendors = new List(); + for (int i = 0; i < 20000; i++) { - var dbContext = SetupDbContext(false); - var orders = new List(); - for (int i = 0; i < 20000; i++) + customers.Add(new TpcCustomer { - orders.Add(new Order { Id = i, Price = 1.57M }); - } - int oldTotal = dbContext.Orders.Where(o => o.Price <= 10).Count(); - int rowsInserted = dbContext.BulkInsert(orders); - int newTotal = dbContext.Orders.Where(o => o.Price <= 10).Count(); - - Assert.IsTrue(rowsInserted == orders.Count, "The number of rows inserted must match the count of order list"); - Assert.IsTrue(newTotal - oldTotal == rowsInserted, "The new count minus the old count should match the number of rows inserted."); + Id = i, + FirstName = string.Format("John_{0}", i), + LastName = string.Format("Smith_{0}", i), + Email = string.Format("john.smith{0}@domain.com", i), + AddedDate = DateTime.UtcNow + }); } - [TestMethod] - public void With_Inheritance_Tpc() + for (int i = 20000; i < 30000; i++) { - var dbContext = SetupDbContext(false); - var customers = new List(); - var vendors = new List(); - for (int i = 0; i < 20000; i++) - { - customers.Add(new TpcCustomer - { - Id = i, - FirstName = string.Format("John_{0}", i), - LastName = string.Format("Smith_{0}", i), - Email = string.Format("john.smith{0}@domain.com", i), - AddedDate = DateTime.UtcNow - }); - } - for (int i = 20000; i < 30000; i++) + vendors.Add(new TpcVendor { - vendors.Add(new TpcVendor - { - Id = i, - FirstName = string.Format("Mike_{0}", i), - LastName = string.Format("Smith_{0}", i), - Email = string.Format("mike.smith{0}@domain.com", i), - Url = string.Format("http://domain.com/mike.smith{0}", i) - }); - } - int oldTotal = dbContext.TpcPeople.Count(); - int customerRowsInserted = dbContext.BulkInsert(customers, o => o.UsePermanentTable = true); - int vendorRowsInserted = dbContext.BulkInsert(vendors, o => o.UsePermanentTable = true); - int rowsInserted = customerRowsInserted + vendorRowsInserted; - int newTotal = dbContext.TpcPeople.Count(); - - Assert.IsTrue(rowsInserted == customers.Count + vendors.Count, "The number of rows inserted must match the count of order list"); - Assert.IsTrue(newTotal - oldTotal == rowsInserted, "The new count minus the old count should match the number of rows inserted."); + Id = i, + FirstName = string.Format("Mike_{0}", i), + LastName = string.Format("Smith_{0}", i), + Email = string.Format("mike.smith{0}@domain.com", i), + Url = string.Format("http://domain.com/mike.smith{0}", i) + }); } - [TestMethod] - public void With_Inheritance_Tph() + int oldTotal = dbContext.TpcPeople.Count(); + int customerRowsInserted = dbContext.BulkInsert(customers, o => o.UsePermanentTable = true); + int vendorRowsInserted = dbContext.BulkInsert(vendors, o => o.UsePermanentTable = true); + int rowsInserted = customerRowsInserted + vendorRowsInserted; + int newTotal = dbContext.TpcPeople.Count(); + + Assert.IsTrue(rowsInserted == customers.Count + vendors.Count, "The number of rows inserted must match the count of order list"); + Assert.IsTrue(newTotal - oldTotal == rowsInserted, "The new count minus the old count should match the number of rows inserted."); + } + [TestMethod] + public void With_Inheritance_Tph() + { + var dbContext = SetupDbContext(false); + var customers = new List(); + var vendors = new List(); + for (int i = 0; i < 20000; i++) { - var dbContext = SetupDbContext(false); - var customers = new List(); - var vendors = new List(); - for (int i = 0; i < 20000; i++) - { - customers.Add(new TphCustomer - { - Id = i, - FirstName = string.Format("John_{0}", i), - LastName = string.Format("Smith_{0}", i), - Email = string.Format("john.smith{0}@domain.com", i), - Phone = "404-555-1111", - AddedDate = DateTime.UtcNow - }); - } - for (int i = 20000; i < 30000; i++) + customers.Add(new TphCustomer { - vendors.Add(new TphVendor - { - Id = i, - FirstName = string.Format("Mike_{0}", i), - LastName = string.Format("Smith_{0}", i), - Phone = "404-555-2222", - Email = string.Format("mike.smith{0}@domain.com", i), - Url = string.Format("http://domain.com/mike.smith{0}", i) - }); - } - int oldTotal = dbContext.TphPeople.Count(); - int customerRowsInserted = dbContext.BulkInsert(customers); - int vendorRowsInserted = dbContext.BulkInsert(vendors); - int rowsInserted = customerRowsInserted + vendorRowsInserted; - int newTotal = dbContext.TphPeople.Count(); - - Assert.IsTrue(rowsInserted == customers.Count + vendors.Count, "The number of rows inserted must match the count of order list"); - Assert.IsTrue(newTotal - oldTotal == rowsInserted, "The new count minus the old count should match the number of rows inserted."); + Id = i, + FirstName = string.Format("John_{0}", i), + LastName = string.Format("Smith_{0}", i), + Email = string.Format("john.smith{0}@domain.com", i), + Phone = "404-555-1111", + AddedDate = DateTime.UtcNow + }); } - [TestMethod] - public void With_Inheritance_Tpt() + for (int i = 20000; i < 30000; i++) { - var dbContext = SetupDbContext(false); - var customers = new List(); - var vendors = new List(); - for (int i = 0; i < 20000; i++) + vendors.Add(new TphVendor { - customers.Add(new TptCustomer - { - Id = i, - FirstName = string.Format("John_{0}", i), - LastName = string.Format("Smith_{0}", i), - Email = string.Format("john.smith{0}@domain.com", i), - Phone = "777-555-1234", - AddedDate = DateTime.UtcNow - }); - } - for (int i = 20000; i < 30000; i++) - { - vendors.Add(new TptVendor - { - Id = i, - FirstName = string.Format("Mike_{0}", i), - LastName = string.Format("Smith_{0}", i), - Email = string.Format("mike.smith{0}@domain.com", i), - Url = string.Format("http://domain.com/mike.smith{0}", i) - }); - } - int oldTotal = dbContext.TptPeople.Count(); - int customerRowsInserted = dbContext.BulkInsert(customers, o => o.UsePermanentTable = true); - int vendorRowsInserted = dbContext.BulkInsert(vendors); - int rowsInserted = customerRowsInserted + vendorRowsInserted; - int newTotal = dbContext.TptPeople.Count(); - - Assert.IsTrue(rowsInserted == customers.Count + vendors.Count, "The number of rows inserted must match the count of order list"); - Assert.IsTrue(newTotal - oldTotal == rowsInserted, "The new count minus the old count should match the number of rows inserted."); + Id = i, + FirstName = string.Format("Mike_{0}", i), + LastName = string.Format("Smith_{0}", i), + Phone = "404-555-2222", + Email = string.Format("mike.smith{0}@domain.com", i), + Url = string.Format("http://domain.com/mike.smith{0}", i) + }); } - [TestMethod] - public void Without_Identity_Column() + int oldTotal = dbContext.TphPeople.Count(); + int customerRowsInserted = dbContext.BulkInsert(customers); + int vendorRowsInserted = dbContext.BulkInsert(vendors); + int rowsInserted = customerRowsInserted + vendorRowsInserted; + int newTotal = dbContext.TphPeople.Count(); + + Assert.IsTrue(rowsInserted == customers.Count + vendors.Count, "The number of rows inserted must match the count of order list"); + Assert.IsTrue(newTotal - oldTotal == rowsInserted, "The new count minus the old count should match the number of rows inserted."); + } + [TestMethod] + public void With_Inheritance_Tpt() + { + var dbContext = SetupDbContext(false); + var customers = new List(); + var vendors = new List(); + for (int i = 0; i < 20000; i++) { - var dbContext = SetupDbContext(true); - var products = new List(); - for (int i = 50000; i < 60000; i++) + customers.Add(new TptCustomer { - products.Add(new Product { Id = i.ToString(), Price = 1.57M }); - } - int oldTotal = dbContext.Products.Where(o => o.Price <= 10).Count(); - int rowsInserted = dbContext.BulkInsert(products); - int newTotal = dbContext.Products.Where(o => o.Price <= 10).Count(); - - Assert.IsTrue(rowsInserted == products.Count, "The number of rows inserted must match the count of order list"); - Assert.IsTrue(newTotal - oldTotal == rowsInserted, "The new count minus the old count should match the number of rows inserted."); + Id = i, + FirstName = string.Format("John_{0}", i), + LastName = string.Format("Smith_{0}", i), + Email = string.Format("john.smith{0}@domain.com", i), + Phone = "777-555-1234", + AddedDate = DateTime.UtcNow + }); } - [TestMethod] - public void With_Options_AutoMapIdentity() + for (int i = 20000; i < 30000; i++) { - var dbContext = SetupDbContext(false); - var orders = new List(); - for (int i = 0; i < 5000; i++) + vendors.Add(new TptVendor { - orders.Add(new Order { ExternalId = i.ToString(), Price = ((decimal)i + 0.55M) }); - } - int rowsAdded = dbContext.BulkInsert(orders, new BulkInsertOptions - { - UsePermanentTable = true + Id = i, + FirstName = string.Format("Mike_{0}", i), + LastName = string.Format("Smith_{0}", i), + Email = string.Format("mike.smith{0}@domain.com", i), + Url = string.Format("http://domain.com/mike.smith{0}", i) }); - bool autoMapIdentityMatched = true; - var ordersInDb = dbContext.Orders.ToList(); - Order order1 = null; - Order order2 = null; - foreach (var order in orders) - { - order1 = order; - var orderinDb = ordersInDb.First(o => o.Id == order.Id); - order2 = orderinDb; - if (!(orderinDb.ExternalId == order.ExternalId && orderinDb.Price == order.Price)) - { - autoMapIdentityMatched = false; - break; - } - } - - Assert.IsTrue(rowsAdded == orders.Count, "The number of rows inserted must match the count of order list"); - Assert.IsTrue(autoMapIdentityMatched, "The auto mapping of ids of entities that were merged failed to match up"); } - [TestMethod] - public void With_Options_IgnoreColumns() + int oldTotal = dbContext.TptPeople.Count(); + int customerRowsInserted = dbContext.BulkInsert(customers, o => o.UsePermanentTable = true); + int vendorRowsInserted = dbContext.BulkInsert(vendors); + int rowsInserted = customerRowsInserted + vendorRowsInserted; + int newTotal = dbContext.TptPeople.Count(); + + Assert.IsTrue(rowsInserted == customers.Count + vendors.Count, "The number of rows inserted must match the count of order list"); + Assert.IsTrue(newTotal - oldTotal == rowsInserted, "The new count minus the old count should match the number of rows inserted."); + } + [TestMethod] + public void Without_Identity_Column() + { + var dbContext = SetupDbContext(true); + var products = new List(); + for (int i = 50000; i < 60000; i++) { - var dbContext = SetupDbContext(false); - var orders = new List(); - for (int i = 0; i < 20000; i++) - { - orders.Add(new Order { Id = i, ExternalId = i.ToString(), Price = 1.57M, Active = true }); - } - int oldTotal = dbContext.Orders.Where(o => o.Price <= 10 && o.ExternalId == null).Count(); - int rowsInserted = dbContext.BulkInsert(orders, options => { options.UsePermanentTable = true; options.IgnoreColumns = o => new { o.ExternalId }; }); - int newTotal = dbContext.Orders.Where(o => o.Price <= 10 && o.ExternalId == null).Count(); + products.Add(new Product { Id = i.ToString(), Price = 1.57M }); + } + int oldTotal = dbContext.Products.Where(o => o.Price <= 10).Count(); + int rowsInserted = dbContext.BulkInsert(products); + int newTotal = dbContext.Products.Where(o => o.Price <= 10).Count(); - Assert.IsTrue(rowsInserted == orders.Count, "The number of rows inserted must match the count of order list"); - Assert.IsTrue(newTotal - oldTotal == rowsInserted, "The new count minus the old count should match the number of rows inserted."); + Assert.IsTrue(rowsInserted == products.Count, "The number of rows inserted must match the count of order list"); + Assert.IsTrue(newTotal - oldTotal == rowsInserted, "The new count minus the old count should match the number of rows inserted."); + } + [TestMethod] + public void With_Options_AutoMapIdentity() + { + var dbContext = SetupDbContext(false); + var orders = new List(); + for (int i = 0; i < 5000; i++) + { + orders.Add(new Order { ExternalId = i.ToString(), Price = ((decimal)i + 0.55M) }); } - [TestMethod] - public void With_Options_InputColumns() + int rowsAdded = dbContext.BulkInsert(orders, new BulkInsertOptions { - var dbContext = SetupDbContext(false); - var orders = new List(); - for (int i = 0; i < 20000; i++) + UsePermanentTable = true + }); + bool autoMapIdentityMatched = true; + var ordersInDb = dbContext.Orders.ToList(); + Order order1 = null; + Order order2 = null; + foreach (var order in orders) + { + order1 = order; + var orderinDb = ordersInDb.First(o => o.Id == order.Id); + order2 = orderinDb; + if (!(orderinDb.ExternalId == order.ExternalId && orderinDb.Price == order.Price)) { - orders.Add(new Order { Id = i, ExternalId = i.ToString(), Price = 1.57M, Active = true, Status = OrderStatus.Completed }); + autoMapIdentityMatched = false; + break; } - int oldTotal = dbContext.Orders.Where(o => o.Price == 1.57M && o.ExternalId == null && o.Active == true).Count(); - int rowsInserted = dbContext.BulkInsert(orders, options => - { - options.UsePermanentTable = true; - options.InputColumns = o => new { o.Price, o.Active, o.AddedDateTime, o.Status }; - }); - int newTotal = dbContext.Orders.Where(o => o.Price == 1.57M && o.ExternalId == null && o.Active == true).Count(); - - Assert.IsTrue(rowsInserted == orders.Count, "The number of rows inserted must match the count of order list"); - Assert.IsTrue(newTotal - oldTotal == rowsInserted, "The new count minus the old count should match the number of rows inserted."); } - [TestMethod] - public void With_KeepIdentity() + + Assert.IsTrue(rowsAdded == orders.Count, "The number of rows inserted must match the count of order list"); + Assert.IsTrue(autoMapIdentityMatched, "The auto mapping of ids of entities that were merged failed to match up"); + } + [TestMethod] + public void With_Options_IgnoreColumns() + { + var dbContext = SetupDbContext(false); + var orders = new List(); + for (int i = 0; i < 20000; i++) { - var dbContext = SetupDbContext(false); - var orders = new List(); - for (int i = 0; i < 20000; i++) - { - orders.Add(new Order { Id = i + 1000, Price = 1.57M }); - } - int oldTotal = dbContext.Orders.Count(); - int rowsInserted = dbContext.BulkInsert(orders, options => { options.KeepIdentity = true; options.BatchSize = 1000; }); - var oldOrders = dbContext.Orders.OrderBy(o => o.Id).ToList(); - var newOrders = dbContext.Orders.OrderBy(o => o.Id).ToList(); - bool allIdentityFieldsMatch = true; - for (int i = 0; i < 20000; i++) - { - if (newOrders[i].Id != oldOrders[i].Id) - { - allIdentityFieldsMatch = false; - break; - } - } - try - { - int rowsInserted2 = dbContext.BulkInsert(orders, new BulkInsertOptions() - { - KeepIdentity = true, - BatchSize = 1000, - }); - } - catch (Exception ex) - { - Assert.IsInstanceOfType(ex, typeof(SqlException)); - Assert.IsTrue(ex.Message.StartsWith("Violation of PRIMARY KEY constraint 'PK_Orders'.")); - } + orders.Add(new Order { Id = i, ExternalId = i.ToString(), Price = 1.57M, Active = true }); + } + int oldTotal = dbContext.Orders.Where(o => o.Price <= 10 && o.ExternalId == null).Count(); + int rowsInserted = dbContext.BulkInsert(orders, options => { options.UsePermanentTable = true; options.IgnoreColumns = o => new { o.ExternalId }; }); + int newTotal = dbContext.Orders.Where(o => o.Price <= 10 && o.ExternalId == null).Count(); - Assert.IsTrue(oldTotal == 0, "There should not be any records in the table"); - Assert.IsTrue(rowsInserted == orders.Count, "The number of rows inserted must match the count of order list"); - Assert.IsTrue(allIdentityFieldsMatch, "The identities between the source and the database should match."); + Assert.IsTrue(rowsInserted == orders.Count, "The number of rows inserted must match the count of order list"); + Assert.IsTrue(newTotal - oldTotal == rowsInserted, "The new count minus the old count should match the number of rows inserted."); + } + [TestMethod] + public void With_Options_InputColumns() + { + var dbContext = SetupDbContext(false); + var orders = new List(); + for (int i = 0; i < 20000; i++) + { + orders.Add(new Order { Id = i, ExternalId = i.ToString(), Price = 1.57M, Active = true, Status = OrderStatus.Completed }); } - [TestMethod] - public void With_Schema() + int oldTotal = dbContext.Orders.Where(o => o.Price == 1.57M && o.ExternalId == null && o.Active == true).Count(); + int rowsInserted = dbContext.BulkInsert(orders, options => { - var dbContext = SetupDbContext(false); - var products = new List(); - for (int i = 1; i < 10000; i++) - { - var key = i.ToString(); - products.Add(new ProductWithCustomSchema - { - Id = key, - Name = $"Product-{key}", - Price = 1.57M - }); - } - int oldTotal = dbContext.ProductsWithCustomSchema.Where(o => o.Price <= 10).Count(); - int rowsInserted = dbContext.BulkInsert(products); - int newTotal = dbContext.ProductsWithCustomSchema.Where(o => o.Price <= 10).Count(); + options.UsePermanentTable = true; + options.InputColumns = o => new { o.Price, o.Active, o.AddedDateTime, o.Status }; + }); + int newTotal = dbContext.Orders.Where(o => o.Price == 1.57M && o.ExternalId == null && o.Active == true).Count(); - Assert.IsTrue(rowsInserted == products.Count, "The number of rows inserted must match the count of order list"); - Assert.IsTrue(newTotal - oldTotal == rowsInserted, "The new count minus the old count should match the number of rows inserted."); + Assert.IsTrue(rowsInserted == orders.Count, "The number of rows inserted must match the count of order list"); + Assert.IsTrue(newTotal - oldTotal == rowsInserted, "The new count minus the old count should match the number of rows inserted."); + } + [TestMethod] + public void With_KeepIdentity() + { + var dbContext = SetupDbContext(false); + var orders = new List(); + for (int i = 0; i < 20000; i++) + { + orders.Add(new Order { Id = i + 1000, Price = 1.57M }); } - [TestMethod] - public void With_Transaction() + int oldTotal = dbContext.Orders.Count(); + int rowsInserted = dbContext.BulkInsert(orders, options => { options.KeepIdentity = true; options.BatchSize = 1000; }); + var oldOrders = dbContext.Orders.OrderBy(o => o.Id).ToList(); + var newOrders = dbContext.Orders.OrderBy(o => o.Id).ToList(); + bool allIdentityFieldsMatch = true; + for (int i = 0; i < 20000; i++) { - var dbContext = SetupDbContext(false); - var orders = new List(); - for (int i = 0; i < 20000; i++) - { - orders.Add(new Order { Id = i, Price = 1.57M }); - } - int oldTotal = dbContext.Orders.Where(o => o.Price <= 10).Count(); - int rowsInserted, newTotal; - using (var transaction = dbContext.Database.BeginTransaction()) + if (newOrders[i].Id != oldOrders[i].Id) { - rowsInserted = dbContext.BulkInsert(orders); - newTotal = dbContext.Orders.Where(o => o.Price <= 10).Count(); - transaction.Rollback(); + allIdentityFieldsMatch = false; + break; } - int rollbackTotal = dbContext.Orders.Where(o => o.Price <= 10).Count(); - - Assert.IsTrue(rowsInserted == orders.Count, "The number of rows inserted must match the count of order list"); - Assert.IsTrue(newTotal - oldTotal == rowsInserted, "The new count minus the old count should match the number of rows inserted."); - Assert.IsTrue(rollbackTotal == oldTotal, "The number of rows after the transacation has been rollbacked should match the original count"); } - [TestMethod] - public void With_Options_InsertIfNotExists() + try { - var dbContext = SetupDbContext(true); - var orders = new List(); - long maxId = dbContext.Orders.Max(o => o.Id); - long expectedRowsInserted = 1000; - int existingRowsToAdd = 100; - long startId = maxId - existingRowsToAdd + 1, endId = maxId + expectedRowsInserted + 1; - for (long i = startId; i < endId; i++) + int rowsInserted2 = dbContext.BulkInsert(orders, new BulkInsertOptions() { - orders.Add(new Order { Id = i, Price = 1.57M }); - } - - int oldTotal = dbContext.Orders.Where(o => o.Price <= 10).Count(); - int rowsInserted = dbContext.BulkInsert(orders, new BulkInsertOptions() { InsertIfNotExists = true }); - int newTotal = dbContext.Orders.Where(o => o.Price <= 10).Count(); - - Assert.IsTrue(rowsInserted == expectedRowsInserted, "The number of rows inserted must match the count of order list"); - Assert.IsTrue(newTotal - oldTotal == expectedRowsInserted, "The new count minus the old count should match the number of rows inserted."); + KeepIdentity = true, + BatchSize = 1000, + }); } - [TestMethod] - public void With_Proxy_Type() + catch (Exception ex) { - var dbContext = SetupDbContext(false); - int oldTotalCount = dbContext.Products.Where(o => o.Price == 10.57M).Count(); + Assert.IsInstanceOfType(ex, typeof(SqlException)); + Assert.IsTrue(ex.Message.StartsWith("Violation of PRIMARY KEY constraint 'PK_Orders'.")); + } - var products = new List(); - for (int i = 0; i < 2000; i++) + Assert.IsTrue(oldTotal == 0, "There should not be any records in the table"); + Assert.IsTrue(rowsInserted == orders.Count, "The number of rows inserted must match the count of order list"); + Assert.IsTrue(allIdentityFieldsMatch, "The identities between the source and the database should match."); + } + [TestMethod] + public void With_Schema() + { + var dbContext = SetupDbContext(false); + var products = new List(); + for (int i = 1; i < 10000; i++) + { + var key = i.ToString(); + products.Add(new ProductWithCustomSchema { - var product = dbContext.Products.CreateProxy(); - product.Id = (-i).ToString(); - product.Price = 10.57M; - products.Add(product); - } - int oldTotal = dbContext.Products.Where(o => o.Price == 10.57M).Count(); - int rowsInserted = dbContext.BulkInsert(products); - int newTotal = dbContext.Products.Where(o => o.Price == 10.57M).Count(); + Id = key, + Name = $"Product-{key}", + Price = 1.57M + }); + } + int oldTotal = dbContext.ProductsWithCustomSchema.Where(o => o.Price <= 10).Count(); + int rowsInserted = dbContext.BulkInsert(products); + int newTotal = dbContext.ProductsWithCustomSchema.Where(o => o.Price <= 10).Count(); - Assert.IsTrue(rowsInserted == products.Count, "The number of rows inserted must match the count of products list"); - Assert.IsTrue(newTotal - oldTotal == rowsInserted, "The new count minus the old count should match the number of rows inserted."); + Assert.IsTrue(rowsInserted == products.Count, "The number of rows inserted must match the count of order list"); + Assert.IsTrue(newTotal - oldTotal == rowsInserted, "The new count minus the old count should match the number of rows inserted."); + } + [TestMethod] + public void With_Transaction() + { + var dbContext = SetupDbContext(false); + var orders = new List(); + for (int i = 0; i < 20000; i++) + { + orders.Add(new Order { Id = i, Price = 1.57M }); } - [TestMethod] - public void With_ValueGenerated_Default() + int oldTotal = dbContext.Orders.Where(o => o.Price <= 10).Count(); + int rowsInserted, newTotal; + using (var transaction = dbContext.Database.BeginTransaction()) { - var dbContext = SetupDbContext(false); - var nowDateTime = DateTime.Now; - var orders = new List(); - for (int i = 0; i < 20000; i++) - { - orders.Add(new Order { Id = i, Price = 1.57M }); - } - int oldTotal = dbContext.Orders.Where(o => o.Price <= 10).Count(); - int rowsInserted = dbContext.BulkInsert(orders); - int newTotal = dbContext.Orders.Where(o => o.Price <= 10 && o.DbAddedDateTime > nowDateTime).Count(); + rowsInserted = dbContext.BulkInsert(orders); + newTotal = dbContext.Orders.Where(o => o.Price <= 10).Count(); + transaction.Rollback(); + } + int rollbackTotal = dbContext.Orders.Where(o => o.Price <= 10).Count(); + + Assert.IsTrue(rowsInserted == orders.Count, "The number of rows inserted must match the count of order list"); + Assert.IsTrue(newTotal - oldTotal == rowsInserted, "The new count minus the old count should match the number of rows inserted."); + Assert.IsTrue(rollbackTotal == oldTotal, "The number of rows after the transacation has been rollbacked should match the original count"); + } + [TestMethod] + public void With_Options_InsertIfNotExists() + { + var dbContext = SetupDbContext(true); + var orders = new List(); + long maxId = dbContext.Orders.Max(o => o.Id); + long expectedRowsInserted = 1000; + int existingRowsToAdd = 100; + long startId = maxId - existingRowsToAdd + 1, endId = maxId + expectedRowsInserted + 1; + for (long i = startId; i < endId; i++) + { + orders.Add(new Order { Id = i, Price = 1.57M }); + } + + int oldTotal = dbContext.Orders.Where(o => o.Price <= 10).Count(); + int rowsInserted = dbContext.BulkInsert(orders, new BulkInsertOptions() { InsertIfNotExists = true }); + int newTotal = dbContext.Orders.Where(o => o.Price <= 10).Count(); - Assert.IsTrue(rowsInserted == orders.Count, "The number of rows inserted must match the count of order list"); - Assert.IsTrue(newTotal - oldTotal == rowsInserted, "The new count minus the old count should match the number of rows inserted."); + Assert.IsTrue(rowsInserted == expectedRowsInserted, "The number of rows inserted must match the count of order list"); + Assert.IsTrue(newTotal - oldTotal == expectedRowsInserted, "The new count minus the old count should match the number of rows inserted."); + } + [TestMethod] + public void With_Proxy_Type() + { + var dbContext = SetupDbContext(false); + int oldTotalCount = dbContext.Products.Where(o => o.Price == 10.57M).Count(); + + var products = new List(); + for (int i = 0; i < 2000; i++) + { + var product = dbContext.Products.CreateProxy(); + product.Id = (-i).ToString(); + product.Price = 10.57M; + products.Add(product); } - [TestMethod] - public void With_ValueGenerated_Computed() + int oldTotal = dbContext.Products.Where(o => o.Price == 10.57M).Count(); + int rowsInserted = dbContext.BulkInsert(products); + int newTotal = dbContext.Products.Where(o => o.Price == 10.57M).Count(); + + Assert.IsTrue(rowsInserted == products.Count, "The number of rows inserted must match the count of products list"); + Assert.IsTrue(newTotal - oldTotal == rowsInserted, "The new count minus the old count should match the number of rows inserted."); + } + [TestMethod] + public void With_ValueGenerated_Default() + { + var dbContext = SetupDbContext(false); + var nowDateTime = DateTime.Now; + var orders = new List(); + for (int i = 0; i < 20000; i++) { - var dbContext = SetupDbContext(false); - var nowDateTime = DateTime.Now; - var orders = new List(); - for (int i = 0; i < 20000; i++) - { - orders.Add(new Order { Id = i, Price = 1.57M, DbModifiedDateTime = nowDateTime }); - } - int oldTotal = dbContext.Orders.Where(o => o.Price <= 10).Count(); - int rowsInserted = dbContext.BulkInsert(orders); - int newTotal = dbContext.Orders.Where(o => o.Price <= 10 && o.DbModifiedDateTime > nowDateTime).Count(); + orders.Add(new Order { Id = i, Price = 1.57M }); + } + int oldTotal = dbContext.Orders.Where(o => o.Price <= 10).Count(); + int rowsInserted = dbContext.BulkInsert(orders); + int newTotal = dbContext.Orders.Where(o => o.Price <= 10 && o.DbAddedDateTime > nowDateTime).Count(); - Assert.IsTrue(rowsInserted == orders.Count, "The number of rows inserted must match the count of order list"); - Assert.IsTrue(newTotal - oldTotal == rowsInserted, "The new count minus the old count should match the number of rows inserted."); + Assert.IsTrue(rowsInserted == orders.Count, "The number of rows inserted must match the count of order list"); + Assert.IsTrue(newTotal - oldTotal == rowsInserted, "The new count minus the old count should match the number of rows inserted."); + } + [TestMethod] + public void With_ValueGenerated_Computed() + { + var dbContext = SetupDbContext(false); + var nowDateTime = DateTime.Now; + var orders = new List(); + for (int i = 0; i < 20000; i++) + { + orders.Add(new Order { Id = i, Price = 1.57M, DbModifiedDateTime = nowDateTime }); } + int oldTotal = dbContext.Orders.Where(o => o.Price <= 10).Count(); + int rowsInserted = dbContext.BulkInsert(orders); + int newTotal = dbContext.Orders.Where(o => o.Price <= 10 && o.DbModifiedDateTime > nowDateTime).Count(); + + Assert.IsTrue(rowsInserted == orders.Count, "The number of rows inserted must match the count of order list"); + Assert.IsTrue(newTotal - oldTotal == rowsInserted, "The new count minus the old count should match the number of rows inserted."); } } \ No newline at end of file diff --git a/N.EntityFrameworkCore.Extensions.Test/DbContextExtensions/BulkInsertAsync.cs b/N.EntityFrameworkCore.Extensions.Test/DbContextExtensions/BulkInsertAsync.cs index 5da3955..a66d7ba 100644 --- a/N.EntityFrameworkCore.Extensions.Test/DbContextExtensions/BulkInsertAsync.cs +++ b/N.EntityFrameworkCore.Extensions.Test/DbContextExtensions/BulkInsertAsync.cs @@ -7,420 +7,419 @@ using Microsoft.VisualStudio.TestTools.UnitTesting; using N.EntityFrameworkCore.Extensions.Test.Data; -namespace N.EntityFrameworkCore.Extensions.Test.DbContextExtensions +namespace N.EntityFrameworkCore.Extensions.Test.DbContextExtensions; + +[TestClass] +public class BulkInsertAsync : DbContextExtensionsBase { - [TestClass] - public class BulkInsertAsync : DbContextExtensionsBase + [TestMethod] + public async Task With_Complex_Key() { - [TestMethod] - public async Task With_Complex_Key() + var dbContext = SetupDbContext(true); + var products = new List(); + for (int i = 50000; i < 60000; i++) { - var dbContext = SetupDbContext(true); - var products = new List(); - for (int i = 50000; i < 60000; i++) - { - var key = i.ToString(); - products.Add(new ProductWithComplexKey { Price = 1.57M }); - } - int oldTotal = dbContext.ProductsWithComplexKey.Where(o => o.Price <= 10).Count(); - int rowsInserted = await dbContext.BulkInsertAsync(products); - int newTotal = dbContext.ProductsWithComplexKey.Where(o => o.Price <= 10).Count(); - - Assert.IsTrue(rowsInserted == products.Count, "The number of rows inserted must match the count of order list"); - Assert.IsTrue(newTotal - oldTotal == rowsInserted, "The new count minus the old count should match the number of rows inserted."); + var key = i.ToString(); + products.Add(new ProductWithComplexKey { Price = 1.57M }); } - [TestMethod] - public async Task With_Default_Options() - { - var dbContext = SetupDbContext(false); - var orders = new List(); - for (int i = 0; i < 20000; i++) - { - orders.Add(new Order { Id = i, Price = 1.57M }); - } - int oldTotal = dbContext.Orders.Where(o => o.Price <= 10).Count(); - int rowsInserted = await dbContext.BulkInsertAsync(orders); - int newTotal = dbContext.Orders.Where(o => o.Price <= 10).Count(); + int oldTotal = dbContext.ProductsWithComplexKey.Where(o => o.Price <= 10).Count(); + int rowsInserted = await dbContext.BulkInsertAsync(products); + int newTotal = dbContext.ProductsWithComplexKey.Where(o => o.Price <= 10).Count(); - Assert.IsTrue(rowsInserted == orders.Count, "The number of rows inserted must match the count of order list"); - Assert.IsTrue(newTotal - oldTotal == rowsInserted, "The new count minus the old count should match the number of rows inserted."); + Assert.IsTrue(rowsInserted == products.Count, "The number of rows inserted must match the count of order list"); + Assert.IsTrue(newTotal - oldTotal == rowsInserted, "The new count minus the old count should match the number of rows inserted."); + } + [TestMethod] + public async Task With_Default_Options() + { + var dbContext = SetupDbContext(false); + var orders = new List(); + for (int i = 0; i < 20000; i++) + { + orders.Add(new Order { Id = i, Price = 1.57M }); } - //[TestMethod] - //public async Task With_IEnumerable() - //{ - // var dbContext = SetupDbContext(false); - // var orders = dbContext.Orders.Where(o => o.Price <= 10); + int oldTotal = dbContext.Orders.Where(o => o.Price <= 10).Count(); + int rowsInserted = await dbContext.BulkInsertAsync(orders); + int newTotal = dbContext.Orders.Where(o => o.Price <= 10).Count(); - // foreach(var order in orders) - // { - // order.Price = 15.75M; - // } - // int oldTotal = orders.Count(); - // int rowsInserted = await dbContext.BulkInsertAsync(orders); - // int newTotal = orders.Count(); + Assert.IsTrue(rowsInserted == orders.Count, "The number of rows inserted must match the count of order list"); + Assert.IsTrue(newTotal - oldTotal == rowsInserted, "The new count minus the old count should match the number of rows inserted."); + } + //[TestMethod] + //public async Task With_IEnumerable() + //{ + // var dbContext = SetupDbContext(false); + // var orders = dbContext.Orders.Where(o => o.Price <= 10); - // Assert.IsTrue(rowsInserted == oldTotal, "The number of rows inserted must match the count of order list"); - // Assert.IsTrue(newTotal - oldTotal == rowsInserted, "The new count minus the old count should match the number of rows inserted."); - //} - [TestMethod] - public async Task With_Inheritance_Tpc() - { - var dbContext = SetupDbContext(false); - var customers = new List(); - var vendors = new List(); - for (int i = 0; i < 20000; i++) - { - customers.Add(new TpcCustomer - { - Id = i, - FirstName = string.Format("John_{0}", i), - LastName = string.Format("Smith_{0}", i), - Email = string.Format("john.smith{0}@domain.com", i), - AddedDate = DateTime.UtcNow - }); - } - for (int i = 20000; i < 30000; i++) - { - vendors.Add(new TpcVendor - { - Id = i, - FirstName = string.Format("Mike_{0}", i), - LastName = string.Format("Smith_{0}", i), - Email = string.Format("mike.smith{0}@domain.com", i), - Url = string.Format("http://domain.com/mike.smith{0}", i) - }); - } - int oldTotal = dbContext.TpcPeople.Count(); - int customerRowsInserted = await dbContext.BulkInsertAsync(customers); - int vendorRowsInserted = await dbContext.BulkInsertAsync(vendors); - int rowsInserted = customerRowsInserted + vendorRowsInserted; - int newTotal = dbContext.TpcPeople.Count(); + // foreach(var order in orders) + // { + // order.Price = 15.75M; + // } + // int oldTotal = orders.Count(); + // int rowsInserted = await dbContext.BulkInsertAsync(orders); + // int newTotal = orders.Count(); - Assert.IsTrue(rowsInserted == customers.Count + vendors.Count, "The number of rows inserted must match the count of order list"); - Assert.IsTrue(newTotal - oldTotal == rowsInserted, "The new count minus the old count should match the number of rows inserted."); - } - [TestMethod] - public async Task With_Inheritance_Tph() + // Assert.IsTrue(rowsInserted == oldTotal, "The number of rows inserted must match the count of order list"); + // Assert.IsTrue(newTotal - oldTotal == rowsInserted, "The new count minus the old count should match the number of rows inserted."); + //} + [TestMethod] + public async Task With_Inheritance_Tpc() + { + var dbContext = SetupDbContext(false); + var customers = new List(); + var vendors = new List(); + for (int i = 0; i < 20000; i++) { - var dbContext = SetupDbContext(false); - var customers = new List(); - var vendors = new List(); - for (int i = 0; i < 20000; i++) - { - customers.Add(new TphCustomer - { - Id = i, - FirstName = string.Format("John_{0}", i), - LastName = string.Format("Smith_{0}", i), - Email = string.Format("john.smith{0}@domain.com", i), - Phone = "404-555-1111", - AddedDate = DateTime.UtcNow - }); - } - for (int i = 20000; i < 30000; i++) + customers.Add(new TpcCustomer { - vendors.Add(new TphVendor - { - Id = i, - FirstName = string.Format("Mike_{0}", i), - LastName = string.Format("Smith_{0}", i), - Phone = "404-555-2222", - Email = string.Format("mike.smith{0}@domain.com", i), - Url = string.Format("http://domain.com/mike.smith{0}", i) - }); - } - int oldTotal = dbContext.TphPeople.Count(); - int customerRowsInserted = await dbContext.BulkInsertAsync(customers); - int vendorRowsInserted = await dbContext.BulkInsertAsync(vendors); - int rowsInserted = customerRowsInserted + vendorRowsInserted; - int newTotal = dbContext.TphPeople.Count(); - - Assert.IsTrue(rowsInserted == customers.Count + vendors.Count, "The number of rows inserted must match the count of order list"); - Assert.IsTrue(newTotal - oldTotal == rowsInserted, "The new count minus the old count should match the number of rows inserted."); + Id = i, + FirstName = string.Format("John_{0}", i), + LastName = string.Format("Smith_{0}", i), + Email = string.Format("john.smith{0}@domain.com", i), + AddedDate = DateTime.UtcNow + }); } - [TestMethod] - public async Task With_Inheritance_Tpt() + for (int i = 20000; i < 30000; i++) { - var dbContext = SetupDbContext(false); - var customers = new List(); - var vendors = new List(); - for (int i = 0; i < 20000; i++) + vendors.Add(new TpcVendor { - customers.Add(new TptCustomer - { - Id = i, - FirstName = string.Format("John_{0}", i), - LastName = string.Format("Smith_{0}", i), - Email = string.Format("john.smith{0}@domain.com", i), - Phone = "777-555-1234", - AddedDate = DateTime.UtcNow - }); - } - for (int i = 20000; i < 30000; i++) - { - vendors.Add(new TptVendor - { - Id = i, - FirstName = string.Format("Mike_{0}", i), - LastName = string.Format("Smith_{0}", i), - Email = string.Format("mike.smith{0}@domain.com", i), - Url = string.Format("http://domain.com/mike.smith{0}", i) - }); - } - int oldTotal = dbContext.TptPeople.Count(); - int customerRowsInserted = await dbContext.BulkInsertAsync(customers, o => o.UsePermanentTable = true); - int vendorRowsInserted = await dbContext.BulkInsertAsync(vendors); - int rowsInserted = customerRowsInserted + vendorRowsInserted; - int newTotal = dbContext.TptPeople.Count(); - - Assert.IsTrue(rowsInserted == customers.Count + vendors.Count, "The number of rows inserted must match the count of order list"); - Assert.IsTrue(newTotal - oldTotal == rowsInserted, "The new count minus the old count should match the number of rows inserted."); + Id = i, + FirstName = string.Format("Mike_{0}", i), + LastName = string.Format("Smith_{0}", i), + Email = string.Format("mike.smith{0}@domain.com", i), + Url = string.Format("http://domain.com/mike.smith{0}", i) + }); } - [TestMethod] - public async Task Without_Identity_Column() + int oldTotal = dbContext.TpcPeople.Count(); + int customerRowsInserted = await dbContext.BulkInsertAsync(customers); + int vendorRowsInserted = await dbContext.BulkInsertAsync(vendors); + int rowsInserted = customerRowsInserted + vendorRowsInserted; + int newTotal = dbContext.TpcPeople.Count(); + + Assert.IsTrue(rowsInserted == customers.Count + vendors.Count, "The number of rows inserted must match the count of order list"); + Assert.IsTrue(newTotal - oldTotal == rowsInserted, "The new count minus the old count should match the number of rows inserted."); + } + [TestMethod] + public async Task With_Inheritance_Tph() + { + var dbContext = SetupDbContext(false); + var customers = new List(); + var vendors = new List(); + for (int i = 0; i < 20000; i++) { - var dbContext = SetupDbContext(true); - var products = new List(); - for (int i = 50000; i < 60000; i++) + customers.Add(new TphCustomer { - products.Add(new Product { Id = i.ToString(), Price = 1.57M }); - } - int oldTotal = dbContext.Products.Where(o => o.Price <= 10).Count(); - int rowsInserted = await dbContext.BulkInsertAsync(products); - int newTotal = dbContext.Products.Where(o => o.Price <= 10).Count(); - - Assert.IsTrue(rowsInserted == products.Count, "The number of rows inserted must match the count of order list"); - Assert.IsTrue(newTotal - oldTotal == rowsInserted, "The new count minus the old count should match the number of rows inserted."); + Id = i, + FirstName = string.Format("John_{0}", i), + LastName = string.Format("Smith_{0}", i), + Email = string.Format("john.smith{0}@domain.com", i), + Phone = "404-555-1111", + AddedDate = DateTime.UtcNow + }); } - [TestMethod] - public async Task With_Options_AutoMapIdentity() + for (int i = 20000; i < 30000; i++) { - - var dbContext = SetupDbContext(false); - var orders = new List(); - for (int i = 0; i < 5000; i++) - { - orders.Add(new Order { ExternalId = i.ToString(), Price = ((decimal)i + 0.55M) }); - } - int rowsAdded = await dbContext.BulkInsertAsync(orders, new BulkInsertOptions + vendors.Add(new TphVendor { - UsePermanentTable = true + Id = i, + FirstName = string.Format("Mike_{0}", i), + LastName = string.Format("Smith_{0}", i), + Phone = "404-555-2222", + Email = string.Format("mike.smith{0}@domain.com", i), + Url = string.Format("http://domain.com/mike.smith{0}", i) }); - bool autoMapIdentityMatched = true; - var ordersInDb = dbContext.Orders.ToList(); - Order order1 = null; - Order order2 = null; - foreach (var order in orders) - { - order1 = order; - var orderinDb = ordersInDb.First(o => o.Id == order.Id); - order2 = orderinDb; - if (!(orderinDb.ExternalId == order.ExternalId && orderinDb.Price == order.Price)) - { - autoMapIdentityMatched = false; - break; - } - } - - Assert.IsTrue(rowsAdded == orders.Count, "The number of rows inserted must match the count of order list"); - Assert.IsTrue(autoMapIdentityMatched, "The auto mapping of ids of entities that were merged failed to match up"); } - [TestMethod] - public async Task With_Options_IgnoreColumns() + int oldTotal = dbContext.TphPeople.Count(); + int customerRowsInserted = await dbContext.BulkInsertAsync(customers); + int vendorRowsInserted = await dbContext.BulkInsertAsync(vendors); + int rowsInserted = customerRowsInserted + vendorRowsInserted; + int newTotal = dbContext.TphPeople.Count(); + + Assert.IsTrue(rowsInserted == customers.Count + vendors.Count, "The number of rows inserted must match the count of order list"); + Assert.IsTrue(newTotal - oldTotal == rowsInserted, "The new count minus the old count should match the number of rows inserted."); + } + [TestMethod] + public async Task With_Inheritance_Tpt() + { + var dbContext = SetupDbContext(false); + var customers = new List(); + var vendors = new List(); + for (int i = 0; i < 20000; i++) { - var dbContext = SetupDbContext(false); - var orders = new List(); - for (int i = 0; i < 20000; i++) + customers.Add(new TptCustomer { - orders.Add(new Order { Id = i, ExternalId = i.ToString(), Price = 1.57M, Active = true }); - } - int oldTotal = dbContext.Orders.Where(o => o.Price <= 10 && o.ExternalId == null).Count(); - int rowsInserted = await dbContext.BulkInsertAsync(orders, options => { options.UsePermanentTable = true; options.IgnoreColumns = o => new { o.ExternalId }; }); - int newTotal = dbContext.Orders.Where(o => o.Price <= 10 && o.ExternalId == null).Count(); - - Assert.IsTrue(rowsInserted == orders.Count, "The number of rows inserted must match the count of order list"); - Assert.IsTrue(newTotal - oldTotal == rowsInserted, "The new count minus the old count should match the number of rows inserted."); + Id = i, + FirstName = string.Format("John_{0}", i), + LastName = string.Format("Smith_{0}", i), + Email = string.Format("john.smith{0}@domain.com", i), + Phone = "777-555-1234", + AddedDate = DateTime.UtcNow + }); } - [TestMethod] - public async Task With_Options_InputColumns() + for (int i = 20000; i < 30000; i++) { - var dbContext = SetupDbContext(false); - var orders = new List(); - for (int i = 0; i < 20000; i++) - { - orders.Add(new Order { Id = i, ExternalId = i.ToString(), Price = 1.57M, Active = true, Status = OrderStatus.Completed }); - } - int oldTotal = dbContext.Orders.Where(o => o.Price == 1.57M && o.ExternalId == null && o.Active == true).Count(); - int rowsInserted = await dbContext.BulkInsertAsync(orders, options => + vendors.Add(new TptVendor { - options.UsePermanentTable = true; - options.InputColumns = o => new { o.Price, o.Active, o.AddedDateTime, o.Status }; + Id = i, + FirstName = string.Format("Mike_{0}", i), + LastName = string.Format("Smith_{0}", i), + Email = string.Format("mike.smith{0}@domain.com", i), + Url = string.Format("http://domain.com/mike.smith{0}", i) }); - int newTotal = dbContext.Orders.Where(o => o.Price == 1.57M && o.ExternalId == null && o.Active == true).Count(); - - Assert.IsTrue(rowsInserted == orders.Count, "The number of rows inserted must match the count of order list"); - Assert.IsTrue(newTotal - oldTotal == rowsInserted, "The new count minus the old count should match the number of rows inserted."); } - [TestMethod] - public async Task With_KeepIdentity() + int oldTotal = dbContext.TptPeople.Count(); + int customerRowsInserted = await dbContext.BulkInsertAsync(customers, o => o.UsePermanentTable = true); + int vendorRowsInserted = await dbContext.BulkInsertAsync(vendors); + int rowsInserted = customerRowsInserted + vendorRowsInserted; + int newTotal = dbContext.TptPeople.Count(); + + Assert.IsTrue(rowsInserted == customers.Count + vendors.Count, "The number of rows inserted must match the count of order list"); + Assert.IsTrue(newTotal - oldTotal == rowsInserted, "The new count minus the old count should match the number of rows inserted."); + } + [TestMethod] + public async Task Without_Identity_Column() + { + var dbContext = SetupDbContext(true); + var products = new List(); + for (int i = 50000; i < 60000; i++) { - var dbContext = SetupDbContext(false); - var orders = new List(); - for (int i = 0; i < 20000; i++) - { - orders.Add(new Order { Id = i + 1000, Price = 1.57M }); - } - int oldTotal = dbContext.Orders.Count(); - int rowsInserted = await dbContext.BulkInsertAsync(orders, options => { options.KeepIdentity = true; options.BatchSize = 1000; }); - var oldOrders = dbContext.Orders.OrderBy(o => o.Id).ToList(); - var newOrders = dbContext.Orders.OrderBy(o => o.Id).ToList(); - bool allIdentityFieldsMatch = true; - for (int i = 0; i < 20000; i++) - { - if (newOrders[i].Id != oldOrders[i].Id) - { - allIdentityFieldsMatch = false; - break; - } - } - try - { - int rowsInserted2 = await dbContext.BulkInsertAsync(orders, new BulkInsertOptions() - { - KeepIdentity = true, - BatchSize = 1000, - }); - } - catch (Exception ex) - { - Assert.IsInstanceOfType(ex, typeof(SqlException)); - Assert.IsTrue(ex.Message.StartsWith("Violation of PRIMARY KEY constraint 'PK_Orders'.")); - } + products.Add(new Product { Id = i.ToString(), Price = 1.57M }); + } + int oldTotal = dbContext.Products.Where(o => o.Price <= 10).Count(); + int rowsInserted = await dbContext.BulkInsertAsync(products); + int newTotal = dbContext.Products.Where(o => o.Price <= 10).Count(); + + Assert.IsTrue(rowsInserted == products.Count, "The number of rows inserted must match the count of order list"); + Assert.IsTrue(newTotal - oldTotal == rowsInserted, "The new count minus the old count should match the number of rows inserted."); + } + [TestMethod] + public async Task With_Options_AutoMapIdentity() + { - Assert.IsTrue(oldTotal == 0, "There should not be any records in the table"); - Assert.IsTrue(rowsInserted == orders.Count, "The number of rows inserted must match the count of order list"); - Assert.IsTrue(allIdentityFieldsMatch, "The identities between the source and the database should match."); + var dbContext = SetupDbContext(false); + var orders = new List(); + for (int i = 0; i < 5000; i++) + { + orders.Add(new Order { ExternalId = i.ToString(), Price = ((decimal)i + 0.55M) }); } - [TestMethod] - public async Task With_Proxy_Type() + int rowsAdded = await dbContext.BulkInsertAsync(orders, new BulkInsertOptions { - var dbContext = SetupDbContext(false); - int oldTotalCount = dbContext.Products.Where(o => o.Price == 10.57M).Count(); - - var products = new List(); - for (int i = 0; i < 2000; i++) + UsePermanentTable = true + }); + bool autoMapIdentityMatched = true; + var ordersInDb = dbContext.Orders.ToList(); + Order order1 = null; + Order order2 = null; + foreach (var order in orders) + { + order1 = order; + var orderinDb = ordersInDb.First(o => o.Id == order.Id); + order2 = orderinDb; + if (!(orderinDb.ExternalId == order.ExternalId && orderinDb.Price == order.Price)) { - var product = dbContext.Products.CreateProxy(); - product.Id = (-i).ToString(); - product.Price = 10.57M; - products.Add(product); + autoMapIdentityMatched = false; + break; } - int oldTotal = dbContext.Products.Where(o => o.Price == 10.57M).Count(); - int rowsInserted = await dbContext.BulkInsertAsync(products); - int newTotal = dbContext.Products.Where(o => o.Price == 10.57M).Count(); + } - Assert.IsTrue(rowsInserted == products.Count, "The number of rows inserted must match the count of products list"); - Assert.IsTrue(newTotal - oldTotal == rowsInserted, "The new count minus the old count should match the number of rows inserted."); + Assert.IsTrue(rowsAdded == orders.Count, "The number of rows inserted must match the count of order list"); + Assert.IsTrue(autoMapIdentityMatched, "The auto mapping of ids of entities that were merged failed to match up"); + } + [TestMethod] + public async Task With_Options_IgnoreColumns() + { + var dbContext = SetupDbContext(false); + var orders = new List(); + for (int i = 0; i < 20000; i++) + { + orders.Add(new Order { Id = i, ExternalId = i.ToString(), Price = 1.57M, Active = true }); } - [TestMethod] - public async Task With_Schema() + int oldTotal = dbContext.Orders.Where(o => o.Price <= 10 && o.ExternalId == null).Count(); + int rowsInserted = await dbContext.BulkInsertAsync(orders, options => { options.UsePermanentTable = true; options.IgnoreColumns = o => new { o.ExternalId }; }); + int newTotal = dbContext.Orders.Where(o => o.Price <= 10 && o.ExternalId == null).Count(); + + Assert.IsTrue(rowsInserted == orders.Count, "The number of rows inserted must match the count of order list"); + Assert.IsTrue(newTotal - oldTotal == rowsInserted, "The new count minus the old count should match the number of rows inserted."); + } + [TestMethod] + public async Task With_Options_InputColumns() + { + var dbContext = SetupDbContext(false); + var orders = new List(); + for (int i = 0; i < 20000; i++) { - var dbContext = SetupDbContext(false); - var products = new List(); - for (int i = 1; i < 10000; i++) - { - var key = i.ToString(); - products.Add(new ProductWithCustomSchema - { - Id = key, - Name = $"Product-{key}", - Price = 1.57M - }); - } - int oldTotal = dbContext.ProductsWithCustomSchema.Where(o => o.Price <= 10).Count(); - int rowsInserted = await dbContext.BulkInsertAsync(products); - int newTotal = dbContext.ProductsWithCustomSchema.Where(o => o.Price <= 10).Count(); + orders.Add(new Order { Id = i, ExternalId = i.ToString(), Price = 1.57M, Active = true, Status = OrderStatus.Completed }); + } + int oldTotal = dbContext.Orders.Where(o => o.Price == 1.57M && o.ExternalId == null && o.Active == true).Count(); + int rowsInserted = await dbContext.BulkInsertAsync(orders, options => + { + options.UsePermanentTable = true; + options.InputColumns = o => new { o.Price, o.Active, o.AddedDateTime, o.Status }; + }); + int newTotal = dbContext.Orders.Where(o => o.Price == 1.57M && o.ExternalId == null && o.Active == true).Count(); - Assert.IsTrue(rowsInserted == products.Count, "The number of rows inserted must match the count of order list"); - Assert.IsTrue(newTotal - oldTotal == rowsInserted, "The new count minus the old count should match the number of rows inserted."); + Assert.IsTrue(rowsInserted == orders.Count, "The number of rows inserted must match the count of order list"); + Assert.IsTrue(newTotal - oldTotal == rowsInserted, "The new count minus the old count should match the number of rows inserted."); + } + [TestMethod] + public async Task With_KeepIdentity() + { + var dbContext = SetupDbContext(false); + var orders = new List(); + for (int i = 0; i < 20000; i++) + { + orders.Add(new Order { Id = i + 1000, Price = 1.57M }); } - [TestMethod] - public async Task With_Transaction() + int oldTotal = dbContext.Orders.Count(); + int rowsInserted = await dbContext.BulkInsertAsync(orders, options => { options.KeepIdentity = true; options.BatchSize = 1000; }); + var oldOrders = dbContext.Orders.OrderBy(o => o.Id).ToList(); + var newOrders = dbContext.Orders.OrderBy(o => o.Id).ToList(); + bool allIdentityFieldsMatch = true; + for (int i = 0; i < 20000; i++) { - var dbContext = SetupDbContext(false); - var orders = new List(); - for (int i = 0; i < 20000; i++) - { - orders.Add(new Order { Id = i, Price = 1.57M }); - } - int oldTotal = dbContext.Orders.Where(o => o.Price <= 10).Count(); - int rowsInserted, newTotal; - using (var transaction = dbContext.Database.BeginTransaction()) + if (newOrders[i].Id != oldOrders[i].Id) { - rowsInserted = await dbContext.BulkInsertAsync(orders); - newTotal = dbContext.Orders.Where(o => o.Price <= 10).Count(); - transaction.Rollback(); + allIdentityFieldsMatch = false; + break; } - int rollbackTotal = dbContext.Orders.Where(o => o.Price <= 10).Count(); - - Assert.IsTrue(rowsInserted == orders.Count, "The number of rows inserted must match the count of order list"); - Assert.IsTrue(newTotal - oldTotal == rowsInserted, "The new count minus the old count should match the number of rows inserted."); - Assert.IsTrue(rollbackTotal == oldTotal, "The number of rows after the transacation has been rollbacked should match the original count"); } - [TestMethod] - public async Task With_Options_InsertIfNotExists() + try { - var dbContext = SetupDbContext(true); - var orders = new List(); - long maxId = dbContext.Orders.Max(o => o.Id); - long expectedRowsInserted = 1000; - int existingRowsToAdd = 100; - long startId = maxId - existingRowsToAdd + 1, endId = maxId + expectedRowsInserted + 1; - for (long i = startId; i < endId; i++) + int rowsInserted2 = await dbContext.BulkInsertAsync(orders, new BulkInsertOptions() { - orders.Add(new Order { Id = i, Price = 1.57M }); - } + KeepIdentity = true, + BatchSize = 1000, + }); + } + catch (Exception ex) + { + Assert.IsInstanceOfType(ex, typeof(SqlException)); + Assert.IsTrue(ex.Message.StartsWith("Violation of PRIMARY KEY constraint 'PK_Orders'.")); + } - int oldTotal = dbContext.Orders.Where(o => o.Price <= 10).Count(); - int rowsInserted = await dbContext.BulkInsertAsync(orders, new BulkInsertOptions() { InsertIfNotExists = true }); - int newTotal = dbContext.Orders.Where(o => o.Price <= 10).Count(); + Assert.IsTrue(oldTotal == 0, "There should not be any records in the table"); + Assert.IsTrue(rowsInserted == orders.Count, "The number of rows inserted must match the count of order list"); + Assert.IsTrue(allIdentityFieldsMatch, "The identities between the source and the database should match."); + } + [TestMethod] + public async Task With_Proxy_Type() + { + var dbContext = SetupDbContext(false); + int oldTotalCount = dbContext.Products.Where(o => o.Price == 10.57M).Count(); - Assert.IsTrue(rowsInserted == expectedRowsInserted, "The number of rows inserted must match the count of order list"); - Assert.IsTrue(newTotal - oldTotal == expectedRowsInserted, "The new count minus the old count should match the number of rows inserted."); + var products = new List(); + for (int i = 0; i < 2000; i++) + { + var product = dbContext.Products.CreateProxy(); + product.Id = (-i).ToString(); + product.Price = 10.57M; + products.Add(product); } - [TestMethod] - public async Task With_ValueGenerated_Default() + int oldTotal = dbContext.Products.Where(o => o.Price == 10.57M).Count(); + int rowsInserted = await dbContext.BulkInsertAsync(products); + int newTotal = dbContext.Products.Where(o => o.Price == 10.57M).Count(); + + Assert.IsTrue(rowsInserted == products.Count, "The number of rows inserted must match the count of products list"); + Assert.IsTrue(newTotal - oldTotal == rowsInserted, "The new count minus the old count should match the number of rows inserted."); + } + [TestMethod] + public async Task With_Schema() + { + var dbContext = SetupDbContext(false); + var products = new List(); + for (int i = 1; i < 10000; i++) { - var dbContext = SetupDbContext(false); - var nowDateTime = DateTime.Now; - var orders = new List(); - for (int i = 0; i < 20000; i++) + var key = i.ToString(); + products.Add(new ProductWithCustomSchema { - orders.Add(new Order { Id = i, Price = 1.57M }); - } - int oldTotal = dbContext.Orders.Where(o => o.Price <= 10).Count(); - int rowsInserted = await dbContext.BulkInsertAsync(orders); - int newTotal = dbContext.Orders.Where(o => o.Price <= 10 && o.DbAddedDateTime > nowDateTime).Count(); + Id = key, + Name = $"Product-{key}", + Price = 1.57M + }); + } + int oldTotal = dbContext.ProductsWithCustomSchema.Where(o => o.Price <= 10).Count(); + int rowsInserted = await dbContext.BulkInsertAsync(products); + int newTotal = dbContext.ProductsWithCustomSchema.Where(o => o.Price <= 10).Count(); - Assert.IsTrue(rowsInserted == orders.Count, "The number of rows inserted must match the count of order list"); - Assert.IsTrue(newTotal - oldTotal == rowsInserted, "The new count minus the old count should match the number of rows inserted."); + Assert.IsTrue(rowsInserted == products.Count, "The number of rows inserted must match the count of order list"); + Assert.IsTrue(newTotal - oldTotal == rowsInserted, "The new count minus the old count should match the number of rows inserted."); + } + [TestMethod] + public async Task With_Transaction() + { + var dbContext = SetupDbContext(false); + var orders = new List(); + for (int i = 0; i < 20000; i++) + { + orders.Add(new Order { Id = i, Price = 1.57M }); } - [TestMethod] - public async Task With_ValueGenerated_Computed() + int oldTotal = dbContext.Orders.Where(o => o.Price <= 10).Count(); + int rowsInserted, newTotal; + using (var transaction = dbContext.Database.BeginTransaction()) { - var dbContext = SetupDbContext(false); - var nowDateTime = DateTime.Now; - var orders = new List(); - for (int i = 0; i < 20000; i++) - { - orders.Add(new Order { Id = i, Price = 1.57M, DbModifiedDateTime = nowDateTime }); - } - int oldTotal = dbContext.Orders.Where(o => o.Price <= 10).Count(); - int rowsInserted = await dbContext.BulkInsertAsync(orders); - int newTotal = dbContext.Orders.Where(o => o.Price <= 10 && o.DbModifiedDateTime > nowDateTime).Count(); + rowsInserted = await dbContext.BulkInsertAsync(orders); + newTotal = dbContext.Orders.Where(o => o.Price <= 10).Count(); + transaction.Rollback(); + } + int rollbackTotal = dbContext.Orders.Where(o => o.Price <= 10).Count(); - Assert.IsTrue(rowsInserted == orders.Count(), "The number of rows inserted must match the count of order list"); - Assert.IsTrue(newTotal - oldTotal == rowsInserted, "The new count minus the old count should match the number of rows inserted."); + Assert.IsTrue(rowsInserted == orders.Count, "The number of rows inserted must match the count of order list"); + Assert.IsTrue(newTotal - oldTotal == rowsInserted, "The new count minus the old count should match the number of rows inserted."); + Assert.IsTrue(rollbackTotal == oldTotal, "The number of rows after the transacation has been rollbacked should match the original count"); + } + [TestMethod] + public async Task With_Options_InsertIfNotExists() + { + var dbContext = SetupDbContext(true); + var orders = new List(); + long maxId = dbContext.Orders.Max(o => o.Id); + long expectedRowsInserted = 1000; + int existingRowsToAdd = 100; + long startId = maxId - existingRowsToAdd + 1, endId = maxId + expectedRowsInserted + 1; + for (long i = startId; i < endId; i++) + { + orders.Add(new Order { Id = i, Price = 1.57M }); + } + + int oldTotal = dbContext.Orders.Where(o => o.Price <= 10).Count(); + int rowsInserted = await dbContext.BulkInsertAsync(orders, new BulkInsertOptions() { InsertIfNotExists = true }); + int newTotal = dbContext.Orders.Where(o => o.Price <= 10).Count(); + + Assert.IsTrue(rowsInserted == expectedRowsInserted, "The number of rows inserted must match the count of order list"); + Assert.IsTrue(newTotal - oldTotal == expectedRowsInserted, "The new count minus the old count should match the number of rows inserted."); + } + [TestMethod] + public async Task With_ValueGenerated_Default() + { + var dbContext = SetupDbContext(false); + var nowDateTime = DateTime.Now; + var orders = new List(); + for (int i = 0; i < 20000; i++) + { + orders.Add(new Order { Id = i, Price = 1.57M }); } + int oldTotal = dbContext.Orders.Where(o => o.Price <= 10).Count(); + int rowsInserted = await dbContext.BulkInsertAsync(orders); + int newTotal = dbContext.Orders.Where(o => o.Price <= 10 && o.DbAddedDateTime > nowDateTime).Count(); + + Assert.IsTrue(rowsInserted == orders.Count, "The number of rows inserted must match the count of order list"); + Assert.IsTrue(newTotal - oldTotal == rowsInserted, "The new count minus the old count should match the number of rows inserted."); + } + [TestMethod] + public async Task With_ValueGenerated_Computed() + { + var dbContext = SetupDbContext(false); + var nowDateTime = DateTime.Now; + var orders = new List(); + for (int i = 0; i < 20000; i++) + { + orders.Add(new Order { Id = i, Price = 1.57M, DbModifiedDateTime = nowDateTime }); + } + int oldTotal = dbContext.Orders.Where(o => o.Price <= 10).Count(); + int rowsInserted = await dbContext.BulkInsertAsync(orders); + int newTotal = dbContext.Orders.Where(o => o.Price <= 10 && o.DbModifiedDateTime > nowDateTime).Count(); + + Assert.IsTrue(rowsInserted == orders.Count(), "The number of rows inserted must match the count of order list"); + Assert.IsTrue(newTotal - oldTotal == rowsInserted, "The new count minus the old count should match the number of rows inserted."); } } \ No newline at end of file diff --git a/N.EntityFrameworkCore.Extensions.Test/DbContextExtensions/BulkMerge.cs b/N.EntityFrameworkCore.Extensions.Test/DbContextExtensions/BulkMerge.cs index f1c75d9..c49a369 100644 --- a/N.EntityFrameworkCore.Extensions.Test/DbContextExtensions/BulkMerge.cs +++ b/N.EntityFrameworkCore.Extensions.Test/DbContextExtensions/BulkMerge.cs @@ -4,351 +4,350 @@ using Microsoft.VisualStudio.TestTools.UnitTesting; using N.EntityFrameworkCore.Extensions.Test.Data; -namespace N.EntityFrameworkCore.Extensions.Test.DbContextExtensions +namespace N.EntityFrameworkCore.Extensions.Test.DbContextExtensions; + +[TestClass] +public class BulkMerge : DbContextExtensionsBase { - [TestClass] - public class BulkMerge : DbContextExtensionsBase + [TestMethod] + public void With_Default_Options() { - [TestMethod] - public void With_Default_Options() + var dbContext = SetupDbContext(true); + var orders = dbContext.Orders.Where(o => o.Id <= 10000).OrderBy(o => o.Id).ToList(); + int ordersToAdd = 5000; + int ordersToUpdate = orders.Count; + foreach (var order in orders) { - var dbContext = SetupDbContext(true); - var orders = dbContext.Orders.Where(o => o.Id <= 10000).OrderBy(o => o.Id).ToList(); - int ordersToAdd = 5000; - int ordersToUpdate = orders.Count; - foreach (var order in orders) - { - order.Price = Convert.ToDecimal(order.Id + .25); - } - for (int i = 0; i < ordersToAdd; i++) - { - orders.Add(new Order { Id = 100000 + i, Price = 3.55M }); - } - var result = dbContext.BulkMerge(orders, o => o.UsePermanentTable = true); - var newOrders = dbContext.Orders.OrderBy(o => o.Id).ToList(); - bool areAddedOrdersMerged = true; - bool areUpdatedOrdersMerged = true; - foreach (var newOrder in newOrders.Where(o => o.Id <= 10000).OrderBy(o => o.Id)) - { - if (newOrder.Price != Convert.ToDecimal(newOrder.Id + .25)) - { - areUpdatedOrdersMerged = false; - break; - } - } - foreach (var newOrder in newOrders.Where(o => o.Id >= 500000).OrderBy(o => o.Id)) - { - if (newOrder.Price != 3.55M) - { - areAddedOrdersMerged = false; - break; - } - } - - Assert.IsTrue(result.RowsAffected == orders.Count(), "The number of rows inserted must match the count of order list"); - Assert.IsTrue(result.RowsUpdated == ordersToUpdate, "The number of rows updated must match"); - Assert.IsTrue(result.RowsInserted == ordersToAdd, "The number of rows added must match"); - Assert.IsTrue(areAddedOrdersMerged, "The orders that were added did not merge correctly"); - Assert.IsTrue(areUpdatedOrdersMerged, "The orders that were updated did not merge correctly"); + order.Price = Convert.ToDecimal(order.Id + .25); } - [TestMethod] - public void With_Inheritance_Tpc() + for (int i = 0; i < ordersToAdd; i++) { - var dbContext = SetupDbContext(true); - var customers = dbContext.TpcPeople.Where(o => o.Id <= 1000).OfType().ToList(); - int customersToAdd = 5000; - int customersToUpdate = customers.Count; - foreach (var customer in customers) - { - customer.FirstName = "BulkMerge_Tpc_Update"; - } - for (int i = 0; i < customersToAdd; i++) - { - customers.Add(new TpcCustomer - { - Id = 10000 + i, - FirstName = "BulkMerge_Tpc_Add", - AddedDate = DateTime.UtcNow - }); - } - var result = dbContext.BulkMerge(customers, options => { options.MergeOnCondition = (s, t) => s.Id == t.Id; }); - int customersAdded = dbContext.TpcPeople.Where(o => o.FirstName == "BulkMerge_Tpc_Add").OfType().Count(); - int customersUpdated = dbContext.TpcPeople.Where(o => o.FirstName == "BulkMerge_Tpc_Update").OfType().Count(); - - Assert.IsTrue(result.RowsAffected == customers.Count, "The number of rows inserted must match the count of customer list"); - Assert.IsTrue(result.RowsUpdated == customersToUpdate, "The number of rows updated must match"); - Assert.IsTrue(result.RowsInserted == customersToAdd, "The number of rows added must match"); - Assert.IsTrue(customersToAdd == customersAdded, "The custmoers that were added did not merge correctly"); - Assert.IsTrue(customersToUpdate == customersUpdated, "The customers that were updated did not merge correctly"); + orders.Add(new Order { Id = 100000 + i, Price = 3.55M }); } - [TestMethod] - public void With_Inheritance_Tph() + var result = dbContext.BulkMerge(orders, o => o.UsePermanentTable = true); + var newOrders = dbContext.Orders.OrderBy(o => o.Id).ToList(); + bool areAddedOrdersMerged = true; + bool areUpdatedOrdersMerged = true; + foreach (var newOrder in newOrders.Where(o => o.Id <= 10000).OrderBy(o => o.Id)) { - var dbContext = SetupDbContext(true); - var customers = dbContext.TphPeople.Where(o => o.Id <= 1000).OfType().ToList(); - int customersToAdd = 5000; - int customersToUpdate = customers.Count; - foreach (var customer in customers) + if (newOrder.Price != Convert.ToDecimal(newOrder.Id + .25)) { - customer.FirstName = "BulkMerge_Tph_Update"; + areUpdatedOrdersMerged = false; + break; } - for (int i = 0; i < customersToAdd; i++) - { - customers.Add(new TphCustomer - { - Id = 10000 + i, - FirstName = "BulkMerge_Tph_Add", - AddedDate = DateTime.UtcNow - }); - } - var result = dbContext.BulkMerge(customers); - int customersAdded = dbContext.TphPeople.Where(o => o.FirstName == "BulkMerge_Tph_Add").OfType().Count(); - int customersUpdated = dbContext.TphPeople.Where(o => o.FirstName == "BulkMerge_Tph_Update").OfType().Count(); - - Assert.IsTrue(result.RowsAffected == customers.Count(), "The number of rows inserted must match the count of customer list"); - Assert.IsTrue(result.RowsUpdated == customersToUpdate, "The number of rows updated must match"); - Assert.IsTrue(result.RowsInserted == customersToAdd, "The number of rows added must match"); - Assert.IsTrue(customersToAdd == customersAdded, "The custmoers that were added did not merge correctly"); - Assert.IsTrue(customersToUpdate == customersUpdated, "The customers that were updated did not merge correctly"); } - [TestMethod] - public void With_Inheritance_Tpt() + foreach (var newOrder in newOrders.Where(o => o.Id >= 500000).OrderBy(o => o.Id)) { - var dbContext = SetupDbContext(true, PopulateDataMode.Tpt); - var customers = dbContext.TptPeople.Where(o => o.Id <= 1000).OfType().ToList(); - int customersToAdd = 5000; - int customersToUpdate = customers.Count; - foreach (var customer in customers) + if (newOrder.Price != 3.55M) { - customer.FirstName = "BulkMerge_Tpt_Update"; + areAddedOrdersMerged = false; + break; } - for (int i = 0; i < customersToAdd; i++) - { - customers.Add(new TptCustomer - { - Id = 10000 + i, - FirstName = "BulkMerge_Tpt_Add", - AddedDate = DateTime.UtcNow - }); - } - var result = dbContext.BulkMerge(customers); - int customersAdded = dbContext.TptPeople.Where(o => o.FirstName == "BulkMerge_Tpt_Add").OfType().Count(); - int customersUpdated = dbContext.TptPeople.Where(o => o.FirstName == "BulkMerge_Tpt_Update").OfType().Count(); + } - Assert.IsTrue(result.RowsAffected == customers.Count(), "The number of rows inserted must match the count of customer list"); - Assert.IsTrue(result.RowsUpdated == customersToUpdate, "The number of rows updated must match"); - Assert.IsTrue(result.RowsInserted == customersToAdd, "The number of rows added must match"); - Assert.IsTrue(customersToAdd == customersAdded, "The custmoers that were added did not merge correctly"); - Assert.IsTrue(customersToUpdate == customersUpdated, "The customers that were updated did not merge correctly"); + Assert.IsTrue(result.RowsAffected == orders.Count(), "The number of rows inserted must match the count of order list"); + Assert.IsTrue(result.RowsUpdated == ordersToUpdate, "The number of rows updated must match"); + Assert.IsTrue(result.RowsInserted == ordersToAdd, "The number of rows added must match"); + Assert.IsTrue(areAddedOrdersMerged, "The orders that were added did not merge correctly"); + Assert.IsTrue(areUpdatedOrdersMerged, "The orders that were updated did not merge correctly"); + } + [TestMethod] + public void With_Inheritance_Tpc() + { + var dbContext = SetupDbContext(true); + var customers = dbContext.TpcPeople.Where(o => o.Id <= 1000).OfType().ToList(); + int customersToAdd = 5000; + int customersToUpdate = customers.Count; + foreach (var customer in customers) + { + customer.FirstName = "BulkMerge_Tpc_Update"; } - [TestMethod] - public void With_Default_Options_MergeOnCondition() + for (int i = 0; i < customersToAdd; i++) { - var dbContext = SetupDbContext(true); - var orders = dbContext.Orders.Where(o => o.Id <= 100 && o.ExternalId != null).OrderBy(o => o.Id).ToList(); - int ordersToAdd = 50; - int ordersToUpdate = orders.Count; - foreach (var order in orders) + customers.Add(new TpcCustomer { - order.Price = Convert.ToDecimal(order.Id + .25); - } - for (int i = 0; i < ordersToAdd; i++) - { - orders.Add(new Order { Id = 100000 + i, Price = 3.55M }); - } - var result = dbContext.BulkMerge(orders, options => { options.MergeOnCondition = (s, t) => s.ExternalId == t.ExternalId; options.BatchSize = 1000; }); - var newOrders = dbContext.Orders.OrderBy(o => o.Id).ToList(); - bool areAddedOrdersMerged = true; - bool areUpdatedOrdersMerged = true; - foreach (var newOrder in newOrders.Where(o => o.Id <= 100 && o.ExternalId != null).OrderBy(o => o.Id)) - { - if (newOrder.Price != Convert.ToDecimal(newOrder.Id + .25)) - { - areUpdatedOrdersMerged = false; - break; - } - } - foreach (var newOrder in newOrders.Where(o => o.Id >= 500000).OrderBy(o => o.Id)) - { - if (newOrder.Price != 3.55M) - { - areAddedOrdersMerged = false; - break; - } - } + Id = 10000 + i, + FirstName = "BulkMerge_Tpc_Add", + AddedDate = DateTime.UtcNow + }); + } + var result = dbContext.BulkMerge(customers, options => { options.MergeOnCondition = (s, t) => s.Id == t.Id; }); + int customersAdded = dbContext.TpcPeople.Where(o => o.FirstName == "BulkMerge_Tpc_Add").OfType().Count(); + int customersUpdated = dbContext.TpcPeople.Where(o => o.FirstName == "BulkMerge_Tpc_Update").OfType().Count(); - Assert.IsTrue(result.RowsAffected == orders.Count(), "The number of rows inserted must match the count of order list"); - Assert.IsTrue(result.RowsUpdated == ordersToUpdate, "The number of rows updated must match"); - Assert.IsTrue(result.RowsInserted == ordersToAdd, "The number of rows added must match"); - Assert.IsTrue(areAddedOrdersMerged, "The orders that were added did not merge correctly"); - Assert.IsTrue(areUpdatedOrdersMerged, "The orders that were updated did not merge correctly"); + Assert.IsTrue(result.RowsAffected == customers.Count, "The number of rows inserted must match the count of customer list"); + Assert.IsTrue(result.RowsUpdated == customersToUpdate, "The number of rows updated must match"); + Assert.IsTrue(result.RowsInserted == customersToAdd, "The number of rows added must match"); + Assert.IsTrue(customersToAdd == customersAdded, "The custmoers that were added did not merge correctly"); + Assert.IsTrue(customersToUpdate == customersUpdated, "The customers that were updated did not merge correctly"); + } + [TestMethod] + public void With_Inheritance_Tph() + { + var dbContext = SetupDbContext(true); + var customers = dbContext.TphPeople.Where(o => o.Id <= 1000).OfType().ToList(); + int customersToAdd = 5000; + int customersToUpdate = customers.Count; + foreach (var customer in customers) + { + customer.FirstName = "BulkMerge_Tph_Update"; } - [TestMethod] - public void With_Options_AutoMapIdentity() + for (int i = 0; i < customersToAdd; i++) { - var dbContext = SetupDbContext(true); - int ordersToUpdate = 3; - int ordersToAdd = 2; - var orders = new List + customers.Add(new TphCustomer { - new Order { ExternalId = "id-1", Price=7.10M }, - new Order { ExternalId = "id-2", Price=9.33M }, - new Order { ExternalId = "id-3", Price=3.25M }, - new Order { ExternalId = "id-1000001", Price=2.15M }, - new Order { ExternalId = "id-1000002", Price=5.75M }, - }; - var result = dbContext.BulkMerge(orders, new BulkMergeOptions - { - MergeOnCondition = (s, t) => s.ExternalId == t.ExternalId, - UsePermanentTable = true + Id = 10000 + i, + FirstName = "BulkMerge_Tph_Add", + AddedDate = DateTime.UtcNow }); - bool autoMapIdentityMatched = true; - foreach (var order in orders) - { - if (!dbContext.Orders.Any(o => o.ExternalId == order.ExternalId && o.Price == order.Price)) - { - autoMapIdentityMatched = false; - break; - } - } + } + var result = dbContext.BulkMerge(customers); + int customersAdded = dbContext.TphPeople.Where(o => o.FirstName == "BulkMerge_Tph_Add").OfType().Count(); + int customersUpdated = dbContext.TphPeople.Where(o => o.FirstName == "BulkMerge_Tph_Update").OfType().Count(); - Assert.IsTrue(result.RowsAffected == ordersToAdd + ordersToUpdate, "The number of rows inserted must match the count of order list"); - Assert.IsTrue(result.RowsUpdated == ordersToUpdate, "The number of rows updated must match"); - Assert.IsTrue(result.RowsInserted == ordersToAdd, "The number of rows added must match"); - Assert.IsTrue(autoMapIdentityMatched, "The auto mapping of ids of entities that were merged failed to match up"); + Assert.IsTrue(result.RowsAffected == customers.Count(), "The number of rows inserted must match the count of customer list"); + Assert.IsTrue(result.RowsUpdated == customersToUpdate, "The number of rows updated must match"); + Assert.IsTrue(result.RowsInserted == customersToAdd, "The number of rows added must match"); + Assert.IsTrue(customersToAdd == customersAdded, "The custmoers that were added did not merge correctly"); + Assert.IsTrue(customersToUpdate == customersUpdated, "The customers that were updated did not merge correctly"); + } + [TestMethod] + public void With_Inheritance_Tpt() + { + var dbContext = SetupDbContext(true, PopulateDataMode.Tpt); + var customers = dbContext.TptPeople.Where(o => o.Id <= 1000).OfType().ToList(); + int customersToAdd = 5000; + int customersToUpdate = customers.Count; + foreach (var customer in customers) + { + customer.FirstName = "BulkMerge_Tpt_Update"; } - [TestMethod] - public void With_merge_Should_include_all_auto_generated_properties() + for (int i = 0; i < customersToAdd; i++) { - var dbContext = SetupDbContext(true); - int ordersToUpdate = 3; - int ordersToAdd = 2; - var orders = new List - { - new Order { ExternalId = "id-1", Price=7.10M }, - new Order { ExternalId = "id-2", Price=9.33M }, - new Order { ExternalId = "id-3", Price=3.25M }, - new Order { ExternalId = "id-1000001", Price=2.15M }, - new Order { ExternalId = "id-1000002", Price=5.75M }, - }; - var result = dbContext.BulkMerge(orders, new BulkMergeOptions + customers.Add(new TptCustomer { - MergeOnCondition = (s, t) => s.ExternalId == t.ExternalId, - AutoMapOutput = true + Id = 10000 + i, + FirstName = "BulkMerge_Tpt_Add", + AddedDate = DateTime.UtcNow }); - var autoMapIdentityMatched = orders.All(x => x.Id != 0); + } + var result = dbContext.BulkMerge(customers); + int customersAdded = dbContext.TptPeople.Where(o => o.FirstName == "BulkMerge_Tpt_Add").OfType().Count(); + int customersUpdated = dbContext.TptPeople.Where(o => o.FirstName == "BulkMerge_Tpt_Update").OfType().Count(); - Assert.IsTrue(result.RowsAffected == ordersToAdd + ordersToUpdate, "The number of rows inserted must match the count of order list"); - Assert.IsTrue(result.RowsUpdated == ordersToUpdate, "The number of rows updated must match"); - Assert.IsTrue(result.RowsInserted == ordersToAdd, "The number of rows added must match"); - Assert.IsTrue(autoMapIdentityMatched, "The auto mapping of ids of entities that were merged failed to match up"); + Assert.IsTrue(result.RowsAffected == customers.Count(), "The number of rows inserted must match the count of customer list"); + Assert.IsTrue(result.RowsUpdated == customersToUpdate, "The number of rows updated must match"); + Assert.IsTrue(result.RowsInserted == customersToAdd, "The number of rows added must match"); + Assert.IsTrue(customersToAdd == customersAdded, "The custmoers that were added did not merge correctly"); + Assert.IsTrue(customersToUpdate == customersUpdated, "The customers that were updated did not merge correctly"); + } + [TestMethod] + public void With_Default_Options_MergeOnCondition() + { + var dbContext = SetupDbContext(true); + var orders = dbContext.Orders.Where(o => o.Id <= 100 && o.ExternalId != null).OrderBy(o => o.Id).ToList(); + int ordersToAdd = 50; + int ordersToUpdate = orders.Count; + foreach (var order in orders) + { + order.Price = Convert.ToDecimal(order.Id + .25); } - [TestMethod] - public void With_Key() + for (int i = 0; i < ordersToAdd; i++) { - var dbContext = SetupDbContext(true); - var products = dbContext.Products.Where(o => o.Price == 1.25M).OrderBy(o => o.Id).ToList(); - int productsToAdd = 5000; - var productsToUpdate = products.ToList(); - foreach (var product in products) - { - product.Price = Convert.ToDecimal(product.Id) + .25M; - } - for (int i = 0; i < productsToAdd; i++) + orders.Add(new Order { Id = 100000 + i, Price = 3.55M }); + } + var result = dbContext.BulkMerge(orders, options => { options.MergeOnCondition = (s, t) => s.ExternalId == t.ExternalId; options.BatchSize = 1000; }); + var newOrders = dbContext.Orders.OrderBy(o => o.Id).ToList(); + bool areAddedOrdersMerged = true; + bool areUpdatedOrdersMerged = true; + foreach (var newOrder in newOrders.Where(o => o.Id <= 100 && o.ExternalId != null).OrderBy(o => o.Id)) + { + if (newOrder.Price != Convert.ToDecimal(newOrder.Id + .25)) { - products.Add(new Product { Id = (20000 + i).ToString(), Price = 3.55M }); + areUpdatedOrdersMerged = false; + break; } - var result = dbContext.BulkMerge(products); - var newProducts = dbContext.Products.OrderBy(o => o.Id).ToList(); - bool areAddedOrdersMerged = true; - bool areUpdatedOrdersMerged = true; - foreach (var newProduct in newProducts.Where(o => productsToUpdate.Select(o => o.Id).Contains(o.Id))) + } + foreach (var newOrder in newOrders.Where(o => o.Id >= 500000).OrderBy(o => o.Id)) + { + if (newOrder.Price != 3.55M) { - if (newProduct.Price != Convert.ToDecimal(newProduct.Id) + .25M) - { - areUpdatedOrdersMerged = false; - break; - } + areAddedOrdersMerged = false; + break; } - foreach (var newProduct in newProducts.Where(o => Convert.ToInt32(o.Id) >= 20000).OrderBy(o => o.Id)) + } + + Assert.IsTrue(result.RowsAffected == orders.Count(), "The number of rows inserted must match the count of order list"); + Assert.IsTrue(result.RowsUpdated == ordersToUpdate, "The number of rows updated must match"); + Assert.IsTrue(result.RowsInserted == ordersToAdd, "The number of rows added must match"); + Assert.IsTrue(areAddedOrdersMerged, "The orders that were added did not merge correctly"); + Assert.IsTrue(areUpdatedOrdersMerged, "The orders that were updated did not merge correctly"); + } + [TestMethod] + public void With_Options_AutoMapIdentity() + { + var dbContext = SetupDbContext(true); + int ordersToUpdate = 3; + int ordersToAdd = 2; + var orders = new List + { + new Order { ExternalId = "id-1", Price=7.10M }, + new Order { ExternalId = "id-2", Price=9.33M }, + new Order { ExternalId = "id-3", Price=3.25M }, + new Order { ExternalId = "id-1000001", Price=2.15M }, + new Order { ExternalId = "id-1000002", Price=5.75M }, + }; + var result = dbContext.BulkMerge(orders, new BulkMergeOptions + { + MergeOnCondition = (s, t) => s.ExternalId == t.ExternalId, + UsePermanentTable = true + }); + bool autoMapIdentityMatched = true; + foreach (var order in orders) + { + if (!dbContext.Orders.Any(o => o.ExternalId == order.ExternalId && o.Price == order.Price)) { - if (newProduct.Price != 3.55M) - { - areAddedOrdersMerged = false; - break; - } + autoMapIdentityMatched = false; + break; } + } + + Assert.IsTrue(result.RowsAffected == ordersToAdd + ordersToUpdate, "The number of rows inserted must match the count of order list"); + Assert.IsTrue(result.RowsUpdated == ordersToUpdate, "The number of rows updated must match"); + Assert.IsTrue(result.RowsInserted == ordersToAdd, "The number of rows added must match"); + Assert.IsTrue(autoMapIdentityMatched, "The auto mapping of ids of entities that were merged failed to match up"); + } + [TestMethod] + public void With_merge_Should_include_all_auto_generated_properties() + { + var dbContext = SetupDbContext(true); + int ordersToUpdate = 3; + int ordersToAdd = 2; + var orders = new List + { + new Order { ExternalId = "id-1", Price=7.10M }, + new Order { ExternalId = "id-2", Price=9.33M }, + new Order { ExternalId = "id-3", Price=3.25M }, + new Order { ExternalId = "id-1000001", Price=2.15M }, + new Order { ExternalId = "id-1000002", Price=5.75M }, + }; + var result = dbContext.BulkMerge(orders, new BulkMergeOptions + { + MergeOnCondition = (s, t) => s.ExternalId == t.ExternalId, + AutoMapOutput = true + }); + var autoMapIdentityMatched = orders.All(x => x.Id != 0); - Assert.IsTrue(result.RowsAffected == products.Count(), "The number of rows inserted must match the count of order list"); - Assert.IsTrue(result.RowsUpdated == productsToUpdate.Count, "The number of rows updated must match"); - Assert.IsTrue(result.RowsInserted == productsToAdd, "The number of rows added must match"); - Assert.IsTrue(areAddedOrdersMerged, "The orders that were added did not merge correctly"); - Assert.IsTrue(areUpdatedOrdersMerged, "The orders that were updated did not merge correctly"); + Assert.IsTrue(result.RowsAffected == ordersToAdd + ordersToUpdate, "The number of rows inserted must match the count of order list"); + Assert.IsTrue(result.RowsUpdated == ordersToUpdate, "The number of rows updated must match"); + Assert.IsTrue(result.RowsInserted == ordersToAdd, "The number of rows added must match"); + Assert.IsTrue(autoMapIdentityMatched, "The auto mapping of ids of entities that were merged failed to match up"); + } + [TestMethod] + public void With_Key() + { + var dbContext = SetupDbContext(true); + var products = dbContext.Products.Where(o => o.Price == 1.25M).OrderBy(o => o.Id).ToList(); + int productsToAdd = 5000; + var productsToUpdate = products.ToList(); + foreach (var product in products) + { + product.Price = Convert.ToDecimal(product.Id) + .25M; } - [TestMethod] - public void With_Transaction() + for (int i = 0; i < productsToAdd; i++) { - var dbContext = SetupDbContext(true); - var orders = dbContext.Orders.Where(o => o.Id <= 10000).OrderBy(o => o.Id).ToList(); - int ordersToAdd = 5000; - int ordersToUpdate = orders.Count; - foreach (var order in orders) - { - order.Price = Convert.ToDecimal(order.Id + .25); - } - for (int i = 0; i < ordersToAdd; i++) - { - orders.Add(new Order { Id = 100000 + i, Price = 3.55M }); - } - BulkMergeResult result; - using (var transaction = dbContext.Database.BeginTransaction()) + products.Add(new Product { Id = (20000 + i).ToString(), Price = 3.55M }); + } + var result = dbContext.BulkMerge(products); + var newProducts = dbContext.Products.OrderBy(o => o.Id).ToList(); + bool areAddedOrdersMerged = true; + bool areUpdatedOrdersMerged = true; + foreach (var newProduct in newProducts.Where(o => productsToUpdate.Select(o => o.Id).Contains(o.Id))) + { + if (newProduct.Price != Convert.ToDecimal(newProduct.Id) + .25M) { - result = dbContext.BulkMerge(orders); - transaction.Rollback(); + areUpdatedOrdersMerged = false; + break; } - int ordersUpdated = dbContext.Orders.Count(o => o.Id <= 10000 && o.Price == ((decimal)o.Id + .25M) && o.Price != 1.25M); - int ordersAdded = dbContext.Orders.Count(o => o.Id >= 100000); - - Assert.IsTrue(result.RowsAffected == orders.Count(), "The number of rows inserted must match the count of order list"); - Assert.IsTrue(result.RowsUpdated == ordersToUpdate, "The number of rows updated must match"); - Assert.IsTrue(result.RowsInserted == ordersToAdd, "The number of rows added must match"); - Assert.IsTrue(ordersAdded == 0, "The number of rows added must equal 0 since transaction was rollbacked"); - Assert.IsTrue(ordersUpdated == 0, "The number of rows updated must equal 0 since transaction was rollbacked"); } - [TestMethod] - public void With_ValueGenerated_Default() + foreach (var newProduct in newProducts.Where(o => Convert.ToInt32(o.Id) >= 20000).OrderBy(o => o.Id)) { - var dbContext = SetupDbContext(false); - var nowDateTime = DateTime.Now; - var orders = new List(); - for (int i = 0; i < 1000; i++) + if (newProduct.Price != 3.55M) { - orders.Add(new Order { Id = i, Price = 1.57M }); + areAddedOrdersMerged = false; + break; } - int oldTotal = dbContext.Orders.Where(o => o.DbAddedDateTime > nowDateTime).Count(); - var mergeResult = dbContext.BulkMerge(orders); - int newTotal = dbContext.Orders.Where(o => o.Price <= 1.57M - && o.DbAddedDateTime > nowDateTime).Count(); + } - Assert.IsTrue(mergeResult.RowsInserted == orders.Count, "The number of rows inserted must match the count of order list"); - Assert.IsTrue(newTotal - oldTotal == mergeResult.RowsInserted, "The new count minus the old count should match the number of rows inserted."); + Assert.IsTrue(result.RowsAffected == products.Count(), "The number of rows inserted must match the count of order list"); + Assert.IsTrue(result.RowsUpdated == productsToUpdate.Count, "The number of rows updated must match"); + Assert.IsTrue(result.RowsInserted == productsToAdd, "The number of rows added must match"); + Assert.IsTrue(areAddedOrdersMerged, "The orders that were added did not merge correctly"); + Assert.IsTrue(areUpdatedOrdersMerged, "The orders that were updated did not merge correctly"); + } + [TestMethod] + public void With_Transaction() + { + var dbContext = SetupDbContext(true); + var orders = dbContext.Orders.Where(o => o.Id <= 10000).OrderBy(o => o.Id).ToList(); + int ordersToAdd = 5000; + int ordersToUpdate = orders.Count; + foreach (var order in orders) + { + order.Price = Convert.ToDecimal(order.Id + .25); } - [TestMethod] - public void With_ValueGenerated_Computed() + for (int i = 0; i < ordersToAdd; i++) { - var dbContext = SetupDbContext(false); - var nowDateTime = DateTime.Now; - var orders = new List(); - for (int i = 0; i < 20000; i++) - { - orders.Add(new Order { Id = i, Price = 1.57M, DbModifiedDateTime = nowDateTime }); - } - int oldTotal = dbContext.Orders.Where(o => o.Price <= 10).Count(); - var result = dbContext.BulkMerge(orders); - int newTotal = dbContext.Orders.Where(o => o.Price <= 10 && o.DbModifiedDateTime > nowDateTime).Count(); + orders.Add(new Order { Id = 100000 + i, Price = 3.55M }); + } + BulkMergeResult result; + using (var transaction = dbContext.Database.BeginTransaction()) + { + result = dbContext.BulkMerge(orders); + transaction.Rollback(); + } + int ordersUpdated = dbContext.Orders.Count(o => o.Id <= 10000 && o.Price == ((decimal)o.Id + .25M) && o.Price != 1.25M); + int ordersAdded = dbContext.Orders.Count(o => o.Id >= 100000); - Assert.IsTrue(result.RowsInserted == orders.Count(), "The number of rows inserted must match the count of order list"); - Assert.IsTrue(newTotal - oldTotal == result.RowsInserted, "The new count minus the old count should match the number of rows inserted."); + Assert.IsTrue(result.RowsAffected == orders.Count(), "The number of rows inserted must match the count of order list"); + Assert.IsTrue(result.RowsUpdated == ordersToUpdate, "The number of rows updated must match"); + Assert.IsTrue(result.RowsInserted == ordersToAdd, "The number of rows added must match"); + Assert.IsTrue(ordersAdded == 0, "The number of rows added must equal 0 since transaction was rollbacked"); + Assert.IsTrue(ordersUpdated == 0, "The number of rows updated must equal 0 since transaction was rollbacked"); + } + [TestMethod] + public void With_ValueGenerated_Default() + { + var dbContext = SetupDbContext(false); + var nowDateTime = DateTime.Now; + var orders = new List(); + for (int i = 0; i < 1000; i++) + { + orders.Add(new Order { Id = i, Price = 1.57M }); } + int oldTotal = dbContext.Orders.Where(o => o.DbAddedDateTime > nowDateTime).Count(); + var mergeResult = dbContext.BulkMerge(orders); + int newTotal = dbContext.Orders.Where(o => o.Price <= 1.57M + && o.DbAddedDateTime > nowDateTime).Count(); + + Assert.IsTrue(mergeResult.RowsInserted == orders.Count, "The number of rows inserted must match the count of order list"); + Assert.IsTrue(newTotal - oldTotal == mergeResult.RowsInserted, "The new count minus the old count should match the number of rows inserted."); + } + [TestMethod] + public void With_ValueGenerated_Computed() + { + var dbContext = SetupDbContext(false); + var nowDateTime = DateTime.Now; + var orders = new List(); + for (int i = 0; i < 20000; i++) + { + orders.Add(new Order { Id = i, Price = 1.57M, DbModifiedDateTime = nowDateTime }); + } + int oldTotal = dbContext.Orders.Where(o => o.Price <= 10).Count(); + var result = dbContext.BulkMerge(orders); + int newTotal = dbContext.Orders.Where(o => o.Price <= 10 && o.DbModifiedDateTime > nowDateTime).Count(); + + Assert.IsTrue(result.RowsInserted == orders.Count(), "The number of rows inserted must match the count of order list"); + Assert.IsTrue(newTotal - oldTotal == result.RowsInserted, "The new count minus the old count should match the number of rows inserted."); } } \ No newline at end of file diff --git a/N.EntityFrameworkCore.Extensions.Test/DbContextExtensions/BulkMergeAsync.cs b/N.EntityFrameworkCore.Extensions.Test/DbContextExtensions/BulkMergeAsync.cs index e7d9a42..74e3cda 100644 --- a/N.EntityFrameworkCore.Extensions.Test/DbContextExtensions/BulkMergeAsync.cs +++ b/N.EntityFrameworkCore.Extensions.Test/DbContextExtensions/BulkMergeAsync.cs @@ -5,368 +5,367 @@ using Microsoft.VisualStudio.TestTools.UnitTesting; using N.EntityFrameworkCore.Extensions.Test.Data; -namespace N.EntityFrameworkCore.Extensions.Test.DbContextExtensions +namespace N.EntityFrameworkCore.Extensions.Test.DbContextExtensions; + +[TestClass] +public class BulkMergeAsync : DbContextExtensionsBase { - [TestClass] - public class BulkMergeAsync : DbContextExtensionsBase + [TestMethod] + public async Task With_Default_Options() { - [TestMethod] - public async Task With_Default_Options() + var dbContext = SetupDbContext(true); + var orders = dbContext.Orders.Where(o => o.Id <= 10000).OrderBy(o => o.Id).ToList(); + int ordersToAdd = 5000; + int ordersToUpdate = orders.Count; + foreach (var order in orders) { - var dbContext = SetupDbContext(true); - var orders = dbContext.Orders.Where(o => o.Id <= 10000).OrderBy(o => o.Id).ToList(); - int ordersToAdd = 5000; - int ordersToUpdate = orders.Count; - foreach (var order in orders) - { - order.Price = Convert.ToDecimal(order.Id + .25); - } - for (int i = 0; i < ordersToAdd; i++) - { - orders.Add(new Order { Id = 100000 + i, Price = 3.55M }); - } - var result = await dbContext.BulkMergeAsync(orders); - var newOrders = dbContext.Orders.OrderBy(o => o.Id).ToList(); - bool areAddedOrdersMerged = true; - bool areUpdatedOrdersMerged = true; - foreach (var newOrder in newOrders.Where(o => o.Id <= 10000).OrderBy(o => o.Id)) - { - if (newOrder.Price != Convert.ToDecimal(newOrder.Id + .25)) - { - areUpdatedOrdersMerged = false; - break; - } - } - foreach (var newOrder in newOrders.Where(o => o.Id >= 500000).OrderBy(o => o.Id)) - { - if (newOrder.Price != 3.55M) - { - areAddedOrdersMerged = false; - break; - } - } - - Assert.IsTrue(result.RowsAffected == orders.Count(), "The number of rows inserted must match the count of order list"); - Assert.IsTrue(result.RowsUpdated == ordersToUpdate, "The number of rows updated must match"); - Assert.IsTrue(result.RowsInserted == ordersToAdd, "The number of rows added must match"); - Assert.IsTrue(areAddedOrdersMerged, "The orders that were added did not merge correctly"); - Assert.IsTrue(areUpdatedOrdersMerged, "The orders that were updated did not merge correctly"); + order.Price = Convert.ToDecimal(order.Id + .25); } - [TestMethod] - public async Task With_Inheritance_Tpc() + for (int i = 0; i < ordersToAdd; i++) { - var dbContext = SetupDbContext(true); - var customers = dbContext.TpcPeople.Where(o => o.Id <= 1000).OfType().ToList(); - int customersToAdd = 5000; - int customersToUpdate = customers.Count; - foreach (var customer in customers) - { - customer.FirstName = "BulkMerge_Tpc_Update"; - } - for (int i = 0; i < customersToAdd; i++) - { - customers.Add(new TpcCustomer - { - Id = 10000 + i, - FirstName = "BulkMerge_Tpc_Add", - AddedDate = DateTime.UtcNow - }); - } - var result = await dbContext.BulkMergeAsync(customers, options => { options.MergeOnCondition = (s, t) => s.Id == t.Id; }); - int customersAdded = dbContext.TpcPeople.Where(o => o.FirstName == "BulkMerge_Tpc_Add").OfType().Count(); - int customersUpdated = dbContext.TpcPeople.Where(o => o.FirstName == "BulkMerge_Tpc_Update").OfType().Count(); - - Assert.IsTrue(result.RowsAffected == customers.Count, "The number of rows inserted must match the count of customer list"); - Assert.IsTrue(result.RowsUpdated == customersToUpdate, "The number of rows updated must match"); - Assert.IsTrue(result.RowsInserted == customersToAdd, "The number of rows added must match"); - Assert.IsTrue(customersToAdd == customersAdded, "The custmoers that were added did not merge correctly"); - Assert.IsTrue(customersToUpdate == customersUpdated, "The customers that were updated did not merge correctly"); + orders.Add(new Order { Id = 100000 + i, Price = 3.55M }); } - [TestMethod] - public async Task With_Inheritance_Tph() + var result = await dbContext.BulkMergeAsync(orders); + var newOrders = dbContext.Orders.OrderBy(o => o.Id).ToList(); + bool areAddedOrdersMerged = true; + bool areUpdatedOrdersMerged = true; + foreach (var newOrder in newOrders.Where(o => o.Id <= 10000).OrderBy(o => o.Id)) { - var dbContext = SetupDbContext(true); - var customers = dbContext.TphPeople.Where(o => o.Id <= 1000).OfType().ToList(); - int customersToAdd = 5000; - int customersToUpdate = customers.Count; - foreach (var customer in customers) - { - customer.FirstName = "BulkMerge_Tph_Update"; - } - for (int i = 0; i < customersToAdd; i++) + if (newOrder.Price != Convert.ToDecimal(newOrder.Id + .25)) { - customers.Add(new TphCustomer - { - Id = 10000 + i, - FirstName = "BulkMerge_Tph_Add", - AddedDate = DateTime.UtcNow - }); + areUpdatedOrdersMerged = false; + break; } - var result = await dbContext.BulkMergeAsync(customers); - int customersAdded = dbContext.TphPeople.Where(o => o.FirstName == "BulkMerge_Tph_Add").OfType().Count(); - int customersUpdated = dbContext.TphPeople.Where(o => o.FirstName == "BulkMerge_Tph_Update").OfType().Count(); - - Assert.IsTrue(result.RowsAffected == customers.Count(), "The number of rows inserted must match the count of customer list"); - Assert.IsTrue(result.RowsUpdated == customersToUpdate, "The number of rows updated must match"); - Assert.IsTrue(result.RowsInserted == customersToAdd, "The number of rows added must match"); - Assert.IsTrue(customersToAdd == customersAdded, "The custmoers that were added did not merge correctly"); - Assert.IsTrue(customersToUpdate == customersUpdated, "The customers that were updated did not merge correctly"); } - [TestMethod] - public async Task With_Inheritance_Tpt() + foreach (var newOrder in newOrders.Where(o => o.Id >= 500000).OrderBy(o => o.Id)) { - var dbContext = SetupDbContext(true, PopulateDataMode.Tpt); - var customers = dbContext.TptPeople.Where(o => o.Id <= 1000).OfType().ToList(); - int customersToAdd = 5000; - int customersToUpdate = customers.Count; - foreach (var customer in customers) - { - customer.FirstName = "BulkMergeAsync_Tpt_Update"; - } - for (int i = 0; i < customersToAdd; i++) + if (newOrder.Price != 3.55M) { - customers.Add(new TptCustomer - { - Id = 10000 + i, - FirstName = "BulkMergeAsync_Tpt_Add", - AddedDate = DateTime.UtcNow - }); + areAddedOrdersMerged = false; + break; } - var result = await dbContext.BulkMergeAsync(customers); - int customersAdded = dbContext.TptPeople.Where(o => o.FirstName == "BulkMergeAsync_Tpt_Add").OfType().Count(); - int customersUpdated = dbContext.TptPeople.Where(o => o.FirstName == "BulkMergeAsync_Tpt_Update").OfType().Count(); + } - Assert.IsTrue(result.RowsAffected == customers.Count(), "The number of rows inserted must match the count of customer list"); - Assert.IsTrue(result.RowsUpdated == customersToUpdate, "The number of rows updated must match"); - Assert.IsTrue(result.RowsInserted == customersToAdd, "The number of rows added must match"); - Assert.IsTrue(customersToAdd == customersAdded, "The custmoers that were added did not merge correctly"); - Assert.IsTrue(customersToUpdate == customersUpdated, "The customers that were updated did not merge correctly"); + Assert.IsTrue(result.RowsAffected == orders.Count(), "The number of rows inserted must match the count of order list"); + Assert.IsTrue(result.RowsUpdated == ordersToUpdate, "The number of rows updated must match"); + Assert.IsTrue(result.RowsInserted == ordersToAdd, "The number of rows added must match"); + Assert.IsTrue(areAddedOrdersMerged, "The orders that were added did not merge correctly"); + Assert.IsTrue(areUpdatedOrdersMerged, "The orders that were updated did not merge correctly"); + } + [TestMethod] + public async Task With_Inheritance_Tpc() + { + var dbContext = SetupDbContext(true); + var customers = dbContext.TpcPeople.Where(o => o.Id <= 1000).OfType().ToList(); + int customersToAdd = 5000; + int customersToUpdate = customers.Count; + foreach (var customer in customers) + { + customer.FirstName = "BulkMerge_Tpc_Update"; } - [TestMethod] - public async Task With_Default_Options_MergeOnCondition() + for (int i = 0; i < customersToAdd; i++) { - var dbContext = SetupDbContext(true); - var orders = dbContext.Orders.Where(o => o.Id <= 100 && o.ExternalId != null).OrderBy(o => o.Id).ToList(); - int ordersToAdd = 50; - int ordersToUpdate = orders.Count; - foreach (var order in orders) - { - order.Price = Convert.ToDecimal(order.Id + .25); - } - for (int i = 0; i < ordersToAdd; i++) + customers.Add(new TpcCustomer { - orders.Add(new Order { Id = 100000 + i, Price = 3.55M }); - } - var result = await dbContext.BulkMergeAsync(orders, options => { options.MergeOnCondition = (s, t) => s.ExternalId == t.ExternalId; options.BatchSize = 1000; }); - var newOrders = dbContext.Orders.OrderBy(o => o.Id).ToList(); - bool areAddedOrdersMerged = true; - bool areUpdatedOrdersMerged = true; - foreach (var newOrder in newOrders.Where(o => o.Id <= 100 && o.ExternalId != null).OrderBy(o => o.Id)) - { - if (newOrder.Price != Convert.ToDecimal(newOrder.Id + .25)) - { - areUpdatedOrdersMerged = false; - break; - } - } - foreach (var newOrder in newOrders.Where(o => o.Id >= 500000).OrderBy(o => o.Id)) - { - if (newOrder.Price != 3.55M) - { - areAddedOrdersMerged = false; - break; - } - } + Id = 10000 + i, + FirstName = "BulkMerge_Tpc_Add", + AddedDate = DateTime.UtcNow + }); + } + var result = await dbContext.BulkMergeAsync(customers, options => { options.MergeOnCondition = (s, t) => s.Id == t.Id; }); + int customersAdded = dbContext.TpcPeople.Where(o => o.FirstName == "BulkMerge_Tpc_Add").OfType().Count(); + int customersUpdated = dbContext.TpcPeople.Where(o => o.FirstName == "BulkMerge_Tpc_Update").OfType().Count(); - Assert.IsTrue(result.RowsAffected == orders.Count(), "The number of rows inserted must match the count of order list"); - Assert.IsTrue(result.RowsUpdated == ordersToUpdate, "The number of rows updated must match"); - Assert.IsTrue(result.RowsInserted == ordersToAdd, "The number of rows added must match"); - Assert.IsTrue(areAddedOrdersMerged, "The orders that were added did not merge correctly"); - Assert.IsTrue(areUpdatedOrdersMerged, "The orders that were updated did not merge correctly"); + Assert.IsTrue(result.RowsAffected == customers.Count, "The number of rows inserted must match the count of customer list"); + Assert.IsTrue(result.RowsUpdated == customersToUpdate, "The number of rows updated must match"); + Assert.IsTrue(result.RowsInserted == customersToAdd, "The number of rows added must match"); + Assert.IsTrue(customersToAdd == customersAdded, "The custmoers that were added did not merge correctly"); + Assert.IsTrue(customersToUpdate == customersUpdated, "The customers that were updated did not merge correctly"); + } + [TestMethod] + public async Task With_Inheritance_Tph() + { + var dbContext = SetupDbContext(true); + var customers = dbContext.TphPeople.Where(o => o.Id <= 1000).OfType().ToList(); + int customersToAdd = 5000; + int customersToUpdate = customers.Count; + foreach (var customer in customers) + { + customer.FirstName = "BulkMerge_Tph_Update"; } - [TestMethod] - public async Task With_Options_AutoMapIdentity() + for (int i = 0; i < customersToAdd; i++) { - var dbContext = SetupDbContext(true); - int ordersToUpdate = 3; - int ordersToAdd = 2; - var orders = new List + customers.Add(new TphCustomer { - new Order { ExternalId = "id-1", Price=7.10M }, - new Order { ExternalId = "id-2", Price=9.33M }, - new Order { ExternalId = "id-3", Price=3.25M }, - new Order { ExternalId = "id-1000001", Price=2.15M }, - new Order { ExternalId = "id-1000002", Price=5.75M }, - }; - var result = await dbContext.BulkMergeAsync(orders, new BulkMergeOptions - { - MergeOnCondition = (s, t) => s.ExternalId == t.ExternalId, - UsePermanentTable = true + Id = 10000 + i, + FirstName = "BulkMerge_Tph_Add", + AddedDate = DateTime.UtcNow }); - bool autoMapIdentityMatched = true; - foreach (var order in orders) - { - if (!dbContext.Orders.Any(o => o.ExternalId == order.ExternalId && o.Price == order.Price)) - { - autoMapIdentityMatched = false; - break; - } - } + } + var result = await dbContext.BulkMergeAsync(customers); + int customersAdded = dbContext.TphPeople.Where(o => o.FirstName == "BulkMerge_Tph_Add").OfType().Count(); + int customersUpdated = dbContext.TphPeople.Where(o => o.FirstName == "BulkMerge_Tph_Update").OfType().Count(); - Assert.IsTrue(result.RowsAffected == ordersToAdd + ordersToUpdate, "The number of rows inserted must match the count of order list"); - Assert.IsTrue(result.RowsUpdated == ordersToUpdate, "The number of rows updated must match"); - Assert.IsTrue(result.RowsInserted == ordersToAdd, "The number of rows added must match"); - Assert.IsTrue(autoMapIdentityMatched, "The auto mapping of ids of entities that were merged failed to match up"); + Assert.IsTrue(result.RowsAffected == customers.Count(), "The number of rows inserted must match the count of customer list"); + Assert.IsTrue(result.RowsUpdated == customersToUpdate, "The number of rows updated must match"); + Assert.IsTrue(result.RowsInserted == customersToAdd, "The number of rows added must match"); + Assert.IsTrue(customersToAdd == customersAdded, "The custmoers that were added did not merge correctly"); + Assert.IsTrue(customersToUpdate == customersUpdated, "The customers that were updated did not merge correctly"); + } + [TestMethod] + public async Task With_Inheritance_Tpt() + { + var dbContext = SetupDbContext(true, PopulateDataMode.Tpt); + var customers = dbContext.TptPeople.Where(o => o.Id <= 1000).OfType().ToList(); + int customersToAdd = 5000; + int customersToUpdate = customers.Count; + foreach (var customer in customers) + { + customer.FirstName = "BulkMergeAsync_Tpt_Update"; } - [TestMethod] - public async Task With_merge_Should_include_all_auto_generated_properties() + for (int i = 0; i < customersToAdd; i++) { - var dbContext = SetupDbContext(true); - int ordersToUpdate = 3; - int ordersToAdd = 2; - var orders = new List - { - new Order { ExternalId = "id-1", Price=7.10M }, - new Order { ExternalId = "id-2", Price=9.33M }, - new Order { ExternalId = "id-3", Price=3.25M }, - new Order { ExternalId = "id-1000001", Price=2.15M }, - new Order { ExternalId = "id-1000002", Price=5.75M }, - }; - var result = await dbContext.BulkMergeAsync(orders, new BulkMergeOptions + customers.Add(new TptCustomer { - MergeOnCondition = (s, t) => s.ExternalId == t.ExternalId, - AutoMapOutput = true + Id = 10000 + i, + FirstName = "BulkMergeAsync_Tpt_Add", + AddedDate = DateTime.UtcNow }); - var autoMapIdentityMatched = orders.All(x => x.Id != 0); + } + var result = await dbContext.BulkMergeAsync(customers); + int customersAdded = dbContext.TptPeople.Where(o => o.FirstName == "BulkMergeAsync_Tpt_Add").OfType().Count(); + int customersUpdated = dbContext.TptPeople.Where(o => o.FirstName == "BulkMergeAsync_Tpt_Update").OfType().Count(); - Assert.IsTrue(result.RowsAffected == ordersToAdd + ordersToUpdate, "The number of rows inserted must match the count of order list"); - Assert.IsTrue(result.RowsUpdated == ordersToUpdate, "The number of rows updated must match"); - Assert.IsTrue(result.RowsInserted == ordersToAdd, "The number of rows added must match"); - Assert.IsTrue(autoMapIdentityMatched, "The auto mapping of ids of entities that were merged failed to match up"); + Assert.IsTrue(result.RowsAffected == customers.Count(), "The number of rows inserted must match the count of customer list"); + Assert.IsTrue(result.RowsUpdated == customersToUpdate, "The number of rows updated must match"); + Assert.IsTrue(result.RowsInserted == customersToAdd, "The number of rows added must match"); + Assert.IsTrue(customersToAdd == customersAdded, "The custmoers that were added did not merge correctly"); + Assert.IsTrue(customersToUpdate == customersUpdated, "The customers that were updated did not merge correctly"); + } + [TestMethod] + public async Task With_Default_Options_MergeOnCondition() + { + var dbContext = SetupDbContext(true); + var orders = dbContext.Orders.Where(o => o.Id <= 100 && o.ExternalId != null).OrderBy(o => o.Id).ToList(); + int ordersToAdd = 50; + int ordersToUpdate = orders.Count; + foreach (var order in orders) + { + order.Price = Convert.ToDecimal(order.Id + .25); } - [TestMethod] - public async Task With_Key() + for (int i = 0; i < ordersToAdd; i++) { - var dbContext = SetupDbContext(true); - var products = dbContext.Products.Where(o => o.Price == 1.25M).OrderBy(o => o.Id).ToList(); - int productsToAdd = 5000; - var productsToUpdate = products.ToList(); - foreach (var product in products) - { - product.Price = Convert.ToDecimal(product.Id) + .25M; - } - for (int i = 0; i < productsToAdd; i++) - { - products.Add(new Product { Id = (20000 + i).ToString(), Price = 3.55M }); - } - var result = await dbContext.BulkMergeAsync(products); - var newProducts = dbContext.Products.OrderBy(o => o.Id).ToList(); - bool areAddedOrdersMerged = true; - bool areUpdatedOrdersMerged = true; - foreach (var newProduct in newProducts.Where(o => productsToUpdate.Select(o => o.Id).Contains(o.Id))) - { - if (newProduct.Price != Convert.ToDecimal(newProduct.Id) + .25M) - { - areUpdatedOrdersMerged = false; - break; - } - } - foreach (var newProduct in newProducts.Where(o => Convert.ToInt32(o.Id) >= 20000).OrderBy(o => o.Id)) - { - if (newProduct.Price != 3.55M) - { - areAddedOrdersMerged = false; - break; - } - } - - Assert.IsTrue(result.RowsAffected == products.Count(), "The number of rows inserted must match the count of order list"); - Assert.IsTrue(result.RowsUpdated == productsToUpdate.Count, "The number of rows updated must match"); - Assert.IsTrue(result.RowsInserted == productsToAdd, "The number of rows added must match"); - Assert.IsTrue(areAddedOrdersMerged, "The orders that were added did not merge correctly"); - Assert.IsTrue(areUpdatedOrdersMerged, "The orders that were updated did not merge correctly"); + orders.Add(new Order { Id = 100000 + i, Price = 3.55M }); } - [TestMethod] - public async Task With_Transaction() + var result = await dbContext.BulkMergeAsync(orders, options => { options.MergeOnCondition = (s, t) => s.ExternalId == t.ExternalId; options.BatchSize = 1000; }); + var newOrders = dbContext.Orders.OrderBy(o => o.Id).ToList(); + bool areAddedOrdersMerged = true; + bool areUpdatedOrdersMerged = true; + foreach (var newOrder in newOrders.Where(o => o.Id <= 100 && o.ExternalId != null).OrderBy(o => o.Id)) { - var dbContext = SetupDbContext(true); - var orders = dbContext.Orders.Where(o => o.Id <= 10000).OrderBy(o => o.Id).ToList(); - int ordersToAdd = 5000; - int ordersToUpdate = orders.Count; - foreach (var order in orders) + if (newOrder.Price != Convert.ToDecimal(newOrder.Id + .25)) { - order.Price = Convert.ToDecimal(order.Id + .25); + areUpdatedOrdersMerged = false; + break; } - for (int i = 0; i < ordersToAdd; i++) + } + foreach (var newOrder in newOrders.Where(o => o.Id >= 500000).OrderBy(o => o.Id)) + { + if (newOrder.Price != 3.55M) { - orders.Add(new Order { Id = 100000 + i, Price = 3.55M }); + areAddedOrdersMerged = false; + break; } - BulkMergeResult result; - using (var transaction = dbContext.Database.BeginTransaction()) + } + + Assert.IsTrue(result.RowsAffected == orders.Count(), "The number of rows inserted must match the count of order list"); + Assert.IsTrue(result.RowsUpdated == ordersToUpdate, "The number of rows updated must match"); + Assert.IsTrue(result.RowsInserted == ordersToAdd, "The number of rows added must match"); + Assert.IsTrue(areAddedOrdersMerged, "The orders that were added did not merge correctly"); + Assert.IsTrue(areUpdatedOrdersMerged, "The orders that were updated did not merge correctly"); + } + [TestMethod] + public async Task With_Options_AutoMapIdentity() + { + var dbContext = SetupDbContext(true); + int ordersToUpdate = 3; + int ordersToAdd = 2; + var orders = new List + { + new Order { ExternalId = "id-1", Price=7.10M }, + new Order { ExternalId = "id-2", Price=9.33M }, + new Order { ExternalId = "id-3", Price=3.25M }, + new Order { ExternalId = "id-1000001", Price=2.15M }, + new Order { ExternalId = "id-1000002", Price=5.75M }, + }; + var result = await dbContext.BulkMergeAsync(orders, new BulkMergeOptions + { + MergeOnCondition = (s, t) => s.ExternalId == t.ExternalId, + UsePermanentTable = true + }); + bool autoMapIdentityMatched = true; + foreach (var order in orders) + { + if (!dbContext.Orders.Any(o => o.ExternalId == order.ExternalId && o.Price == order.Price)) { - result = await dbContext.BulkMergeAsync(orders); - transaction.Rollback(); + autoMapIdentityMatched = false; + break; } - int ordersUpdated = dbContext.Orders.Count(o => o.Id <= 10000 && o.Price == ((decimal)o.Id + .25M) && o.Price != 1.25M); - int ordersAdded = dbContext.Orders.Count(o => o.Id >= 100000); + } + + Assert.IsTrue(result.RowsAffected == ordersToAdd + ordersToUpdate, "The number of rows inserted must match the count of order list"); + Assert.IsTrue(result.RowsUpdated == ordersToUpdate, "The number of rows updated must match"); + Assert.IsTrue(result.RowsInserted == ordersToAdd, "The number of rows added must match"); + Assert.IsTrue(autoMapIdentityMatched, "The auto mapping of ids of entities that were merged failed to match up"); + } + [TestMethod] + public async Task With_merge_Should_include_all_auto_generated_properties() + { + var dbContext = SetupDbContext(true); + int ordersToUpdate = 3; + int ordersToAdd = 2; + var orders = new List + { + new Order { ExternalId = "id-1", Price=7.10M }, + new Order { ExternalId = "id-2", Price=9.33M }, + new Order { ExternalId = "id-3", Price=3.25M }, + new Order { ExternalId = "id-1000001", Price=2.15M }, + new Order { ExternalId = "id-1000002", Price=5.75M }, + }; + var result = await dbContext.BulkMergeAsync(orders, new BulkMergeOptions + { + MergeOnCondition = (s, t) => s.ExternalId == t.ExternalId, + AutoMapOutput = true + }); + var autoMapIdentityMatched = orders.All(x => x.Id != 0); - Assert.IsTrue(result.RowsAffected == orders.Count(), "The number of rows inserted must match the count of order list"); - Assert.IsTrue(result.RowsUpdated == ordersToUpdate, "The number of rows updated must match"); - Assert.IsTrue(result.RowsInserted == ordersToAdd, "The number of rows added must match"); - Assert.IsTrue(ordersAdded == 0, "The number of rows added must equal 0 since transaction was rollbacked"); - Assert.IsTrue(ordersUpdated == 0, "The number of rows updated must equal 0 since transaction was rollbacked"); + Assert.IsTrue(result.RowsAffected == ordersToAdd + ordersToUpdate, "The number of rows inserted must match the count of order list"); + Assert.IsTrue(result.RowsUpdated == ordersToUpdate, "The number of rows updated must match"); + Assert.IsTrue(result.RowsInserted == ordersToAdd, "The number of rows added must match"); + Assert.IsTrue(autoMapIdentityMatched, "The auto mapping of ids of entities that were merged failed to match up"); + } + [TestMethod] + public async Task With_Key() + { + var dbContext = SetupDbContext(true); + var products = dbContext.Products.Where(o => o.Price == 1.25M).OrderBy(o => o.Id).ToList(); + int productsToAdd = 5000; + var productsToUpdate = products.ToList(); + foreach (var product in products) + { + product.Price = Convert.ToDecimal(product.Id) + .25M; + } + for (int i = 0; i < productsToAdd; i++) + { + products.Add(new Product { Id = (20000 + i).ToString(), Price = 3.55M }); } - [TestMethod] - public async Task With_ValueGenerated_Default() + var result = await dbContext.BulkMergeAsync(products); + var newProducts = dbContext.Products.OrderBy(o => o.Id).ToList(); + bool areAddedOrdersMerged = true; + bool areUpdatedOrdersMerged = true; + foreach (var newProduct in newProducts.Where(o => productsToUpdate.Select(o => o.Id).Contains(o.Id))) { - var dbContext = SetupDbContext(false); - var nowDateTime = DateTime.Now; - var orders = new List(); - for (int i = 0; i < 1000; i++) + if (newProduct.Price != Convert.ToDecimal(newProduct.Id) + .25M) { - orders.Add(new Order { Id = i, Price = 1.57M }); + areUpdatedOrdersMerged = false; + break; } - int oldTotal = dbContext.Orders.Where(o => o.DbAddedDateTime > nowDateTime).Count(); - var mergeResult = await dbContext.BulkMergeAsync(orders); - int newTotal = dbContext.Orders.Where(o => o.Price <= 1.57M - && o.DbAddedDateTime > nowDateTime).Count(); - - Assert.IsTrue(mergeResult.RowsInserted == orders.Count, "The number of rows inserted must match the count of order list"); - Assert.IsTrue(newTotal - oldTotal == mergeResult.RowsInserted, "The new count minus the old count should match the number of rows inserted."); } - [TestMethod] - public async Task With_ValueGenerated_Computed() + foreach (var newProduct in newProducts.Where(o => Convert.ToInt32(o.Id) >= 20000).OrderBy(o => o.Id)) { - var dbContext = SetupDbContext(false); - var nowDateTime = DateTime.Now; - var orders = new List(); - for (int i = 0; i < 20000; i++) + if (newProduct.Price != 3.55M) { - orders.Add(new Order { Id = i, Price = 1.57M, DbModifiedDateTime = nowDateTime }); + areAddedOrdersMerged = false; + break; } - int oldTotal = dbContext.Orders.Where(o => o.Price <= 10).Count(); - var result = await dbContext.BulkMergeAsync(orders); - int newTotal = dbContext.Orders.Where(o => o.Price <= 10 && o.DbModifiedDateTime > nowDateTime).Count(); + } - Assert.IsTrue(result.RowsInserted == orders.Count(), "The number of rows inserted must match the count of order list"); - Assert.IsTrue(newTotal - oldTotal == result.RowsInserted, "The new count minus the old count should match the number of rows inserted."); + Assert.IsTrue(result.RowsAffected == products.Count(), "The number of rows inserted must match the count of order list"); + Assert.IsTrue(result.RowsUpdated == productsToUpdate.Count, "The number of rows updated must match"); + Assert.IsTrue(result.RowsInserted == productsToAdd, "The number of rows added must match"); + Assert.IsTrue(areAddedOrdersMerged, "The orders that were added did not merge correctly"); + Assert.IsTrue(areUpdatedOrdersMerged, "The orders that were updated did not merge correctly"); + } + [TestMethod] + public async Task With_Transaction() + { + var dbContext = SetupDbContext(true); + var orders = dbContext.Orders.Where(o => o.Id <= 10000).OrderBy(o => o.Id).ToList(); + int ordersToAdd = 5000; + int ordersToUpdate = orders.Count; + foreach (var order in orders) + { + order.Price = Convert.ToDecimal(order.Id + .25); } - [TestMethod] - public async Task With_Merge_On_Enum() + for (int i = 0; i < ordersToAdd; i++) { - var dbContext = SetupDbContext(true); - await dbContext.BulkSaveChangesAsync(); - var nowDateTime = DateTime.Now; - var orders = new List(); - for (int i = 0; i < 20; i++) - { - orders.Add(new Order { Id = i, Price = 1.57M, DbModifiedDateTime = nowDateTime, Status = OrderStatus.Completed }); - } + orders.Add(new Order { Id = 100000 + i, Price = 3.55M }); + } + BulkMergeResult result; + using (var transaction = dbContext.Database.BeginTransaction()) + { + result = await dbContext.BulkMergeAsync(orders); + transaction.Rollback(); + } + int ordersUpdated = dbContext.Orders.Count(o => o.Id <= 10000 && o.Price == ((decimal)o.Id + .25M) && o.Price != 1.25M); + int ordersAdded = dbContext.Orders.Count(o => o.Id >= 100000); - var result = await dbContext.BulkMergeAsync(orders, options => options.MergeOnCondition = (s, t) => s.Id == t.Id && s.Status == t.Status); + Assert.IsTrue(result.RowsAffected == orders.Count(), "The number of rows inserted must match the count of order list"); + Assert.IsTrue(result.RowsUpdated == ordersToUpdate, "The number of rows updated must match"); + Assert.IsTrue(result.RowsInserted == ordersToAdd, "The number of rows added must match"); + Assert.IsTrue(ordersAdded == 0, "The number of rows added must equal 0 since transaction was rollbacked"); + Assert.IsTrue(ordersUpdated == 0, "The number of rows updated must equal 0 since transaction was rollbacked"); + } + [TestMethod] + public async Task With_ValueGenerated_Default() + { + var dbContext = SetupDbContext(false); + var nowDateTime = DateTime.Now; + var orders = new List(); + for (int i = 0; i < 1000; i++) + { + orders.Add(new Order { Id = i, Price = 1.57M }); + } + int oldTotal = dbContext.Orders.Where(o => o.DbAddedDateTime > nowDateTime).Count(); + var mergeResult = await dbContext.BulkMergeAsync(orders); + int newTotal = dbContext.Orders.Where(o => o.Price <= 1.57M + && o.DbAddedDateTime > nowDateTime).Count(); + + Assert.IsTrue(mergeResult.RowsInserted == orders.Count, "The number of rows inserted must match the count of order list"); + Assert.IsTrue(newTotal - oldTotal == mergeResult.RowsInserted, "The new count minus the old count should match the number of rows inserted."); + } + [TestMethod] + public async Task With_ValueGenerated_Computed() + { + var dbContext = SetupDbContext(false); + var nowDateTime = DateTime.Now; + var orders = new List(); + for (int i = 0; i < 20000; i++) + { + orders.Add(new Order { Id = i, Price = 1.57M, DbModifiedDateTime = nowDateTime }); + } + int oldTotal = dbContext.Orders.Where(o => o.Price <= 10).Count(); + var result = await dbContext.BulkMergeAsync(orders); + int newTotal = dbContext.Orders.Where(o => o.Price <= 10 && o.DbModifiedDateTime > nowDateTime).Count(); - Assert.AreEqual(1, result.RowsInserted); - Assert.AreEqual(19, result.RowsUpdated); + Assert.IsTrue(result.RowsInserted == orders.Count(), "The number of rows inserted must match the count of order list"); + Assert.IsTrue(newTotal - oldTotal == result.RowsInserted, "The new count minus the old count should match the number of rows inserted."); + } + [TestMethod] + public async Task With_Merge_On_Enum() + { + var dbContext = SetupDbContext(true); + await dbContext.BulkSaveChangesAsync(); + var nowDateTime = DateTime.Now; + var orders = new List(); + for (int i = 0; i < 20; i++) + { + orders.Add(new Order { Id = i, Price = 1.57M, DbModifiedDateTime = nowDateTime, Status = OrderStatus.Completed }); } + + var result = await dbContext.BulkMergeAsync(orders, options => options.MergeOnCondition = (s, t) => s.Id == t.Id && s.Status == t.Status); + + Assert.AreEqual(1, result.RowsInserted); + Assert.AreEqual(19, result.RowsUpdated); } } \ No newline at end of file diff --git a/N.EntityFrameworkCore.Extensions.Test/DbContextExtensions/BulkSaveChanges.cs b/N.EntityFrameworkCore.Extensions.Test/DbContextExtensions/BulkSaveChanges.cs index 139c36a..c290166 100644 --- a/N.EntityFrameworkCore.Extensions.Test/DbContextExtensions/BulkSaveChanges.cs +++ b/N.EntityFrameworkCore.Extensions.Test/DbContextExtensions/BulkSaveChanges.cs @@ -7,258 +7,257 @@ using Microsoft.VisualStudio.TestTools.UnitTesting; using N.EntityFrameworkCore.Extensions.Test.Data; -namespace N.EntityFrameworkCore.Extensions.Test.DbContextExtensions +namespace N.EntityFrameworkCore.Extensions.Test.DbContextExtensions; + +[TestClass] +public class BulkSaveChanges : DbContextExtensionsBase { - [TestClass] - public class BulkSaveChanges : DbContextExtensionsBase + [TestMethod] + public void With_Default_Options() { - [TestMethod] - public void With_Default_Options() + var dbContext = SetupDbContext(true); + var totalCount = dbContext.Orders.Count(); + + //Add new orders + var ordersToAdd = new List(); + for (int i = 0; i < 2000; i++) { - var dbContext = SetupDbContext(true); - var totalCount = dbContext.Orders.Count(); + ordersToAdd.Add(new Order { Id = -i, Price = 10.57M }); + } + dbContext.Orders.AddRange(ordersToAdd); - //Add new orders - var ordersToAdd = new List(); - for (int i = 0; i < 2000; i++) - { - ordersToAdd.Add(new Order { Id = -i, Price = 10.57M }); - } - dbContext.Orders.AddRange(ordersToAdd); + //Delete orders + var ordersToDelete = dbContext.Orders.Where(o => o.Price <= 5).ToList(); + dbContext.Orders.RemoveRange(ordersToDelete); - //Delete orders - var ordersToDelete = dbContext.Orders.Where(o => o.Price <= 5).ToList(); - dbContext.Orders.RemoveRange(ordersToDelete); + //Update existing orders + var ordersToUpdate = dbContext.Orders.Where(o => o.Price > 5 && o.Price <= 10).ToList(); + foreach (var orderToUpdate in ordersToUpdate) + { + orderToUpdate.Price = 99M; + } - //Update existing orders - var ordersToUpdate = dbContext.Orders.Where(o => o.Price > 5 && o.Price <= 10).ToList(); - foreach (var orderToUpdate in ordersToUpdate) - { - orderToUpdate.Price = 99M; - } + int rowsAffected = dbContext.BulkSaveChanges(); + int ordersAddedCount = dbContext.Orders.Where(o => o.Price == 10.57M).Count(); + int ordersDeletedCount = dbContext.Orders.Where(o => o.Price <= 5).Count(); + int ordersUpdatedCount = dbContext.Orders.Where(o => o.Price == 99M).Count(); - int rowsAffected = dbContext.BulkSaveChanges(); - int ordersAddedCount = dbContext.Orders.Where(o => o.Price == 10.57M).Count(); - int ordersDeletedCount = dbContext.Orders.Where(o => o.Price <= 5).Count(); - int ordersUpdatedCount = dbContext.Orders.Where(o => o.Price == 99M).Count(); + Assert.IsTrue(rowsAffected == ordersToAdd.Count + ordersToDelete.Count + ordersToUpdate.Count, "The number of rows affected must equal the sum of entities added, deleted and updated"); + Assert.IsTrue(ordersAddedCount == ordersToAdd.Count(), "The number of orders to add did not match what was expected."); + Assert.IsTrue(ordersDeletedCount == 0, "The number of orders that was deleted did not match what was expected."); + Assert.IsTrue(ordersUpdatedCount == ordersToUpdate.Count(), "The number of orders that was updated did not match what was expected."); + } + [TestMethod] + public void With_Add_Changes() + { + var dbContext = SetupDbContext(true); + var oldTotalCount = dbContext.Orders.Where(o => o.Price == 10.57M).Count(); - Assert.IsTrue(rowsAffected == ordersToAdd.Count + ordersToDelete.Count + ordersToUpdate.Count, "The number of rows affected must equal the sum of entities added, deleted and updated"); - Assert.IsTrue(ordersAddedCount == ordersToAdd.Count(), "The number of orders to add did not match what was expected."); - Assert.IsTrue(ordersDeletedCount == 0, "The number of orders that was deleted did not match what was expected."); - Assert.IsTrue(ordersUpdatedCount == ordersToUpdate.Count(), "The number of orders that was updated did not match what was expected."); - } - [TestMethod] - public void With_Add_Changes() + var ordersToAdd = new List(); + for (int i = 0; i < 2000; i++) { - var dbContext = SetupDbContext(true); - var oldTotalCount = dbContext.Orders.Where(o => o.Price == 10.57M).Count(); + ordersToAdd.Add(new Order { Id = -i, Price = 10.57M }); + } + dbContext.Orders.AddRange(ordersToAdd); - var ordersToAdd = new List(); - for (int i = 0; i < 2000; i++) - { - ordersToAdd.Add(new Order { Id = -i, Price = 10.57M }); - } - dbContext.Orders.AddRange(ordersToAdd); + int rowsAffected = dbContext.BulkSaveChanges(); + int newTotalCount = dbContext.Orders.Where(o => o.Price == 10.57M).Count(); - int rowsAffected = dbContext.BulkSaveChanges(); - int newTotalCount = dbContext.Orders.Where(o => o.Price == 10.57M).Count(); + Assert.IsTrue(rowsAffected == ordersToAdd.Count, "The number of rows affected must equal the sum of entities added, deleted and updated"); + Assert.IsTrue(oldTotalCount + ordersToAdd.Count == newTotalCount, "The number of orders to add did not match what was expected."); + } + [TestMethod] + public void With_Delete_Changes() + { + var dbContext = SetupDbContext(true); + var oldTotalCount = dbContext.Orders.Where(o => o.Price <= 5).Count(); - Assert.IsTrue(rowsAffected == ordersToAdd.Count, "The number of rows affected must equal the sum of entities added, deleted and updated"); - Assert.IsTrue(oldTotalCount + ordersToAdd.Count == newTotalCount, "The number of orders to add did not match what was expected."); - } - [TestMethod] - public void With_Delete_Changes() - { - var dbContext = SetupDbContext(true); - var oldTotalCount = dbContext.Orders.Where(o => o.Price <= 5).Count(); + //Delete orders + var ordersToDelete = dbContext.Orders.Where(o => o.Price <= 5).ToList(); + dbContext.Orders.RemoveRange(ordersToDelete); - //Delete orders - var ordersToDelete = dbContext.Orders.Where(o => o.Price <= 5).ToList(); - dbContext.Orders.RemoveRange(ordersToDelete); + int rowsAffected = dbContext.BulkSaveChanges(); + int newTotalCount = dbContext.Orders.Where(o => o.Price <= 5).Count(); - int rowsAffected = dbContext.BulkSaveChanges(); - int newTotalCount = dbContext.Orders.Where(o => o.Price <= 5).Count(); + Assert.IsTrue(rowsAffected == ordersToDelete.Count, "The number of rows affected must equal the sum of entities added, deleted and updated"); + Assert.IsTrue(oldTotalCount - ordersToDelete.Count == newTotalCount, "The number of orders to add did not match what was expected."); + } + [TestMethod] + public void With_Update_Changes() + { + var dbContext = SetupDbContext(true); + var oldTotalCount = dbContext.Orders.Where(o => o.Price <= 10).Count(); - Assert.IsTrue(rowsAffected == ordersToDelete.Count, "The number of rows affected must equal the sum of entities added, deleted and updated"); - Assert.IsTrue(oldTotalCount - ordersToDelete.Count == newTotalCount, "The number of orders to add did not match what was expected."); - } - [TestMethod] - public void With_Update_Changes() + //Update existing orders + var ordersToUpdate = dbContext.Orders.Where(o => o.Price <= 10).ToList(); + foreach (var orderToUpdate in ordersToUpdate) { - var dbContext = SetupDbContext(true); - var oldTotalCount = dbContext.Orders.Where(o => o.Price <= 10).Count(); - - //Update existing orders - var ordersToUpdate = dbContext.Orders.Where(o => o.Price <= 10).ToList(); - foreach (var orderToUpdate in ordersToUpdate) - { - orderToUpdate.Price = 99M; - } + orderToUpdate.Price = 99M; + } - int rowsAffected = dbContext.BulkSaveChanges(); - int newTotalCount = dbContext.Orders.Where(o => o.Price <= 10).Count(); - int expectedCount = dbContext.Orders.Where(o => o.Price == 99M).Count(); + int rowsAffected = dbContext.BulkSaveChanges(); + int newTotalCount = dbContext.Orders.Where(o => o.Price <= 10).Count(); + int expectedCount = dbContext.Orders.Where(o => o.Price == 99M).Count(); - Assert.IsTrue(rowsAffected == ordersToUpdate.Count, "The number of rows affected must equal the sum of entities added, deleted and updated"); - Assert.IsTrue(oldTotalCount - ordersToUpdate.Count == newTotalCount, "The number of orders to add did not match what was expected."); - } - [TestMethod] - public void With_Inheritance_Tpc() + Assert.IsTrue(rowsAffected == ordersToUpdate.Count, "The number of rows affected must equal the sum of entities added, deleted and updated"); + Assert.IsTrue(oldTotalCount - ordersToUpdate.Count == newTotalCount, "The number of orders to add did not match what was expected."); + } + [TestMethod] + public void With_Inheritance_Tpc() + { + var dbContext = SetupDbContext(true, PopulateDataMode.Tpc); + //Delete Customers + var customersToDelete = dbContext.TpcPeople.OfType().Where(o => o.Id <= 1000); + int expectedRowsDeleted = customersToDelete.Count(); + dbContext.TpcPeople.RemoveRange(customersToDelete); + //Update Customers + var customersToUpdate = dbContext.TpcPeople.OfType().Where(o => o.Id > 1000 && o.Id <= 1500); + int expectedRowsUpdated = customersToUpdate.Count(); + foreach (var customerToUpdate in customersToUpdate) { - var dbContext = SetupDbContext(true, PopulateDataMode.Tpc); - //Delete Customers - var customersToDelete = dbContext.TpcPeople.OfType().Where(o => o.Id <= 1000); - int expectedRowsDeleted = customersToDelete.Count(); - dbContext.TpcPeople.RemoveRange(customersToDelete); - //Update Customers - var customersToUpdate = dbContext.TpcPeople.OfType().Where(o => o.Id > 1000 && o.Id <= 1500); - int expectedRowsUpdated = customersToUpdate.Count(); - foreach (var customerToUpdate in customersToUpdate) - { - customerToUpdate.FirstName = "CustomerUpdated"; - } - //Add New Customers - long maxId = dbContext.TpcPeople.OfType().Max(o => o.Id); - int expectedRowsAdded = 3000; - for (long i = maxId + 1; i <= maxId + expectedRowsAdded; i++) - { - dbContext.TpcPeople.Add(new TpcCustomer - { - Id = i, - FirstName = string.Format("John_{0}", i), - LastName = string.Format("Smith_{0}", i), - Email = string.Format("john.smith{0}@domain.com", i), - AddedDate = DateTime.UtcNow - }); - } - int rowsAffected = dbContext.BulkSaveChanges(); - int rowsAfterDelete = customersToDelete.Count(); - int rowsUpdated = customersToUpdate.Where(o => o.FirstName == "CustomerUpdated").Count(); - int rowsAdded = dbContext.TpcPeople.OfType().Where(o => o.Id > maxId).Count(); - int expectedRowsAffected = expectedRowsDeleted + expectedRowsUpdated + expectedRowsAdded; - - Assert.IsTrue(rowsAfterDelete == 0, "The number of rows deleted not not match what was expected."); - Assert.IsTrue(rowsUpdated == expectedRowsUpdated, "The number of rows updated not not match what was expected."); - Assert.IsTrue(rowsAdded == expectedRowsAdded, "The number of rows added not not match what was expected."); - Assert.IsTrue(rowsAffected == expectedRowsAffected, "The new count minus the old count should match the number of rows inserted."); + customerToUpdate.FirstName = "CustomerUpdated"; } - [TestMethod] - public void With_Inheritance_Tph() + //Add New Customers + long maxId = dbContext.TpcPeople.OfType().Max(o => o.Id); + int expectedRowsAdded = 3000; + for (long i = maxId + 1; i <= maxId + expectedRowsAdded; i++) { - var dbContext = SetupDbContext(true, PopulateDataMode.Tph); - //Delete Customers - var customersToDelete = dbContext.TphCustomers.Where(o => o.Id <= 1000); - int expectedRowsDeleted = customersToDelete.Count(); - dbContext.TphCustomers.RemoveRange(customersToDelete); - //Update Customers - var customersToUpdate = dbContext.TphCustomers.Where(o => o.Id > 1000 && o.Id <= 1500); - int expectedRowsUpdated = customersToUpdate.Count(); - foreach (var customerToUpdate in customersToUpdate) - { - customerToUpdate.FirstName = "CustomerUpdated"; - } - //Add New Customers - long maxId = dbContext.TphPeople.Max(o => o.Id); - int expectedRowsAdded = 3000; - for (long i = maxId + 1; i <= maxId + expectedRowsAdded; i++) + dbContext.TpcPeople.Add(new TpcCustomer { - dbContext.TphCustomers.Add(new TphCustomer - { - Id = i, - FirstName = string.Format("John_{0}", i), - LastName = string.Format("Smith_{0}", i), - Email = string.Format("john.smith{0}@domain.com", i), - AddedDate = DateTime.UtcNow - }); - } - int rowsAffected = dbContext.BulkSaveChanges(); - int rowsAfterDelete = customersToDelete.Count(); - int rowsUpdated = customersToUpdate.Where(o => o.FirstName == "CustomerUpdated").Count(); - int rowsAdded = dbContext.TphCustomers.Where(o => o.Id > maxId).Count(); - int expectedRowsAffected = expectedRowsDeleted + expectedRowsUpdated + expectedRowsAdded; + Id = i, + FirstName = string.Format("John_{0}", i), + LastName = string.Format("Smith_{0}", i), + Email = string.Format("john.smith{0}@domain.com", i), + AddedDate = DateTime.UtcNow + }); + } + int rowsAffected = dbContext.BulkSaveChanges(); + int rowsAfterDelete = customersToDelete.Count(); + int rowsUpdated = customersToUpdate.Where(o => o.FirstName == "CustomerUpdated").Count(); + int rowsAdded = dbContext.TpcPeople.OfType().Where(o => o.Id > maxId).Count(); + int expectedRowsAffected = expectedRowsDeleted + expectedRowsUpdated + expectedRowsAdded; - Assert.IsTrue(expectedRowsDeleted > 0, "The expected number of rows to delete must be greater than zero."); - Assert.IsTrue(rowsAfterDelete == 0, "The number of rows deleted not not match what was expected."); - Assert.IsTrue(rowsUpdated == expectedRowsUpdated, "The number of rows updated not not match what was expected."); - Assert.IsTrue(rowsAdded == expectedRowsAdded, "The number of rows added not not match what was expected."); - Assert.IsTrue(rowsAffected == expectedRowsAffected, "The new count minus the old count should match the number of rows inserted."); + Assert.IsTrue(rowsAfterDelete == 0, "The number of rows deleted not not match what was expected."); + Assert.IsTrue(rowsUpdated == expectedRowsUpdated, "The number of rows updated not not match what was expected."); + Assert.IsTrue(rowsAdded == expectedRowsAdded, "The number of rows added not not match what was expected."); + Assert.IsTrue(rowsAffected == expectedRowsAffected, "The new count minus the old count should match the number of rows inserted."); + } + [TestMethod] + public void With_Inheritance_Tph() + { + var dbContext = SetupDbContext(true, PopulateDataMode.Tph); + //Delete Customers + var customersToDelete = dbContext.TphCustomers.Where(o => o.Id <= 1000); + int expectedRowsDeleted = customersToDelete.Count(); + dbContext.TphCustomers.RemoveRange(customersToDelete); + //Update Customers + var customersToUpdate = dbContext.TphCustomers.Where(o => o.Id > 1000 && o.Id <= 1500); + int expectedRowsUpdated = customersToUpdate.Count(); + foreach (var customerToUpdate in customersToUpdate) + { + customerToUpdate.FirstName = "CustomerUpdated"; } - [TestMethod] - public void With_Inheritance_Tpt() + //Add New Customers + long maxId = dbContext.TphPeople.Max(o => o.Id); + int expectedRowsAdded = 3000; + for (long i = maxId + 1; i <= maxId + expectedRowsAdded; i++) { - var dbContext = SetupDbContext(true, PopulateDataMode.Tpt); - //Delete Customers - var customersToDelete = dbContext.TptCustomers.Where(o => o.Id <= 1000); - int expectedRowsDeleted = customersToDelete.Count(); - dbContext.TptCustomers.RemoveRange(customersToDelete); - //Update Customers - var customersToUpdate = dbContext.TptCustomers.Where(o => o.Id > 1000 && o.Id <= 1500); - int expectedRowsUpdated = customersToUpdate.Count(); - foreach (var customerToUpdate in customersToUpdate) + dbContext.TphCustomers.Add(new TphCustomer { - customerToUpdate.Email = "name@domain.com"; - customerToUpdate.FirstName = "CustomerUpdated"; - } - //Add New Customers - long maxId = dbContext.TptPeople.Max(o => o.Id); - int expectedRowsAdded = 3000; - for (long i = maxId + 1; i <= maxId + expectedRowsAdded; i++) - { - dbContext.TptCustomers.Add(new TptCustomer - { - Id = i, - FirstName = string.Format("John_{0}", i), - LastName = string.Format("Smith_{0}", i), - Email = string.Format("john.smith{0}@domain.com", i), - AddedDate = DateTime.UtcNow - }); - } - int rowsAffected = dbContext.BulkSaveChanges(); - int rowsAfterDelete = customersToDelete.Count(); - int rowsUpdated = customersToUpdate.Where(o => o.FirstName == "CustomerUpdated").Count(); - int rowsAdded = dbContext.TptCustomers.Where(o => o.Id > maxId).Count(); - int expectedRowsAffected = expectedRowsDeleted + expectedRowsUpdated + expectedRowsAdded; + Id = i, + FirstName = string.Format("John_{0}", i), + LastName = string.Format("Smith_{0}", i), + Email = string.Format("john.smith{0}@domain.com", i), + AddedDate = DateTime.UtcNow + }); + } + int rowsAffected = dbContext.BulkSaveChanges(); + int rowsAfterDelete = customersToDelete.Count(); + int rowsUpdated = customersToUpdate.Where(o => o.FirstName == "CustomerUpdated").Count(); + int rowsAdded = dbContext.TphCustomers.Where(o => o.Id > maxId).Count(); + int expectedRowsAffected = expectedRowsDeleted + expectedRowsUpdated + expectedRowsAdded; - Assert.IsTrue(rowsAfterDelete == 0, "The number of rows deleted not not match what was expected."); - Assert.IsTrue(rowsUpdated == expectedRowsUpdated, "The number of rows updated not not match what was expected."); - Assert.IsTrue(rowsAdded == expectedRowsAdded, "The number of rows added not not match what was expected."); - Assert.IsTrue(rowsAffected == expectedRowsAffected, "The new count minus the old count should match the number of rows inserted."); + Assert.IsTrue(expectedRowsDeleted > 0, "The expected number of rows to delete must be greater than zero."); + Assert.IsTrue(rowsAfterDelete == 0, "The number of rows deleted not not match what was expected."); + Assert.IsTrue(rowsUpdated == expectedRowsUpdated, "The number of rows updated not not match what was expected."); + Assert.IsTrue(rowsAdded == expectedRowsAdded, "The number of rows added not not match what was expected."); + Assert.IsTrue(rowsAffected == expectedRowsAffected, "The new count minus the old count should match the number of rows inserted."); + } + [TestMethod] + public void With_Inheritance_Tpt() + { + var dbContext = SetupDbContext(true, PopulateDataMode.Tpt); + //Delete Customers + var customersToDelete = dbContext.TptCustomers.Where(o => o.Id <= 1000); + int expectedRowsDeleted = customersToDelete.Count(); + dbContext.TptCustomers.RemoveRange(customersToDelete); + //Update Customers + var customersToUpdate = dbContext.TptCustomers.Where(o => o.Id > 1000 && o.Id <= 1500); + int expectedRowsUpdated = customersToUpdate.Count(); + foreach (var customerToUpdate in customersToUpdate) + { + customerToUpdate.Email = "name@domain.com"; + customerToUpdate.FirstName = "CustomerUpdated"; } - [TestMethod] - public void With_Schema() + //Add New Customers + long maxId = dbContext.TptPeople.Max(o => o.Id); + int expectedRowsAdded = 3000; + for (long i = maxId + 1; i <= maxId + expectedRowsAdded; i++) { - var dbContext = SetupDbContext(true, PopulateDataMode.Schema); - var totalCount = dbContext.ProductsWithCustomSchema.Count(); - - //Add new products - var productsToAdd = new List(); - for (int i = 0; i < 2000; i++) + dbContext.TptCustomers.Add(new TptCustomer { - productsToAdd.Add(new ProductWithCustomSchema { Id = (-i).ToString(), Price = 10.57M }); - } - dbContext.ProductsWithCustomSchema.AddRange(productsToAdd); + Id = i, + FirstName = string.Format("John_{0}", i), + LastName = string.Format("Smith_{0}", i), + Email = string.Format("john.smith{0}@domain.com", i), + AddedDate = DateTime.UtcNow + }); + } + int rowsAffected = dbContext.BulkSaveChanges(); + int rowsAfterDelete = customersToDelete.Count(); + int rowsUpdated = customersToUpdate.Where(o => o.FirstName == "CustomerUpdated").Count(); + int rowsAdded = dbContext.TptCustomers.Where(o => o.Id > maxId).Count(); + int expectedRowsAffected = expectedRowsDeleted + expectedRowsUpdated + expectedRowsAdded; - //Delete products - var productsToDelete = dbContext.ProductsWithCustomSchema.Where(o => o.Price <= 5).ToList(); - dbContext.ProductsWithCustomSchema.RemoveRange(productsToDelete); + Assert.IsTrue(rowsAfterDelete == 0, "The number of rows deleted not not match what was expected."); + Assert.IsTrue(rowsUpdated == expectedRowsUpdated, "The number of rows updated not not match what was expected."); + Assert.IsTrue(rowsAdded == expectedRowsAdded, "The number of rows added not not match what was expected."); + Assert.IsTrue(rowsAffected == expectedRowsAffected, "The new count minus the old count should match the number of rows inserted."); + } + [TestMethod] + public void With_Schema() + { + var dbContext = SetupDbContext(true, PopulateDataMode.Schema); + var totalCount = dbContext.ProductsWithCustomSchema.Count(); - //Update existing products - var productsToUpdate = dbContext.ProductsWithCustomSchema.Where(o => o.Price > 5 && o.Price <= 10).ToList(); - foreach (var productToUpdate in productsToUpdate) - { - productToUpdate.Price = 99M; - } + //Add new products + var productsToAdd = new List(); + for (int i = 0; i < 2000; i++) + { + productsToAdd.Add(new ProductWithCustomSchema { Id = (-i).ToString(), Price = 10.57M }); + } + dbContext.ProductsWithCustomSchema.AddRange(productsToAdd); - int rowsAffected = dbContext.BulkSaveChanges(); - int productsAddedCount = dbContext.ProductsWithCustomSchema.Where(o => o.Price == 10.57M).Count(); - int productsDeletedCount = dbContext.ProductsWithCustomSchema.Where(o => o.Price <= 5).Count(); - int productsUpdatedCount = dbContext.ProductsWithCustomSchema.Where(o => o.Price == 99M).Count(); + //Delete products + var productsToDelete = dbContext.ProductsWithCustomSchema.Where(o => o.Price <= 5).ToList(); + dbContext.ProductsWithCustomSchema.RemoveRange(productsToDelete); - Assert.IsTrue(rowsAffected == productsToAdd.Count + productsToDelete.Count + productsToUpdate.Count, "The number of rows affected must equal the sum of entities added, deleted and updated"); - Assert.IsTrue(productsAddedCount == productsToAdd.Count(), "The number of products to add did not match what was expected."); - Assert.IsTrue(productsDeletedCount == 0, "The number of products that was deleted did not match what was expected."); - Assert.IsTrue(productsUpdatedCount == productsToUpdate.Count(), "The number of products that was updated did not match what was expected."); + //Update existing products + var productsToUpdate = dbContext.ProductsWithCustomSchema.Where(o => o.Price > 5 && o.Price <= 10).ToList(); + foreach (var productToUpdate in productsToUpdate) + { + productToUpdate.Price = 99M; } + + int rowsAffected = dbContext.BulkSaveChanges(); + int productsAddedCount = dbContext.ProductsWithCustomSchema.Where(o => o.Price == 10.57M).Count(); + int productsDeletedCount = dbContext.ProductsWithCustomSchema.Where(o => o.Price <= 5).Count(); + int productsUpdatedCount = dbContext.ProductsWithCustomSchema.Where(o => o.Price == 99M).Count(); + + Assert.IsTrue(rowsAffected == productsToAdd.Count + productsToDelete.Count + productsToUpdate.Count, "The number of rows affected must equal the sum of entities added, deleted and updated"); + Assert.IsTrue(productsAddedCount == productsToAdd.Count(), "The number of products to add did not match what was expected."); + Assert.IsTrue(productsDeletedCount == 0, "The number of products that was deleted did not match what was expected."); + Assert.IsTrue(productsUpdatedCount == productsToUpdate.Count(), "The number of products that was updated did not match what was expected."); } } \ No newline at end of file diff --git a/N.EntityFrameworkCore.Extensions.Test/DbContextExtensions/BulkSaveChangesAsync.cs b/N.EntityFrameworkCore.Extensions.Test/DbContextExtensions/BulkSaveChangesAsync.cs index 9b31633..713deea 100644 --- a/N.EntityFrameworkCore.Extensions.Test/DbContextExtensions/BulkSaveChangesAsync.cs +++ b/N.EntityFrameworkCore.Extensions.Test/DbContextExtensions/BulkSaveChangesAsync.cs @@ -7,258 +7,257 @@ using Microsoft.VisualStudio.TestTools.UnitTesting; using N.EntityFrameworkCore.Extensions.Test.Data; -namespace N.EntityFrameworkCore.Extensions.Test.DbContextExtensions +namespace N.EntityFrameworkCore.Extensions.Test.DbContextExtensions; + +[TestClass] +public class BulkSaveChangesAsync : DbContextExtensionsBase { - [TestClass] - public class BulkSaveChangesAsync : DbContextExtensionsBase + [TestMethod] + public async Task With_All_Changes() { - [TestMethod] - public async Task With_All_Changes() + var dbContext = SetupDbContext(true); + var totalCount = dbContext.Orders.Count(); + + //Add new orders + var ordersToAdd = new List(); + for (int i = 0; i < 2000; i++) { - var dbContext = SetupDbContext(true); - var totalCount = dbContext.Orders.Count(); + ordersToAdd.Add(new Order { Id = -i, Price = 10.57M }); + } + dbContext.Orders.AddRange(ordersToAdd); - //Add new orders - var ordersToAdd = new List(); - for (int i = 0; i < 2000; i++) - { - ordersToAdd.Add(new Order { Id = -i, Price = 10.57M }); - } - dbContext.Orders.AddRange(ordersToAdd); + //Delete orders + var ordersToDelete = dbContext.Orders.Where(o => o.Price <= 5).ToList(); + dbContext.Orders.RemoveRange(ordersToDelete); - //Delete orders - var ordersToDelete = dbContext.Orders.Where(o => o.Price <= 5).ToList(); - dbContext.Orders.RemoveRange(ordersToDelete); + //Update existing orders + var ordersToUpdate = dbContext.Orders.Where(o => o.Price > 5 && o.Price <= 10).ToList(); + foreach (var orderToUpdate in ordersToUpdate) + { + orderToUpdate.Price = 99M; + } - //Update existing orders - var ordersToUpdate = dbContext.Orders.Where(o => o.Price > 5 && o.Price <= 10).ToList(); - foreach (var orderToUpdate in ordersToUpdate) - { - orderToUpdate.Price = 99M; - } + int rowsAffected = await dbContext.BulkSaveChangesAsync(); + int ordersAddedCount = dbContext.Orders.Where(o => o.Price == 10.57M).Count(); + int ordersDeletedCount = dbContext.Orders.Where(o => o.Price <= 5).Count(); + int ordersUpdatedCount = dbContext.Orders.Where(o => o.Price == 99M).Count(); - int rowsAffected = await dbContext.BulkSaveChangesAsync(); - int ordersAddedCount = dbContext.Orders.Where(o => o.Price == 10.57M).Count(); - int ordersDeletedCount = dbContext.Orders.Where(o => o.Price <= 5).Count(); - int ordersUpdatedCount = dbContext.Orders.Where(o => o.Price == 99M).Count(); + Assert.IsTrue(rowsAffected == ordersToAdd.Count + ordersToDelete.Count + ordersToUpdate.Count, "The number of rows affected must equal the sum of entities added, deleted and updated"); + Assert.IsTrue(ordersAddedCount == ordersToAdd.Count(), "The number of orders to add did not match what was expected."); + Assert.IsTrue(ordersDeletedCount == 0, "The number of orders that was deleted did not match what was expected."); + Assert.IsTrue(ordersUpdatedCount == ordersToUpdate.Count(), "The number of orders that was updated did not match what was expected."); + } + [TestMethod] + public async Task With_Add_Changes() + { + var dbContext = SetupDbContext(true); + var oldTotalCount = dbContext.Orders.Where(o => o.Price == 10.57M).Count(); - Assert.IsTrue(rowsAffected == ordersToAdd.Count + ordersToDelete.Count + ordersToUpdate.Count, "The number of rows affected must equal the sum of entities added, deleted and updated"); - Assert.IsTrue(ordersAddedCount == ordersToAdd.Count(), "The number of orders to add did not match what was expected."); - Assert.IsTrue(ordersDeletedCount == 0, "The number of orders that was deleted did not match what was expected."); - Assert.IsTrue(ordersUpdatedCount == ordersToUpdate.Count(), "The number of orders that was updated did not match what was expected."); - } - [TestMethod] - public async Task With_Add_Changes() + var ordersToAdd = new List(); + for (int i = 0; i < 2000; i++) { - var dbContext = SetupDbContext(true); - var oldTotalCount = dbContext.Orders.Where(o => o.Price == 10.57M).Count(); + ordersToAdd.Add(new Order { Id = -i, Price = 10.57M }); + } + dbContext.Orders.AddRange(ordersToAdd); - var ordersToAdd = new List(); - for (int i = 0; i < 2000; i++) - { - ordersToAdd.Add(new Order { Id = -i, Price = 10.57M }); - } - dbContext.Orders.AddRange(ordersToAdd); + int rowsAffected = await dbContext.BulkSaveChangesAsync(); + int newTotalCount = dbContext.Orders.Where(o => o.Price == 10.57M).Count(); - int rowsAffected = await dbContext.BulkSaveChangesAsync(); - int newTotalCount = dbContext.Orders.Where(o => o.Price == 10.57M).Count(); + Assert.IsTrue(rowsAffected == ordersToAdd.Count, "The number of rows affected must equal the sum of entities added, deleted and updated"); + Assert.IsTrue(oldTotalCount + ordersToAdd.Count == newTotalCount, "The number of orders to add did not match what was expected."); + } + [TestMethod] + public async Task With_Delete_Changes() + { + var dbContext = SetupDbContext(true); + var oldTotalCount = dbContext.Orders.Where(o => o.Price <= 5).Count(); - Assert.IsTrue(rowsAffected == ordersToAdd.Count, "The number of rows affected must equal the sum of entities added, deleted and updated"); - Assert.IsTrue(oldTotalCount + ordersToAdd.Count == newTotalCount, "The number of orders to add did not match what was expected."); - } - [TestMethod] - public async Task With_Delete_Changes() - { - var dbContext = SetupDbContext(true); - var oldTotalCount = dbContext.Orders.Where(o => o.Price <= 5).Count(); + //Delete orders + var ordersToDelete = dbContext.Orders.Where(o => o.Price <= 5).ToList(); + dbContext.Orders.RemoveRange(ordersToDelete); - //Delete orders - var ordersToDelete = dbContext.Orders.Where(o => o.Price <= 5).ToList(); - dbContext.Orders.RemoveRange(ordersToDelete); + int rowsAffected = await dbContext.BulkSaveChangesAsync(); + int newTotalCount = dbContext.Orders.Where(o => o.Price <= 5).Count(); - int rowsAffected = await dbContext.BulkSaveChangesAsync(); - int newTotalCount = dbContext.Orders.Where(o => o.Price <= 5).Count(); + Assert.IsTrue(rowsAffected == ordersToDelete.Count, "The number of rows affected must equal the sum of entities added, deleted and updated"); + Assert.IsTrue(oldTotalCount - ordersToDelete.Count == newTotalCount, "The number of orders to add did not match what was expected."); + } + [TestMethod] + public async Task With_Update_Changes() + { + var dbContext = SetupDbContext(true); + var oldTotalCount = dbContext.Orders.Where(o => o.Price <= 10).Count(); - Assert.IsTrue(rowsAffected == ordersToDelete.Count, "The number of rows affected must equal the sum of entities added, deleted and updated"); - Assert.IsTrue(oldTotalCount - ordersToDelete.Count == newTotalCount, "The number of orders to add did not match what was expected."); - } - [TestMethod] - public async Task With_Update_Changes() + //Update existing orders + var ordersToUpdate = dbContext.Orders.Where(o => o.Price <= 10).ToList(); + foreach (var orderToUpdate in ordersToUpdate) { - var dbContext = SetupDbContext(true); - var oldTotalCount = dbContext.Orders.Where(o => o.Price <= 10).Count(); - - //Update existing orders - var ordersToUpdate = dbContext.Orders.Where(o => o.Price <= 10).ToList(); - foreach (var orderToUpdate in ordersToUpdate) - { - orderToUpdate.Price = 99M; - } + orderToUpdate.Price = 99M; + } - int rowsAffected = await dbContext.BulkSaveChangesAsync(); - int newTotalCount = dbContext.Orders.Where(o => o.Price <= 10).Count(); - int expectedCount = dbContext.Orders.Where(o => o.Price == 99M).Count(); + int rowsAffected = await dbContext.BulkSaveChangesAsync(); + int newTotalCount = dbContext.Orders.Where(o => o.Price <= 10).Count(); + int expectedCount = dbContext.Orders.Where(o => o.Price == 99M).Count(); - Assert.IsTrue(rowsAffected == ordersToUpdate.Count, "The number of rows affected must equal the sum of entities added, deleted and updated"); - Assert.IsTrue(oldTotalCount - ordersToUpdate.Count == newTotalCount, "The number of orders to add did not match what was expected."); - } - [TestMethod] - public async Task With_Inheritance_Tpc() + Assert.IsTrue(rowsAffected == ordersToUpdate.Count, "The number of rows affected must equal the sum of entities added, deleted and updated"); + Assert.IsTrue(oldTotalCount - ordersToUpdate.Count == newTotalCount, "The number of orders to add did not match what was expected."); + } + [TestMethod] + public async Task With_Inheritance_Tpc() + { + var dbContext = SetupDbContext(true, PopulateDataMode.Tpc); + //Delete Customers + var customersToDelete = dbContext.TpcPeople.OfType().Where(o => o.Id <= 1000); + int expectedRowsDeleted = customersToDelete.Count(); + dbContext.TpcPeople.RemoveRange(customersToDelete); + //Update Customers + var customersToUpdate = dbContext.TpcPeople.OfType().Where(o => o.Id > 1000 && o.Id <= 1500); + int expectedRowsUpdated = customersToUpdate.Count(); + foreach (var customerToUpdate in customersToUpdate) { - var dbContext = SetupDbContext(true, PopulateDataMode.Tpc); - //Delete Customers - var customersToDelete = dbContext.TpcPeople.OfType().Where(o => o.Id <= 1000); - int expectedRowsDeleted = customersToDelete.Count(); - dbContext.TpcPeople.RemoveRange(customersToDelete); - //Update Customers - var customersToUpdate = dbContext.TpcPeople.OfType().Where(o => o.Id > 1000 && o.Id <= 1500); - int expectedRowsUpdated = customersToUpdate.Count(); - foreach (var customerToUpdate in customersToUpdate) - { - customerToUpdate.FirstName = "CustomerUpdated"; - } - //Add New Customers - long maxId = dbContext.TpcPeople.OfType().Max(o => o.Id); - int expectedRowsAdded = 3000; - for (long i = maxId + 1; i <= maxId + expectedRowsAdded; i++) - { - dbContext.TpcPeople.Add(new TpcCustomer - { - Id = i, - FirstName = string.Format("John_{0}", i), - LastName = string.Format("Smith_{0}", i), - Email = string.Format("john.smith{0}@domain.com", i), - AddedDate = DateTime.UtcNow - }); - } - int rowsAffected = await dbContext.BulkSaveChangesAsync(); - int rowsAfterDelete = customersToDelete.Count(); - int rowsUpdated = customersToUpdate.Where(o => o.FirstName == "CustomerUpdated").Count(); - int rowsAdded = dbContext.TpcPeople.OfType().Where(o => o.Id > maxId).Count(); - int expectedRowsAffected = expectedRowsDeleted + expectedRowsUpdated + expectedRowsAdded; - - Assert.IsTrue(rowsAfterDelete == 0, "The number of rows deleted not not match what was expected."); - Assert.IsTrue(rowsUpdated == expectedRowsUpdated, "The number of rows updated not not match what was expected."); - Assert.IsTrue(rowsAdded == expectedRowsAdded, "The number of rows added not not match what was expected."); - Assert.IsTrue(rowsAffected == expectedRowsAffected, "The new count minus the old count should match the number of rows inserted."); + customerToUpdate.FirstName = "CustomerUpdated"; } - [TestMethod] - public async Task With_Inheritance_Tph() + //Add New Customers + long maxId = dbContext.TpcPeople.OfType().Max(o => o.Id); + int expectedRowsAdded = 3000; + for (long i = maxId + 1; i <= maxId + expectedRowsAdded; i++) { - var dbContext = SetupDbContext(true, PopulateDataMode.Tph); - //Delete Customers - var customersToDelete = dbContext.TphCustomers.Where(o => o.Id <= 1000); - int expectedRowsDeleted = customersToDelete.Count(); - dbContext.TphCustomers.RemoveRange(customersToDelete); - //Update Customers - var customersToUpdate = dbContext.TphCustomers.Where(o => o.Id > 1000 && o.Id <= 1500); - int expectedRowsUpdated = customersToUpdate.Count(); - foreach (var customerToUpdate in customersToUpdate) - { - customerToUpdate.FirstName = "CustomerUpdated"; - } - //Add New Customers - long maxId = dbContext.TphPeople.Max(o => o.Id); - int expectedRowsAdded = 3000; - for (long i = maxId + 1; i <= maxId + expectedRowsAdded; i++) + dbContext.TpcPeople.Add(new TpcCustomer { - dbContext.TphCustomers.Add(new TphCustomer - { - Id = i, - FirstName = string.Format("John_{0}", i), - LastName = string.Format("Smith_{0}", i), - Email = string.Format("john.smith{0}@domain.com", i), - AddedDate = DateTime.UtcNow - }); - } - int rowsAffected = await dbContext.BulkSaveChangesAsync(); - int rowsAfterDelete = customersToDelete.Count(); - int rowsUpdated = customersToUpdate.Where(o => o.FirstName == "CustomerUpdated").Count(); - int rowsAdded = dbContext.TphCustomers.Where(o => o.Id > maxId).Count(); - int expectedRowsAffected = expectedRowsDeleted + expectedRowsUpdated + expectedRowsAdded; + Id = i, + FirstName = string.Format("John_{0}", i), + LastName = string.Format("Smith_{0}", i), + Email = string.Format("john.smith{0}@domain.com", i), + AddedDate = DateTime.UtcNow + }); + } + int rowsAffected = await dbContext.BulkSaveChangesAsync(); + int rowsAfterDelete = customersToDelete.Count(); + int rowsUpdated = customersToUpdate.Where(o => o.FirstName == "CustomerUpdated").Count(); + int rowsAdded = dbContext.TpcPeople.OfType().Where(o => o.Id > maxId).Count(); + int expectedRowsAffected = expectedRowsDeleted + expectedRowsUpdated + expectedRowsAdded; - Assert.IsTrue(expectedRowsDeleted > 0, "The expected number of rows to delete must be greater than zero."); - Assert.IsTrue(rowsAfterDelete == 0, "The number of rows deleted not not match what was expected."); - Assert.IsTrue(rowsUpdated == expectedRowsUpdated, "The number of rows updated not not match what was expected."); - Assert.IsTrue(rowsAdded == expectedRowsAdded, "The number of rows added not not match what was expected."); - Assert.IsTrue(rowsAffected == expectedRowsAffected, "The new count minus the old count should match the number of rows inserted."); + Assert.IsTrue(rowsAfterDelete == 0, "The number of rows deleted not not match what was expected."); + Assert.IsTrue(rowsUpdated == expectedRowsUpdated, "The number of rows updated not not match what was expected."); + Assert.IsTrue(rowsAdded == expectedRowsAdded, "The number of rows added not not match what was expected."); + Assert.IsTrue(rowsAffected == expectedRowsAffected, "The new count minus the old count should match the number of rows inserted."); + } + [TestMethod] + public async Task With_Inheritance_Tph() + { + var dbContext = SetupDbContext(true, PopulateDataMode.Tph); + //Delete Customers + var customersToDelete = dbContext.TphCustomers.Where(o => o.Id <= 1000); + int expectedRowsDeleted = customersToDelete.Count(); + dbContext.TphCustomers.RemoveRange(customersToDelete); + //Update Customers + var customersToUpdate = dbContext.TphCustomers.Where(o => o.Id > 1000 && o.Id <= 1500); + int expectedRowsUpdated = customersToUpdate.Count(); + foreach (var customerToUpdate in customersToUpdate) + { + customerToUpdate.FirstName = "CustomerUpdated"; } - [TestMethod] - public async Task With_Inheritance_Tpt() + //Add New Customers + long maxId = dbContext.TphPeople.Max(o => o.Id); + int expectedRowsAdded = 3000; + for (long i = maxId + 1; i <= maxId + expectedRowsAdded; i++) { - var dbContext = SetupDbContext(true, PopulateDataMode.Tpt); - //Delete Customers - var customersToDelete = dbContext.TptCustomers.Where(o => o.Id <= 1000); - int expectedRowsDeleted = customersToDelete.Count(); - dbContext.TptCustomers.RemoveRange(customersToDelete); - //Update Customers - var customersToUpdate = dbContext.TptCustomers.Where(o => o.Id > 1000 && o.Id <= 1500); - int expectedRowsUpdated = customersToUpdate.Count(); - foreach (var customerToUpdate in customersToUpdate) + dbContext.TphCustomers.Add(new TphCustomer { - customerToUpdate.Email = "name@domain.com"; - customerToUpdate.FirstName = "CustomerUpdated"; - } - //Add New Customers - long maxId = dbContext.TptPeople.Max(o => o.Id); - int expectedRowsAdded = 3000; - for (long i = maxId + 1; i <= maxId + expectedRowsAdded; i++) - { - dbContext.TptCustomers.Add(new TptCustomer - { - Id = i, - FirstName = string.Format("John_{0}", i), - LastName = string.Format("Smith_{0}", i), - Email = string.Format("john.smith{0}@domain.com", i), - AddedDate = DateTime.UtcNow - }); - } - int rowsAffected = await dbContext.BulkSaveChangesAsync(); - int rowsAfterDelete = customersToDelete.Count(); - int rowsUpdated = customersToUpdate.Where(o => o.FirstName == "CustomerUpdated").Count(); - int rowsAdded = dbContext.TptCustomers.Where(o => o.Id > maxId).Count(); - int expectedRowsAffected = expectedRowsDeleted + expectedRowsUpdated + expectedRowsAdded; + Id = i, + FirstName = string.Format("John_{0}", i), + LastName = string.Format("Smith_{0}", i), + Email = string.Format("john.smith{0}@domain.com", i), + AddedDate = DateTime.UtcNow + }); + } + int rowsAffected = await dbContext.BulkSaveChangesAsync(); + int rowsAfterDelete = customersToDelete.Count(); + int rowsUpdated = customersToUpdate.Where(o => o.FirstName == "CustomerUpdated").Count(); + int rowsAdded = dbContext.TphCustomers.Where(o => o.Id > maxId).Count(); + int expectedRowsAffected = expectedRowsDeleted + expectedRowsUpdated + expectedRowsAdded; - Assert.IsTrue(rowsAfterDelete == 0, "The number of rows deleted not not match what was expected."); - Assert.IsTrue(rowsUpdated == expectedRowsUpdated, "The number of rows updated not not match what was expected."); - Assert.IsTrue(rowsAdded == expectedRowsAdded, "The number of rows added not not match what was expected."); - Assert.IsTrue(rowsAffected == expectedRowsAffected, "The new count minus the old count should match the number of rows inserted."); + Assert.IsTrue(expectedRowsDeleted > 0, "The expected number of rows to delete must be greater than zero."); + Assert.IsTrue(rowsAfterDelete == 0, "The number of rows deleted not not match what was expected."); + Assert.IsTrue(rowsUpdated == expectedRowsUpdated, "The number of rows updated not not match what was expected."); + Assert.IsTrue(rowsAdded == expectedRowsAdded, "The number of rows added not not match what was expected."); + Assert.IsTrue(rowsAffected == expectedRowsAffected, "The new count minus the old count should match the number of rows inserted."); + } + [TestMethod] + public async Task With_Inheritance_Tpt() + { + var dbContext = SetupDbContext(true, PopulateDataMode.Tpt); + //Delete Customers + var customersToDelete = dbContext.TptCustomers.Where(o => o.Id <= 1000); + int expectedRowsDeleted = customersToDelete.Count(); + dbContext.TptCustomers.RemoveRange(customersToDelete); + //Update Customers + var customersToUpdate = dbContext.TptCustomers.Where(o => o.Id > 1000 && o.Id <= 1500); + int expectedRowsUpdated = customersToUpdate.Count(); + foreach (var customerToUpdate in customersToUpdate) + { + customerToUpdate.Email = "name@domain.com"; + customerToUpdate.FirstName = "CustomerUpdated"; } - [TestMethod] - public async Task with_Schema() + //Add New Customers + long maxId = dbContext.TptPeople.Max(o => o.Id); + int expectedRowsAdded = 3000; + for (long i = maxId + 1; i <= maxId + expectedRowsAdded; i++) { - var dbContext = SetupDbContext(true, PopulateDataMode.Schema); - var totalCount = await dbContext.ProductsWithCustomSchema.CountAsync(); - - //Add new products - var productsToAdd = new List(); - for (int i = 0; i < 2000; i++) + dbContext.TptCustomers.Add(new TptCustomer { - productsToAdd.Add(new ProductWithCustomSchema { Id = (-i).ToString(), Price = 10.57M }); - } - dbContext.ProductsWithCustomSchema.AddRange(productsToAdd); + Id = i, + FirstName = string.Format("John_{0}", i), + LastName = string.Format("Smith_{0}", i), + Email = string.Format("john.smith{0}@domain.com", i), + AddedDate = DateTime.UtcNow + }); + } + int rowsAffected = await dbContext.BulkSaveChangesAsync(); + int rowsAfterDelete = customersToDelete.Count(); + int rowsUpdated = customersToUpdate.Where(o => o.FirstName == "CustomerUpdated").Count(); + int rowsAdded = dbContext.TptCustomers.Where(o => o.Id > maxId).Count(); + int expectedRowsAffected = expectedRowsDeleted + expectedRowsUpdated + expectedRowsAdded; - //Delete products - var productsToDelete = dbContext.ProductsWithCustomSchema.Where(o => o.Price <= 5).ToList(); - dbContext.ProductsWithCustomSchema.RemoveRange(productsToDelete); + Assert.IsTrue(rowsAfterDelete == 0, "The number of rows deleted not not match what was expected."); + Assert.IsTrue(rowsUpdated == expectedRowsUpdated, "The number of rows updated not not match what was expected."); + Assert.IsTrue(rowsAdded == expectedRowsAdded, "The number of rows added not not match what was expected."); + Assert.IsTrue(rowsAffected == expectedRowsAffected, "The new count minus the old count should match the number of rows inserted."); + } + [TestMethod] + public async Task with_Schema() + { + var dbContext = SetupDbContext(true, PopulateDataMode.Schema); + var totalCount = await dbContext.ProductsWithCustomSchema.CountAsync(); - //Update existing products - var productsToUpdate = dbContext.ProductsWithCustomSchema.Where(o => o.Price > 5 && o.Price <= 10).ToList(); - foreach (var productToUpdate in productsToUpdate) - { - productToUpdate.Price = 99M; - } + //Add new products + var productsToAdd = new List(); + for (int i = 0; i < 2000; i++) + { + productsToAdd.Add(new ProductWithCustomSchema { Id = (-i).ToString(), Price = 10.57M }); + } + dbContext.ProductsWithCustomSchema.AddRange(productsToAdd); - int rowsAffected = await dbContext.BulkSaveChangesAsync(); - int productsAddedCount = await dbContext.ProductsWithCustomSchema.Where(o => o.Price == 10.57M).CountAsync(); - int productsDeletedCount = await dbContext.ProductsWithCustomSchema.Where(o => o.Price <= 5).CountAsync(); - int productsUpdatedCount = await dbContext.ProductsWithCustomSchema.Where(o => o.Price == 99M).CountAsync(); + //Delete products + var productsToDelete = dbContext.ProductsWithCustomSchema.Where(o => o.Price <= 5).ToList(); + dbContext.ProductsWithCustomSchema.RemoveRange(productsToDelete); - Assert.IsTrue(rowsAffected == productsToAdd.Count + productsToDelete.Count + productsToUpdate.Count, "The number of rows affected must equal the sum of entities added, deleted and updated"); - Assert.IsTrue(productsAddedCount == productsToAdd.Count(), "The number of products to add did not match what was expected."); - Assert.IsTrue(productsDeletedCount == 0, "The number of products that was deleted did not match what was expected."); - Assert.IsTrue(productsUpdatedCount == productsToUpdate.Count(), "The number of products that was updated did not match what was expected."); + //Update existing products + var productsToUpdate = dbContext.ProductsWithCustomSchema.Where(o => o.Price > 5 && o.Price <= 10).ToList(); + foreach (var productToUpdate in productsToUpdate) + { + productToUpdate.Price = 99M; } + + int rowsAffected = await dbContext.BulkSaveChangesAsync(); + int productsAddedCount = await dbContext.ProductsWithCustomSchema.Where(o => o.Price == 10.57M).CountAsync(); + int productsDeletedCount = await dbContext.ProductsWithCustomSchema.Where(o => o.Price <= 5).CountAsync(); + int productsUpdatedCount = await dbContext.ProductsWithCustomSchema.Where(o => o.Price == 99M).CountAsync(); + + Assert.IsTrue(rowsAffected == productsToAdd.Count + productsToDelete.Count + productsToUpdate.Count, "The number of rows affected must equal the sum of entities added, deleted and updated"); + Assert.IsTrue(productsAddedCount == productsToAdd.Count(), "The number of products to add did not match what was expected."); + Assert.IsTrue(productsDeletedCount == 0, "The number of products that was deleted did not match what was expected."); + Assert.IsTrue(productsUpdatedCount == productsToUpdate.Count(), "The number of products that was updated did not match what was expected."); } } \ No newline at end of file diff --git a/N.EntityFrameworkCore.Extensions.Test/DbContextExtensions/BulkSync.cs b/N.EntityFrameworkCore.Extensions.Test/DbContextExtensions/BulkSync.cs index 61c6f95..3240ca5 100644 --- a/N.EntityFrameworkCore.Extensions.Test/DbContextExtensions/BulkSync.cs +++ b/N.EntityFrameworkCore.Extensions.Test/DbContextExtensions/BulkSync.cs @@ -4,239 +4,238 @@ using Microsoft.VisualStudio.TestTools.UnitTesting; using N.EntityFrameworkCore.Extensions.Test.Data; -namespace N.EntityFrameworkCore.Extensions.Test.DbContextExtensions +namespace N.EntityFrameworkCore.Extensions.Test.DbContextExtensions; + +[TestClass] +public class BulkSync : DbContextExtensionsBase { - [TestClass] - public class BulkSync : DbContextExtensionsBase + [TestMethod] + public void With_Default_Options() { - [TestMethod] - public void With_Default_Options() - { - var dbContext = SetupDbContext(true); - int oldTotal = dbContext.Orders.Count(); - var orders = dbContext.Orders.Where(o => o.Id <= 10000).OrderBy(o => o.Id).ToList(); - int ordersToAdd = 5000; - int ordersToUpdate = orders.Count; - foreach (var order in orders) - { - order.Price = Convert.ToDecimal(order.Id + .25); - } - for (int i = 0; i < ordersToAdd; i++) - { - orders.Add(new Order { Id = 100000 + i, Price = 3.55M }); - } - var result = dbContext.BulkSync(orders); - var newOrders = dbContext.Orders.OrderBy(o => o.Id).ToList(); - bool areAddedOrdersMerged = true; - bool areUpdatedOrdersMerged = true; - foreach (var newOrder in newOrders.Where(o => o.Id <= 10000).OrderBy(o => o.Id)) + var dbContext = SetupDbContext(true); + int oldTotal = dbContext.Orders.Count(); + var orders = dbContext.Orders.Where(o => o.Id <= 10000).OrderBy(o => o.Id).ToList(); + int ordersToAdd = 5000; + int ordersToUpdate = orders.Count; + foreach (var order in orders) + { + order.Price = Convert.ToDecimal(order.Id + .25); + } + for (int i = 0; i < ordersToAdd; i++) + { + orders.Add(new Order { Id = 100000 + i, Price = 3.55M }); + } + var result = dbContext.BulkSync(orders); + var newOrders = dbContext.Orders.OrderBy(o => o.Id).ToList(); + bool areAddedOrdersMerged = true; + bool areUpdatedOrdersMerged = true; + foreach (var newOrder in newOrders.Where(o => o.Id <= 10000).OrderBy(o => o.Id)) + { + if (newOrder.Price != Convert.ToDecimal(newOrder.Id + .25)) { - if (newOrder.Price != Convert.ToDecimal(newOrder.Id + .25)) - { - areUpdatedOrdersMerged = false; - break; - } + areUpdatedOrdersMerged = false; + break; } - foreach (var newOrder in newOrders.Where(o => o.Id >= 500000).OrderBy(o => o.Id)) + } + foreach (var newOrder in newOrders.Where(o => o.Id >= 500000).OrderBy(o => o.Id)) + { + if (newOrder.Price != 3.55M) { - if (newOrder.Price != 3.55M) - { - areAddedOrdersMerged = false; - break; - } + areAddedOrdersMerged = false; + break; } - - Assert.IsTrue(result.RowsAffected == oldTotal + ordersToAdd, "The number of rows inserted must match the count of order list"); - Assert.IsTrue(result.RowsUpdated == ordersToUpdate, "The number of rows updated must match"); - Assert.IsTrue(result.RowsInserted == ordersToAdd, "The number of rows added must match"); - Assert.IsTrue(result.RowsDeleted == oldTotal - orders.Count() + ordersToAdd, "The number of rows deleted must match the difference from the total existing orders to the new orders to add/update"); - Assert.IsTrue(areAddedOrdersMerged, "The orders that were added did not merge correctly"); - Assert.IsTrue(areUpdatedOrdersMerged, "The orders that were updated did not merge correctly"); } - [TestMethod] - public void With_Inheritance_Tpc() - { - var dbContext = SetupDbContext(true, PopulateDataMode.Tpc); - var customers = dbContext.TpcPeople.Where(o => o.Id <= 1000).OfType().ToList(); - int customersToAdd = 5000; - int customersToUpdate = customers.Count; - int customersToDelete = dbContext.TpcPeople.OfType().Count() - customersToUpdate; - foreach (var customer in customers) - { - customer.FirstName = "BulkSync_Tpc_Update"; - } - for (int i = 0; i < customersToAdd; i++) - { - customers.Add(new TpcCustomer - { - Id = 10000 + i, - FirstName = "BulkSync_Tpc_Add", - AddedDate = DateTime.UtcNow - }); - } - var result = dbContext.BulkSync(customers, options => { options.MergeOnCondition = (s, t) => s.Id == t.Id; }); - int customersAdded = dbContext.TpcPeople.Where(o => o.FirstName == "BulkSync_Tpc_Add").OfType().Count(); - int customersUpdated = dbContext.TpcPeople.Where(o => o.FirstName == "BulkSync_Tpc_Update").OfType().Count(); - int newCustomerTotal = dbContext.TpcPeople.OfType().Count(); + Assert.IsTrue(result.RowsAffected == oldTotal + ordersToAdd, "The number of rows inserted must match the count of order list"); + Assert.IsTrue(result.RowsUpdated == ordersToUpdate, "The number of rows updated must match"); + Assert.IsTrue(result.RowsInserted == ordersToAdd, "The number of rows added must match"); + Assert.IsTrue(result.RowsDeleted == oldTotal - orders.Count() + ordersToAdd, "The number of rows deleted must match the difference from the total existing orders to the new orders to add/update"); + Assert.IsTrue(areAddedOrdersMerged, "The orders that were added did not merge correctly"); + Assert.IsTrue(areUpdatedOrdersMerged, "The orders that were updated did not merge correctly"); + } + [TestMethod] + public void With_Inheritance_Tpc() + { + var dbContext = SetupDbContext(true, PopulateDataMode.Tpc); + var customers = dbContext.TpcPeople.Where(o => o.Id <= 1000).OfType().ToList(); + int customersToAdd = 5000; + int customersToUpdate = customers.Count; + int customersToDelete = dbContext.TpcPeople.OfType().Count() - customersToUpdate; - Assert.IsTrue(result.RowsAffected == customersAdded + customersToUpdate + customersToDelete, "The number of rows affected must match the sum of customers added, updated and deleted."); - Assert.IsTrue(result.RowsUpdated == customersToUpdate, "The number of rows updated must match"); - Assert.IsTrue(result.RowsInserted == customersToAdd, "The number of rows added must match"); - Assert.IsTrue(result.RowsDeleted == customersToDelete, "The number of rows deleted must match the difference from the total existing orders to the new orders to add/update"); - Assert.IsTrue(customersToAdd == customersAdded, "The custmoers that were added did not merge correctly"); - Assert.IsTrue(customersToUpdate == customersUpdated, "The customers that were updated did not merge correctly"); - Assert.IsTrue(newCustomerTotal == customersToAdd + customersToUpdate, "The count of customers in the database should match the sum of customers added and updated."); + foreach (var customer in customers) + { + customer.FirstName = "BulkSync_Tpc_Update"; } - [TestMethod] - public void With_Inheritance_Tph() - { - var dbContext = SetupDbContext(true, PopulateDataMode.Tph); - var customers = dbContext.TphCustomers.Where(o => o.Id <= 1000).ToList(); - int customersToAdd = 5000; - int customersToUpdate = customers.Count; - int customersToDelete = dbContext.TphPeople.Count() - customersToUpdate; - - foreach (var customer in customers) - { - customer.FirstName = "BulkSync_Tph_Update"; - } - for (int i = 0; i < customersToAdd; i++) + for (int i = 0; i < customersToAdd; i++) + { + customers.Add(new TpcCustomer { - customers.Add(new TphCustomer - { - Id = 10000 + i, - FirstName = "BulkSync_Tph_Add", - AddedDate = DateTime.UtcNow - }); - } - var result = dbContext.BulkSync(customers, options => { options.UsePermanentTable = true; options.MergeOnCondition = (s, t) => s.Id == t.Id; }); - int customersAdded = dbContext.TphCustomers.Where(o => o.FirstName == "BulkSync_Tph_Add").Count(); - int customersUpdated = dbContext.TphCustomers.Where(o => o.FirstName == "BulkSync_Tph_Update").Count(); - int newCustomerTotal = dbContext.TphCustomers.Count(); - - Assert.IsTrue(result.RowsAffected == customersAdded + customersToUpdate + customersToDelete, "The number of rows affected must match the sum of customers added, updated and deleted."); - Assert.IsTrue(result.RowsUpdated == customersToUpdate, "The number of rows updated must match"); - Assert.IsTrue(result.RowsInserted == customersToAdd, "The number of rows added must match"); - Assert.IsTrue(result.RowsDeleted == customersToDelete, "The number of rows deleted must match the difference from the total existing orders to the new orders to add/update"); - Assert.IsTrue(customersToAdd == customersAdded, "The customers that were added did not merge correctly"); - Assert.IsTrue(customersToUpdate == customersUpdated, "The customers that were updated did not merge correctly"); - Assert.IsTrue(newCustomerTotal == customersToAdd + customersToUpdate, "The count of customers in the database should match the sum of customers added and updated."); + Id = 10000 + i, + FirstName = "BulkSync_Tpc_Add", + AddedDate = DateTime.UtcNow + }); } - [TestMethod] - public void With_Inheritance_Tpt() - { - var dbContext = SetupDbContext(true, PopulateDataMode.Tpt); - var customers = dbContext.TptPeople.Where(o => o.Id <= 1000).OfType().ToList(); - int customersToAdd = 5000; - int customersToUpdate = customers.Count; - int customersToDelete = dbContext.TptCustomers.Count() - customersToUpdate; + var result = dbContext.BulkSync(customers, options => { options.MergeOnCondition = (s, t) => s.Id == t.Id; }); + int customersAdded = dbContext.TpcPeople.Where(o => o.FirstName == "BulkSync_Tpc_Add").OfType().Count(); + int customersUpdated = dbContext.TpcPeople.Where(o => o.FirstName == "BulkSync_Tpc_Update").OfType().Count(); + int newCustomerTotal = dbContext.TpcPeople.OfType().Count(); - foreach (var customer in customers) - { - customer.FirstName = "BulkSync_Tpt_Update"; - } - for (int i = 0; i < customersToAdd; i++) - { - customers.Add(new TptCustomer - { - Id = 10000 + i, - FirstName = "BulkSync_Tpt_Add", - AddedDate = DateTime.UtcNow - }); - } - var result = dbContext.BulkSync(customers, options => { options.MergeOnCondition = (s, t) => s.Id == t.Id; }); - int customersAdded = dbContext.TptPeople.Where(o => o.FirstName == "BulkSync_Tpt_Add").OfType().Count(); - int customersUpdated = dbContext.TptPeople.Where(o => o.FirstName == "BulkSync_Tpt_Update").OfType().Count(); - int newCustomerTotal = dbContext.TptPeople.OfType().Count(); + Assert.IsTrue(result.RowsAffected == customersAdded + customersToUpdate + customersToDelete, "The number of rows affected must match the sum of customers added, updated and deleted."); + Assert.IsTrue(result.RowsUpdated == customersToUpdate, "The number of rows updated must match"); + Assert.IsTrue(result.RowsInserted == customersToAdd, "The number of rows added must match"); + Assert.IsTrue(result.RowsDeleted == customersToDelete, "The number of rows deleted must match the difference from the total existing orders to the new orders to add/update"); + Assert.IsTrue(customersToAdd == customersAdded, "The custmoers that were added did not merge correctly"); + Assert.IsTrue(customersToUpdate == customersUpdated, "The customers that were updated did not merge correctly"); + Assert.IsTrue(newCustomerTotal == customersToAdd + customersToUpdate, "The count of customers in the database should match the sum of customers added and updated."); + } + [TestMethod] + public void With_Inheritance_Tph() + { + var dbContext = SetupDbContext(true, PopulateDataMode.Tph); + var customers = dbContext.TphCustomers.Where(o => o.Id <= 1000).ToList(); + int customersToAdd = 5000; + int customersToUpdate = customers.Count; + int customersToDelete = dbContext.TphPeople.Count() - customersToUpdate; - Assert.IsTrue(result.RowsAffected == customersAdded + customersToUpdate + customersToDelete, "The number of rows affected must match the sum of customers added, updated and deleted."); - Assert.IsTrue(result.RowsUpdated == customersToUpdate, "The number of rows updated must match"); - Assert.IsTrue(result.RowsInserted == customersToAdd, "The number of rows added must match"); - Assert.IsTrue(result.RowsDeleted == customersToDelete, "The number of rows deleted must match the difference from the total existing orders to the new orders to add/update"); - Assert.IsTrue(customersToAdd == customersAdded, "The custmoers that were added did not merge correctly"); - Assert.IsTrue(customersToUpdate == customersUpdated, "The customers that were updated did not merge correctly"); - Assert.IsTrue(newCustomerTotal == customersToAdd + customersToUpdate, "The count of customers in the database should match the sum of customers added and updated."); + foreach (var customer in customers) + { + customer.FirstName = "BulkSync_Tph_Update"; } - [TestMethod] - public void With_Options_AutoMapIdentity() - { - var dbContext = SetupDbContext(true); - int oldTotal = dbContext.Orders.Count(); - int ordersToUpdate = 3; - int ordersToAdd = 2; - var orders = new List - { - new Order { ExternalId = "id-1", Price=7.10M }, - new Order { ExternalId = "id-2", Price=9.33M }, - new Order { ExternalId = "id-3", Price=3.25M }, - new Order { ExternalId = "id-1000001", Price=2.15M }, - new Order { ExternalId = "id-1000002", Price=5.75M }, - }; - var result = dbContext.BulkSync(orders, options => { options.MergeOnCondition = (s, t) => s.ExternalId == t.ExternalId; options.UsePermanentTable = true; }); - bool autoMapIdentityMatched = true; - foreach (var order in orders) + for (int i = 0; i < customersToAdd; i++) + { + customers.Add(new TphCustomer { - if (!dbContext.Orders.Any(o => o.ExternalId == order.ExternalId && o.Price == order.Price)) - { - autoMapIdentityMatched = false; - break; - } - } + Id = 10000 + i, + FirstName = "BulkSync_Tph_Add", + AddedDate = DateTime.UtcNow + }); + } + var result = dbContext.BulkSync(customers, options => { options.UsePermanentTable = true; options.MergeOnCondition = (s, t) => s.Id == t.Id; }); + int customersAdded = dbContext.TphCustomers.Where(o => o.FirstName == "BulkSync_Tph_Add").Count(); + int customersUpdated = dbContext.TphCustomers.Where(o => o.FirstName == "BulkSync_Tph_Update").Count(); + int newCustomerTotal = dbContext.TphCustomers.Count(); - Assert.IsTrue(result.RowsAffected == oldTotal + ordersToAdd, "The number of rows inserted must match the count of order list"); - Assert.IsTrue(result.RowsUpdated == ordersToUpdate, "The number of rows updated must match"); - Assert.IsTrue(result.RowsInserted == ordersToAdd, "The number of rows added must match"); - Assert.IsTrue(result.RowsDeleted == oldTotal - orders.Count() + ordersToAdd, "The number of rows deleted must match the difference from the total existing orders to the new orders to add/update"); - Assert.IsTrue(autoMapIdentityMatched, "The auto mapping of ids of entities that were merged failed to match up"); + Assert.IsTrue(result.RowsAffected == customersAdded + customersToUpdate + customersToDelete, "The number of rows affected must match the sum of customers added, updated and deleted."); + Assert.IsTrue(result.RowsUpdated == customersToUpdate, "The number of rows updated must match"); + Assert.IsTrue(result.RowsInserted == customersToAdd, "The number of rows added must match"); + Assert.IsTrue(result.RowsDeleted == customersToDelete, "The number of rows deleted must match the difference from the total existing orders to the new orders to add/update"); + Assert.IsTrue(customersToAdd == customersAdded, "The customers that were added did not merge correctly"); + Assert.IsTrue(customersToUpdate == customersUpdated, "The customers that were updated did not merge correctly"); + Assert.IsTrue(newCustomerTotal == customersToAdd + customersToUpdate, "The count of customers in the database should match the sum of customers added and updated."); + } + [TestMethod] + public void With_Inheritance_Tpt() + { + var dbContext = SetupDbContext(true, PopulateDataMode.Tpt); + var customers = dbContext.TptPeople.Where(o => o.Id <= 1000).OfType().ToList(); + int customersToAdd = 5000; + int customersToUpdate = customers.Count; + int customersToDelete = dbContext.TptCustomers.Count() - customersToUpdate; + + foreach (var customer in customers) + { + customer.FirstName = "BulkSync_Tpt_Update"; } - [TestMethod] - public void With_Options_MergeOnCondition() - { - var dbContext = SetupDbContext(true); - int oldTotal = dbContext.Orders.Count(); - var orders = dbContext.Orders.Where(o => o.Id <= 100 && o.ExternalId != null).OrderBy(o => o.Id).ToList(); - int ordersToAdd = 50; - int ordersToUpdate = orders.Count; - foreach (var order in orders) + for (int i = 0; i < customersToAdd; i++) + { + customers.Add(new TptCustomer { - order.Price = Convert.ToDecimal(order.Id + .25); - } - for (int i = 0; i < ordersToAdd; i++) + Id = 10000 + i, + FirstName = "BulkSync_Tpt_Add", + AddedDate = DateTime.UtcNow + }); + } + var result = dbContext.BulkSync(customers, options => { options.MergeOnCondition = (s, t) => s.Id == t.Id; }); + int customersAdded = dbContext.TptPeople.Where(o => o.FirstName == "BulkSync_Tpt_Add").OfType().Count(); + int customersUpdated = dbContext.TptPeople.Where(o => o.FirstName == "BulkSync_Tpt_Update").OfType().Count(); + int newCustomerTotal = dbContext.TptPeople.OfType().Count(); + + Assert.IsTrue(result.RowsAffected == customersAdded + customersToUpdate + customersToDelete, "The number of rows affected must match the sum of customers added, updated and deleted."); + Assert.IsTrue(result.RowsUpdated == customersToUpdate, "The number of rows updated must match"); + Assert.IsTrue(result.RowsInserted == customersToAdd, "The number of rows added must match"); + Assert.IsTrue(result.RowsDeleted == customersToDelete, "The number of rows deleted must match the difference from the total existing orders to the new orders to add/update"); + Assert.IsTrue(customersToAdd == customersAdded, "The custmoers that were added did not merge correctly"); + Assert.IsTrue(customersToUpdate == customersUpdated, "The customers that were updated did not merge correctly"); + Assert.IsTrue(newCustomerTotal == customersToAdd + customersToUpdate, "The count of customers in the database should match the sum of customers added and updated."); + } + [TestMethod] + public void With_Options_AutoMapIdentity() + { + var dbContext = SetupDbContext(true); + int oldTotal = dbContext.Orders.Count(); + int ordersToUpdate = 3; + int ordersToAdd = 2; + var orders = new List + { + new Order { ExternalId = "id-1", Price=7.10M }, + new Order { ExternalId = "id-2", Price=9.33M }, + new Order { ExternalId = "id-3", Price=3.25M }, + new Order { ExternalId = "id-1000001", Price=2.15M }, + new Order { ExternalId = "id-1000002", Price=5.75M }, + }; + var result = dbContext.BulkSync(orders, options => { options.MergeOnCondition = (s, t) => s.ExternalId == t.ExternalId; options.UsePermanentTable = true; }); + bool autoMapIdentityMatched = true; + foreach (var order in orders) + { + if (!dbContext.Orders.Any(o => o.ExternalId == order.ExternalId && o.Price == order.Price)) { - orders.Add(new Order { Id = 100000 + i, Price = 3.55M }); + autoMapIdentityMatched = false; + break; } - var result = dbContext.BulkSync(orders, new BulkSyncOptions - { - MergeOnCondition = (s, t) => s.ExternalId == t.ExternalId, - BatchSize = 1000 - }); - var newOrders = dbContext.Orders.OrderBy(o => o.Id).ToList(); - bool areAddedOrdersMerged = true; - bool areUpdatedOrdersMerged = true; - foreach (var newOrder in newOrders.Where(o => o.Id <= 100 && o.ExternalId != null).OrderBy(o => o.Id)) + } + + Assert.IsTrue(result.RowsAffected == oldTotal + ordersToAdd, "The number of rows inserted must match the count of order list"); + Assert.IsTrue(result.RowsUpdated == ordersToUpdate, "The number of rows updated must match"); + Assert.IsTrue(result.RowsInserted == ordersToAdd, "The number of rows added must match"); + Assert.IsTrue(result.RowsDeleted == oldTotal - orders.Count() + ordersToAdd, "The number of rows deleted must match the difference from the total existing orders to the new orders to add/update"); + Assert.IsTrue(autoMapIdentityMatched, "The auto mapping of ids of entities that were merged failed to match up"); + } + [TestMethod] + public void With_Options_MergeOnCondition() + { + var dbContext = SetupDbContext(true); + int oldTotal = dbContext.Orders.Count(); + var orders = dbContext.Orders.Where(o => o.Id <= 100 && o.ExternalId != null).OrderBy(o => o.Id).ToList(); + int ordersToAdd = 50; + int ordersToUpdate = orders.Count; + foreach (var order in orders) + { + order.Price = Convert.ToDecimal(order.Id + .25); + } + for (int i = 0; i < ordersToAdd; i++) + { + orders.Add(new Order { Id = 100000 + i, Price = 3.55M }); + } + var result = dbContext.BulkSync(orders, new BulkSyncOptions + { + MergeOnCondition = (s, t) => s.ExternalId == t.ExternalId, + BatchSize = 1000 + }); + var newOrders = dbContext.Orders.OrderBy(o => o.Id).ToList(); + bool areAddedOrdersMerged = true; + bool areUpdatedOrdersMerged = true; + foreach (var newOrder in newOrders.Where(o => o.Id <= 100 && o.ExternalId != null).OrderBy(o => o.Id)) + { + if (newOrder.Price != Convert.ToDecimal(newOrder.Id + .25)) { - if (newOrder.Price != Convert.ToDecimal(newOrder.Id + .25)) - { - areUpdatedOrdersMerged = false; - break; - } + areUpdatedOrdersMerged = false; + break; } - foreach (var newOrder in newOrders.Where(o => o.Id >= 500000).OrderBy(o => o.Id)) + } + foreach (var newOrder in newOrders.Where(o => o.Id >= 500000).OrderBy(o => o.Id)) + { + if (newOrder.Price != 3.55M) { - if (newOrder.Price != 3.55M) - { - areAddedOrdersMerged = false; - break; - } + areAddedOrdersMerged = false; + break; } - - Assert.IsTrue(result.RowsAffected == oldTotal + ordersToAdd, "The number of rows inserted must match the count of order list"); - Assert.IsTrue(result.RowsUpdated == ordersToUpdate, "The number of rows updated must match"); - Assert.IsTrue(result.RowsInserted == ordersToAdd, "The number of rows added must match"); - Assert.IsTrue(result.RowsDeleted == oldTotal - orders.Count() + ordersToAdd, "The number of rows deleted must match the difference from the total existing orders to the new orders to add/update"); - Assert.IsTrue(areAddedOrdersMerged, "The orders that were added did not merge correctly"); - Assert.IsTrue(areUpdatedOrdersMerged, "The orders that were updated did not merge correctly"); } + + Assert.IsTrue(result.RowsAffected == oldTotal + ordersToAdd, "The number of rows inserted must match the count of order list"); + Assert.IsTrue(result.RowsUpdated == ordersToUpdate, "The number of rows updated must match"); + Assert.IsTrue(result.RowsInserted == ordersToAdd, "The number of rows added must match"); + Assert.IsTrue(result.RowsDeleted == oldTotal - orders.Count() + ordersToAdd, "The number of rows deleted must match the difference from the total existing orders to the new orders to add/update"); + Assert.IsTrue(areAddedOrdersMerged, "The orders that were added did not merge correctly"); + Assert.IsTrue(areUpdatedOrdersMerged, "The orders that were updated did not merge correctly"); } } \ No newline at end of file diff --git a/N.EntityFrameworkCore.Extensions.Test/DbContextExtensions/BulkSyncAsync.cs b/N.EntityFrameworkCore.Extensions.Test/DbContextExtensions/BulkSyncAsync.cs index 9f10205..1108a0a 100644 --- a/N.EntityFrameworkCore.Extensions.Test/DbContextExtensions/BulkSyncAsync.cs +++ b/N.EntityFrameworkCore.Extensions.Test/DbContextExtensions/BulkSyncAsync.cs @@ -6,239 +6,238 @@ using Microsoft.VisualStudio.TestTools.UnitTesting; using N.EntityFrameworkCore.Extensions.Test.Data; -namespace N.EntityFrameworkCore.Extensions.Test.DbContextExtensions +namespace N.EntityFrameworkCore.Extensions.Test.DbContextExtensions; + +[TestClass] +public class BulkSyncAsync : DbContextExtensionsBase { - [TestClass] - public class BulkSyncAsync : DbContextExtensionsBase + [TestMethod] + public async Task With_Default_Options() { - [TestMethod] - public async Task With_Default_Options() - { - var dbContext = SetupDbContext(true); - int oldTotal = dbContext.Orders.Count(); - var orders = dbContext.Orders.Where(o => o.Id <= 10000).OrderBy(o => o.Id).ToList(); - int ordersToAdd = 5000; - int ordersToUpdate = orders.Count; - foreach (var order in orders) - { - order.Price = Convert.ToDecimal(order.Id + .25); - } - for (int i = 0; i < ordersToAdd; i++) - { - orders.Add(new Order { Id = 100000 + i, Price = 3.55M }); - } - var result = await dbContext.BulkSyncAsync(orders); - var newOrders = dbContext.Orders.OrderBy(o => o.Id).ToList(); - bool areAddedOrdersMerged = true; - bool areUpdatedOrdersMerged = true; - foreach (var newOrder in newOrders.Where(o => o.Id <= 10000).OrderBy(o => o.Id)) + var dbContext = SetupDbContext(true); + int oldTotal = dbContext.Orders.Count(); + var orders = dbContext.Orders.Where(o => o.Id <= 10000).OrderBy(o => o.Id).ToList(); + int ordersToAdd = 5000; + int ordersToUpdate = orders.Count; + foreach (var order in orders) + { + order.Price = Convert.ToDecimal(order.Id + .25); + } + for (int i = 0; i < ordersToAdd; i++) + { + orders.Add(new Order { Id = 100000 + i, Price = 3.55M }); + } + var result = await dbContext.BulkSyncAsync(orders); + var newOrders = dbContext.Orders.OrderBy(o => o.Id).ToList(); + bool areAddedOrdersMerged = true; + bool areUpdatedOrdersMerged = true; + foreach (var newOrder in newOrders.Where(o => o.Id <= 10000).OrderBy(o => o.Id)) + { + if (newOrder.Price != Convert.ToDecimal(newOrder.Id + .25)) { - if (newOrder.Price != Convert.ToDecimal(newOrder.Id + .25)) - { - areUpdatedOrdersMerged = false; - break; - } + areUpdatedOrdersMerged = false; + break; } - foreach (var newOrder in newOrders.Where(o => o.Id >= 500000).OrderBy(o => o.Id)) + } + foreach (var newOrder in newOrders.Where(o => o.Id >= 500000).OrderBy(o => o.Id)) + { + if (newOrder.Price != 3.55M) { - if (newOrder.Price != 3.55M) - { - areAddedOrdersMerged = false; - break; - } + areAddedOrdersMerged = false; + break; } - - Assert.IsTrue(result.RowsAffected == oldTotal + ordersToAdd, "The number of rows inserted must match the count of order list"); - Assert.IsTrue(result.RowsUpdated == ordersToUpdate, "The number of rows updated must match"); - Assert.IsTrue(result.RowsInserted == ordersToAdd, "The number of rows added must match"); - Assert.IsTrue(result.RowsDeleted == oldTotal - orders.Count() + ordersToAdd, "The number of rows deleted must match the difference from the total existing orders to the new orders to add/update"); - Assert.IsTrue(areAddedOrdersMerged, "The orders that were added did not merge correctly"); - Assert.IsTrue(areUpdatedOrdersMerged, "The orders that were updated did not merge correctly"); } - [TestMethod] - public async Task With_Inheritance_Tpc() - { - var dbContext = SetupDbContext(true, PopulateDataMode.Tpc); - var customers = await dbContext.TpcPeople.Where(o => o.Id <= 1000).OfType().ToListAsync(); - int customersToAdd = 5000; - int customersToUpdate = customers.Count; - int customersToDelete = dbContext.TpcPeople.OfType().Count() - customersToUpdate; - foreach (var customer in customers) - { - customer.FirstName = "BulkSync_Tpc_Update"; - } - for (int i = 0; i < customersToAdd; i++) - { - customers.Add(new TpcCustomer - { - Id = 10000 + i, - FirstName = "BulkSync_Tpc_Add", - AddedDate = DateTime.UtcNow - }); - } - var result = await dbContext.BulkSyncAsync(customers, options => { options.MergeOnCondition = (s, t) => s.Id == t.Id; }); - int customersAdded = dbContext.TpcPeople.Where(o => o.FirstName == "BulkSync_Tpc_Add").OfType().Count(); - int customersUpdated = dbContext.TpcPeople.Where(o => o.FirstName == "BulkSync_Tpc_Update").OfType().Count(); - int newCustomerTotal = dbContext.TpcPeople.OfType().Count(); + Assert.IsTrue(result.RowsAffected == oldTotal + ordersToAdd, "The number of rows inserted must match the count of order list"); + Assert.IsTrue(result.RowsUpdated == ordersToUpdate, "The number of rows updated must match"); + Assert.IsTrue(result.RowsInserted == ordersToAdd, "The number of rows added must match"); + Assert.IsTrue(result.RowsDeleted == oldTotal - orders.Count() + ordersToAdd, "The number of rows deleted must match the difference from the total existing orders to the new orders to add/update"); + Assert.IsTrue(areAddedOrdersMerged, "The orders that were added did not merge correctly"); + Assert.IsTrue(areUpdatedOrdersMerged, "The orders that were updated did not merge correctly"); + } + [TestMethod] + public async Task With_Inheritance_Tpc() + { + var dbContext = SetupDbContext(true, PopulateDataMode.Tpc); + var customers = await dbContext.TpcPeople.Where(o => o.Id <= 1000).OfType().ToListAsync(); + int customersToAdd = 5000; + int customersToUpdate = customers.Count; + int customersToDelete = dbContext.TpcPeople.OfType().Count() - customersToUpdate; - Assert.IsTrue(result.RowsAffected == customersAdded + customersToUpdate + customersToDelete, "The number of rows affected must match the sum of customers added, updated and deleted."); - Assert.IsTrue(result.RowsUpdated == customersToUpdate, "The number of rows updated must match"); - Assert.IsTrue(result.RowsInserted == customersToAdd, "The number of rows added must match"); - Assert.IsTrue(result.RowsDeleted == customersToDelete, "The number of rows deleted must match the difference from the total existing orders to the new orders to add/update"); - Assert.IsTrue(customersToAdd == customersAdded, "The custmoers that were added did not merge correctly"); - Assert.IsTrue(customersToUpdate == customersUpdated, "The customers that were updated did not merge correctly"); - Assert.IsTrue(newCustomerTotal == customersToAdd + customersToUpdate, "The count of customers in the database should match the sum of customers added and updated."); + foreach (var customer in customers) + { + customer.FirstName = "BulkSync_Tpc_Update"; } - [TestMethod] - public async Task With_Inheritance_Tph() - { - var dbContext = SetupDbContext(true, PopulateDataMode.Tph); - var customers = await dbContext.TphCustomers.Where(o => o.Id <= 1000).ToListAsync(); - int customersToAdd = 5000; - int customersToUpdate = customers.Count; - int customersToDelete = dbContext.TphPeople.Count() - customersToUpdate; - - foreach (var customer in customers) - { - customer.FirstName = "BulkSync_Tph_Update"; - } - for (int i = 0; i < customersToAdd; i++) + for (int i = 0; i < customersToAdd; i++) + { + customers.Add(new TpcCustomer { - customers.Add(new TphCustomer - { - Id = 10000 + i, - FirstName = "BulkSync_Tph_Add", - AddedDate = DateTime.UtcNow - }); - } - var result = await dbContext.BulkSyncAsync(customers, options => { options.UsePermanentTable = true; options.MergeOnCondition = (s, t) => s.Id == t.Id; }); - int customersAdded = dbContext.TphCustomers.Where(o => o.FirstName == "BulkSync_Tph_Add").Count(); - int customersUpdated = dbContext.TphCustomers.Where(o => o.FirstName == "BulkSync_Tph_Update").Count(); - int newCustomerTotal = dbContext.TphCustomers.Count(); - - Assert.IsTrue(result.RowsAffected == customersAdded + customersToUpdate + customersToDelete, "The number of rows affected must match the sum of customers added, updated and deleted."); - Assert.IsTrue(result.RowsUpdated == customersToUpdate, "The number of rows updated must match"); - Assert.IsTrue(result.RowsInserted == customersToAdd, "The number of rows added must match"); - Assert.IsTrue(result.RowsDeleted == customersToDelete, "The number of rows deleted must match the difference from the total existing orders to the new orders to add/update"); - Assert.IsTrue(customersToAdd == customersAdded, "The customers that were added did not merge correctly"); - Assert.IsTrue(customersToUpdate == customersUpdated, "The customers that were updated did not merge correctly"); - Assert.IsTrue(newCustomerTotal == customersToAdd + customersToUpdate, "The count of customers in the database should match the sum of customers added and updated."); + Id = 10000 + i, + FirstName = "BulkSync_Tpc_Add", + AddedDate = DateTime.UtcNow + }); } - [TestMethod] - public async Task With_Inheritance_Tpt() - { - var dbContext = SetupDbContext(true, PopulateDataMode.Tpt); - var customers = await dbContext.TptPeople.Where(o => o.Id <= 1000).OfType().ToListAsync(); - int customersToAdd = 5000; - int customersToUpdate = customers.Count; - int customersToDelete = dbContext.TptCustomers.Count() - customersToUpdate; + var result = await dbContext.BulkSyncAsync(customers, options => { options.MergeOnCondition = (s, t) => s.Id == t.Id; }); + int customersAdded = dbContext.TpcPeople.Where(o => o.FirstName == "BulkSync_Tpc_Add").OfType().Count(); + int customersUpdated = dbContext.TpcPeople.Where(o => o.FirstName == "BulkSync_Tpc_Update").OfType().Count(); + int newCustomerTotal = dbContext.TpcPeople.OfType().Count(); - foreach (var customer in customers) - { - customer.FirstName = "BulkSync_Tpt_Update"; - } - for (int i = 0; i < customersToAdd; i++) - { - customers.Add(new TptCustomer - { - Id = 10000 + i, - FirstName = "BulkSync_Tpt_Add", - AddedDate = DateTime.UtcNow - }); - } - var result = await dbContext.BulkSyncAsync(customers, options => { options.MergeOnCondition = (s, t) => s.Id == t.Id; }); - int customersAdded = dbContext.TptPeople.Where(o => o.FirstName == "BulkSync_Tpt_Add").OfType().Count(); - int customersUpdated = dbContext.TptPeople.Where(o => o.FirstName == "BulkSync_Tpt_Update").OfType().Count(); - int newCustomerTotal = dbContext.TptPeople.OfType().Count(); + Assert.IsTrue(result.RowsAffected == customersAdded + customersToUpdate + customersToDelete, "The number of rows affected must match the sum of customers added, updated and deleted."); + Assert.IsTrue(result.RowsUpdated == customersToUpdate, "The number of rows updated must match"); + Assert.IsTrue(result.RowsInserted == customersToAdd, "The number of rows added must match"); + Assert.IsTrue(result.RowsDeleted == customersToDelete, "The number of rows deleted must match the difference from the total existing orders to the new orders to add/update"); + Assert.IsTrue(customersToAdd == customersAdded, "The custmoers that were added did not merge correctly"); + Assert.IsTrue(customersToUpdate == customersUpdated, "The customers that were updated did not merge correctly"); + Assert.IsTrue(newCustomerTotal == customersToAdd + customersToUpdate, "The count of customers in the database should match the sum of customers added and updated."); + } + [TestMethod] + public async Task With_Inheritance_Tph() + { + var dbContext = SetupDbContext(true, PopulateDataMode.Tph); + var customers = await dbContext.TphCustomers.Where(o => o.Id <= 1000).ToListAsync(); + int customersToAdd = 5000; + int customersToUpdate = customers.Count; + int customersToDelete = dbContext.TphPeople.Count() - customersToUpdate; - Assert.IsTrue(result.RowsAffected == customersAdded + customersToUpdate + customersToDelete, "The number of rows affected must match the sum of customers added, updated and deleted."); - Assert.IsTrue(result.RowsUpdated == customersToUpdate, "The number of rows updated must match"); - Assert.IsTrue(result.RowsInserted == customersToAdd, "The number of rows added must match"); - Assert.IsTrue(result.RowsDeleted == customersToDelete, "The number of rows deleted must match the difference from the total existing orders to the new orders to add/update"); - Assert.IsTrue(customersToAdd == customersAdded, "The custmoers that were added did not merge correctly"); - Assert.IsTrue(customersToUpdate == customersUpdated, "The customers that were updated did not merge correctly"); - Assert.IsTrue(newCustomerTotal == customersToAdd + customersToUpdate, "The count of customers in the database should match the sum of customers added and updated."); + foreach (var customer in customers) + { + customer.FirstName = "BulkSync_Tph_Update"; } - [TestMethod] - public async Task With_Options_AutoMapIdentity() - { - var dbContext = SetupDbContext(true); - int oldTotal = dbContext.Orders.Count(); - int ordersToUpdate = 3; - int ordersToAdd = 2; - var orders = new List - { - new Order { ExternalId = "id-1", Price=7.10M }, - new Order { ExternalId = "id-2", Price=9.33M }, - new Order { ExternalId = "id-3", Price=3.25M }, - new Order { ExternalId = "id-1000001", Price=2.15M }, - new Order { ExternalId = "id-1000002", Price=5.75M }, - }; - var result = await dbContext.BulkSyncAsync(orders, options => { options.MergeOnCondition = (s, t) => s.ExternalId == t.ExternalId; options.UsePermanentTable = true; }); - bool autoMapIdentityMatched = true; - foreach (var order in orders) + for (int i = 0; i < customersToAdd; i++) + { + customers.Add(new TphCustomer { - if (!dbContext.Orders.Any(o => o.ExternalId == order.ExternalId && o.Price == order.Price)) - { - autoMapIdentityMatched = false; - break; - } - } + Id = 10000 + i, + FirstName = "BulkSync_Tph_Add", + AddedDate = DateTime.UtcNow + }); + } + var result = await dbContext.BulkSyncAsync(customers, options => { options.UsePermanentTable = true; options.MergeOnCondition = (s, t) => s.Id == t.Id; }); + int customersAdded = dbContext.TphCustomers.Where(o => o.FirstName == "BulkSync_Tph_Add").Count(); + int customersUpdated = dbContext.TphCustomers.Where(o => o.FirstName == "BulkSync_Tph_Update").Count(); + int newCustomerTotal = dbContext.TphCustomers.Count(); - Assert.IsTrue(result.RowsAffected == oldTotal + ordersToAdd, "The number of rows inserted must match the count of order list"); - Assert.IsTrue(result.RowsUpdated == ordersToUpdate, "The number of rows updated must match"); - Assert.IsTrue(result.RowsInserted == ordersToAdd, "The number of rows added must match"); - Assert.IsTrue(result.RowsDeleted == oldTotal - orders.Count() + ordersToAdd, "The number of rows deleted must match the difference from the total existing orders to the new orders to add/update"); - Assert.IsTrue(autoMapIdentityMatched, "The auto mapping of ids of entities that were merged failed to match up"); + Assert.IsTrue(result.RowsAffected == customersAdded + customersToUpdate + customersToDelete, "The number of rows affected must match the sum of customers added, updated and deleted."); + Assert.IsTrue(result.RowsUpdated == customersToUpdate, "The number of rows updated must match"); + Assert.IsTrue(result.RowsInserted == customersToAdd, "The number of rows added must match"); + Assert.IsTrue(result.RowsDeleted == customersToDelete, "The number of rows deleted must match the difference from the total existing orders to the new orders to add/update"); + Assert.IsTrue(customersToAdd == customersAdded, "The customers that were added did not merge correctly"); + Assert.IsTrue(customersToUpdate == customersUpdated, "The customers that were updated did not merge correctly"); + Assert.IsTrue(newCustomerTotal == customersToAdd + customersToUpdate, "The count of customers in the database should match the sum of customers added and updated."); + } + [TestMethod] + public async Task With_Inheritance_Tpt() + { + var dbContext = SetupDbContext(true, PopulateDataMode.Tpt); + var customers = await dbContext.TptPeople.Where(o => o.Id <= 1000).OfType().ToListAsync(); + int customersToAdd = 5000; + int customersToUpdate = customers.Count; + int customersToDelete = dbContext.TptCustomers.Count() - customersToUpdate; + + foreach (var customer in customers) + { + customer.FirstName = "BulkSync_Tpt_Update"; } - [TestMethod] - public async Task With_Options_MergeOnCondition() - { - var dbContext = SetupDbContext(true); - int oldTotal = dbContext.Orders.Count(); - var orders = dbContext.Orders.Where(o => o.Id <= 100 && o.ExternalId != null).OrderBy(o => o.Id).ToList(); - int ordersToAdd = 50; - int ordersToUpdate = orders.Count; - foreach (var order in orders) + for (int i = 0; i < customersToAdd; i++) + { + customers.Add(new TptCustomer { - order.Price = Convert.ToDecimal(order.Id + .25); - } - for (int i = 0; i < ordersToAdd; i++) + Id = 10000 + i, + FirstName = "BulkSync_Tpt_Add", + AddedDate = DateTime.UtcNow + }); + } + var result = await dbContext.BulkSyncAsync(customers, options => { options.MergeOnCondition = (s, t) => s.Id == t.Id; }); + int customersAdded = dbContext.TptPeople.Where(o => o.FirstName == "BulkSync_Tpt_Add").OfType().Count(); + int customersUpdated = dbContext.TptPeople.Where(o => o.FirstName == "BulkSync_Tpt_Update").OfType().Count(); + int newCustomerTotal = dbContext.TptPeople.OfType().Count(); + + Assert.IsTrue(result.RowsAffected == customersAdded + customersToUpdate + customersToDelete, "The number of rows affected must match the sum of customers added, updated and deleted."); + Assert.IsTrue(result.RowsUpdated == customersToUpdate, "The number of rows updated must match"); + Assert.IsTrue(result.RowsInserted == customersToAdd, "The number of rows added must match"); + Assert.IsTrue(result.RowsDeleted == customersToDelete, "The number of rows deleted must match the difference from the total existing orders to the new orders to add/update"); + Assert.IsTrue(customersToAdd == customersAdded, "The custmoers that were added did not merge correctly"); + Assert.IsTrue(customersToUpdate == customersUpdated, "The customers that were updated did not merge correctly"); + Assert.IsTrue(newCustomerTotal == customersToAdd + customersToUpdate, "The count of customers in the database should match the sum of customers added and updated."); + } + [TestMethod] + public async Task With_Options_AutoMapIdentity() + { + var dbContext = SetupDbContext(true); + int oldTotal = dbContext.Orders.Count(); + int ordersToUpdate = 3; + int ordersToAdd = 2; + var orders = new List + { + new Order { ExternalId = "id-1", Price=7.10M }, + new Order { ExternalId = "id-2", Price=9.33M }, + new Order { ExternalId = "id-3", Price=3.25M }, + new Order { ExternalId = "id-1000001", Price=2.15M }, + new Order { ExternalId = "id-1000002", Price=5.75M }, + }; + var result = await dbContext.BulkSyncAsync(orders, options => { options.MergeOnCondition = (s, t) => s.ExternalId == t.ExternalId; options.UsePermanentTable = true; }); + bool autoMapIdentityMatched = true; + foreach (var order in orders) + { + if (!dbContext.Orders.Any(o => o.ExternalId == order.ExternalId && o.Price == order.Price)) { - orders.Add(new Order { Id = 100000 + i, Price = 3.55M }); + autoMapIdentityMatched = false; + break; } - var result = await dbContext.BulkSyncAsync(orders, new BulkSyncOptions - { - MergeOnCondition = (s, t) => s.ExternalId == t.ExternalId, - BatchSize = 1000 - }); - var newOrders = dbContext.Orders.OrderBy(o => o.Id).ToList(); - bool areAddedOrdersMerged = true; - bool areUpdatedOrdersMerged = true; - foreach (var newOrder in newOrders.Where(o => o.Id <= 100 && o.ExternalId != null).OrderBy(o => o.Id)) + } + + Assert.IsTrue(result.RowsAffected == oldTotal + ordersToAdd, "The number of rows inserted must match the count of order list"); + Assert.IsTrue(result.RowsUpdated == ordersToUpdate, "The number of rows updated must match"); + Assert.IsTrue(result.RowsInserted == ordersToAdd, "The number of rows added must match"); + Assert.IsTrue(result.RowsDeleted == oldTotal - orders.Count() + ordersToAdd, "The number of rows deleted must match the difference from the total existing orders to the new orders to add/update"); + Assert.IsTrue(autoMapIdentityMatched, "The auto mapping of ids of entities that were merged failed to match up"); + } + [TestMethod] + public async Task With_Options_MergeOnCondition() + { + var dbContext = SetupDbContext(true); + int oldTotal = dbContext.Orders.Count(); + var orders = dbContext.Orders.Where(o => o.Id <= 100 && o.ExternalId != null).OrderBy(o => o.Id).ToList(); + int ordersToAdd = 50; + int ordersToUpdate = orders.Count; + foreach (var order in orders) + { + order.Price = Convert.ToDecimal(order.Id + .25); + } + for (int i = 0; i < ordersToAdd; i++) + { + orders.Add(new Order { Id = 100000 + i, Price = 3.55M }); + } + var result = await dbContext.BulkSyncAsync(orders, new BulkSyncOptions + { + MergeOnCondition = (s, t) => s.ExternalId == t.ExternalId, + BatchSize = 1000 + }); + var newOrders = dbContext.Orders.OrderBy(o => o.Id).ToList(); + bool areAddedOrdersMerged = true; + bool areUpdatedOrdersMerged = true; + foreach (var newOrder in newOrders.Where(o => o.Id <= 100 && o.ExternalId != null).OrderBy(o => o.Id)) + { + if (newOrder.Price != Convert.ToDecimal(newOrder.Id + .25)) { - if (newOrder.Price != Convert.ToDecimal(newOrder.Id + .25)) - { - areUpdatedOrdersMerged = false; - break; - } + areUpdatedOrdersMerged = false; + break; } - foreach (var newOrder in newOrders.Where(o => o.Id >= 500000).OrderBy(o => o.Id)) + } + foreach (var newOrder in newOrders.Where(o => o.Id >= 500000).OrderBy(o => o.Id)) + { + if (newOrder.Price != 3.55M) { - if (newOrder.Price != 3.55M) - { - areAddedOrdersMerged = false; - break; - } + areAddedOrdersMerged = false; + break; } - - Assert.IsTrue(result.RowsAffected == oldTotal + ordersToAdd, "The number of rows inserted must match the count of order list"); - Assert.IsTrue(result.RowsUpdated == ordersToUpdate, "The number of rows updated must match"); - Assert.IsTrue(result.RowsInserted == ordersToAdd, "The number of rows added must match"); - Assert.IsTrue(result.RowsDeleted == oldTotal - orders.Count() + ordersToAdd, "The number of rows deleted must match the difference from the total existing orders to the new orders to add/update"); - Assert.IsTrue(areAddedOrdersMerged, "The orders that were added did not merge correctly"); - Assert.IsTrue(areUpdatedOrdersMerged, "The orders that were updated did not merge correctly"); } + + Assert.IsTrue(result.RowsAffected == oldTotal + ordersToAdd, "The number of rows inserted must match the count of order list"); + Assert.IsTrue(result.RowsUpdated == ordersToUpdate, "The number of rows updated must match"); + Assert.IsTrue(result.RowsInserted == ordersToAdd, "The number of rows added must match"); + Assert.IsTrue(result.RowsDeleted == oldTotal - orders.Count() + ordersToAdd, "The number of rows deleted must match the difference from the total existing orders to the new orders to add/update"); + Assert.IsTrue(areAddedOrdersMerged, "The orders that were added did not merge correctly"); + Assert.IsTrue(areUpdatedOrdersMerged, "The orders that were updated did not merge correctly"); } } \ No newline at end of file diff --git a/N.EntityFrameworkCore.Extensions.Test/DbContextExtensions/BulkUpdate.cs b/N.EntityFrameworkCore.Extensions.Test/DbContextExtensions/BulkUpdate.cs index 028d462..fbcd228 100644 --- a/N.EntityFrameworkCore.Extensions.Test/DbContextExtensions/BulkUpdate.cs +++ b/N.EntityFrameworkCore.Extensions.Test/DbContextExtensions/BulkUpdate.cs @@ -6,242 +6,241 @@ using Microsoft.VisualStudio.TestTools.UnitTesting; using N.EntityFrameworkCore.Extensions.Test.Data; -namespace N.EntityFrameworkCore.Extensions.Test.DbContextExtensions +namespace N.EntityFrameworkCore.Extensions.Test.DbContextExtensions; + +[TestClass] +public class BulkUpdate : DbContextExtensionsBase { - [TestClass] - public class BulkUpdate : DbContextExtensionsBase + [TestMethod] + public void With_ComplexKey() { - [TestMethod] - public void With_ComplexKey() + var dbContext = SetupDbContext(true); + var products = dbContext.ProductsWithComplexKey.Where(o => o.Price == 1.25M).ToList(); + foreach (var product in products) { - var dbContext = SetupDbContext(true); - var products = dbContext.ProductsWithComplexKey.Where(o => o.Price == 1.25M).ToList(); - foreach (var product in products) - { - product.Price = 2.35M; - } - var oldTotal = dbContext.ProductsWithComplexKey.Where(o => o.Price == 2.35M).Count(); - int rowsUpdated = dbContext.BulkUpdate(products); - var newTotal = dbContext.ProductsWithComplexKey.Where(o => o.Price == 2.35M).Count(); - - Assert.IsTrue(products.Count > 0, "There must be orders in database that match this condition (Price = $1.25)"); - Assert.IsTrue(rowsUpdated == products.Count, "The number of rows updated must match the count of entities that were retrieved"); - Assert.IsTrue(newTotal == rowsUpdated + oldTotal, "The count of new orders must be equal the number of rows updated in the database."); + product.Price = 2.35M; } - [TestMethod] - public void With_Default_Options() - { - var dbContext = SetupDbContext(true); - var orders = dbContext.Orders.Where(o => o.Price == 1.25M).OrderBy(o => o.Id).ToList(); - long maxId = 0; - foreach (var order in orders) - { - order.Price = 2.35M; - maxId = order.Id; - } - int rowsUpdated = dbContext.BulkUpdate(orders); - var newOrders = dbContext.Orders.Where(o => o.Price == 2.35M).OrderBy(o => o.Id).Count(); - int entitiesWithChanges = dbContext.ChangeTracker.Entries().Where(t => t.State == EntityState.Modified).Count(); + var oldTotal = dbContext.ProductsWithComplexKey.Where(o => o.Price == 2.35M).Count(); + int rowsUpdated = dbContext.BulkUpdate(products); + var newTotal = dbContext.ProductsWithComplexKey.Where(o => o.Price == 2.35M).Count(); - Assert.IsTrue(orders.Count > 0, "There must be orders in database that match this condition (Price = $1.25)"); - Assert.IsTrue(rowsUpdated == orders.Count, "The number of rows updated must match the count of entities that were retrieved"); - Assert.IsTrue(newOrders == rowsUpdated, "The count of new orders must be equal the number of rows updated in the database."); - } - [TestMethod] - public void With_Inheritance_Tpc() + Assert.IsTrue(products.Count > 0, "There must be orders in database that match this condition (Price = $1.25)"); + Assert.IsTrue(rowsUpdated == products.Count, "The number of rows updated must match the count of entities that were retrieved"); + Assert.IsTrue(newTotal == rowsUpdated + oldTotal, "The count of new orders must be equal the number of rows updated in the database."); + } + [TestMethod] + public void With_Default_Options() + { + var dbContext = SetupDbContext(true); + var orders = dbContext.Orders.Where(o => o.Price == 1.25M).OrderBy(o => o.Id).ToList(); + long maxId = 0; + foreach (var order in orders) { - var dbContext = SetupDbContext(true, PopulateDataMode.Tpc); - var customers = dbContext.TpcPeople.Where(o => o.LastName != "BulkUpdate_Tpc").OfType().ToList(); - var vendors = dbContext.TpcPeople.OfType().ToList(); - foreach (var customer in customers) - { - customer.FirstName = string.Format("Id={0}", customer.Id); - customer.LastName = "BulkUpdate_Tpc"; - } - int rowsUpdated = dbContext.BulkUpdate(customers); - var newCustomers = dbContext.TpcPeople.Where(o => o.LastName == "BulkUpdate_Tpc").OfType().Count(); - int entitiesWithChanges = dbContext.ChangeTracker.Entries().Where(t => t.State == EntityState.Modified).Count(); - - Assert.IsTrue(vendors.Count > 0 && vendors.Count != customers.Count, "There should be vendor records in the database"); - Assert.IsTrue(customers.Count > 0, "There must be customers in database that match this condition (Price = $1.25)"); - Assert.IsTrue(rowsUpdated == customers.Count, "The number of rows updated must match the count of entities that were retrieved"); - Assert.IsTrue(newCustomers == rowsUpdated, "The count of new customers must be equal the number of rows updated in the database."); + order.Price = 2.35M; + maxId = order.Id; } - [TestMethod] - public void With_Inheritance_Tph() - { - var dbContext = SetupDbContext(true, PopulateDataMode.Tph); - var customers = dbContext.TphPeople.Where(o => o.LastName != "BulkUpdateTest").OfType().ToList(); - var vendors = dbContext.TphPeople.OfType().ToList(); - foreach (var customer in customers) - { - customer.FirstName = string.Format("Id={0}", customer.Id); - customer.LastName = "BulkUpdateTest"; - } - int rowsUpdated = dbContext.BulkUpdate(customers); - var newCustomers = dbContext.TphPeople.Where(o => o.LastName == "BulkUpdateTest").OrderBy(o => o.Id).Count(); - int entitiesWithChanges = dbContext.ChangeTracker.Entries().Where(t => t.State == EntityState.Modified).Count(); + int rowsUpdated = dbContext.BulkUpdate(orders); + var newOrders = dbContext.Orders.Where(o => o.Price == 2.35M).OrderBy(o => o.Id).Count(); + int entitiesWithChanges = dbContext.ChangeTracker.Entries().Where(t => t.State == EntityState.Modified).Count(); - Assert.IsTrue(vendors.Count > 0 && vendors.Count != customers.Count, "There should be vendor records in the database"); - Assert.IsTrue(customers.Count > 0, "There must be customers in database that match this condition (Price = $1.25)"); - Assert.IsTrue(rowsUpdated == customers.Count, "The number of rows updated must match the count of entities that were retrieved"); - Assert.IsTrue(newCustomers == rowsUpdated, "The count of new customers must be equal the number of rows updated in the database."); - } - [TestMethod] - public void With_Inheritance_Tpt() + Assert.IsTrue(orders.Count > 0, "There must be orders in database that match this condition (Price = $1.25)"); + Assert.IsTrue(rowsUpdated == orders.Count, "The number of rows updated must match the count of entities that were retrieved"); + Assert.IsTrue(newOrders == rowsUpdated, "The count of new orders must be equal the number of rows updated in the database."); + } + [TestMethod] + public void With_Inheritance_Tpc() + { + var dbContext = SetupDbContext(true, PopulateDataMode.Tpc); + var customers = dbContext.TpcPeople.Where(o => o.LastName != "BulkUpdate_Tpc").OfType().ToList(); + var vendors = dbContext.TpcPeople.OfType().ToList(); + foreach (var customer in customers) { - var dbContext = SetupDbContext(true, PopulateDataMode.Tpt); - var customers = dbContext.TptCustomers.Where(o => o.LastName != "BulkUpdateTest").ToList(); - foreach (var customer in customers) - { - customer.FirstName = string.Format("Id={0}", customer.Id); - customer.LastName = "BulkUpdateTest"; - } - int rowsUpdated = dbContext.BulkUpdate(customers); - var newCustomers = dbContext.TptCustomers.Where(o => o.LastName == "BulkUpdateTest").OrderBy(o => o.Id).Count(); - //int entitiesWithChanges = dbContext.ChangeTracker.Entries().Where(t => t.State == EntityState.Modified).Count(); - - Assert.IsTrue(customers.Count > 0, "There must be customers in database that match this condition (Price = $1.25)"); - Assert.IsTrue(rowsUpdated == customers.Count, "The number of rows updated must match the count of entities that were retrieved"); - Assert.IsTrue(newCustomers == rowsUpdated, "The count of new customers must be equal the number of rows updated in the database."); + customer.FirstName = string.Format("Id={0}", customer.Id); + customer.LastName = "BulkUpdate_Tpc"; } - [TestMethod] - public void With_Options_InputColumns_PropertyExpression() - { - var dbContext = SetupDbContext(true); - var orders = dbContext.Orders.Where(o => o.Price == 1.25M && o.ExternalId != null).OrderBy(o => o.Id).ToList(); - foreach (var order in orders) - { - order.Price = 2.35M; - order.ExternalId = null; - } - var oldTotal = dbContext.Orders.Where(o => o.Price == 2.35M && o.ExternalId != null).Count(); - int rowsUpdated = dbContext.BulkUpdate(orders, options => { options.InputColumns = o => o.Price; }); - var newTotal1 = dbContext.Orders.Where(o => o.Price == 2.35M && o.ExternalId != null).Count(); - var newTotal2 = dbContext.Orders.Where(o => o.Price == 1.25M && o.ExternalId != null).Count(); + int rowsUpdated = dbContext.BulkUpdate(customers); + var newCustomers = dbContext.TpcPeople.Where(o => o.LastName == "BulkUpdate_Tpc").OfType().Count(); + int entitiesWithChanges = dbContext.ChangeTracker.Entries().Where(t => t.State == EntityState.Modified).Count(); - Assert.IsTrue(orders.Count > 0, "There must be orders in database that match this condition (Price = $1.25)"); - Assert.IsTrue(newTotal1 == rowsUpdated + oldTotal, "The count of new orders must be equal the number of rows updated in the database."); - Assert.IsTrue(newTotal2 == 0, "There should be not records with condition (Price = $1.25)"); - } - [TestMethod] - public void With_Options_InputColumns_NewExpression() + Assert.IsTrue(vendors.Count > 0 && vendors.Count != customers.Count, "There should be vendor records in the database"); + Assert.IsTrue(customers.Count > 0, "There must be customers in database that match this condition (Price = $1.25)"); + Assert.IsTrue(rowsUpdated == customers.Count, "The number of rows updated must match the count of entities that were retrieved"); + Assert.IsTrue(newCustomers == rowsUpdated, "The count of new customers must be equal the number of rows updated in the database."); + } + [TestMethod] + public void With_Inheritance_Tph() + { + var dbContext = SetupDbContext(true, PopulateDataMode.Tph); + var customers = dbContext.TphPeople.Where(o => o.LastName != "BulkUpdateTest").OfType().ToList(); + var vendors = dbContext.TphPeople.OfType().ToList(); + foreach (var customer in customers) { - var dbContext = SetupDbContext(true); - var orders = dbContext.Orders.Where(o => o.Price == 1.25M && o.ExternalId != null).OrderBy(o => o.Id).ToList(); - foreach (var order in orders) - { - order.Price = 2.35M; - order.ExternalId = null; - } - var oldTotal = dbContext.Orders.Where(o => o.Price == 2.35M && o.ExternalId != null).Count(); - int rowsUpdated = dbContext.BulkUpdate(orders, options => { options.InputColumns = o => new { o.Price }; }); - var newTotal1 = dbContext.Orders.Where(o => o.Price == 2.35M && o.ExternalId != null).Count(); - var newTotal2 = dbContext.Orders.Where(o => o.Price == 1.25M && o.ExternalId != null).Count(); + customer.FirstName = string.Format("Id={0}", customer.Id); + customer.LastName = "BulkUpdateTest"; + } + int rowsUpdated = dbContext.BulkUpdate(customers); + var newCustomers = dbContext.TphPeople.Where(o => o.LastName == "BulkUpdateTest").OrderBy(o => o.Id).Count(); + int entitiesWithChanges = dbContext.ChangeTracker.Entries().Where(t => t.State == EntityState.Modified).Count(); - Assert.IsTrue(orders.Count > 0, "There must be orders in database that match this condition (Price = $1.25)"); - Assert.IsTrue(newTotal1 == rowsUpdated + oldTotal, "The count of new orders must be equal the number of rows updated in the database."); - Assert.IsTrue(newTotal2 == 0, "There should be not records with condition (Price = $1.25)"); + Assert.IsTrue(vendors.Count > 0 && vendors.Count != customers.Count, "There should be vendor records in the database"); + Assert.IsTrue(customers.Count > 0, "There must be customers in database that match this condition (Price = $1.25)"); + Assert.IsTrue(rowsUpdated == customers.Count, "The number of rows updated must match the count of entities that were retrieved"); + Assert.IsTrue(newCustomers == rowsUpdated, "The count of new customers must be equal the number of rows updated in the database."); + } + [TestMethod] + public void With_Inheritance_Tpt() + { + var dbContext = SetupDbContext(true, PopulateDataMode.Tpt); + var customers = dbContext.TptCustomers.Where(o => o.LastName != "BulkUpdateTest").ToList(); + foreach (var customer in customers) + { + customer.FirstName = string.Format("Id={0}", customer.Id); + customer.LastName = "BulkUpdateTest"; } - [TestMethod] - public void With_Options_IgnoreColumns_PropertyExpression() + int rowsUpdated = dbContext.BulkUpdate(customers); + var newCustomers = dbContext.TptCustomers.Where(o => o.LastName == "BulkUpdateTest").OrderBy(o => o.Id).Count(); + //int entitiesWithChanges = dbContext.ChangeTracker.Entries().Where(t => t.State == EntityState.Modified).Count(); + + Assert.IsTrue(customers.Count > 0, "There must be customers in database that match this condition (Price = $1.25)"); + Assert.IsTrue(rowsUpdated == customers.Count, "The number of rows updated must match the count of entities that were retrieved"); + Assert.IsTrue(newCustomers == rowsUpdated, "The count of new customers must be equal the number of rows updated in the database."); + } + [TestMethod] + public void With_Options_InputColumns_PropertyExpression() + { + var dbContext = SetupDbContext(true); + var orders = dbContext.Orders.Where(o => o.Price == 1.25M && o.ExternalId != null).OrderBy(o => o.Id).ToList(); + foreach (var order in orders) { - var dbContext = SetupDbContext(true); - var orders = dbContext.Orders.Where(o => o.Price == 1.25M && o.ExternalId != null).OrderBy(o => o.Id).ToList(); - foreach (var order in orders) - { - order.Price = 2.35M; - order.ExternalId = null; - } - var oldTotal = dbContext.Orders.Where(o => o.Price == 2.35M && o.ExternalId != null).Count(); - int rowsUpdated = dbContext.BulkUpdate(orders, options => { options.IgnoreColumns = o => o.ExternalId; }); - var newTotal1 = dbContext.Orders.Where(o => o.Price == 2.35M && o.ExternalId != null).Count(); - var newTotal2 = dbContext.Orders.Where(o => o.Price == 1.25M && o.ExternalId != null).Count(); + order.Price = 2.35M; + order.ExternalId = null; + } + var oldTotal = dbContext.Orders.Where(o => o.Price == 2.35M && o.ExternalId != null).Count(); + int rowsUpdated = dbContext.BulkUpdate(orders, options => { options.InputColumns = o => o.Price; }); + var newTotal1 = dbContext.Orders.Where(o => o.Price == 2.35M && o.ExternalId != null).Count(); + var newTotal2 = dbContext.Orders.Where(o => o.Price == 1.25M && o.ExternalId != null).Count(); - Assert.IsTrue(orders.Count > 0, "There must be orders in database that match this condition (Price = $1.25)"); - Assert.IsTrue(newTotal1 == rowsUpdated + oldTotal, "The count of new orders must be equal the number of rows updated in the database."); - Assert.IsTrue(newTotal2 == 0, "There should be not records with condition (Price = $1.25)"); + Assert.IsTrue(orders.Count > 0, "There must be orders in database that match this condition (Price = $1.25)"); + Assert.IsTrue(newTotal1 == rowsUpdated + oldTotal, "The count of new orders must be equal the number of rows updated in the database."); + Assert.IsTrue(newTotal2 == 0, "There should be not records with condition (Price = $1.25)"); + } + [TestMethod] + public void With_Options_InputColumns_NewExpression() + { + var dbContext = SetupDbContext(true); + var orders = dbContext.Orders.Where(o => o.Price == 1.25M && o.ExternalId != null).OrderBy(o => o.Id).ToList(); + foreach (var order in orders) + { + order.Price = 2.35M; + order.ExternalId = null; } - [TestMethod] - public void With_Options_IgnoreColumns_NewExpression() + var oldTotal = dbContext.Orders.Where(o => o.Price == 2.35M && o.ExternalId != null).Count(); + int rowsUpdated = dbContext.BulkUpdate(orders, options => { options.InputColumns = o => new { o.Price }; }); + var newTotal1 = dbContext.Orders.Where(o => o.Price == 2.35M && o.ExternalId != null).Count(); + var newTotal2 = dbContext.Orders.Where(o => o.Price == 1.25M && o.ExternalId != null).Count(); + + Assert.IsTrue(orders.Count > 0, "There must be orders in database that match this condition (Price = $1.25)"); + Assert.IsTrue(newTotal1 == rowsUpdated + oldTotal, "The count of new orders must be equal the number of rows updated in the database."); + Assert.IsTrue(newTotal2 == 0, "There should be not records with condition (Price = $1.25)"); + } + [TestMethod] + public void With_Options_IgnoreColumns_PropertyExpression() + { + var dbContext = SetupDbContext(true); + var orders = dbContext.Orders.Where(o => o.Price == 1.25M && o.ExternalId != null).OrderBy(o => o.Id).ToList(); + foreach (var order in orders) { - var dbContext = SetupDbContext(true); - var orders = dbContext.Orders.Where(o => o.Price == 1.25M && o.ExternalId != null).OrderBy(o => o.Id).ToList(); - foreach (var order in orders) - { - order.Price = 2.35M; - order.ExternalId = null; - } - var oldTotal = dbContext.Orders.Where(o => o.Price == 2.35M && o.ExternalId != null).Count(); - int rowsUpdated = dbContext.BulkUpdate(orders, options => { options.IgnoreColumns = o => new { o.ExternalId }; }); - var newTotal1 = dbContext.Orders.Where(o => o.Price == 2.35M && o.ExternalId != null).Count(); - var newTotal2 = dbContext.Orders.Where(o => o.Price == 1.25M && o.ExternalId != null).Count(); + order.Price = 2.35M; + order.ExternalId = null; + } + var oldTotal = dbContext.Orders.Where(o => o.Price == 2.35M && o.ExternalId != null).Count(); + int rowsUpdated = dbContext.BulkUpdate(orders, options => { options.IgnoreColumns = o => o.ExternalId; }); + var newTotal1 = dbContext.Orders.Where(o => o.Price == 2.35M && o.ExternalId != null).Count(); + var newTotal2 = dbContext.Orders.Where(o => o.Price == 1.25M && o.ExternalId != null).Count(); - Assert.IsTrue(orders.Count > 0, "There must be orders in database that match this condition (Price = $1.25)"); - Assert.IsTrue(newTotal1 == rowsUpdated + oldTotal, "The count of new orders must be equal the number of rows updated in the database."); - Assert.IsTrue(newTotal2 == 0, "There should be not records with condition (Price = $1.25)"); + Assert.IsTrue(orders.Count > 0, "There must be orders in database that match this condition (Price = $1.25)"); + Assert.IsTrue(newTotal1 == rowsUpdated + oldTotal, "The count of new orders must be equal the number of rows updated in the database."); + Assert.IsTrue(newTotal2 == 0, "There should be not records with condition (Price = $1.25)"); + } + [TestMethod] + public void With_Options_IgnoreColumns_NewExpression() + { + var dbContext = SetupDbContext(true); + var orders = dbContext.Orders.Where(o => o.Price == 1.25M && o.ExternalId != null).OrderBy(o => o.Id).ToList(); + foreach (var order in orders) + { + order.Price = 2.35M; + order.ExternalId = null; } - [TestMethod] - public void With_Options_UpdateOnCondition() + var oldTotal = dbContext.Orders.Where(o => o.Price == 2.35M && o.ExternalId != null).Count(); + int rowsUpdated = dbContext.BulkUpdate(orders, options => { options.IgnoreColumns = o => new { o.ExternalId }; }); + var newTotal1 = dbContext.Orders.Where(o => o.Price == 2.35M && o.ExternalId != null).Count(); + var newTotal2 = dbContext.Orders.Where(o => o.Price == 1.25M && o.ExternalId != null).Count(); + + Assert.IsTrue(orders.Count > 0, "There must be orders in database that match this condition (Price = $1.25)"); + Assert.IsTrue(newTotal1 == rowsUpdated + oldTotal, "The count of new orders must be equal the number of rows updated in the database."); + Assert.IsTrue(newTotal2 == 0, "There should be not records with condition (Price = $1.25)"); + } + [TestMethod] + public void With_Options_UpdateOnCondition() + { + var dbContext = SetupDbContext(true); + var orders = dbContext.Orders.Where(o => o.Price == 1.25M).OrderBy(o => o.Id).ToList(); + int ordersWithExternalId = orders.Where(o => o.ExternalId != null).Count(); + foreach (var order in orders) { - var dbContext = SetupDbContext(true); - var orders = dbContext.Orders.Where(o => o.Price == 1.25M).OrderBy(o => o.Id).ToList(); - int ordersWithExternalId = orders.Where(o => o.ExternalId != null).Count(); - foreach (var order in orders) - { - order.Price = 2.35M; - } - var oldTotal = dbContext.Orders.Where(o => o.Price == 2.35M && o.ExternalId != null).Count(); - int rowsUpdated = dbContext.BulkUpdate(orders, options => { options.UpdateOnCondition = (s, t) => s.ExternalId == t.ExternalId; }); - var newTotal = dbContext.Orders.Where(o => o.Price == 2.35M && o.ExternalId != null).Count(); + order.Price = 2.35M; + } + var oldTotal = dbContext.Orders.Where(o => o.Price == 2.35M && o.ExternalId != null).Count(); + int rowsUpdated = dbContext.BulkUpdate(orders, options => { options.UpdateOnCondition = (s, t) => s.ExternalId == t.ExternalId; }); + var newTotal = dbContext.Orders.Where(o => o.Price == 2.35M && o.ExternalId != null).Count(); - Assert.IsTrue(orders.Count > 0, "There must be orders in database that match this condition (Price = $1.25)"); - Assert.IsTrue(rowsUpdated == ordersWithExternalId, "The number of rows updated must match the count of entities that were retrieved"); - Assert.IsTrue(newTotal == rowsUpdated + oldTotal, "The count of new orders must be equal the number of rows updated in the database."); + Assert.IsTrue(orders.Count > 0, "There must be orders in database that match this condition (Price = $1.25)"); + Assert.IsTrue(rowsUpdated == ordersWithExternalId, "The number of rows updated must match the count of entities that were retrieved"); + Assert.IsTrue(newTotal == rowsUpdated + oldTotal, "The count of new orders must be equal the number of rows updated in the database."); + } + [TestMethod] + public void With_Options_UpdateOnCondition_Enum() + { + var dbContext = SetupDbContext(true); + var products = dbContext.Products.Where(o => o.Price == 1.25M).OrderBy(o => o.Id).ToList(); + foreach (var product in products) + { + product.Price = 2.35M; } - [TestMethod] - public void With_Options_UpdateOnCondition_Enum() + int rowsUpdated = dbContext.BulkUpdate(products, o => { - var dbContext = SetupDbContext(true); - var products = dbContext.Products.Where(o => o.Price == 1.25M).OrderBy(o => o.Id).ToList(); - foreach (var product in products) - { - product.Price = 2.35M; - } - int rowsUpdated = dbContext.BulkUpdate(products, o => - { - o.UpdateOnCondition = (s, t) => s.Id == t.Id && s.StatusEnum == t.StatusEnum; - }); - var newProducts = dbContext.Products.Where(o => o.Price == 2.35M).OrderBy(o => o.Id).Count(); + o.UpdateOnCondition = (s, t) => s.Id == t.Id && s.StatusEnum == t.StatusEnum; + }); + var newProducts = dbContext.Products.Where(o => o.Price == 2.35M).OrderBy(o => o.Id).Count(); - Assert.IsTrue(products.Count > 0, "There must be products in database that match this condition (Price = $1.25)"); - Assert.IsTrue(rowsUpdated == products.Count, "The number of rows updated must match the count of entities that were retrieved"); - Assert.IsTrue(newProducts == rowsUpdated, "The count of new products must be equal the number of rows updated in the database."); + Assert.IsTrue(products.Count > 0, "There must be products in database that match this condition (Price = $1.25)"); + Assert.IsTrue(rowsUpdated == products.Count, "The number of rows updated must match the count of entities that were retrieved"); + Assert.IsTrue(newProducts == rowsUpdated, "The count of new products must be equal the number of rows updated in the database."); + } + [TestMethod] + public void With_Transaction() + { + var dbContext = SetupDbContext(true); + var orders = dbContext.Orders.Where(o => o.Price == 1.25M).OrderBy(o => o.Id).ToList(); + long maxId = 0; + foreach (var order in orders) + { + order.Price = 2.35M; + maxId = order.Id; } - [TestMethod] - public void With_Transaction() + int rowsUpdated, newOrders; + using (var transaction = dbContext.Database.BeginTransaction()) { - var dbContext = SetupDbContext(true); - var orders = dbContext.Orders.Where(o => o.Price == 1.25M).OrderBy(o => o.Id).ToList(); - long maxId = 0; - foreach (var order in orders) - { - order.Price = 2.35M; - maxId = order.Id; - } - int rowsUpdated, newOrders; - using (var transaction = dbContext.Database.BeginTransaction()) - { - rowsUpdated = dbContext.BulkUpdate(orders); - newOrders = dbContext.Orders.Where(o => o.Price == 2.35M).Count(); - transaction.Rollback(); - } - int rollbackTotal = dbContext.Orders.Where(o => o.Price == 1.25M).Count(); - - Assert.IsTrue(orders.Count > 0, "There must be orders in database that match this condition (Price = $1.25)"); - Assert.IsTrue(rowsUpdated == orders.Count, "The number of rows updated must match the count of entities that were retrieved"); - Assert.IsTrue(newOrders == rowsUpdated, "The count of new orders must be equal the number of rows updated in the database."); - Assert.IsTrue(rollbackTotal == orders.Count, "The number of rows after the transacation has been rollbacked should match the original count"); + rowsUpdated = dbContext.BulkUpdate(orders); + newOrders = dbContext.Orders.Where(o => o.Price == 2.35M).Count(); + transaction.Rollback(); } + int rollbackTotal = dbContext.Orders.Where(o => o.Price == 1.25M).Count(); + + Assert.IsTrue(orders.Count > 0, "There must be orders in database that match this condition (Price = $1.25)"); + Assert.IsTrue(rowsUpdated == orders.Count, "The number of rows updated must match the count of entities that were retrieved"); + Assert.IsTrue(newOrders == rowsUpdated, "The count of new orders must be equal the number of rows updated in the database."); + Assert.IsTrue(rollbackTotal == orders.Count, "The number of rows after the transacation has been rollbacked should match the original count"); } } \ No newline at end of file diff --git a/N.EntityFrameworkCore.Extensions.Test/DbContextExtensions/BulkUpdateAsync.cs b/N.EntityFrameworkCore.Extensions.Test/DbContextExtensions/BulkUpdateAsync.cs index a928090..2db7a94 100644 --- a/N.EntityFrameworkCore.Extensions.Test/DbContextExtensions/BulkUpdateAsync.cs +++ b/N.EntityFrameworkCore.Extensions.Test/DbContextExtensions/BulkUpdateAsync.cs @@ -6,241 +6,240 @@ using Microsoft.VisualStudio.TestTools.UnitTesting; using N.EntityFrameworkCore.Extensions.Test.Data; -namespace N.EntityFrameworkCore.Extensions.Test.DbContextExtensions +namespace N.EntityFrameworkCore.Extensions.Test.DbContextExtensions; + +[TestClass] +public class BulkUpdateAsync : DbContextExtensionsBase { - [TestClass] - public class BulkUpdateAsync : DbContextExtensionsBase + [TestMethod()] + public async Task With_ComplexKey() { - [TestMethod()] - public async Task With_ComplexKey() + var dbContext = SetupDbContext(true); + var products = dbContext.ProductsWithComplexKey.Where(o => o.Price == 1.25M).ToList(); + foreach (var product in products) { - var dbContext = SetupDbContext(true); - var products = dbContext.ProductsWithComplexKey.Where(o => o.Price == 1.25M).ToList(); - foreach (var product in products) - { - product.Price = 2.35M; - } - var oldTotal = dbContext.ProductsWithComplexKey.Where(o => o.Price == 2.35M).Count(); - int rowsUpdated = await dbContext.BulkUpdateAsync(products); - var newTotal = dbContext.ProductsWithComplexKey.Where(o => o.Price == 2.35M).Count(); - - Assert.IsTrue(products.Count > 0, "There must be orders in database that match this condition (Price = $1.25)"); - Assert.IsTrue(rowsUpdated == products.Count, "The number of rows updated must match the count of entities that were retrieved"); - Assert.IsTrue(newTotal == rowsUpdated + oldTotal, "The count of new orders must be equal the number of rows updated in the database."); + product.Price = 2.35M; } - [TestMethod] - public async Task With_Default_Options() - { - var dbContext = SetupDbContext(true); - var orders = dbContext.Orders.Where(o => o.Price == 1.25M).OrderBy(o => o.Id).ToList(); - long maxId = 0; - foreach (var order in orders) - { - order.Price = 2.35M; - maxId = order.Id; - } - int rowsUpdated = await dbContext.BulkUpdateAsync(orders); - var newOrders = dbContext.Orders.Where(o => o.Price == 2.35M).OrderBy(o => o.Id).Count(); - int entitiesWithChanges = dbContext.ChangeTracker.Entries().Where(t => t.State == EntityState.Modified).Count(); + var oldTotal = dbContext.ProductsWithComplexKey.Where(o => o.Price == 2.35M).Count(); + int rowsUpdated = await dbContext.BulkUpdateAsync(products); + var newTotal = dbContext.ProductsWithComplexKey.Where(o => o.Price == 2.35M).Count(); - Assert.IsTrue(orders.Count > 0, "There must be orders in database that match this condition (Price = $1.25)"); - Assert.IsTrue(rowsUpdated == orders.Count, "The number of rows updated must match the count of entities that were retrieved"); - Assert.IsTrue(newOrders == rowsUpdated, "The count of new orders must be equal the number of rows updated in the database."); - } - [TestMethod] - public async Task With_Inheritance_Tpc() + Assert.IsTrue(products.Count > 0, "There must be orders in database that match this condition (Price = $1.25)"); + Assert.IsTrue(rowsUpdated == products.Count, "The number of rows updated must match the count of entities that were retrieved"); + Assert.IsTrue(newTotal == rowsUpdated + oldTotal, "The count of new orders must be equal the number of rows updated in the database."); + } + [TestMethod] + public async Task With_Default_Options() + { + var dbContext = SetupDbContext(true); + var orders = dbContext.Orders.Where(o => o.Price == 1.25M).OrderBy(o => o.Id).ToList(); + long maxId = 0; + foreach (var order in orders) { - var dbContext = SetupDbContext(true, PopulateDataMode.Tpc); - var customers = dbContext.TpcPeople.Where(o => o.LastName != "BulkUpdateTest").OfType().ToList(); - var vendors = dbContext.TpcPeople.OfType().ToList(); - foreach (var customer in customers) - { - customer.FirstName = string.Format("Id={0}", customer.Id); - customer.LastName = "BulkUpdate_Tpc"; - } - int rowsUpdated = await dbContext.BulkUpdateAsync(customers, options => { options.UpdateOnCondition = (s, t) => s.Id == t.Id; }); - var newCustomers = dbContext.TpcPeople.Where(o => o.LastName == "BulkUpdate_Tpc").OfType().Count(); - int entitiesWithChanges = dbContext.ChangeTracker.Entries().Where(t => t.State == EntityState.Modified).Count(); - - Assert.IsTrue(vendors.Count > 0 && vendors.Count != customers.Count, "There should be vendor records in the database"); - Assert.IsTrue(customers.Count > 0, "There must be customers in database that match this condition (Price = $1.25)"); - Assert.IsTrue(rowsUpdated == customers.Count, "The number of rows updated must match the count of entities that were retrieved"); - Assert.IsTrue(newCustomers == rowsUpdated, "The count of new customers must be equal the number of rows updated in the database."); + order.Price = 2.35M; + maxId = order.Id; } - [TestMethod] - public async Task With_Inheritance_Tph() - { - var dbContext = SetupDbContext(true, PopulateDataMode.Tph); - var customers = dbContext.TphPeople.Where(o => o.LastName != "BulkUpdateTest").OfType().ToList(); - var vendors = dbContext.TphPeople.OfType().ToList(); - foreach (var customer in customers) - { - customer.FirstName = string.Format("Id={0}", customer.Id); - customer.LastName = "BulkUpdateTest"; - } - int rowsUpdated = await dbContext.BulkUpdateAsync(customers); - var newCustomers = dbContext.TphPeople.Where(o => o.LastName == "BulkUpdateTest").OrderBy(o => o.Id).Count(); - int entitiesWithChanges = dbContext.ChangeTracker.Entries().Where(t => t.State == EntityState.Modified).Count(); + int rowsUpdated = await dbContext.BulkUpdateAsync(orders); + var newOrders = dbContext.Orders.Where(o => o.Price == 2.35M).OrderBy(o => o.Id).Count(); + int entitiesWithChanges = dbContext.ChangeTracker.Entries().Where(t => t.State == EntityState.Modified).Count(); - Assert.IsTrue(vendors.Count > 0 && vendors.Count != customers.Count, "There should be vendor records in the database"); - Assert.IsTrue(customers.Count > 0, "There must be customers in database that match this condition (Price = $1.25)"); - Assert.IsTrue(rowsUpdated == customers.Count, "The number of rows updated must match the count of entities that were retrieved"); - Assert.IsTrue(newCustomers == rowsUpdated, "The count of new customers must be equal the number of rows updated in the database."); - } - [TestMethod] - public async Task With_Inheritance_Tpt() + Assert.IsTrue(orders.Count > 0, "There must be orders in database that match this condition (Price = $1.25)"); + Assert.IsTrue(rowsUpdated == orders.Count, "The number of rows updated must match the count of entities that were retrieved"); + Assert.IsTrue(newOrders == rowsUpdated, "The count of new orders must be equal the number of rows updated in the database."); + } + [TestMethod] + public async Task With_Inheritance_Tpc() + { + var dbContext = SetupDbContext(true, PopulateDataMode.Tpc); + var customers = dbContext.TpcPeople.Where(o => o.LastName != "BulkUpdateTest").OfType().ToList(); + var vendors = dbContext.TpcPeople.OfType().ToList(); + foreach (var customer in customers) { - var dbContext = SetupDbContext(true, PopulateDataMode.Tpt); - var customers = dbContext.TptCustomers.Where(o => o.LastName != "BulkUpdateTest").ToList(); - foreach (var customer in customers) - { - customer.FirstName = string.Format("Id={0}", customer.Id); - customer.LastName = "BulkUpdateTest"; - } - int rowsUpdated = await dbContext.BulkUpdateAsync(customers); - var newCustomers = await dbContext.TptCustomers.Where(o => o.LastName == "BulkUpdateTest").CountAsync(); - - Assert.IsTrue(customers.Count > 0, "There must be customers in database that match this condition (Price = $1.25)"); - Assert.IsTrue(rowsUpdated == customers.Count, "The number of rows updated must match the count of entities that were retrieved"); - Assert.IsTrue(newCustomers == rowsUpdated, "The count of new customers must be equal the number of rows updated in the database."); + customer.FirstName = string.Format("Id={0}", customer.Id); + customer.LastName = "BulkUpdate_Tpc"; } - [TestMethod] - public async Task With_Options_InputColumns_PropertyExpression() - { - var dbContext = SetupDbContext(true); - var orders = dbContext.Orders.Where(o => o.Price == 1.25M && o.ExternalId != null).OrderBy(o => o.Id).ToList(); - foreach (var order in orders) - { - order.Price = 2.35M; - order.ExternalId = null; - } - var oldTotal = dbContext.Orders.Where(o => o.Price == 2.35M && o.ExternalId != null).Count(); - int rowsUpdated = await dbContext.BulkUpdateAsync(orders, options => { options.InputColumns = o => o.Price; }); - var newTotal1 = dbContext.Orders.Where(o => o.Price == 2.35M && o.ExternalId != null).Count(); - var newTotal2 = dbContext.Orders.Where(o => o.Price == 1.25M && o.ExternalId != null).Count(); + int rowsUpdated = await dbContext.BulkUpdateAsync(customers, options => { options.UpdateOnCondition = (s, t) => s.Id == t.Id; }); + var newCustomers = dbContext.TpcPeople.Where(o => o.LastName == "BulkUpdate_Tpc").OfType().Count(); + int entitiesWithChanges = dbContext.ChangeTracker.Entries().Where(t => t.State == EntityState.Modified).Count(); - Assert.IsTrue(orders.Count > 0, "There must be orders in database that match this condition (Price = $1.25)"); - Assert.IsTrue(newTotal1 == rowsUpdated + oldTotal, "The count of new orders must be equal the number of rows updated in the database."); - Assert.IsTrue(newTotal2 == 0, "There should be not records with condition (Price = $1.25)"); - } - [TestMethod] - public async Task With_Options_InputColumns_NewExpression() + Assert.IsTrue(vendors.Count > 0 && vendors.Count != customers.Count, "There should be vendor records in the database"); + Assert.IsTrue(customers.Count > 0, "There must be customers in database that match this condition (Price = $1.25)"); + Assert.IsTrue(rowsUpdated == customers.Count, "The number of rows updated must match the count of entities that were retrieved"); + Assert.IsTrue(newCustomers == rowsUpdated, "The count of new customers must be equal the number of rows updated in the database."); + } + [TestMethod] + public async Task With_Inheritance_Tph() + { + var dbContext = SetupDbContext(true, PopulateDataMode.Tph); + var customers = dbContext.TphPeople.Where(o => o.LastName != "BulkUpdateTest").OfType().ToList(); + var vendors = dbContext.TphPeople.OfType().ToList(); + foreach (var customer in customers) { - var dbContext = SetupDbContext(true); - var orders = dbContext.Orders.Where(o => o.Price == 1.25M && o.ExternalId != null).OrderBy(o => o.Id).ToList(); - foreach (var order in orders) - { - order.Price = 2.35M; - order.ExternalId = null; - } - var oldTotal = dbContext.Orders.Where(o => o.Price == 2.35M && o.ExternalId != null).Count(); - int rowsUpdated = await dbContext.BulkUpdateAsync(orders, options => { options.InputColumns = o => new { o.Price }; }); - var newTotal1 = dbContext.Orders.Where(o => o.Price == 2.35M && o.ExternalId != null).Count(); - var newTotal2 = dbContext.Orders.Where(o => o.Price == 1.25M && o.ExternalId != null).Count(); + customer.FirstName = string.Format("Id={0}", customer.Id); + customer.LastName = "BulkUpdateTest"; + } + int rowsUpdated = await dbContext.BulkUpdateAsync(customers); + var newCustomers = dbContext.TphPeople.Where(o => o.LastName == "BulkUpdateTest").OrderBy(o => o.Id).Count(); + int entitiesWithChanges = dbContext.ChangeTracker.Entries().Where(t => t.State == EntityState.Modified).Count(); - Assert.IsTrue(orders.Count() > 0, "There must be orders in database that match this condition (Price = $1.25)"); - Assert.IsTrue(newTotal1 == rowsUpdated + oldTotal, "The count of new orders must be equal the number of rows updated in the database."); - Assert.IsTrue(newTotal2 == 0, "There should be not records with condition (Price = $1.25)"); + Assert.IsTrue(vendors.Count > 0 && vendors.Count != customers.Count, "There should be vendor records in the database"); + Assert.IsTrue(customers.Count > 0, "There must be customers in database that match this condition (Price = $1.25)"); + Assert.IsTrue(rowsUpdated == customers.Count, "The number of rows updated must match the count of entities that were retrieved"); + Assert.IsTrue(newCustomers == rowsUpdated, "The count of new customers must be equal the number of rows updated in the database."); + } + [TestMethod] + public async Task With_Inheritance_Tpt() + { + var dbContext = SetupDbContext(true, PopulateDataMode.Tpt); + var customers = dbContext.TptCustomers.Where(o => o.LastName != "BulkUpdateTest").ToList(); + foreach (var customer in customers) + { + customer.FirstName = string.Format("Id={0}", customer.Id); + customer.LastName = "BulkUpdateTest"; } - [TestMethod] - public async Task With_Options_IgnoreColumns_PropertyExpression() + int rowsUpdated = await dbContext.BulkUpdateAsync(customers); + var newCustomers = await dbContext.TptCustomers.Where(o => o.LastName == "BulkUpdateTest").CountAsync(); + + Assert.IsTrue(customers.Count > 0, "There must be customers in database that match this condition (Price = $1.25)"); + Assert.IsTrue(rowsUpdated == customers.Count, "The number of rows updated must match the count of entities that were retrieved"); + Assert.IsTrue(newCustomers == rowsUpdated, "The count of new customers must be equal the number of rows updated in the database."); + } + [TestMethod] + public async Task With_Options_InputColumns_PropertyExpression() + { + var dbContext = SetupDbContext(true); + var orders = dbContext.Orders.Where(o => o.Price == 1.25M && o.ExternalId != null).OrderBy(o => o.Id).ToList(); + foreach (var order in orders) { - var dbContext = SetupDbContext(true); - var orders = dbContext.Orders.Where(o => o.Price == 1.25M && o.ExternalId != null).OrderBy(o => o.Id).ToList(); - foreach (var order in orders) - { - order.Price = 2.35M; - order.ExternalId = null; - } - var oldTotal = dbContext.Orders.Where(o => o.Price == 2.35M && o.ExternalId != null).Count(); - int rowsUpdated = await dbContext.BulkUpdateAsync(orders, options => { options.IgnoreColumns = o => o.ExternalId; }); - var newTotal1 = dbContext.Orders.Where(o => o.Price == 2.35M && o.ExternalId != null).Count(); - var newTotal2 = dbContext.Orders.Where(o => o.Price == 1.25M && o.ExternalId != null).Count(); + order.Price = 2.35M; + order.ExternalId = null; + } + var oldTotal = dbContext.Orders.Where(o => o.Price == 2.35M && o.ExternalId != null).Count(); + int rowsUpdated = await dbContext.BulkUpdateAsync(orders, options => { options.InputColumns = o => o.Price; }); + var newTotal1 = dbContext.Orders.Where(o => o.Price == 2.35M && o.ExternalId != null).Count(); + var newTotal2 = dbContext.Orders.Where(o => o.Price == 1.25M && o.ExternalId != null).Count(); - Assert.IsTrue(orders.Count > 0, "There must be orders in database that match this condition (Price = $1.25)"); - Assert.IsTrue(newTotal1 == rowsUpdated + oldTotal, "The count of new orders must be equal the number of rows updated in the database."); - Assert.IsTrue(newTotal2 == 0, "There should be not records with condition (Price = $1.25)"); + Assert.IsTrue(orders.Count > 0, "There must be orders in database that match this condition (Price = $1.25)"); + Assert.IsTrue(newTotal1 == rowsUpdated + oldTotal, "The count of new orders must be equal the number of rows updated in the database."); + Assert.IsTrue(newTotal2 == 0, "There should be not records with condition (Price = $1.25)"); + } + [TestMethod] + public async Task With_Options_InputColumns_NewExpression() + { + var dbContext = SetupDbContext(true); + var orders = dbContext.Orders.Where(o => o.Price == 1.25M && o.ExternalId != null).OrderBy(o => o.Id).ToList(); + foreach (var order in orders) + { + order.Price = 2.35M; + order.ExternalId = null; } - [TestMethod] - public async Task With_Options_IgnoreColumns_NewExpression() + var oldTotal = dbContext.Orders.Where(o => o.Price == 2.35M && o.ExternalId != null).Count(); + int rowsUpdated = await dbContext.BulkUpdateAsync(orders, options => { options.InputColumns = o => new { o.Price }; }); + var newTotal1 = dbContext.Orders.Where(o => o.Price == 2.35M && o.ExternalId != null).Count(); + var newTotal2 = dbContext.Orders.Where(o => o.Price == 1.25M && o.ExternalId != null).Count(); + + Assert.IsTrue(orders.Count() > 0, "There must be orders in database that match this condition (Price = $1.25)"); + Assert.IsTrue(newTotal1 == rowsUpdated + oldTotal, "The count of new orders must be equal the number of rows updated in the database."); + Assert.IsTrue(newTotal2 == 0, "There should be not records with condition (Price = $1.25)"); + } + [TestMethod] + public async Task With_Options_IgnoreColumns_PropertyExpression() + { + var dbContext = SetupDbContext(true); + var orders = dbContext.Orders.Where(o => o.Price == 1.25M && o.ExternalId != null).OrderBy(o => o.Id).ToList(); + foreach (var order in orders) { - var dbContext = SetupDbContext(true); - var orders = dbContext.Orders.Where(o => o.Price == 1.25M && o.ExternalId != null).OrderBy(o => o.Id).ToList(); - foreach (var order in orders) - { - order.Price = 2.35M; - order.ExternalId = null; - } - var oldTotal = dbContext.Orders.Where(o => o.Price == 2.35M && o.ExternalId != null).Count(); - int rowsUpdated = await dbContext.BulkUpdateAsync(orders, options => { options.IgnoreColumns = o => new { o.ExternalId }; }); - var newTotal1 = dbContext.Orders.Where(o => o.Price == 2.35M && o.ExternalId != null).Count(); - var newTotal2 = dbContext.Orders.Where(o => o.Price == 1.25M && o.ExternalId != null).Count(); + order.Price = 2.35M; + order.ExternalId = null; + } + var oldTotal = dbContext.Orders.Where(o => o.Price == 2.35M && o.ExternalId != null).Count(); + int rowsUpdated = await dbContext.BulkUpdateAsync(orders, options => { options.IgnoreColumns = o => o.ExternalId; }); + var newTotal1 = dbContext.Orders.Where(o => o.Price == 2.35M && o.ExternalId != null).Count(); + var newTotal2 = dbContext.Orders.Where(o => o.Price == 1.25M && o.ExternalId != null).Count(); - Assert.IsTrue(orders.Count > 0, "There must be orders in database that match this condition (Price = $1.25)"); - Assert.IsTrue(newTotal1 == rowsUpdated + oldTotal, "The count of new orders must be equal the number of rows updated in the database."); - Assert.IsTrue(newTotal2 == 0, "There should be not records with condition (Price = $1.25)"); + Assert.IsTrue(orders.Count > 0, "There must be orders in database that match this condition (Price = $1.25)"); + Assert.IsTrue(newTotal1 == rowsUpdated + oldTotal, "The count of new orders must be equal the number of rows updated in the database."); + Assert.IsTrue(newTotal2 == 0, "There should be not records with condition (Price = $1.25)"); + } + [TestMethod] + public async Task With_Options_IgnoreColumns_NewExpression() + { + var dbContext = SetupDbContext(true); + var orders = dbContext.Orders.Where(o => o.Price == 1.25M && o.ExternalId != null).OrderBy(o => o.Id).ToList(); + foreach (var order in orders) + { + order.Price = 2.35M; + order.ExternalId = null; } - [TestMethod] - public async Task With_Options_UpdateOnCondition() + var oldTotal = dbContext.Orders.Where(o => o.Price == 2.35M && o.ExternalId != null).Count(); + int rowsUpdated = await dbContext.BulkUpdateAsync(orders, options => { options.IgnoreColumns = o => new { o.ExternalId }; }); + var newTotal1 = dbContext.Orders.Where(o => o.Price == 2.35M && o.ExternalId != null).Count(); + var newTotal2 = dbContext.Orders.Where(o => o.Price == 1.25M && o.ExternalId != null).Count(); + + Assert.IsTrue(orders.Count > 0, "There must be orders in database that match this condition (Price = $1.25)"); + Assert.IsTrue(newTotal1 == rowsUpdated + oldTotal, "The count of new orders must be equal the number of rows updated in the database."); + Assert.IsTrue(newTotal2 == 0, "There should be not records with condition (Price = $1.25)"); + } + [TestMethod] + public async Task With_Options_UpdateOnCondition() + { + var dbContext = SetupDbContext(true); + var orders = dbContext.Orders.Where(o => o.Price == 1.25M).OrderBy(o => o.Id).ToList(); + int ordersWithExternalId = orders.Where(o => o.ExternalId != null).Count(); + foreach (var order in orders) { - var dbContext = SetupDbContext(true); - var orders = dbContext.Orders.Where(o => o.Price == 1.25M).OrderBy(o => o.Id).ToList(); - int ordersWithExternalId = orders.Where(o => o.ExternalId != null).Count(); - foreach (var order in orders) - { - order.Price = 2.35M; - } - var oldTotal = dbContext.Orders.Where(o => o.Price == 2.35M && o.ExternalId != null).Count(); - int rowsUpdated = await dbContext.BulkUpdateAsync(orders, options => { options.UpdateOnCondition = (s, t) => s.ExternalId == t.ExternalId; }); - var newTotal = dbContext.Orders.Where(o => o.Price == 2.35M && o.ExternalId != null).Count(); + order.Price = 2.35M; + } + var oldTotal = dbContext.Orders.Where(o => o.Price == 2.35M && o.ExternalId != null).Count(); + int rowsUpdated = await dbContext.BulkUpdateAsync(orders, options => { options.UpdateOnCondition = (s, t) => s.ExternalId == t.ExternalId; }); + var newTotal = dbContext.Orders.Where(o => o.Price == 2.35M && o.ExternalId != null).Count(); - Assert.IsTrue(orders.Count > 0, "There must be orders in database that match this condition (Price = $1.25)"); - Assert.IsTrue(rowsUpdated == ordersWithExternalId, "The number of rows updated must match the count of entities that were retrieved"); - Assert.IsTrue(newTotal == rowsUpdated + oldTotal, "The count of new orders must be equal the number of rows updated in the database."); + Assert.IsTrue(orders.Count > 0, "There must be orders in database that match this condition (Price = $1.25)"); + Assert.IsTrue(rowsUpdated == ordersWithExternalId, "The number of rows updated must match the count of entities that were retrieved"); + Assert.IsTrue(newTotal == rowsUpdated + oldTotal, "The count of new orders must be equal the number of rows updated in the database."); + } + [TestMethod] + public async Task With_Options_UpdateOnCondition_Enum() + { + var dbContext = SetupDbContext(true); + var products = dbContext.Products.Where(o => o.Price == 1.25M).OrderBy(o => o.Id).ToList(); + foreach (var product in products) + { + product.Price = 2.35M; } - [TestMethod] - public async Task With_Options_UpdateOnCondition_Enum() + int rowsUpdated = await dbContext.BulkUpdateAsync(products, o => { - var dbContext = SetupDbContext(true); - var products = dbContext.Products.Where(o => o.Price == 1.25M).OrderBy(o => o.Id).ToList(); - foreach (var product in products) - { - product.Price = 2.35M; - } - int rowsUpdated = await dbContext.BulkUpdateAsync(products, o => - { - o.UpdateOnCondition = (s, t) => s.Id == t.Id && s.StatusEnum == t.StatusEnum; - }); - var newProducts = dbContext.Products.Where(o => o.Price == 2.35M).OrderBy(o => o.Id).Count(); + o.UpdateOnCondition = (s, t) => s.Id == t.Id && s.StatusEnum == t.StatusEnum; + }); + var newProducts = dbContext.Products.Where(o => o.Price == 2.35M).OrderBy(o => o.Id).Count(); - Assert.IsTrue(products.Count > 0, "There must be products in database that match this condition (Price = $1.25)"); - Assert.IsTrue(rowsUpdated == products.Count, "The number of rows updated must match the count of entities that were retrieved"); - Assert.IsTrue(newProducts == rowsUpdated, "The count of new products must be equal the number of rows updated in the database."); + Assert.IsTrue(products.Count > 0, "There must be products in database that match this condition (Price = $1.25)"); + Assert.IsTrue(rowsUpdated == products.Count, "The number of rows updated must match the count of entities that were retrieved"); + Assert.IsTrue(newProducts == rowsUpdated, "The count of new products must be equal the number of rows updated in the database."); + } + [TestMethod] + public async Task With_Transaction() + { + var dbContext = SetupDbContext(true); + var orders = dbContext.Orders.Where(o => o.Price == 1.25M).OrderBy(o => o.Id).ToList(); + long maxId = 0; + foreach (var order in orders) + { + order.Price = 2.35M; + maxId = order.Id; } - [TestMethod] - public async Task With_Transaction() + int rowsUpdated, newOrders; + using (var transaction = dbContext.Database.BeginTransaction()) { - var dbContext = SetupDbContext(true); - var orders = dbContext.Orders.Where(o => o.Price == 1.25M).OrderBy(o => o.Id).ToList(); - long maxId = 0; - foreach (var order in orders) - { - order.Price = 2.35M; - maxId = order.Id; - } - int rowsUpdated, newOrders; - using (var transaction = dbContext.Database.BeginTransaction()) - { - rowsUpdated = await dbContext.BulkUpdateAsync(orders); - newOrders = dbContext.Orders.Where(o => o.Price == 2.35M).Count(); - transaction.Rollback(); - } - int rollbackTotal = dbContext.Orders.Where(o => o.Price == 1.25M).Count(); - - Assert.IsTrue(orders.Count > 0, "There must be orders in database that match this condition (Price = $1.25)"); - Assert.IsTrue(rowsUpdated == orders.Count, "The number of rows updated must match the count of entities that were retrieved"); - Assert.IsTrue(newOrders == rowsUpdated, "The count of new orders must be equal the number of rows updated in the database."); - Assert.IsTrue(rollbackTotal == orders.Count, "The number of rows after the transacation has been rollbacked should match the original count"); + rowsUpdated = await dbContext.BulkUpdateAsync(orders); + newOrders = dbContext.Orders.Where(o => o.Price == 2.35M).Count(); + transaction.Rollback(); } + int rollbackTotal = dbContext.Orders.Where(o => o.Price == 1.25M).Count(); + + Assert.IsTrue(orders.Count > 0, "There must be orders in database that match this condition (Price = $1.25)"); + Assert.IsTrue(rowsUpdated == orders.Count, "The number of rows updated must match the count of entities that were retrieved"); + Assert.IsTrue(newOrders == rowsUpdated, "The count of new orders must be equal the number of rows updated in the database."); + Assert.IsTrue(rollbackTotal == orders.Count, "The number of rows after the transacation has been rollbacked should match the original count"); } } \ No newline at end of file diff --git a/N.EntityFrameworkCore.Extensions.Test/DbContextExtensions/DbContextExtensionsBase.cs b/N.EntityFrameworkCore.Extensions.Test/DbContextExtensions/DbContextExtensionsBase.cs index bd2b77a..a34be60 100644 --- a/N.EntityFrameworkCore.Extensions.Test/DbContextExtensions/DbContextExtensionsBase.cs +++ b/N.EntityFrameworkCore.Extensions.Test/DbContextExtensions/DbContextExtensionsBase.cs @@ -7,248 +7,247 @@ using N.EntityFrameworkCore.Extensions.Test.Data; using N.EntityFrameworkCore.Extensions.Test.Data.Enums; -namespace N.EntityFrameworkCore.Extensions.Test.DbContextExtensions +namespace N.EntityFrameworkCore.Extensions.Test.DbContextExtensions; + +public enum PopulateDataMode +{ + Normal, + Tpc, + Tph, + Tpt, + Schema +} +[TestClass] +public class DbContextExtensionsBase { - public enum PopulateDataMode + [TestInitialize] + public void Init() { - Normal, - Tpc, - Tph, - Tpt, - Schema + TestDbContext dbContext = new TestDbContext(); + dbContext.Database.EnsureCreated(); } - [TestClass] - public class DbContextExtensionsBase + protected TestDbContext SetupDbContext(bool populateData, PopulateDataMode mode = PopulateDataMode.Normal) { - [TestInitialize] - public void Init() - { - TestDbContext dbContext = new TestDbContext(); - dbContext.Database.EnsureCreated(); - } - protected TestDbContext SetupDbContext(bool populateData, PopulateDataMode mode = PopulateDataMode.Normal) + TestDbContext dbContext = new TestDbContext(); + dbContext.Orders.Truncate(); + dbContext.Products.Truncate(); + dbContext.ProductCategories.Clear(); + dbContext.ProductsWithCustomSchema.Truncate(); + dbContext.Database.ClearTable("TpcCustomer"); + dbContext.Database.ClearTable("TpcVendor"); + dbContext.TphPeople.Truncate(); + dbContext.Database.ClearTable("TptPeople"); + dbContext.Database.ClearTable("TptCustomer"); + dbContext.Database.ClearTable("TptVendor"); + dbContext.Database.DropTable("ProductsUnderTen", true); + dbContext.Database.DropTable("OrdersUnderTen", true); + dbContext.Database.DropTable("OrdersLast30Days", true); + if (populateData) { - TestDbContext dbContext = new TestDbContext(); - dbContext.Orders.Truncate(); - dbContext.Products.Truncate(); - dbContext.ProductCategories.Clear(); - dbContext.ProductsWithCustomSchema.Truncate(); - dbContext.Database.ClearTable("TpcCustomer"); - dbContext.Database.ClearTable("TpcVendor"); - dbContext.TphPeople.Truncate(); - dbContext.Database.ClearTable("TptPeople"); - dbContext.Database.ClearTable("TptCustomer"); - dbContext.Database.ClearTable("TptVendor"); - dbContext.Database.DropTable("ProductsUnderTen", true); - dbContext.Database.DropTable("OrdersUnderTen", true); - dbContext.Database.DropTable("OrdersLast30Days", true); - if (populateData) + if (mode == PopulateDataMode.Normal) { - if (mode == PopulateDataMode.Normal) + var orders = new List(); + int id = 1; + for (int i = 0; i < 2050; i++) { - var orders = new List(); - int id = 1; - for (int i = 0; i < 2050; i++) - { - DateTime addedDateTime = DateTime.UtcNow.AddDays(-id); - orders.Add(new Order - { - Id = id, - ExternalId = string.Format("id-{0}", i), - Price = 1.25M, - AddedDateTime = addedDateTime, - ModifiedDateTime = addedDateTime.AddHours(3), - Status = OrderStatus.Completed - }); - id++; - } - for (int i = 0; i < 1050; i++) - { - orders.Add(new Order { Id = id, Price = 5.35M }); - id++; - } - for (int i = 0; i < 2050; i++) - { - orders.Add(new Order { Id = id, Price = 1.25M }); - id++; - } - for (int i = 0; i < 6000; i++) - { - orders.Add(new Order { Id = id, Price = 15.35M }); - id++; - } - for (int i = 0; i < 6000; i++) - { - orders.Add(new Order { Id = id, Price = 15.35M }); - id++; - } + DateTime addedDateTime = DateTime.UtcNow.AddDays(-id); + orders.Add(new Order + { + Id = id, + ExternalId = string.Format("id-{0}", i), + Price = 1.25M, + AddedDateTime = addedDateTime, + ModifiedDateTime = addedDateTime.AddHours(3), + Status = OrderStatus.Completed + }); + id++; + } + for (int i = 0; i < 1050; i++) + { + orders.Add(new Order { Id = id, Price = 5.35M }); + id++; + } + for (int i = 0; i < 2050; i++) + { + orders.Add(new Order { Id = id, Price = 1.25M }); + id++; + } + for (int i = 0; i < 6000; i++) + { + orders.Add(new Order { Id = id, Price = 15.35M }); + id++; + } + for (int i = 0; i < 6000; i++) + { + orders.Add(new Order { Id = id, Price = 15.35M }); + id++; + } - Debug.WriteLine("Last Id for Order is {0}", id); - dbContext.BulkInsert(orders, new BulkInsertOptions() { KeepIdentity = true }); + Debug.WriteLine("Last Id for Order is {0}", id); + dbContext.BulkInsert(orders, new BulkInsertOptions() { KeepIdentity = true }); - var productCategories = new List() - { - new ProductCategory { Id=1, Name="Category-1", Active=true}, - new ProductCategory { Id=2, Name="Category-2", Active=true}, - new ProductCategory { Id=3, Name="Category-3", Active=true}, - new ProductCategory { Id=4, Name="Category-4", Active=false}, - }; - dbContext.BulkInsert(productCategories, o => { o.KeepIdentity = true; o.UsePermanentTable = true; }); - var products = new List(); - id = 1; - for (int i = 0; i < 2050; i++) - { - products.Add(new Product - { - Id = i.ToString(), - Price = 1.25M, - OutOfStock = false, - ProductCategoryId = 4, - StatusEnum = ProductStatus.InStock, - Color = Color.Black, - Position = new Position { Building = 5, Aisle = 33, Bay = i }, - }); - id++; - } - for (int i = 2050; i < 7000; i++) - { - products.Add(new Product { Id = i.ToString(), Price = 1.25M, OutOfStock = true, StatusEnum = ProductStatus.OutOfStock }); - id++; - } + var productCategories = new List() + { + new ProductCategory { Id=1, Name="Category-1", Active=true}, + new ProductCategory { Id=2, Name="Category-2", Active=true}, + new ProductCategory { Id=3, Name="Category-3", Active=true}, + new ProductCategory { Id=4, Name="Category-4", Active=false}, + }; + dbContext.BulkInsert(productCategories, o => { o.KeepIdentity = true; o.UsePermanentTable = true; }); + var products = new List(); + id = 1; + for (int i = 0; i < 2050; i++) + { + products.Add(new Product + { + Id = i.ToString(), + Price = 1.25M, + OutOfStock = false, + ProductCategoryId = 4, + StatusEnum = ProductStatus.InStock, + Color = Color.Black, + Position = new Position { Building = 5, Aisle = 33, Bay = i }, + }); + id++; + } + for (int i = 2050; i < 7000; i++) + { + products.Add(new Product { Id = i.ToString(), Price = 1.25M, OutOfStock = true, StatusEnum = ProductStatus.OutOfStock }); + id++; + } - Debug.WriteLine("Last Id for Product is {0}", id); - dbContext.BulkInsert(products, new BulkInsertOptions() { KeepIdentity = false, AutoMapOutput = false, UsePermanentTable = true }); + Debug.WriteLine("Last Id for Product is {0}", id); + dbContext.BulkInsert(products, new BulkInsertOptions() { KeepIdentity = false, AutoMapOutput = false, UsePermanentTable = true }); - //ProductWithComplexKey - var productsWithComplexKey = new List(); - id = 1; + //ProductWithComplexKey + var productsWithComplexKey = new List(); + id = 1; - for (int i = 0; i < 2050; i++) - { - productsWithComplexKey.Add(new ProductWithComplexKey { Price = 1.25M }); - id++; - } + for (int i = 0; i < 2050; i++) + { + productsWithComplexKey.Add(new ProductWithComplexKey { Price = 1.25M }); + id++; + } - Debug.WriteLine("Last Id for ProductsWithComplexKey is {0}", id); - dbContext.BulkInsert(productsWithComplexKey, new BulkInsertOptions() { KeepIdentity = false, AutoMapOutput = false }); + Debug.WriteLine("Last Id for ProductsWithComplexKey is {0}", id); + dbContext.BulkInsert(productsWithComplexKey, new BulkInsertOptions() { KeepIdentity = false, AutoMapOutput = false }); + } + else if (mode == PopulateDataMode.Tph) + { + //TPH Customers & Vendors + var tphCustomers = new List(); + var tphVendors = new List(); + for (int i = 0; i < 2000; i++) + { + tphCustomers.Add(new TphCustomer + { + Id = i, + FirstName = string.Format("John_{0}", i), + LastName = string.Format("Smith_{0}", i), + Email = string.Format("john.smith{0}@domain.com", i), + Phone = "404-555-1111", + AddedDate = DateTime.UtcNow + }); } - else if (mode == PopulateDataMode.Tph) + for (int i = 2000; i < 3000; i++) { - //TPH Customers & Vendors - var tphCustomers = new List(); - var tphVendors = new List(); - for (int i = 0; i < 2000; i++) - { - tphCustomers.Add(new TphCustomer - { - Id = i, - FirstName = string.Format("John_{0}", i), - LastName = string.Format("Smith_{0}", i), - Email = string.Format("john.smith{0}@domain.com", i), - Phone = "404-555-1111", - AddedDate = DateTime.UtcNow - }); - } - for (int i = 2000; i < 3000; i++) - { - tphVendors.Add(new TphVendor - { - Id = i, - FirstName = string.Format("Mike_{0}", i), - LastName = string.Format("Smith_{0}", i), - Phone = "404-555-2222", - Email = string.Format("mike.smith{0}@domain.com", i), - Url = string.Format("http://domain.com/mike.smith{0}", i) - }); - } - dbContext.BulkInsert(tphCustomers, new BulkInsertOptions() { KeepIdentity = true }); - dbContext.BulkInsert(tphVendors, new BulkInsertOptions() { KeepIdentity = true }); - } - else if (mode == PopulateDataMode.Tpc) - { - //TPC Customers & Vendors - var tpcCustomers = new List(); - var tpcVendors = new List(); - for (int i = 1; i <= 2000; i++) - { - tpcCustomers.Add(new TpcCustomer - { - Id = i, - FirstName = string.Format("John_{0}", i), - LastName = string.Format("Smith_{0}", i), - Email = string.Format("john.smith{0}@domain.com", i), - Phone = "404-555-1111", - AddedDate = DateTime.UtcNow - }); - } - for (int i = 2001; i <= 3000; i++) - { - tpcVendors.Add(new TpcVendor - { - Id = i, - FirstName = string.Format("Mike_{0}", i), - LastName = string.Format("Smith_{0}", i), - Phone = "404-555-2222", - Email = string.Format("mike.smith{0}@domain.com", i), - Url = string.Format("http://domain.com/mike.smith{0}", i) - }); - } - dbContext.BulkInsert(tpcCustomers, new BulkInsertOptions() { KeepIdentity = true }); - dbContext.BulkInsert(tpcVendors, new BulkInsertOptions() { KeepIdentity = true }); - } - else if (mode == PopulateDataMode.Tpt) - { - //Customers & Vendors - var tptCustomers = new List(); - var tptVendors = new List(); - for (int i = 1; i <= 2000; i++) - { - tptCustomers.Add(new TptCustomer - { - Id = i, - FirstName = string.Format("John_{0}", i), - LastName = string.Format("Smith_{0}", i), - Email = string.Format("john.smith{0}@domain.com", i), - Phone = "404-555-1111", - AddedDate = DateTime.UtcNow - }); - } - for (int i = 2001; i < 3000; i++) - { - tptVendors.Add(new TptVendor - { - Id = i, - FirstName = string.Format("Mike_{0}", i), - LastName = string.Format("Smith_{0}", i), - Phone = "404-555-2222", - Email = string.Format("mike.smith{0}@domain.com", i), - Url = string.Format("http://domain.com/mike.smith{0}", i) - }); - } - dbContext.BulkInsert(tptCustomers, new BulkInsertOptions() { KeepIdentity = true, UsePermanentTable = true }); - dbContext.BulkInsert(tptVendors, new BulkInsertOptions() { KeepIdentity = true }); - } - else if (mode == PopulateDataMode.Schema) - { - //ProductWithCustomSchema - var productsWithCustomSchema = new List(); - int id = 1; - - for (int i = 0; i < 2050; i++) - { - productsWithCustomSchema.Add(new ProductWithCustomSchema { Id = id.ToString(), Price = 1.25M }); - id++; - } - for (int i = 2050; i < 5000; i++) - { - productsWithCustomSchema.Add(new ProductWithCustomSchema { Id = id.ToString(), Price = 6.75M }); - id++; - } + tphVendors.Add(new TphVendor + { + Id = i, + FirstName = string.Format("Mike_{0}", i), + LastName = string.Format("Smith_{0}", i), + Phone = "404-555-2222", + Email = string.Format("mike.smith{0}@domain.com", i), + Url = string.Format("http://domain.com/mike.smith{0}", i) + }); + } + dbContext.BulkInsert(tphCustomers, new BulkInsertOptions() { KeepIdentity = true }); + dbContext.BulkInsert(tphVendors, new BulkInsertOptions() { KeepIdentity = true }); + } + else if (mode == PopulateDataMode.Tpc) + { + //TPC Customers & Vendors + var tpcCustomers = new List(); + var tpcVendors = new List(); + for (int i = 1; i <= 2000; i++) + { + tpcCustomers.Add(new TpcCustomer + { + Id = i, + FirstName = string.Format("John_{0}", i), + LastName = string.Format("Smith_{0}", i), + Email = string.Format("john.smith{0}@domain.com", i), + Phone = "404-555-1111", + AddedDate = DateTime.UtcNow + }); + } + for (int i = 2001; i <= 3000; i++) + { + tpcVendors.Add(new TpcVendor + { + Id = i, + FirstName = string.Format("Mike_{0}", i), + LastName = string.Format("Smith_{0}", i), + Phone = "404-555-2222", + Email = string.Format("mike.smith{0}@domain.com", i), + Url = string.Format("http://domain.com/mike.smith{0}", i) + }); + } + dbContext.BulkInsert(tpcCustomers, new BulkInsertOptions() { KeepIdentity = true }); + dbContext.BulkInsert(tpcVendors, new BulkInsertOptions() { KeepIdentity = true }); + } + else if (mode == PopulateDataMode.Tpt) + { + //Customers & Vendors + var tptCustomers = new List(); + var tptVendors = new List(); + for (int i = 1; i <= 2000; i++) + { + tptCustomers.Add(new TptCustomer + { + Id = i, + FirstName = string.Format("John_{0}", i), + LastName = string.Format("Smith_{0}", i), + Email = string.Format("john.smith{0}@domain.com", i), + Phone = "404-555-1111", + AddedDate = DateTime.UtcNow + }); + } + for (int i = 2001; i < 3000; i++) + { + tptVendors.Add(new TptVendor + { + Id = i, + FirstName = string.Format("Mike_{0}", i), + LastName = string.Format("Smith_{0}", i), + Phone = "404-555-2222", + Email = string.Format("mike.smith{0}@domain.com", i), + Url = string.Format("http://domain.com/mike.smith{0}", i) + }); + } + dbContext.BulkInsert(tptCustomers, new BulkInsertOptions() { KeepIdentity = true, UsePermanentTable = true }); + dbContext.BulkInsert(tptVendors, new BulkInsertOptions() { KeepIdentity = true }); + } + else if (mode == PopulateDataMode.Schema) + { + //ProductWithCustomSchema + var productsWithCustomSchema = new List(); + int id = 1; - dbContext.BulkInsert(productsWithCustomSchema); + for (int i = 0; i < 2050; i++) + { + productsWithCustomSchema.Add(new ProductWithCustomSchema { Id = id.ToString(), Price = 1.25M }); + id++; } + for (int i = 2050; i < 5000; i++) + { + productsWithCustomSchema.Add(new ProductWithCustomSchema { Id = id.ToString(), Price = 6.75M }); + id++; + } + + dbContext.BulkInsert(productsWithCustomSchema); } - return dbContext; } + return dbContext; } } \ No newline at end of file diff --git a/N.EntityFrameworkCore.Extensions.Test/DbContextExtensions/DeleteFromQuery.cs b/N.EntityFrameworkCore.Extensions.Test/DbContextExtensions/DeleteFromQuery.cs index 79c40f4..86514d9 100644 --- a/N.EntityFrameworkCore.Extensions.Test/DbContextExtensions/DeleteFromQuery.cs +++ b/N.EntityFrameworkCore.Extensions.Test/DbContextExtensions/DeleteFromQuery.cs @@ -3,147 +3,146 @@ using System.Threading.Tasks; using Microsoft.VisualStudio.TestTools.UnitTesting; -namespace N.EntityFrameworkCore.Extensions.Test.DbContextExtensions +namespace N.EntityFrameworkCore.Extensions.Test.DbContextExtensions; + +[TestClass] +public class DeleteFromQuery : DbContextExtensionsBase { - [TestClass] - public class DeleteFromQuery : DbContextExtensionsBase + [TestMethod] + public void With_Boolean_Value() { - [TestMethod] - public void With_Boolean_Value() - { - var dbContext = SetupDbContext(true); - var products = dbContext.Products.Where(p => p.OutOfStock); - int oldTotal = products.Count(a => a.OutOfStock); - int rowUpdated = products.DeleteFromQuery(); - int newTotal = dbContext.Products.Count(o => o.OutOfStock); + var dbContext = SetupDbContext(true); + var products = dbContext.Products.Where(p => p.OutOfStock); + int oldTotal = products.Count(a => a.OutOfStock); + int rowUpdated = products.DeleteFromQuery(); + int newTotal = dbContext.Products.Count(o => o.OutOfStock); - Assert.IsTrue(oldTotal > 0, "There must be products in database that match this condition (OutOfStock == true)"); - Assert.IsTrue(rowUpdated == oldTotal, "The number of rows update must match the count of rows that match the condition (OutOfStock == false)"); - Assert.IsTrue(newTotal == 0, "The new count must be 0 to indicate all records were updated"); - } - [TestMethod] - public void With_Child_Relationship() - { - var dbContext = SetupDbContext(true); - var products = dbContext.Products.Where(p => !p.ProductCategory.Active); - int oldTotal = products.Count(); - int rowsDeleted = products.DeleteFromQuery(); - int newTotal = products.Count(); + Assert.IsTrue(oldTotal > 0, "There must be products in database that match this condition (OutOfStock == true)"); + Assert.IsTrue(rowUpdated == oldTotal, "The number of rows update must match the count of rows that match the condition (OutOfStock == false)"); + Assert.IsTrue(newTotal == 0, "The new count must be 0 to indicate all records were updated"); + } + [TestMethod] + public void With_Child_Relationship() + { + var dbContext = SetupDbContext(true); + var products = dbContext.Products.Where(p => !p.ProductCategory.Active); + int oldTotal = products.Count(); + int rowsDeleted = products.DeleteFromQuery(); + int newTotal = products.Count(); - Assert.IsTrue(oldTotal > 0, "There must be products in database that match this condition (ProductCategory.Active == false)"); - Assert.IsTrue(rowsDeleted == oldTotal, "The number of rows update must match the count of rows that match the condition (ProductCategory.Active == false)"); - Assert.IsTrue(newTotal == 0, "The new count must be 0 to indicate all records were deleted"); - } - [TestMethod] - public void With_Decimal_Using_IQuerable() - { - var dbContext = SetupDbContext(true); - var orders = dbContext.Orders.Where(o => o.Price <= 10); - int oldTotal = orders.Count(); - int rowsDeleted = orders.DeleteFromQuery(); - int newTotal = orders.Count(); + Assert.IsTrue(oldTotal > 0, "There must be products in database that match this condition (ProductCategory.Active == false)"); + Assert.IsTrue(rowsDeleted == oldTotal, "The number of rows update must match the count of rows that match the condition (ProductCategory.Active == false)"); + Assert.IsTrue(newTotal == 0, "The new count must be 0 to indicate all records were deleted"); + } + [TestMethod] + public void With_Decimal_Using_IQuerable() + { + var dbContext = SetupDbContext(true); + var orders = dbContext.Orders.Where(o => o.Price <= 10); + int oldTotal = orders.Count(); + int rowsDeleted = orders.DeleteFromQuery(); + int newTotal = orders.Count(); - Assert.IsTrue(oldTotal > 0, "There must be orders in database that match this condition"); - Assert.IsTrue(rowsDeleted == oldTotal, "The number of rows deleted must match the count of existing rows in database"); - Assert.IsTrue(newTotal == 0, "Delete() Failed: must be 0 to indicate all records were deleted"); - } - [TestMethod] - public void With_Decimal_Using_IEnumerable() - { - var dbContext = SetupDbContext(true); - var orders = dbContext.Orders.Where(o => o.Price <= 10); - int oldTotal = orders.Count(); - int rowsDeleted = orders.DeleteFromQuery(); - int newTotal = orders.Count(); + Assert.IsTrue(oldTotal > 0, "There must be orders in database that match this condition"); + Assert.IsTrue(rowsDeleted == oldTotal, "The number of rows deleted must match the count of existing rows in database"); + Assert.IsTrue(newTotal == 0, "Delete() Failed: must be 0 to indicate all records were deleted"); + } + [TestMethod] + public void With_Decimal_Using_IEnumerable() + { + var dbContext = SetupDbContext(true); + var orders = dbContext.Orders.Where(o => o.Price <= 10); + int oldTotal = orders.Count(); + int rowsDeleted = orders.DeleteFromQuery(); + int newTotal = orders.Count(); - Assert.IsTrue(oldTotal > 0, "There must be orders in database that match this condition"); - Assert.IsTrue(rowsDeleted == oldTotal, "The number of rows deleted must match the count of existing rows in database"); - Assert.IsTrue(newTotal == 0, "The new count must be 0 to indicate all records were deleted"); - } - [TestMethod] - public void With_DateTime() - { - var dbContext = SetupDbContext(true); - int oldTotal = dbContext.Orders.Count(); - DateTime dateTime = dbContext.Orders.Max(o => o.AddedDateTime).AddDays(-30); - int rowsToDelete = dbContext.Orders.Where(o => o.ModifiedDateTime != null && o.ModifiedDateTime >= dateTime).Count(); - int rowsDeleted = dbContext.Orders.Where(o => o.ModifiedDateTime != null && o.ModifiedDateTime >= dateTime) - .DeleteFromQuery(); - int newTotal = dbContext.Orders.Count(); + Assert.IsTrue(oldTotal > 0, "There must be orders in database that match this condition"); + Assert.IsTrue(rowsDeleted == oldTotal, "The number of rows deleted must match the count of existing rows in database"); + Assert.IsTrue(newTotal == 0, "The new count must be 0 to indicate all records were deleted"); + } + [TestMethod] + public void With_DateTime() + { + var dbContext = SetupDbContext(true); + int oldTotal = dbContext.Orders.Count(); + DateTime dateTime = dbContext.Orders.Max(o => o.AddedDateTime).AddDays(-30); + int rowsToDelete = dbContext.Orders.Where(o => o.ModifiedDateTime != null && o.ModifiedDateTime >= dateTime).Count(); + int rowsDeleted = dbContext.Orders.Where(o => o.ModifiedDateTime != null && o.ModifiedDateTime >= dateTime) + .DeleteFromQuery(); + int newTotal = dbContext.Orders.Count(); - Assert.IsTrue(oldTotal > 0, "There must be orders in database that match this condition"); - Assert.IsTrue(rowsDeleted == rowsToDelete, "The number of rows deleted must match the count of the rows that matched in the database"); - Assert.IsTrue(oldTotal - newTotal == rowsDeleted, "The rows deleted must match the new count minues the old count"); - } - [TestMethod] - public void With_Delete_All() - { - var dbContext = SetupDbContext(true); - int oldTotal = dbContext.Orders.Count(); - int rowsDeleted = dbContext.Orders.DeleteFromQuery(); - int newTotal = dbContext.Orders.Count(); + Assert.IsTrue(oldTotal > 0, "There must be orders in database that match this condition"); + Assert.IsTrue(rowsDeleted == rowsToDelete, "The number of rows deleted must match the count of the rows that matched in the database"); + Assert.IsTrue(oldTotal - newTotal == rowsDeleted, "The rows deleted must match the new count minues the old count"); + } + [TestMethod] + public void With_Delete_All() + { + var dbContext = SetupDbContext(true); + int oldTotal = dbContext.Orders.Count(); + int rowsDeleted = dbContext.Orders.DeleteFromQuery(); + int newTotal = dbContext.Orders.Count(); - Assert.IsTrue(oldTotal > 0, "There must be orders in database that match this condition"); - Assert.IsTrue(rowsDeleted == oldTotal, "The number of rows deleted must match the count of existing rows in database"); - Assert.IsTrue(newTotal == 0, "The new count must be 0 to indicate all records were deleted"); - } - [TestMethod] - public void With_Different_Values() - { - var dbContext = SetupDbContext(true); - int oldTotal = dbContext.Orders.Count(); - DateTime dateTime = dbContext.Orders.Max(o => o.AddedDateTime).AddDays(-30); - var orders = dbContext.Orders.Where(o => o.Id == 1 && o.Active && o.ModifiedDateTime >= dateTime); - int rowsToDelete = orders.Count(); - int rowsDeleted = orders.DeleteFromQuery(); - int newTotal = dbContext.Orders.Count(); + Assert.IsTrue(oldTotal > 0, "There must be orders in database that match this condition"); + Assert.IsTrue(rowsDeleted == oldTotal, "The number of rows deleted must match the count of existing rows in database"); + Assert.IsTrue(newTotal == 0, "The new count must be 0 to indicate all records were deleted"); + } + [TestMethod] + public void With_Different_Values() + { + var dbContext = SetupDbContext(true); + int oldTotal = dbContext.Orders.Count(); + DateTime dateTime = dbContext.Orders.Max(o => o.AddedDateTime).AddDays(-30); + var orders = dbContext.Orders.Where(o => o.Id == 1 && o.Active && o.ModifiedDateTime >= dateTime); + int rowsToDelete = orders.Count(); + int rowsDeleted = orders.DeleteFromQuery(); + int newTotal = dbContext.Orders.Count(); - Assert.IsTrue(oldTotal > 0, "There must be orders in database that match this condition"); - Assert.IsTrue(rowsDeleted == rowsToDelete, "The number of rows deleted must match the count of the rows that matched in the database"); - Assert.IsTrue(oldTotal - newTotal == rowsDeleted, "The rows deleted must match the new count minues the old count"); - } - [TestMethod] - public void With_Empty_List() - { - var dbContext = SetupDbContext(false); - int oldTotal = dbContext.Orders.Count(); - int rowsDeleted = dbContext.Orders.DeleteFromQuery(); - int newTotal = dbContext.Orders.Count(); + Assert.IsTrue(oldTotal > 0, "There must be orders in database that match this condition"); + Assert.IsTrue(rowsDeleted == rowsToDelete, "The number of rows deleted must match the count of the rows that matched in the database"); + Assert.IsTrue(oldTotal - newTotal == rowsDeleted, "The rows deleted must match the new count minues the old count"); + } + [TestMethod] + public void With_Empty_List() + { + var dbContext = SetupDbContext(false); + int oldTotal = dbContext.Orders.Count(); + int rowsDeleted = dbContext.Orders.DeleteFromQuery(); + int newTotal = dbContext.Orders.Count(); - Assert.IsTrue(oldTotal == 0, "There must be no orders in database that match this condition"); - Assert.IsTrue(rowsDeleted == oldTotal, "The number of rows deleted must match the count of existing rows in database"); - Assert.IsTrue(newTotal == 0, "The new count must be 0 to indicate all records were deleted"); - } - [TestMethod] - public void With_Schema() - { - var dbContext = SetupDbContext(true, PopulateDataMode.Schema); - int oldTotal = dbContext.ProductsWithCustomSchema.Count(); - int rowsDeleted = dbContext.ProductsWithCustomSchema.DeleteFromQuery(); - int newTotal = dbContext.ProductsWithCustomSchema.Count(); + Assert.IsTrue(oldTotal == 0, "There must be no orders in database that match this condition"); + Assert.IsTrue(rowsDeleted == oldTotal, "The number of rows deleted must match the count of existing rows in database"); + Assert.IsTrue(newTotal == 0, "The new count must be 0 to indicate all records were deleted"); + } + [TestMethod] + public void With_Schema() + { + var dbContext = SetupDbContext(true, PopulateDataMode.Schema); + int oldTotal = dbContext.ProductsWithCustomSchema.Count(); + int rowsDeleted = dbContext.ProductsWithCustomSchema.DeleteFromQuery(); + int newTotal = dbContext.ProductsWithCustomSchema.Count(); - Assert.IsTrue(oldTotal > 0, "There must be products in database that match this condition"); - Assert.IsTrue(rowsDeleted == oldTotal, "The number of rows deleted must match the count of existing rows in database"); - Assert.IsTrue(newTotal == 0, "The new count must be 0 to indicate all records were deleted"); - } - [TestMethod] - public void With_Transaction() + Assert.IsTrue(oldTotal > 0, "There must be products in database that match this condition"); + Assert.IsTrue(rowsDeleted == oldTotal, "The number of rows deleted must match the count of existing rows in database"); + Assert.IsTrue(newTotal == 0, "The new count must be 0 to indicate all records were deleted"); + } + [TestMethod] + public void With_Transaction() + { + var dbContext = SetupDbContext(true); + int rowsDeleted; + int oldTotal = dbContext.Orders.Count(); + var orders = dbContext.Orders.Where(o => o.Price <= 10); + int rowsToDelete = orders.Count(); + using (var transaction = dbContext.Database.BeginTransaction()) { - var dbContext = SetupDbContext(true); - int rowsDeleted; - int oldTotal = dbContext.Orders.Count(); - var orders = dbContext.Orders.Where(o => o.Price <= 10); - int rowsToDelete = orders.Count(); - using (var transaction = dbContext.Database.BeginTransaction()) - { - rowsDeleted = orders.DeleteFromQuery(); - transaction.Rollback(); - } - int newTotal = dbContext.Orders.Count(); - - Assert.IsTrue(oldTotal > 0, "There must be orders in database that match this condition (Price < $10)"); - Assert.IsTrue(rowsDeleted == orders.Count(), "The number of rows update must match the count of rows that match the condtion (Price < $10)"); - Assert.IsTrue(newTotal == oldTotal, "The new count must match the old count since the transaction was rollbacked"); + rowsDeleted = orders.DeleteFromQuery(); + transaction.Rollback(); } + int newTotal = dbContext.Orders.Count(); + + Assert.IsTrue(oldTotal > 0, "There must be orders in database that match this condition (Price < $10)"); + Assert.IsTrue(rowsDeleted == orders.Count(), "The number of rows update must match the count of rows that match the condtion (Price < $10)"); + Assert.IsTrue(newTotal == oldTotal, "The new count must match the old count since the transaction was rollbacked"); } } \ No newline at end of file diff --git a/N.EntityFrameworkCore.Extensions.Test/DbContextExtensions/DeleteFromQueryAsync.cs b/N.EntityFrameworkCore.Extensions.Test/DbContextExtensions/DeleteFromQueryAsync.cs index fec1b20..81505c2 100644 --- a/N.EntityFrameworkCore.Extensions.Test/DbContextExtensions/DeleteFromQueryAsync.cs +++ b/N.EntityFrameworkCore.Extensions.Test/DbContextExtensions/DeleteFromQueryAsync.cs @@ -4,147 +4,146 @@ using System.Threading.Tasks; using Microsoft.VisualStudio.TestTools.UnitTesting; -namespace N.EntityFrameworkCore.Extensions.Test.DbContextExtensions +namespace N.EntityFrameworkCore.Extensions.Test.DbContextExtensions; + +[TestClass] +public class DeleteFromQueryAsync : DbContextExtensionsBase { - [TestClass] - public class DeleteFromQueryAsync : DbContextExtensionsBase + [TestMethod] + public async Task With_Boolean_Value() { - [TestMethod] - public async Task With_Boolean_Value() - { - var dbContext = SetupDbContext(true); - var products = dbContext.Products.Where(p => p.OutOfStock); - int oldTotal = products.Count(a => a.OutOfStock); - int rowUpdated = await products.DeleteFromQueryAsync(); - int newTotal = dbContext.Products.Count(o => o.OutOfStock); + var dbContext = SetupDbContext(true); + var products = dbContext.Products.Where(p => p.OutOfStock); + int oldTotal = products.Count(a => a.OutOfStock); + int rowUpdated = await products.DeleteFromQueryAsync(); + int newTotal = dbContext.Products.Count(o => o.OutOfStock); - Assert.IsTrue(oldTotal > 0, "There must be products in database that match this condition (OutOfStock == true)"); - Assert.IsTrue(rowUpdated == oldTotal, "The number of rows update must match the count of rows that match the condition (OutOfStock == false)"); - Assert.IsTrue(newTotal == 0, "The new count must be 0 to indicate all records were updated"); - } - [TestMethod] - public async Task With_Child_Relationship() - { - var dbContext = SetupDbContext(true); - var products = dbContext.Products.Where(p => !p.ProductCategory.Active); - int oldTotal = products.Count(); - int rowsDeleted = await products.DeleteFromQueryAsync(); - int newTotal = products.Count(); + Assert.IsTrue(oldTotal > 0, "There must be products in database that match this condition (OutOfStock == true)"); + Assert.IsTrue(rowUpdated == oldTotal, "The number of rows update must match the count of rows that match the condition (OutOfStock == false)"); + Assert.IsTrue(newTotal == 0, "The new count must be 0 to indicate all records were updated"); + } + [TestMethod] + public async Task With_Child_Relationship() + { + var dbContext = SetupDbContext(true); + var products = dbContext.Products.Where(p => !p.ProductCategory.Active); + int oldTotal = products.Count(); + int rowsDeleted = await products.DeleteFromQueryAsync(); + int newTotal = products.Count(); - Assert.IsTrue(oldTotal > 0, "There must be products in database that match this condition (ProductCategory.Active == false)"); - Assert.IsTrue(rowsDeleted == oldTotal, "The number of rows update must match the count of rows that match the condition (ProductCategory.Active == false)"); - Assert.IsTrue(newTotal == 0, "The new count must be 0 to indicate all records were deleted"); - } - [TestMethod] - public async Task With_Decimal_Using_IQuerable() - { - var dbContext = SetupDbContext(true); - var orders = dbContext.Orders.Where(o => o.Price <= 10); - int oldTotal = orders.Count(); - int rowsDeleted = await orders.DeleteFromQueryAsync(); - int newTotal = orders.Count(); + Assert.IsTrue(oldTotal > 0, "There must be products in database that match this condition (ProductCategory.Active == false)"); + Assert.IsTrue(rowsDeleted == oldTotal, "The number of rows update must match the count of rows that match the condition (ProductCategory.Active == false)"); + Assert.IsTrue(newTotal == 0, "The new count must be 0 to indicate all records were deleted"); + } + [TestMethod] + public async Task With_Decimal_Using_IQuerable() + { + var dbContext = SetupDbContext(true); + var orders = dbContext.Orders.Where(o => o.Price <= 10); + int oldTotal = orders.Count(); + int rowsDeleted = await orders.DeleteFromQueryAsync(); + int newTotal = orders.Count(); - Assert.IsTrue(oldTotal > 0, "There must be orders in database that match this condition"); - Assert.IsTrue(rowsDeleted == oldTotal, "The number of rows deleted must match the count of existing rows in database"); - Assert.IsTrue(newTotal == 0, "Delete() Failed: must be 0 to indicate all records were deleted"); - } - [TestMethod] - public async Task With_Decimal_Using_IEnumerable() - { - var dbContext = SetupDbContext(true); - var orders = dbContext.Orders.Where(o => o.Price <= 10); - int oldTotal = orders.Count(); - int rowsDeleted = await orders.DeleteFromQueryAsync(); - int newTotal = orders.Count(); + Assert.IsTrue(oldTotal > 0, "There must be orders in database that match this condition"); + Assert.IsTrue(rowsDeleted == oldTotal, "The number of rows deleted must match the count of existing rows in database"); + Assert.IsTrue(newTotal == 0, "Delete() Failed: must be 0 to indicate all records were deleted"); + } + [TestMethod] + public async Task With_Decimal_Using_IEnumerable() + { + var dbContext = SetupDbContext(true); + var orders = dbContext.Orders.Where(o => o.Price <= 10); + int oldTotal = orders.Count(); + int rowsDeleted = await orders.DeleteFromQueryAsync(); + int newTotal = orders.Count(); - Assert.IsTrue(oldTotal > 0, "There must be orders in database that match this condition"); - Assert.IsTrue(rowsDeleted == oldTotal, "The number of rows deleted must match the count of existing rows in database"); - Assert.IsTrue(newTotal == 0, "The new count must be 0 to indicate all records were deleted"); - } - [TestMethod] - public async Task With_DateTime() - { - var dbContext = SetupDbContext(true); - int oldTotal = dbContext.Orders.Count(); - DateTime dateTime = dbContext.Orders.Max(o => o.AddedDateTime).AddDays(-30); - int rowsToDelete = dbContext.Orders.Where(o => o.ModifiedDateTime != null && o.ModifiedDateTime >= dateTime).Count(); - int rowsDeleted = await dbContext.Orders.Where(o => o.ModifiedDateTime != null && o.ModifiedDateTime >= dateTime) - .DeleteFromQueryAsync(); - int newTotal = dbContext.Orders.Count(); + Assert.IsTrue(oldTotal > 0, "There must be orders in database that match this condition"); + Assert.IsTrue(rowsDeleted == oldTotal, "The number of rows deleted must match the count of existing rows in database"); + Assert.IsTrue(newTotal == 0, "The new count must be 0 to indicate all records were deleted"); + } + [TestMethod] + public async Task With_DateTime() + { + var dbContext = SetupDbContext(true); + int oldTotal = dbContext.Orders.Count(); + DateTime dateTime = dbContext.Orders.Max(o => o.AddedDateTime).AddDays(-30); + int rowsToDelete = dbContext.Orders.Where(o => o.ModifiedDateTime != null && o.ModifiedDateTime >= dateTime).Count(); + int rowsDeleted = await dbContext.Orders.Where(o => o.ModifiedDateTime != null && o.ModifiedDateTime >= dateTime) + .DeleteFromQueryAsync(); + int newTotal = dbContext.Orders.Count(); - Assert.IsTrue(oldTotal > 0, "There must be orders in database that match this condition"); - Assert.IsTrue(rowsDeleted == rowsToDelete, "The number of rows deleted must match the count of the rows that matched in the database"); - Assert.IsTrue(oldTotal - newTotal == rowsDeleted, "The rows deleted must match the new count minues the old count"); - } - [TestMethod] - public async Task With_Delete_All() - { - var dbContext = SetupDbContext(true); - int oldTotal = dbContext.Orders.Count(); - int rowsDeleted = await dbContext.Orders.DeleteFromQueryAsync(); - int newTotal = dbContext.Orders.Count(); + Assert.IsTrue(oldTotal > 0, "There must be orders in database that match this condition"); + Assert.IsTrue(rowsDeleted == rowsToDelete, "The number of rows deleted must match the count of the rows that matched in the database"); + Assert.IsTrue(oldTotal - newTotal == rowsDeleted, "The rows deleted must match the new count minues the old count"); + } + [TestMethod] + public async Task With_Delete_All() + { + var dbContext = SetupDbContext(true); + int oldTotal = dbContext.Orders.Count(); + int rowsDeleted = await dbContext.Orders.DeleteFromQueryAsync(); + int newTotal = dbContext.Orders.Count(); - Assert.IsTrue(oldTotal > 0, "There must be orders in database that match this condition"); - Assert.IsTrue(rowsDeleted == oldTotal, "The number of rows deleted must match the count of existing rows in database"); - Assert.IsTrue(newTotal == 0, "The new count must be 0 to indicate all records were deleted"); - } - [TestMethod] - public async Task With_Different_Values() - { - var dbContext = SetupDbContext(true); - int oldTotal = dbContext.Orders.Count(); - DateTime dateTime = dbContext.Orders.Max(o => o.AddedDateTime).AddDays(-30); - var orders = dbContext.Orders.Where(o => o.Id == 1 && o.Active && o.ModifiedDateTime >= dateTime); - int rowsToDelete = orders.Count(); - int rowsDeleted = await orders.DeleteFromQueryAsync(); - int newTotal = dbContext.Orders.Count(); + Assert.IsTrue(oldTotal > 0, "There must be orders in database that match this condition"); + Assert.IsTrue(rowsDeleted == oldTotal, "The number of rows deleted must match the count of existing rows in database"); + Assert.IsTrue(newTotal == 0, "The new count must be 0 to indicate all records were deleted"); + } + [TestMethod] + public async Task With_Different_Values() + { + var dbContext = SetupDbContext(true); + int oldTotal = dbContext.Orders.Count(); + DateTime dateTime = dbContext.Orders.Max(o => o.AddedDateTime).AddDays(-30); + var orders = dbContext.Orders.Where(o => o.Id == 1 && o.Active && o.ModifiedDateTime >= dateTime); + int rowsToDelete = orders.Count(); + int rowsDeleted = await orders.DeleteFromQueryAsync(); + int newTotal = dbContext.Orders.Count(); - Assert.IsTrue(oldTotal > 0, "There must be orders in database that match this condition"); - Assert.IsTrue(rowsDeleted == rowsToDelete, "The number of rows deleted must match the count of the rows that matched in the database"); - Assert.IsTrue(oldTotal - newTotal == rowsDeleted, "The rows deleted must match the new count minues the old count"); - } - [TestMethod] - public async Task With_Empty_List() - { - var dbContext = SetupDbContext(false); - int oldTotal = dbContext.Orders.Count(); - int rowsDeleted = await dbContext.Orders.DeleteFromQueryAsync(); - int newTotal = dbContext.Orders.Count(); + Assert.IsTrue(oldTotal > 0, "There must be orders in database that match this condition"); + Assert.IsTrue(rowsDeleted == rowsToDelete, "The number of rows deleted must match the count of the rows that matched in the database"); + Assert.IsTrue(oldTotal - newTotal == rowsDeleted, "The rows deleted must match the new count minues the old count"); + } + [TestMethod] + public async Task With_Empty_List() + { + var dbContext = SetupDbContext(false); + int oldTotal = dbContext.Orders.Count(); + int rowsDeleted = await dbContext.Orders.DeleteFromQueryAsync(); + int newTotal = dbContext.Orders.Count(); - Assert.IsTrue(oldTotal == 0, "There must be no orders in database that match this condition"); - Assert.IsTrue(rowsDeleted == oldTotal, "The number of rows deleted must match the count of existing rows in database"); - Assert.IsTrue(newTotal == 0, "The new count must be 0 to indicate all records were deleted"); - } - [TestMethod] - public async Task With_Schema() - { - var dbContext = SetupDbContext(true, PopulateDataMode.Schema); - int oldTotal = dbContext.ProductsWithCustomSchema.Count(); - int rowsDeleted = await dbContext.ProductsWithCustomSchema.DeleteFromQueryAsync(); - int newTotal = dbContext.ProductsWithCustomSchema.Count(); + Assert.IsTrue(oldTotal == 0, "There must be no orders in database that match this condition"); + Assert.IsTrue(rowsDeleted == oldTotal, "The number of rows deleted must match the count of existing rows in database"); + Assert.IsTrue(newTotal == 0, "The new count must be 0 to indicate all records were deleted"); + } + [TestMethod] + public async Task With_Schema() + { + var dbContext = SetupDbContext(true, PopulateDataMode.Schema); + int oldTotal = dbContext.ProductsWithCustomSchema.Count(); + int rowsDeleted = await dbContext.ProductsWithCustomSchema.DeleteFromQueryAsync(); + int newTotal = dbContext.ProductsWithCustomSchema.Count(); - Assert.IsTrue(oldTotal > 0, "There must be products in database that match this condition"); - Assert.IsTrue(rowsDeleted == oldTotal, "The number of rows deleted must match the count of existing rows in database"); - Assert.IsTrue(newTotal == 0, "The new count must be 0 to indicate all records were deleted"); - } - [TestMethod] - public async Task With_Transaction() + Assert.IsTrue(oldTotal > 0, "There must be products in database that match this condition"); + Assert.IsTrue(rowsDeleted == oldTotal, "The number of rows deleted must match the count of existing rows in database"); + Assert.IsTrue(newTotal == 0, "The new count must be 0 to indicate all records were deleted"); + } + [TestMethod] + public async Task With_Transaction() + { + var dbContext = SetupDbContext(true); + int rowsDeleted; + int oldTotal = dbContext.Orders.Count(); + var orders = dbContext.Orders.Where(o => o.Price <= 10); + int rowsToDelete = orders.Count(); + using (var transaction = dbContext.Database.BeginTransaction()) { - var dbContext = SetupDbContext(true); - int rowsDeleted; - int oldTotal = dbContext.Orders.Count(); - var orders = dbContext.Orders.Where(o => o.Price <= 10); - int rowsToDelete = orders.Count(); - using (var transaction = dbContext.Database.BeginTransaction()) - { - rowsDeleted = await orders.DeleteFromQueryAsync(); - transaction.Rollback(); - } - int newTotal = dbContext.Orders.Count(); - - Assert.IsTrue(oldTotal > 0, "There must be orders in database that match this condition (Price < $10)"); - Assert.IsTrue(rowsDeleted == orders.Count(), "The number of rows update must match the count of rows that match the condtion (Price < $10)"); - Assert.IsTrue(newTotal == oldTotal, "The new count must match the old count since the transaction was rollbacked"); + rowsDeleted = await orders.DeleteFromQueryAsync(); + transaction.Rollback(); } + int newTotal = dbContext.Orders.Count(); + + Assert.IsTrue(oldTotal > 0, "There must be orders in database that match this condition (Price < $10)"); + Assert.IsTrue(rowsDeleted == orders.Count(), "The number of rows update must match the count of rows that match the condtion (Price < $10)"); + Assert.IsTrue(newTotal == oldTotal, "The new count must match the old count since the transaction was rollbacked"); } } \ No newline at end of file diff --git a/N.EntityFrameworkCore.Extensions.Test/DbContextExtensions/Fetch.cs b/N.EntityFrameworkCore.Extensions.Test/DbContextExtensions/Fetch.cs index 5fec86d..d4c84d2 100644 --- a/N.EntityFrameworkCore.Extensions.Test/DbContextExtensions/Fetch.cs +++ b/N.EntityFrameworkCore.Extensions.Test/DbContextExtensions/Fetch.cs @@ -2,177 +2,176 @@ using System.Linq; using Microsoft.VisualStudio.TestTools.UnitTesting; -namespace N.EntityFrameworkCore.Extensions.Test.DbContextExtensions +namespace N.EntityFrameworkCore.Extensions.Test.DbContextExtensions; + +[TestClass] +public class Fetch : DbContextExtensionsBase { - [TestClass] - public class Fetch : DbContextExtensionsBase + [TestMethod] + public void With_BulkInsert() { - [TestMethod] - public void With_BulkInsert() + var dbContext = SetupDbContext(true); + DateTime dateTime = dbContext.Orders.Max(o => o.AddedDateTime).AddDays(-30); + var orders = dbContext.Orders.Where(o => o.AddedDateTime <= dateTime); + int totalOrdersToFetch = orders.Count(); + int totalOrdersFetched = 0; + int batchSize = 5000; + orders.Fetch(result => { - var dbContext = SetupDbContext(true); - DateTime dateTime = dbContext.Orders.Max(o => o.AddedDateTime).AddDays(-30); - var orders = dbContext.Orders.Where(o => o.AddedDateTime <= dateTime); - int totalOrdersToFetch = orders.Count(); - int totalOrdersFetched = 0; - int batchSize = 5000; - orders.Fetch(result => + totalOrdersFetched += result.Results.Count(); + var ordersFetched = result.Results; + foreach (var orderFetched in ordersFetched) { - totalOrdersFetched += result.Results.Count(); - var ordersFetched = result.Results; - foreach (var orderFetched in ordersFetched) - { - orderFetched.Price = 75; - } - dbContext.BulkInsert(ordersFetched); - }, options => { options.BatchSize = batchSize; }); + orderFetched.Price = 75; + } + dbContext.BulkInsert(ordersFetched); + }, options => { options.BatchSize = batchSize; }); - int totalOrder = orders.Count(); - int totalOrderInserted = orders.Where(o => o.Price == 75).Count(); - Assert.IsTrue(totalOrdersToFetch == totalOrdersFetched, "The total number of rows fetched must match the number of rows to fetch"); - Assert.IsTrue(totalOrderInserted == totalOrdersFetched, "The total number of rows updated must match the number of rows that were fetched"); - Assert.IsTrue(totalOrder - totalOrdersToFetch == totalOrderInserted, "The total number of rows must match the number of rows that were updated"); - } - [TestMethod] - public void With_BulkUpdate() + int totalOrder = orders.Count(); + int totalOrderInserted = orders.Where(o => o.Price == 75).Count(); + Assert.IsTrue(totalOrdersToFetch == totalOrdersFetched, "The total number of rows fetched must match the number of rows to fetch"); + Assert.IsTrue(totalOrderInserted == totalOrdersFetched, "The total number of rows updated must match the number of rows that were fetched"); + Assert.IsTrue(totalOrder - totalOrdersToFetch == totalOrderInserted, "The total number of rows must match the number of rows that were updated"); + } + [TestMethod] + public void With_BulkUpdate() + { + var dbContext = SetupDbContext(true); + DateTime dateTime = dbContext.Orders.Max(o => o.AddedDateTime).AddDays(-30); + var orders = dbContext.Orders.Where(o => o.AddedDateTime <= dateTime); + int totalOrdersToFetch = orders.Count(); + int totalOrdersFetched = 0; + int batchSize = 5000; + orders.Fetch(result => { - var dbContext = SetupDbContext(true); - DateTime dateTime = dbContext.Orders.Max(o => o.AddedDateTime).AddDays(-30); - var orders = dbContext.Orders.Where(o => o.AddedDateTime <= dateTime); - int totalOrdersToFetch = orders.Count(); - int totalOrdersFetched = 0; - int batchSize = 5000; - orders.Fetch(result => + totalOrdersFetched += result.Results.Count(); + var ordersFetched = result.Results; + foreach (var orderFetched in ordersFetched) { - totalOrdersFetched += result.Results.Count(); - var ordersFetched = result.Results; - foreach (var orderFetched in ordersFetched) - { - orderFetched.Price = 75; - } - dbContext.BulkUpdate(ordersFetched); - }, options => { options.BatchSize = batchSize; }); + orderFetched.Price = 75; + } + dbContext.BulkUpdate(ordersFetched); + }, options => { options.BatchSize = batchSize; }); + + int totalOrder = orders.Count(); + int totalOrderUpdated = orders.Where(o => o.Price == 75).Count(); + Assert.IsTrue(totalOrdersToFetch == totalOrdersFetched, "The total number of rows fetched must match the number of rows to fetch"); + Assert.IsTrue(totalOrderUpdated == totalOrdersFetched, "The total number of rows updated must match the number of rows that were fetched"); + Assert.IsTrue(totalOrder == totalOrderUpdated, "The total number of rows must match the number of rows that were updated"); + } + [TestMethod] + public void With_DateTime() + { + var dbContext = SetupDbContext(true); + int batchSize = 1000; + int batchCount = 0; + int totalCount = 0; + DateTime dateTime = dbContext.Orders.Max(o => o.AddedDateTime).AddDays(-30); + var orders = dbContext.Orders.Where(o => o.AddedDateTime <= dateTime); + int expectedTotalCount = orders.Count(); + int expectedBatchCount = (int)Math.Ceiling(expectedTotalCount / (decimal)batchSize); - int totalOrder = orders.Count(); - int totalOrderUpdated = orders.Where(o => o.Price == 75).Count(); - Assert.IsTrue(totalOrdersToFetch == totalOrdersFetched, "The total number of rows fetched must match the number of rows to fetch"); - Assert.IsTrue(totalOrderUpdated == totalOrdersFetched, "The total number of rows updated must match the number of rows that were fetched"); - Assert.IsTrue(totalOrder == totalOrderUpdated, "The total number of rows must match the number of rows that were updated"); - } - [TestMethod] - public void With_DateTime() + orders.Fetch(result => { - var dbContext = SetupDbContext(true); - int batchSize = 1000; - int batchCount = 0; - int totalCount = 0; - DateTime dateTime = dbContext.Orders.Max(o => o.AddedDateTime).AddDays(-30); - var orders = dbContext.Orders.Where(o => o.AddedDateTime <= dateTime); - int expectedTotalCount = orders.Count(); - int expectedBatchCount = (int)Math.Ceiling(expectedTotalCount / (decimal)batchSize); + batchCount++; + totalCount += result.Results.Count(); + Assert.IsTrue(result.Results.Count <= batchSize, "The count of results in each batch callback should less than or equal to the batchSize"); + }, options => { options.BatchSize = batchSize; }); - orders.Fetch(result => - { - batchCount++; - totalCount += result.Results.Count(); - Assert.IsTrue(result.Results.Count <= batchSize, "The count of results in each batch callback should less than or equal to the batchSize"); - }, options => { options.BatchSize = batchSize; }); + Assert.IsTrue(expectedTotalCount > 0, "There must be orders in database that match this condition"); + Assert.IsTrue(expectedTotalCount == totalCount, "The total number of rows fetched must match the count of existing rows in database"); + Assert.IsTrue(expectedBatchCount == batchCount, "The total number of batches fetched must match what is expected"); + } + [TestMethod] + public void With_Decimal() + { + var dbContext = SetupDbContext(true); + int batchSize = 1000; + int batchCount = 0; + int totalCount = 0; + var orders = dbContext.Orders.Where(o => o.Price < 10M); + int expectedTotalCount = orders.Count(); + int expectedBatchCount = (int)Math.Ceiling(expectedTotalCount / (decimal)batchSize); - Assert.IsTrue(expectedTotalCount > 0, "There must be orders in database that match this condition"); - Assert.IsTrue(expectedTotalCount == totalCount, "The total number of rows fetched must match the count of existing rows in database"); - Assert.IsTrue(expectedBatchCount == batchCount, "The total number of batches fetched must match what is expected"); - } - [TestMethod] - public void With_Decimal() + orders.Fetch(result => { - var dbContext = SetupDbContext(true); - int batchSize = 1000; - int batchCount = 0; - int totalCount = 0; - var orders = dbContext.Orders.Where(o => o.Price < 10M); - int expectedTotalCount = orders.Count(); - int expectedBatchCount = (int)Math.Ceiling(expectedTotalCount / (decimal)batchSize); + batchCount++; + totalCount += result.Results.Count(); + Assert.IsTrue(result.Results.Count <= batchSize, "The count of results in each batch callback should less than or equal to the batchSize"); + }, options => { options.BatchSize = batchSize; }); - orders.Fetch(result => - { - batchCount++; - totalCount += result.Results.Count(); - Assert.IsTrue(result.Results.Count <= batchSize, "The count of results in each batch callback should less than or equal to the batchSize"); - }, options => { options.BatchSize = batchSize; }); + Assert.IsTrue(expectedTotalCount > 0, "There must be orders in database that match this condition"); + Assert.IsTrue(expectedTotalCount == totalCount, "The total number of rows fetched must match the count of existing rows in database"); + Assert.IsTrue(expectedBatchCount == batchCount, "The total number of batches fetched must match what is expected"); + } + [TestMethod] + public void With_Enum() + { + var dbContext = SetupDbContext(true); + int batchSize = 1000; + int batchCount = 0; + int totalCount = 0; + var products = dbContext.Products.Where(o => o.Price < 10M); + int expectedTotalCount = products.Count(); + int expectedBatchCount = (int)Math.Ceiling(expectedTotalCount / (decimal)batchSize); - Assert.IsTrue(expectedTotalCount > 0, "There must be orders in database that match this condition"); - Assert.IsTrue(expectedTotalCount == totalCount, "The total number of rows fetched must match the count of existing rows in database"); - Assert.IsTrue(expectedBatchCount == batchCount, "The total number of batches fetched must match what is expected"); - } - [TestMethod] - public void With_Enum() + products.Fetch(result => { - var dbContext = SetupDbContext(true); - int batchSize = 1000; - int batchCount = 0; - int totalCount = 0; - var products = dbContext.Products.Where(o => o.Price < 10M); - int expectedTotalCount = products.Count(); - int expectedBatchCount = (int)Math.Ceiling(expectedTotalCount / (decimal)batchSize); + batchCount++; + totalCount += result.Results.Count(); + Assert.IsTrue(result.Results.Count <= batchSize, "The count of results in each batch callback should less than or equal to the batchSize"); + }, options => { options.BatchSize = batchSize; }); - products.Fetch(result => - { - batchCount++; - totalCount += result.Results.Count(); - Assert.IsTrue(result.Results.Count <= batchSize, "The count of results in each batch callback should less than or equal to the batchSize"); - }, options => { options.BatchSize = batchSize; }); + Assert.IsTrue(expectedTotalCount > 0, "There must be products in database that match this condition"); + Assert.IsTrue(expectedTotalCount == totalCount, "The total number of rows fetched must match the count of existing rows in database"); + Assert.IsTrue(expectedBatchCount == batchCount, "The total number of batches fetched must match what is expected"); + } + [TestMethod] + public void With_Options_IgnoreColumns() + { + var dbContext = SetupDbContext(true); + int batchSize = 1000; + int batchCount = 0; + int totalCount = 0; + var orders = dbContext.Orders.Where(o => o.Price < 10M); + int expectedTotalCount = orders.Count(); + int expectedBatchCount = (int)Math.Ceiling(expectedTotalCount / (decimal)batchSize); - Assert.IsTrue(expectedTotalCount > 0, "There must be products in database that match this condition"); - Assert.IsTrue(expectedTotalCount == totalCount, "The total number of rows fetched must match the count of existing rows in database"); - Assert.IsTrue(expectedBatchCount == batchCount, "The total number of batches fetched must match what is expected"); - } - [TestMethod] - public void With_Options_IgnoreColumns() + orders.Fetch(result => { - var dbContext = SetupDbContext(true); - int batchSize = 1000; - int batchCount = 0; - int totalCount = 0; - var orders = dbContext.Orders.Where(o => o.Price < 10M); - int expectedTotalCount = orders.Count(); - int expectedBatchCount = (int)Math.Ceiling(expectedTotalCount / (decimal)batchSize); + batchCount++; + totalCount += result.Results.Count(); + bool isAllExternalIdNull = !result.Results.Any(o => o.ExternalId != null); + Assert.IsTrue(isAllExternalIdNull, "All records should have ExternalId equal to NULL since it was not loaded."); + Assert.IsTrue(result.Results.Count <= batchSize, "The count of results in each batch callback should less than or equal to the batchSize"); + }, options => { options.BatchSize = batchSize; options.IgnoreColumns = s => new { s.ExternalId }; }); - orders.Fetch(result => - { - batchCount++; - totalCount += result.Results.Count(); - bool isAllExternalIdNull = !result.Results.Any(o => o.ExternalId != null); - Assert.IsTrue(isAllExternalIdNull, "All records should have ExternalId equal to NULL since it was not loaded."); - Assert.IsTrue(result.Results.Count <= batchSize, "The count of results in each batch callback should less than or equal to the batchSize"); - }, options => { options.BatchSize = batchSize; options.IgnoreColumns = s => new { s.ExternalId }; }); + Assert.IsTrue(expectedTotalCount > 0, "There must be orders in database that match this condition"); + Assert.IsTrue(expectedTotalCount == totalCount, "The total number of rows fetched must match the count of existing rows in database"); + Assert.IsTrue(expectedBatchCount == batchCount, "The total number of batches fetched must match what is expected"); + } + [TestMethod] + public void With_Options_InputColumns() + { + var dbContext = SetupDbContext(true); + int batchSize = 1000; + int batchCount = 0; + int totalCount = 0; + var orders = dbContext.Orders.Where(o => o.Price < 10M); + int expectedTotalCount = orders.Count(); + int expectedBatchCount = (int)Math.Ceiling(expectedTotalCount / (decimal)batchSize); - Assert.IsTrue(expectedTotalCount > 0, "There must be orders in database that match this condition"); - Assert.IsTrue(expectedTotalCount == totalCount, "The total number of rows fetched must match the count of existing rows in database"); - Assert.IsTrue(expectedBatchCount == batchCount, "The total number of batches fetched must match what is expected"); - } - [TestMethod] - public void With_Options_InputColumns() + orders.Fetch(result => { - var dbContext = SetupDbContext(true); - int batchSize = 1000; - int batchCount = 0; - int totalCount = 0; - var orders = dbContext.Orders.Where(o => o.Price < 10M); - int expectedTotalCount = orders.Count(); - int expectedBatchCount = (int)Math.Ceiling(expectedTotalCount / (decimal)batchSize); - - orders.Fetch(result => - { - batchCount++; - totalCount += result.Results.Count(); - bool isAllExternalIdNull = !result.Results.Any(o => o.ExternalId != null); - Assert.IsTrue(isAllExternalIdNull, "All records should have ExternalId equal to NULL since it was not loaded."); - Assert.IsTrue(result.Results.Count <= batchSize, "The count of results in each batch callback should less than or equal to the batchSize"); - }, options => { options.BatchSize = batchSize; options.InputColumns = s => new { s.Id, s.Price }; }); + batchCount++; + totalCount += result.Results.Count(); + bool isAllExternalIdNull = !result.Results.Any(o => o.ExternalId != null); + Assert.IsTrue(isAllExternalIdNull, "All records should have ExternalId equal to NULL since it was not loaded."); + Assert.IsTrue(result.Results.Count <= batchSize, "The count of results in each batch callback should less than or equal to the batchSize"); + }, options => { options.BatchSize = batchSize; options.InputColumns = s => new { s.Id, s.Price }; }); - Assert.IsTrue(expectedTotalCount > 0, "There must be orders in database that match this condition"); - Assert.IsTrue(expectedTotalCount == totalCount, "The total number of rows fetched must match the count of existing rows in database"); - Assert.IsTrue(expectedBatchCount == batchCount, "The total number of batches fetched must match what is expected"); - } + Assert.IsTrue(expectedTotalCount > 0, "There must be orders in database that match this condition"); + Assert.IsTrue(expectedTotalCount == totalCount, "The total number of rows fetched must match the count of existing rows in database"); + Assert.IsTrue(expectedBatchCount == batchCount, "The total number of batches fetched must match what is expected"); } } \ No newline at end of file diff --git a/N.EntityFrameworkCore.Extensions.Test/DbContextExtensions/FetchAsync.cs b/N.EntityFrameworkCore.Extensions.Test/DbContextExtensions/FetchAsync.cs index c854bcd..c9a4865 100644 --- a/N.EntityFrameworkCore.Extensions.Test/DbContextExtensions/FetchAsync.cs +++ b/N.EntityFrameworkCore.Extensions.Test/DbContextExtensions/FetchAsync.cs @@ -3,192 +3,191 @@ using System.Threading.Tasks; using Microsoft.VisualStudio.TestTools.UnitTesting; -namespace N.EntityFrameworkCore.Extensions.Test.DbContextExtensions +namespace N.EntityFrameworkCore.Extensions.Test.DbContextExtensions; + +[TestClass] +public class FetchAsync : DbContextExtensionsBase { - [TestClass] - public class FetchAsync : DbContextExtensionsBase + [TestMethod] + public async Task With_BulkInsert() { - [TestMethod] - public async Task With_BulkInsert() + var dbContext = SetupDbContext(true); + DateTime dateTime = dbContext.Orders.Max(o => o.AddedDateTime).AddDays(-30); + var orders = dbContext.Orders.Where(o => o.AddedDateTime <= dateTime); + int totalOrdersToFetch = orders.Count(); + int totalOrdersFetched = 0; + int batchSize = 5000; + await orders.FetchAsync(async result => { - var dbContext = SetupDbContext(true); - DateTime dateTime = dbContext.Orders.Max(o => o.AddedDateTime).AddDays(-30); - var orders = dbContext.Orders.Where(o => o.AddedDateTime <= dateTime); - int totalOrdersToFetch = orders.Count(); - int totalOrdersFetched = 0; - int batchSize = 5000; - await orders.FetchAsync(async result => + totalOrdersFetched += result.Results.Count; + var ordersFetched = result.Results; + foreach (var orderFetched in ordersFetched) { - totalOrdersFetched += result.Results.Count; - var ordersFetched = result.Results; - foreach (var orderFetched in ordersFetched) - { - orderFetched.Price = 75; - } - await dbContext.BulkInsertAsync(ordersFetched); - }, options => { options.BatchSize = batchSize; }); + orderFetched.Price = 75; + } + await dbContext.BulkInsertAsync(ordersFetched); + }, options => { options.BatchSize = batchSize; }); - int totalOrder = orders.Count(); - int totalOrderInserted = orders.Where(o => o.Price == 75).Count(); - Assert.IsTrue(totalOrdersToFetch == totalOrdersFetched, "The total number of rows fetched must match the number of rows to fetch"); - Assert.IsTrue(totalOrderInserted == totalOrdersFetched, "The total number of rows updated must match the number of rows that were fetched"); - Assert.IsTrue(totalOrder - totalOrdersToFetch == totalOrderInserted, "The total number of rows must match the number of rows that were updated"); - } - [TestMethod] - public async Task With_BulkUpdate() + int totalOrder = orders.Count(); + int totalOrderInserted = orders.Where(o => o.Price == 75).Count(); + Assert.IsTrue(totalOrdersToFetch == totalOrdersFetched, "The total number of rows fetched must match the number of rows to fetch"); + Assert.IsTrue(totalOrderInserted == totalOrdersFetched, "The total number of rows updated must match the number of rows that were fetched"); + Assert.IsTrue(totalOrder - totalOrdersToFetch == totalOrderInserted, "The total number of rows must match the number of rows that were updated"); + } + [TestMethod] + public async Task With_BulkUpdate() + { + var dbContext = SetupDbContext(true); + DateTime dateTime = dbContext.Orders.Max(o => o.AddedDateTime).AddDays(-30); + var orders = dbContext.Orders.Where(o => o.AddedDateTime <= dateTime); + int totalOrdersToFetch = orders.Count(); + int totalOrdersFetched = 0; + int batchSize = 5000; + await orders.FetchAsync(async result => { - var dbContext = SetupDbContext(true); - DateTime dateTime = dbContext.Orders.Max(o => o.AddedDateTime).AddDays(-30); - var orders = dbContext.Orders.Where(o => o.AddedDateTime <= dateTime); - int totalOrdersToFetch = orders.Count(); - int totalOrdersFetched = 0; - int batchSize = 5000; - await orders.FetchAsync(async result => + totalOrdersFetched += result.Results.Count; + var ordersFetched = result.Results; + foreach (var orderFetched in ordersFetched) { - totalOrdersFetched += result.Results.Count; - var ordersFetched = result.Results; - foreach (var orderFetched in ordersFetched) - { - orderFetched.Price = 75; - } - await dbContext.BulkUpdateAsync(ordersFetched); - }, options => { options.BatchSize = batchSize; }); + orderFetched.Price = 75; + } + await dbContext.BulkUpdateAsync(ordersFetched); + }, options => { options.BatchSize = batchSize; }); - int totalOrder = orders.Count(); - int totalOrderUpdated = orders.Where(o => o.Price == 75).Count(); - Assert.IsTrue(totalOrdersToFetch == totalOrdersFetched, "The total number of rows fetched must match the number of rows to fetch"); - Assert.IsTrue(totalOrderUpdated == totalOrdersFetched, "The total number of rows updated must match the number of rows that were fetched"); - Assert.IsTrue(totalOrder == totalOrderUpdated, "The total number of rows must match the number of rows that were updated"); - } - [TestMethod] - public async Task With_DateTime() - { - var dbContext = SetupDbContext(true); - int batchSize = 1000; - int batchCount = 0; - int totalCount = 0; - DateTime dateTime = dbContext.Orders.Max(o => o.AddedDateTime).AddDays(-30); - var orders = dbContext.Orders.Where(o => o.AddedDateTime <= dateTime); - int expectedTotalCount = orders.Count(); - int expectedBatchCount = (int)Math.Ceiling(expectedTotalCount / (decimal)batchSize); + int totalOrder = orders.Count(); + int totalOrderUpdated = orders.Where(o => o.Price == 75).Count(); + Assert.IsTrue(totalOrdersToFetch == totalOrdersFetched, "The total number of rows fetched must match the number of rows to fetch"); + Assert.IsTrue(totalOrderUpdated == totalOrdersFetched, "The total number of rows updated must match the number of rows that were fetched"); + Assert.IsTrue(totalOrder == totalOrderUpdated, "The total number of rows must match the number of rows that were updated"); + } + [TestMethod] + public async Task With_DateTime() + { + var dbContext = SetupDbContext(true); + int batchSize = 1000; + int batchCount = 0; + int totalCount = 0; + DateTime dateTime = dbContext.Orders.Max(o => o.AddedDateTime).AddDays(-30); + var orders = dbContext.Orders.Where(o => o.AddedDateTime <= dateTime); + int expectedTotalCount = orders.Count(); + int expectedBatchCount = (int)Math.Ceiling(expectedTotalCount / (decimal)batchSize); - await orders.FetchAsync(async result => + await orders.FetchAsync(async result => + { + await Task.Run(() => { - await Task.Run(() => - { - batchCount++; - totalCount += result.Results.Count; - Assert.IsTrue(result.Results.Count <= batchSize, "The count of results in each batch callback should less than or equal to the batchSize"); - }); - }, options => { options.BatchSize = batchSize; }); + batchCount++; + totalCount += result.Results.Count; + Assert.IsTrue(result.Results.Count <= batchSize, "The count of results in each batch callback should less than or equal to the batchSize"); + }); + }, options => { options.BatchSize = batchSize; }); - Assert.IsTrue(expectedTotalCount > 0, "There must be orders in database that match this condition"); - Assert.IsTrue(expectedTotalCount == totalCount, "The total number of rows fetched must match the count of existing rows in database"); - Assert.IsTrue(expectedBatchCount == batchCount, "The total number of batches fetched must match what is expected"); - } - [TestMethod] - public async Task With_Decimal() - { - var dbContext = SetupDbContext(true); - int batchSize = 1000; - int batchCount = 0; - int totalCount = 0; - var orders = dbContext.Orders.Where(o => o.Price < 10M); - int expectedTotalCount = orders.Count(); - int expectedBatchCount = (int)Math.Ceiling(expectedTotalCount / (decimal)batchSize); + Assert.IsTrue(expectedTotalCount > 0, "There must be orders in database that match this condition"); + Assert.IsTrue(expectedTotalCount == totalCount, "The total number of rows fetched must match the count of existing rows in database"); + Assert.IsTrue(expectedBatchCount == batchCount, "The total number of batches fetched must match what is expected"); + } + [TestMethod] + public async Task With_Decimal() + { + var dbContext = SetupDbContext(true); + int batchSize = 1000; + int batchCount = 0; + int totalCount = 0; + var orders = dbContext.Orders.Where(o => o.Price < 10M); + int expectedTotalCount = orders.Count(); + int expectedBatchCount = (int)Math.Ceiling(expectedTotalCount / (decimal)batchSize); - await orders.FetchAsync(async result => + await orders.FetchAsync(async result => + { + await Task.Run(() => { - await Task.Run(() => - { - batchCount++; - totalCount += result.Results.Count(); - Assert.IsTrue(result.Results.Count <= batchSize, "The count of results in each batch callback should less than or equal to the batchSize"); - }); - }, options => { options.BatchSize = batchSize; }); + batchCount++; + totalCount += result.Results.Count(); + Assert.IsTrue(result.Results.Count <= batchSize, "The count of results in each batch callback should less than or equal to the batchSize"); + }); + }, options => { options.BatchSize = batchSize; }); - Assert.IsTrue(expectedTotalCount > 0, "There must be orders in database that match this condition"); - Assert.IsTrue(expectedTotalCount == totalCount, "The total number of rows fetched must match the count of existing rows in database"); - Assert.IsTrue(expectedBatchCount == batchCount, "The total number of batches fetched must match what is expected"); - } - [TestMethod] - public async Task With_Enum() - { - var dbContext = SetupDbContext(true); - int batchSize = 1000; - int batchCount = 0; - int totalCount = 0; - var products = dbContext.Products.Where(o => o.Price < 10M); - int expectedTotalCount = products.Count(); - int expectedBatchCount = (int)Math.Ceiling(expectedTotalCount / (decimal)batchSize); + Assert.IsTrue(expectedTotalCount > 0, "There must be orders in database that match this condition"); + Assert.IsTrue(expectedTotalCount == totalCount, "The total number of rows fetched must match the count of existing rows in database"); + Assert.IsTrue(expectedBatchCount == batchCount, "The total number of batches fetched must match what is expected"); + } + [TestMethod] + public async Task With_Enum() + { + var dbContext = SetupDbContext(true); + int batchSize = 1000; + int batchCount = 0; + int totalCount = 0; + var products = dbContext.Products.Where(o => o.Price < 10M); + int expectedTotalCount = products.Count(); + int expectedBatchCount = (int)Math.Ceiling(expectedTotalCount / (decimal)batchSize); - await products.FetchAsync(async result => + await products.FetchAsync(async result => + { + await Task.Run(() => { - await Task.Run(() => - { - batchCount++; - totalCount += result.Results.Count(); - Assert.IsTrue(result.Results.Count <= batchSize, "The count of results in each batch callback should less than or equal to the batchSize"); - }); - }, options => { options.BatchSize = batchSize; }); + batchCount++; + totalCount += result.Results.Count(); + Assert.IsTrue(result.Results.Count <= batchSize, "The count of results in each batch callback should less than or equal to the batchSize"); + }); + }, options => { options.BatchSize = batchSize; }); - Assert.IsTrue(expectedTotalCount > 0, "There must be products in database that match this condition"); - Assert.IsTrue(expectedTotalCount == totalCount, "The total number of rows fetched must match the count of existing rows in database"); - Assert.IsTrue(expectedBatchCount == batchCount, "The total number of batches fetched must match what is expected"); - } - [TestMethod] - public async Task With_Options_IgnoreColumns() - { - var dbContext = SetupDbContext(true); - int batchSize = 1000; - int batchCount = 0; - int totalCount = 0; - var orders = dbContext.Orders.Where(o => o.Price < 10M); - int expectedTotalCount = orders.Count(); - int expectedBatchCount = (int)Math.Ceiling(expectedTotalCount / (decimal)batchSize); + Assert.IsTrue(expectedTotalCount > 0, "There must be products in database that match this condition"); + Assert.IsTrue(expectedTotalCount == totalCount, "The total number of rows fetched must match the count of existing rows in database"); + Assert.IsTrue(expectedBatchCount == batchCount, "The total number of batches fetched must match what is expected"); + } + [TestMethod] + public async Task With_Options_IgnoreColumns() + { + var dbContext = SetupDbContext(true); + int batchSize = 1000; + int batchCount = 0; + int totalCount = 0; + var orders = dbContext.Orders.Where(o => o.Price < 10M); + int expectedTotalCount = orders.Count(); + int expectedBatchCount = (int)Math.Ceiling(expectedTotalCount / (decimal)batchSize); - await orders.FetchAsync(async result => + await orders.FetchAsync(async result => + { + await Task.Run(() => { - await Task.Run(() => - { - batchCount++; - totalCount += result.Results.Count; - bool isAllExternalIdNull = !result.Results.Any(o => o.ExternalId != null); - Assert.IsTrue(isAllExternalIdNull, "All records should have ExternalId equal to NULL since it was not loaded."); - Assert.IsTrue(result.Results.Count <= batchSize, "The count of results in each batch callback should less than or equal to the batchSize"); - }); - }, options => { options.BatchSize = batchSize; options.IgnoreColumns = s => new { s.ExternalId }; }); + batchCount++; + totalCount += result.Results.Count; + bool isAllExternalIdNull = !result.Results.Any(o => o.ExternalId != null); + Assert.IsTrue(isAllExternalIdNull, "All records should have ExternalId equal to NULL since it was not loaded."); + Assert.IsTrue(result.Results.Count <= batchSize, "The count of results in each batch callback should less than or equal to the batchSize"); + }); + }, options => { options.BatchSize = batchSize; options.IgnoreColumns = s => new { s.ExternalId }; }); - Assert.IsTrue(expectedTotalCount > 0, "There must be orders in database that match this condition"); - Assert.IsTrue(expectedTotalCount == totalCount, "The total number of rows fetched must match the count of existing rows in database"); - Assert.IsTrue(expectedBatchCount == batchCount, "The total number of batches fetched must match what is expected"); - } - [TestMethod] - public async Task With_Options_InputColumns() - { - var dbContext = SetupDbContext(true); - int batchSize = 1000; - int batchCount = 0; - int totalCount = 0; - var orders = dbContext.Orders.Where(o => o.Price < 10M); - int expectedTotalCount = orders.Count(); - int expectedBatchCount = (int)Math.Ceiling(expectedTotalCount / (decimal)batchSize); + Assert.IsTrue(expectedTotalCount > 0, "There must be orders in database that match this condition"); + Assert.IsTrue(expectedTotalCount == totalCount, "The total number of rows fetched must match the count of existing rows in database"); + Assert.IsTrue(expectedBatchCount == batchCount, "The total number of batches fetched must match what is expected"); + } + [TestMethod] + public async Task With_Options_InputColumns() + { + var dbContext = SetupDbContext(true); + int batchSize = 1000; + int batchCount = 0; + int totalCount = 0; + var orders = dbContext.Orders.Where(o => o.Price < 10M); + int expectedTotalCount = orders.Count(); + int expectedBatchCount = (int)Math.Ceiling(expectedTotalCount / (decimal)batchSize); - await orders.FetchAsync(async result => + await orders.FetchAsync(async result => + { + await Task.Run(() => { - await Task.Run(() => - { - batchCount++; - totalCount += result.Results.Count(); - bool isAllExternalIdNull = !result.Results.Any(o => o.ExternalId != null); - Assert.IsTrue(isAllExternalIdNull, "All records should have ExternalId equal to NULL since it was not loaded."); - Assert.IsTrue(result.Results.Count <= batchSize, "The count of results in each batch callback should less than or equal to the batchSize"); - }); - }, options => { options.BatchSize = batchSize; options.InputColumns = s => new { s.Id, s.Price }; }); + batchCount++; + totalCount += result.Results.Count(); + bool isAllExternalIdNull = !result.Results.Any(o => o.ExternalId != null); + Assert.IsTrue(isAllExternalIdNull, "All records should have ExternalId equal to NULL since it was not loaded."); + Assert.IsTrue(result.Results.Count <= batchSize, "The count of results in each batch callback should less than or equal to the batchSize"); + }); + }, options => { options.BatchSize = batchSize; options.InputColumns = s => new { s.Id, s.Price }; }); - Assert.IsTrue(expectedTotalCount > 0, "There must be orders in database that match this condition"); - Assert.IsTrue(expectedTotalCount == totalCount, "The total number of rows fetched must match the count of existing rows in database"); - Assert.IsTrue(expectedBatchCount == batchCount, "The total number of batches fetched must match what is expected"); - } + Assert.IsTrue(expectedTotalCount > 0, "There must be orders in database that match this condition"); + Assert.IsTrue(expectedTotalCount == totalCount, "The total number of rows fetched must match the count of existing rows in database"); + Assert.IsTrue(expectedBatchCount == batchCount, "The total number of batches fetched must match what is expected"); } } \ No newline at end of file diff --git a/N.EntityFrameworkCore.Extensions.Test/DbContextExtensions/InsertFromQuery.cs b/N.EntityFrameworkCore.Extensions.Test/DbContextExtensions/InsertFromQuery.cs index a933051..0cdfbc6 100644 --- a/N.EntityFrameworkCore.Extensions.Test/DbContextExtensions/InsertFromQuery.cs +++ b/N.EntityFrameworkCore.Extensions.Test/DbContextExtensions/InsertFromQuery.cs @@ -2,70 +2,69 @@ using System.Linq; using Microsoft.VisualStudio.TestTools.UnitTesting; -namespace N.EntityFrameworkCore.Extensions.Test.DbContextExtensions +namespace N.EntityFrameworkCore.Extensions.Test.DbContextExtensions; + +[TestClass] +public class InsertFromQuery : DbContextExtensionsBase { - [TestClass] - public class InsertFromQuery : DbContextExtensionsBase + [TestMethod] + public void With_DateTime_Value() { - [TestMethod] - public void With_DateTime_Value() - { - var dbContext = SetupDbContext(true); - string tableName = "OrdersLast30Days"; - DateTime dateTime = dbContext.Orders.Max(o => o.AddedDateTime).AddDays(-30); - int oldTotal = dbContext.Orders.Count(); + var dbContext = SetupDbContext(true); + string tableName = "OrdersLast30Days"; + DateTime dateTime = dbContext.Orders.Max(o => o.AddedDateTime).AddDays(-30); + int oldTotal = dbContext.Orders.Count(); - var orders = dbContext.Orders.Where(o => o.AddedDateTime >= dateTime); - int oldSourceTotal = orders.Count(); - int rowsInserted = orders.InsertFromQuery(tableName, - o => new { o.Id, o.ExternalId, o.Price, o.AddedDateTime, o.ModifiedDateTime, o.Active }); - int newSourceTotal = orders.Count(); - int newTargetTotal = orders.UsingTable(tableName).Count(); + var orders = dbContext.Orders.Where(o => o.AddedDateTime >= dateTime); + int oldSourceTotal = orders.Count(); + int rowsInserted = orders.InsertFromQuery(tableName, + o => new { o.Id, o.ExternalId, o.Price, o.AddedDateTime, o.ModifiedDateTime, o.Active }); + int newSourceTotal = orders.Count(); + int newTargetTotal = orders.UsingTable(tableName).Count(); - Assert.IsTrue(oldTotal > oldSourceTotal, "The total should be greater then the number of rows selected from the source table"); - Assert.IsTrue(oldSourceTotal > 0, "There should be existing data in the source table"); - Assert.IsTrue(oldSourceTotal == newSourceTotal, "There should not be any change in the count of rows in the source table"); - Assert.IsTrue(rowsInserted == oldSourceTotal, "The number of records inserted must match the count of the source table"); - Assert.IsTrue(rowsInserted == newTargetTotal, "The different in count in the target table before and after the insert must match the total row inserted"); - } - [TestMethod] - public void With_Decimal_Value() - { - var dbContext = SetupDbContext(true); - string tableName = "OrdersUnderTen"; - var orders = dbContext.Orders.Where(o => o.Price < 10M); - int oldSourceTotal = orders.Count(); - int rowsInserted = dbContext.Orders.Where(o => o.Price < 10M).InsertFromQuery(tableName, o => new { o.Id, o.Price, o.AddedDateTime, o.Active }); - int newSourceTotal = orders.Count(); - int newTargetTotal = orders.UsingTable(tableName).Count(); + Assert.IsTrue(oldTotal > oldSourceTotal, "The total should be greater then the number of rows selected from the source table"); + Assert.IsTrue(oldSourceTotal > 0, "There should be existing data in the source table"); + Assert.IsTrue(oldSourceTotal == newSourceTotal, "There should not be any change in the count of rows in the source table"); + Assert.IsTrue(rowsInserted == oldSourceTotal, "The number of records inserted must match the count of the source table"); + Assert.IsTrue(rowsInserted == newTargetTotal, "The different in count in the target table before and after the insert must match the total row inserted"); + } + [TestMethod] + public void With_Decimal_Value() + { + var dbContext = SetupDbContext(true); + string tableName = "OrdersUnderTen"; + var orders = dbContext.Orders.Where(o => o.Price < 10M); + int oldSourceTotal = orders.Count(); + int rowsInserted = dbContext.Orders.Where(o => o.Price < 10M).InsertFromQuery(tableName, o => new { o.Id, o.Price, o.AddedDateTime, o.Active }); + int newSourceTotal = orders.Count(); + int newTargetTotal = orders.UsingTable(tableName).Count(); - Assert.IsTrue(oldSourceTotal > 0, "There should be existing data in the source table"); - Assert.IsTrue(oldSourceTotal == newSourceTotal, "There should not be any change in the count of rows in the source table"); - Assert.IsTrue(rowsInserted == oldSourceTotal, "The number of records inserted must match the count of the source table"); - Assert.IsTrue(rowsInserted == newTargetTotal, "The different in count in the target table before and after the insert must match the total row inserted"); - } - [TestMethod] - public void With_Transaction() + Assert.IsTrue(oldSourceTotal > 0, "There should be existing data in the source table"); + Assert.IsTrue(oldSourceTotal == newSourceTotal, "There should not be any change in the count of rows in the source table"); + Assert.IsTrue(rowsInserted == oldSourceTotal, "The number of records inserted must match the count of the source table"); + Assert.IsTrue(rowsInserted == newTargetTotal, "The different in count in the target table before and after the insert must match the total row inserted"); + } + [TestMethod] + public void With_Transaction() + { + var dbContext = SetupDbContext(true); + string tableName = "OrdersUnderTen"; + int rowsInserted; + bool tableExistsBefore, tableExistsAfter; + int oldSourceTotal = dbContext.Orders.Where(o => o.Price < 10M).Count(); + using (var transaction = dbContext.Database.BeginTransaction()) { - var dbContext = SetupDbContext(true); - string tableName = "OrdersUnderTen"; - int rowsInserted; - bool tableExistsBefore, tableExistsAfter; - int oldSourceTotal = dbContext.Orders.Where(o => o.Price < 10M).Count(); - using (var transaction = dbContext.Database.BeginTransaction()) - { - rowsInserted = dbContext.Orders.Where(o => o.Price < 10M).InsertFromQuery(tableName, o => new { o.Price, o.Id, o.AddedDateTime, o.Active }); - tableExistsBefore = dbContext.Database.TableExists(tableName); - transaction.Rollback(); - } - tableExistsAfter = dbContext.Database.TableExists(tableName); - int newSourceTotal = dbContext.Orders.Where(o => o.Price < 10M).Count(); - - Assert.IsTrue(oldSourceTotal > 0, "There must be orders in database that match this condition (Price < $10)"); - Assert.IsTrue(rowsInserted == oldSourceTotal, "The number of rows update must match the count of rows that match the condtion (Price < $10)"); - Assert.IsTrue(newSourceTotal == oldSourceTotal, "The new count must match the old count since the transaction was rollbacked"); - Assert.IsTrue(tableExistsBefore, string.Format("Table {0} should exist before transaction rollback", tableName)); - Assert.IsFalse(tableExistsAfter, string.Format("Table {0} should not exist after transaction rollback", tableName)); + rowsInserted = dbContext.Orders.Where(o => o.Price < 10M).InsertFromQuery(tableName, o => new { o.Price, o.Id, o.AddedDateTime, o.Active }); + tableExistsBefore = dbContext.Database.TableExists(tableName); + transaction.Rollback(); } + tableExistsAfter = dbContext.Database.TableExists(tableName); + int newSourceTotal = dbContext.Orders.Where(o => o.Price < 10M).Count(); + + Assert.IsTrue(oldSourceTotal > 0, "There must be orders in database that match this condition (Price < $10)"); + Assert.IsTrue(rowsInserted == oldSourceTotal, "The number of rows update must match the count of rows that match the condtion (Price < $10)"); + Assert.IsTrue(newSourceTotal == oldSourceTotal, "The new count must match the old count since the transaction was rollbacked"); + Assert.IsTrue(tableExistsBefore, string.Format("Table {0} should exist before transaction rollback", tableName)); + Assert.IsFalse(tableExistsAfter, string.Format("Table {0} should not exist after transaction rollback", tableName)); } } \ No newline at end of file diff --git a/N.EntityFrameworkCore.Extensions.Test/DbContextExtensions/InsertFromQueryAsync.cs b/N.EntityFrameworkCore.Extensions.Test/DbContextExtensions/InsertFromQueryAsync.cs index 2eeb8f9..7c7071a 100644 --- a/N.EntityFrameworkCore.Extensions.Test/DbContextExtensions/InsertFromQueryAsync.cs +++ b/N.EntityFrameworkCore.Extensions.Test/DbContextExtensions/InsertFromQueryAsync.cs @@ -4,86 +4,85 @@ using Microsoft.EntityFrameworkCore; using Microsoft.VisualStudio.TestTools.UnitTesting; -namespace N.EntityFrameworkCore.Extensions.Test.DbContextExtensions +namespace N.EntityFrameworkCore.Extensions.Test.DbContextExtensions; + +[TestClass] +public class InsertFromQueryAsync : DbContextExtensionsBase { - [TestClass] - public class InsertFromQueryAsync : DbContextExtensionsBase + [TestMethod] + public async Task With_DateTime_Value() { - [TestMethod] - public async Task With_DateTime_Value() - { - var dbContext = SetupDbContext(true); - string tableName = "OrdersLast30Days"; - DateTime dateTime = dbContext.Orders.Max(o => o.AddedDateTime).AddDays(-30); - int oldTotal = dbContext.Orders.Count(); + var dbContext = SetupDbContext(true); + string tableName = "OrdersLast30Days"; + DateTime dateTime = dbContext.Orders.Max(o => o.AddedDateTime).AddDays(-30); + int oldTotal = dbContext.Orders.Count(); - var orders = dbContext.Orders.Where(o => o.AddedDateTime >= dateTime); - int oldSourceTotal = orders.Count(); - int rowsInserted = await orders.InsertFromQueryAsync(tableName, - o => new { o.Id, o.ExternalId, o.Price, o.AddedDateTime, o.ModifiedDateTime, o.Active }); - int newSourceTotal = orders.Count(); - int newTargetTotal = orders.UsingTable(tableName).Count(); + var orders = dbContext.Orders.Where(o => o.AddedDateTime >= dateTime); + int oldSourceTotal = orders.Count(); + int rowsInserted = await orders.InsertFromQueryAsync(tableName, + o => new { o.Id, o.ExternalId, o.Price, o.AddedDateTime, o.ModifiedDateTime, o.Active }); + int newSourceTotal = orders.Count(); + int newTargetTotal = orders.UsingTable(tableName).Count(); - Assert.IsTrue(oldTotal > oldSourceTotal, "The total should be greater then the number of rows selected from the source table"); - Assert.IsTrue(oldSourceTotal > 0, "There should be existing data in the source table"); - Assert.IsTrue(oldSourceTotal == newSourceTotal, "There should not be any change in the count of rows in the source table"); - Assert.IsTrue(rowsInserted == oldSourceTotal, "The number of records inserted must match the count of the source table"); - Assert.IsTrue(rowsInserted == newTargetTotal, "The different in count in the target table before and after the insert must match the total row inserted"); - } - [TestMethod] - public async Task With_Decimal_Value() - { - var dbContext = SetupDbContext(true); - string tableName = "OrdersUnderTen"; - var orders = dbContext.Orders.Where(o => o.Price < 10M); - int oldSourceTotal = orders.Count(); - int rowsInserted = await dbContext.Orders.Where(o => o.Price < 10M).InsertFromQueryAsync(tableName, o => new { o.Id, o.Price, o.AddedDateTime, o.Active }); - int newSourceTotal = orders.Count(); - int newTargetTotal = orders.UsingTable(tableName).Count(); + Assert.IsTrue(oldTotal > oldSourceTotal, "The total should be greater then the number of rows selected from the source table"); + Assert.IsTrue(oldSourceTotal > 0, "There should be existing data in the source table"); + Assert.IsTrue(oldSourceTotal == newSourceTotal, "There should not be any change in the count of rows in the source table"); + Assert.IsTrue(rowsInserted == oldSourceTotal, "The number of records inserted must match the count of the source table"); + Assert.IsTrue(rowsInserted == newTargetTotal, "The different in count in the target table before and after the insert must match the total row inserted"); + } + [TestMethod] + public async Task With_Decimal_Value() + { + var dbContext = SetupDbContext(true); + string tableName = "OrdersUnderTen"; + var orders = dbContext.Orders.Where(o => o.Price < 10M); + int oldSourceTotal = orders.Count(); + int rowsInserted = await dbContext.Orders.Where(o => o.Price < 10M).InsertFromQueryAsync(tableName, o => new { o.Id, o.Price, o.AddedDateTime, o.Active }); + int newSourceTotal = orders.Count(); + int newTargetTotal = orders.UsingTable(tableName).Count(); - Assert.IsTrue(oldSourceTotal > 0, "There should be existing data in the source table"); - Assert.IsTrue(oldSourceTotal == newSourceTotal, "There should not be any change in the count of rows in the source table"); - Assert.IsTrue(rowsInserted == oldSourceTotal, "The number of records inserted must match the count of the source table"); - Assert.IsTrue(rowsInserted == newTargetTotal, "The different in count in the target table before and after the insert must match the total row inserted"); - } - [TestMethod] - public async Task With_Schema() - { - var dbContext = SetupDbContext(true, PopulateDataMode.Schema); - string tableName = "ProductsUnderTen"; - var products = dbContext.ProductsWithCustomSchema.Where(o => o.Price < 10M); - int oldSourceTotal = products.Count(); - int rowsInserted = await dbContext.ProductsWithCustomSchema.Where(o => o.Price < 10M).InsertFromQueryAsync(tableName, o => new { o.Id, o.Price }); - int newSourceTotal = products.Count(); - int newTargetTotal = products.UsingTable(tableName).Count(); + Assert.IsTrue(oldSourceTotal > 0, "There should be existing data in the source table"); + Assert.IsTrue(oldSourceTotal == newSourceTotal, "There should not be any change in the count of rows in the source table"); + Assert.IsTrue(rowsInserted == oldSourceTotal, "The number of records inserted must match the count of the source table"); + Assert.IsTrue(rowsInserted == newTargetTotal, "The different in count in the target table before and after the insert must match the total row inserted"); + } + [TestMethod] + public async Task With_Schema() + { + var dbContext = SetupDbContext(true, PopulateDataMode.Schema); + string tableName = "ProductsUnderTen"; + var products = dbContext.ProductsWithCustomSchema.Where(o => o.Price < 10M); + int oldSourceTotal = products.Count(); + int rowsInserted = await dbContext.ProductsWithCustomSchema.Where(o => o.Price < 10M).InsertFromQueryAsync(tableName, o => new { o.Id, o.Price }); + int newSourceTotal = products.Count(); + int newTargetTotal = products.UsingTable(tableName).Count(); - Assert.IsTrue(oldSourceTotal > 0, "There should be existing data in the source table"); - Assert.IsTrue(oldSourceTotal == newSourceTotal, "There should not be any change in the count of rows in the source table"); - Assert.IsTrue(rowsInserted == oldSourceTotal, "The number of records inserted must match the count of the source table"); - Assert.IsTrue(rowsInserted == newTargetTotal, "The different in count in the target table before and after the insert must match the total row inserted"); - } - [TestMethod] - public async Task With_Transaction() + Assert.IsTrue(oldSourceTotal > 0, "There should be existing data in the source table"); + Assert.IsTrue(oldSourceTotal == newSourceTotal, "There should not be any change in the count of rows in the source table"); + Assert.IsTrue(rowsInserted == oldSourceTotal, "The number of records inserted must match the count of the source table"); + Assert.IsTrue(rowsInserted == newTargetTotal, "The different in count in the target table before and after the insert must match the total row inserted"); + } + [TestMethod] + public async Task With_Transaction() + { + var dbContext = SetupDbContext(true); + string tableName = "OrdersUnderTen"; + int rowsInserted; + bool tableExistsBefore, tableExistsAfter; + int oldSourceTotal = dbContext.Orders.Where(o => o.Price < 10M).Count(); + using (var transaction = dbContext.Database.BeginTransaction()) { - var dbContext = SetupDbContext(true); - string tableName = "OrdersUnderTen"; - int rowsInserted; - bool tableExistsBefore, tableExistsAfter; - int oldSourceTotal = dbContext.Orders.Where(o => o.Price < 10M).Count(); - using (var transaction = dbContext.Database.BeginTransaction()) - { - rowsInserted = await dbContext.Orders.Where(o => o.Price < 10M).InsertFromQueryAsync(tableName, o => new { o.Price, o.Id, o.AddedDateTime, o.Active }); - tableExistsBefore = dbContext.Database.TableExists(tableName); - transaction.Rollback(); - } - tableExistsAfter = dbContext.Database.TableExists(tableName); - int newSourceTotal = dbContext.Orders.Where(o => o.Price < 10M).Count(); - - Assert.IsTrue(oldSourceTotal > 0, "There must be orders in database that match this condition (Price < $10)"); - Assert.IsTrue(rowsInserted == oldSourceTotal, "The number of rows update must match the count of rows that match the condtion (Price < $10)"); - Assert.IsTrue(newSourceTotal == oldSourceTotal, "The new count must match the old count since the transaction was rollbacked"); - Assert.IsTrue(tableExistsBefore, string.Format("Table {0} should exist before transaction rollback", tableName)); - Assert.IsFalse(tableExistsAfter, string.Format("Table {0} should not exist after transaction rollback", tableName)); + rowsInserted = await dbContext.Orders.Where(o => o.Price < 10M).InsertFromQueryAsync(tableName, o => new { o.Price, o.Id, o.AddedDateTime, o.Active }); + tableExistsBefore = dbContext.Database.TableExists(tableName); + transaction.Rollback(); } + tableExistsAfter = dbContext.Database.TableExists(tableName); + int newSourceTotal = dbContext.Orders.Where(o => o.Price < 10M).Count(); + + Assert.IsTrue(oldSourceTotal > 0, "There must be orders in database that match this condition (Price < $10)"); + Assert.IsTrue(rowsInserted == oldSourceTotal, "The number of rows update must match the count of rows that match the condtion (Price < $10)"); + Assert.IsTrue(newSourceTotal == oldSourceTotal, "The new count must match the old count since the transaction was rollbacked"); + Assert.IsTrue(tableExistsBefore, string.Format("Table {0} should exist before transaction rollback", tableName)); + Assert.IsFalse(tableExistsAfter, string.Format("Table {0} should not exist after transaction rollback", tableName)); } } \ No newline at end of file diff --git a/N.EntityFrameworkCore.Extensions.Test/DbContextExtensions/QueryToCsvFile.cs b/N.EntityFrameworkCore.Extensions.Test/DbContextExtensions/QueryToCsvFile.cs index 78b5265..8bd91de 100644 --- a/N.EntityFrameworkCore.Extensions.Test/DbContextExtensions/QueryToCsvFile.cs +++ b/N.EntityFrameworkCore.Extensions.Test/DbContextExtensions/QueryToCsvFile.cs @@ -2,47 +2,46 @@ using System.Linq; using Microsoft.VisualStudio.TestTools.UnitTesting; -namespace N.EntityFrameworkCore.Extensions.Test.DbContextExtensions +namespace N.EntityFrameworkCore.Extensions.Test.DbContextExtensions; + +[TestClass] +public class QueryToCsvFile : DbContextExtensionsBase { - [TestClass] - public class QueryToCsvFile : DbContextExtensionsBase + [TestMethod] + public void With_Default_Options() { - [TestMethod] - public void With_Default_Options() - { - var dbContext = SetupDbContext(true); - var query = dbContext.Orders.Where(o => o.Price < 10M); - int count = query.Count(); - var queryToCsvFileResult = query.QueryToCsvFile("QueryToCsvFile-Test.csv"); + var dbContext = SetupDbContext(true); + var query = dbContext.Orders.Where(o => o.Price < 10M); + int count = query.Count(); + var queryToCsvFileResult = query.QueryToCsvFile("QueryToCsvFile-Test.csv"); - Assert.IsTrue(count > 0, "There should be existing data in the source table"); - Assert.IsTrue(queryToCsvFileResult.DataRowCount == count, "The number of data rows written to the file should match the count from the database"); - Assert.IsTrue(queryToCsvFileResult.TotalRowCount == count + 1, "The total number of rows written to the file should match the count from the database plus the header row"); - } - [TestMethod] - public void With_Options_ColumnDelimiter_TextQualifer_HeaderRow() - { - var dbContext = SetupDbContext(true); - var query = dbContext.Orders.Where(o => o.Price < 10M); - int count = query.Count(); - var queryToCsvFileResult = query.QueryToCsvFile("QueryToCsvFile_Options_ColumnDelimiter_TextQualifer_HeaderRow-Test.csv", options => { options.ColumnDelimiter = "|"; options.TextQualifer = "\""; options.IncludeHeaderRow = false; }); + Assert.IsTrue(count > 0, "There should be existing data in the source table"); + Assert.IsTrue(queryToCsvFileResult.DataRowCount == count, "The number of data rows written to the file should match the count from the database"); + Assert.IsTrue(queryToCsvFileResult.TotalRowCount == count + 1, "The total number of rows written to the file should match the count from the database plus the header row"); + } + [TestMethod] + public void With_Options_ColumnDelimiter_TextQualifer_HeaderRow() + { + var dbContext = SetupDbContext(true); + var query = dbContext.Orders.Where(o => o.Price < 10M); + int count = query.Count(); + var queryToCsvFileResult = query.QueryToCsvFile("QueryToCsvFile_Options_ColumnDelimiter_TextQualifer_HeaderRow-Test.csv", options => { options.ColumnDelimiter = "|"; options.TextQualifer = "\""; options.IncludeHeaderRow = false; }); - Assert.IsTrue(count > 0, "There should be existing data in the source table"); - Assert.IsTrue(queryToCsvFileResult.DataRowCount == count, "The number of data rows written to the file should match the count from the database"); - Assert.IsTrue(queryToCsvFileResult.TotalRowCount == count, "The total number of rows written to the file should match the count from the database without any header row"); - } - [TestMethod] - public void Using_FileStream() - { - var dbContext = SetupDbContext(true); - var query = dbContext.Orders.Where(o => o.Price < 10M); - int count = query.Count(); - var fileStream = File.Create("QueryToCsvFile_Stream-Test.csv"); - var queryToCsvFileResult = query.QueryToCsvFile(fileStream); + Assert.IsTrue(count > 0, "There should be existing data in the source table"); + Assert.IsTrue(queryToCsvFileResult.DataRowCount == count, "The number of data rows written to the file should match the count from the database"); + Assert.IsTrue(queryToCsvFileResult.TotalRowCount == count, "The total number of rows written to the file should match the count from the database without any header row"); + } + [TestMethod] + public void Using_FileStream() + { + var dbContext = SetupDbContext(true); + var query = dbContext.Orders.Where(o => o.Price < 10M); + int count = query.Count(); + var fileStream = File.Create("QueryToCsvFile_Stream-Test.csv"); + var queryToCsvFileResult = query.QueryToCsvFile(fileStream); - Assert.IsTrue(count > 0, "There should be existing data in the source table"); - Assert.IsTrue(queryToCsvFileResult.DataRowCount == count, "The number of data rows written to the file should match the count from the database"); - Assert.IsTrue(queryToCsvFileResult.TotalRowCount == count + 1, "The total number of rows written to the file should match the count from the database plus the header row"); - } + Assert.IsTrue(count > 0, "There should be existing data in the source table"); + Assert.IsTrue(queryToCsvFileResult.DataRowCount == count, "The number of data rows written to the file should match the count from the database"); + Assert.IsTrue(queryToCsvFileResult.TotalRowCount == count + 1, "The total number of rows written to the file should match the count from the database plus the header row"); } } \ No newline at end of file diff --git a/N.EntityFrameworkCore.Extensions.Test/DbContextExtensions/QueryToCsvFileAsync.cs b/N.EntityFrameworkCore.Extensions.Test/DbContextExtensions/QueryToCsvFileAsync.cs index bab8164..5aff479 100644 --- a/N.EntityFrameworkCore.Extensions.Test/DbContextExtensions/QueryToCsvFileAsync.cs +++ b/N.EntityFrameworkCore.Extensions.Test/DbContextExtensions/QueryToCsvFileAsync.cs @@ -3,47 +3,46 @@ using System.Threading.Tasks; using Microsoft.VisualStudio.TestTools.UnitTesting; -namespace N.EntityFrameworkCore.Extensions.Test.DbContextExtensions +namespace N.EntityFrameworkCore.Extensions.Test.DbContextExtensions; + +[TestClass] +public class QueryToCsvFileAsync : DbContextExtensionsBase { - [TestClass] - public class QueryToCsvFileAsync : DbContextExtensionsBase + [TestMethod] + public async Task With_Default_Options() { - [TestMethod] - public async Task With_Default_Options() - { - var dbContext = SetupDbContext(true); - var query = dbContext.Orders.Where(o => o.Price < 10M); - int count = query.Count(); - var queryToCsvFileResult = await query.QueryToCsvFileAsync("QueryToCsvFile-Test.csv"); + var dbContext = SetupDbContext(true); + var query = dbContext.Orders.Where(o => o.Price < 10M); + int count = query.Count(); + var queryToCsvFileResult = await query.QueryToCsvFileAsync("QueryToCsvFile-Test.csv"); - Assert.IsTrue(count > 0, "There should be existing data in the source table"); - Assert.IsTrue(queryToCsvFileResult.DataRowCount == count, "The number of data rows written to the file should match the count from the database"); - Assert.IsTrue(queryToCsvFileResult.TotalRowCount == count + 1, "The total number of rows written to the file should match the count from the database plus the header row"); - } - [TestMethod] - public async Task With_Options_ColumnDelimiter_TextQualifer_HeaderRow() - { - var dbContext = SetupDbContext(true); - var query = dbContext.Orders.Where(o => o.Price < 10M); - int count = query.Count(); - var queryToCsvFileResult = await query.QueryToCsvFileAsync("QueryToCsvFile_Options_ColumnDelimiter_TextQualifer_HeaderRow-Test.csv", options => { options.ColumnDelimiter = "|"; options.TextQualifer = "\""; options.IncludeHeaderRow = false; }); + Assert.IsTrue(count > 0, "There should be existing data in the source table"); + Assert.IsTrue(queryToCsvFileResult.DataRowCount == count, "The number of data rows written to the file should match the count from the database"); + Assert.IsTrue(queryToCsvFileResult.TotalRowCount == count + 1, "The total number of rows written to the file should match the count from the database plus the header row"); + } + [TestMethod] + public async Task With_Options_ColumnDelimiter_TextQualifer_HeaderRow() + { + var dbContext = SetupDbContext(true); + var query = dbContext.Orders.Where(o => o.Price < 10M); + int count = query.Count(); + var queryToCsvFileResult = await query.QueryToCsvFileAsync("QueryToCsvFile_Options_ColumnDelimiter_TextQualifer_HeaderRow-Test.csv", options => { options.ColumnDelimiter = "|"; options.TextQualifer = "\""; options.IncludeHeaderRow = false; }); - Assert.IsTrue(count > 0, "There should be existing data in the source table"); - Assert.IsTrue(queryToCsvFileResult.DataRowCount == count, "The number of data rows written to the file should match the count from the database"); - Assert.IsTrue(queryToCsvFileResult.TotalRowCount == count, "The total number of rows written to the file should match the count from the database without any header row"); - } - [TestMethod] - public async Task Using_FileStream() - { - var dbContext = SetupDbContext(true); - var query = dbContext.Orders.Where(o => o.Price < 10M); - int count = query.Count(); - var fileStream = File.Create("QueryToCsvFile_Stream-Test.csv"); - var queryToCsvFileResult = await query.QueryToCsvFileAsync(fileStream); + Assert.IsTrue(count > 0, "There should be existing data in the source table"); + Assert.IsTrue(queryToCsvFileResult.DataRowCount == count, "The number of data rows written to the file should match the count from the database"); + Assert.IsTrue(queryToCsvFileResult.TotalRowCount == count, "The total number of rows written to the file should match the count from the database without any header row"); + } + [TestMethod] + public async Task Using_FileStream() + { + var dbContext = SetupDbContext(true); + var query = dbContext.Orders.Where(o => o.Price < 10M); + int count = query.Count(); + var fileStream = File.Create("QueryToCsvFile_Stream-Test.csv"); + var queryToCsvFileResult = await query.QueryToCsvFileAsync(fileStream); - Assert.IsTrue(count > 0, "There should be existing data in the source table"); - Assert.IsTrue(queryToCsvFileResult.DataRowCount == count, "The number of data rows written to the file should match the count from the database"); - Assert.IsTrue(queryToCsvFileResult.TotalRowCount == count + 1, "The total number of rows written to the file should match the count from the database plus the header row"); - } + Assert.IsTrue(count > 0, "There should be existing data in the source table"); + Assert.IsTrue(queryToCsvFileResult.DataRowCount == count, "The number of data rows written to the file should match the count from the database"); + Assert.IsTrue(queryToCsvFileResult.TotalRowCount == count + 1, "The total number of rows written to the file should match the count from the database plus the header row"); } } \ No newline at end of file diff --git a/N.EntityFrameworkCore.Extensions.Test/DbContextExtensions/UpdateFromQuery.cs b/N.EntityFrameworkCore.Extensions.Test/DbContextExtensions/UpdateFromQuery.cs index b2fa7f6..b278b62 100644 --- a/N.EntityFrameworkCore.Extensions.Test/DbContextExtensions/UpdateFromQuery.cs +++ b/N.EntityFrameworkCore.Extensions.Test/DbContextExtensions/UpdateFromQuery.cs @@ -8,270 +8,269 @@ using N.EntityFrameworkCore.Extensions.Test.Data; using N.EntityFrameworkCore.Extensions.Test.Data.Enums; -namespace N.EntityFrameworkCore.Extensions.Test.DbContextExtensions +namespace N.EntityFrameworkCore.Extensions.Test.DbContextExtensions; + +[TestClass] +public class UpdateFromQuery : DbContextExtensionsBase { - [TestClass] - public class UpdateFromQuery : DbContextExtensionsBase + [TestMethod] + public void With_Boolean_Value() { - [TestMethod] - public void With_Boolean_Value() - { - var dbContext = SetupDbContext(true); - int oldTotal = dbContext.Products.Count(a => a.OutOfStock); - int rowUpdated = dbContext.Products.Where(a => a.OutOfStock).UpdateFromQuery(a => new Product { OutOfStock = false }); - int newTotal = dbContext.Products.Count(o => o.OutOfStock); + var dbContext = SetupDbContext(true); + int oldTotal = dbContext.Products.Count(a => a.OutOfStock); + int rowUpdated = dbContext.Products.Where(a => a.OutOfStock).UpdateFromQuery(a => new Product { OutOfStock = false }); + int newTotal = dbContext.Products.Count(o => o.OutOfStock); - Assert.IsTrue(oldTotal > 0, "There must be articles in database that match this condition (OutOfStock == true)"); - Assert.IsTrue(rowUpdated == oldTotal, "The number of rows update must match the count of rows that match the condition (OutOfStock == false)"); - Assert.IsTrue(newTotal == 0, "The new count must be 0 to indicate all records were updated"); - } - [TestMethod] - public void With_Concatenating_String() - { - var dbContext = SetupDbContext(true); - var orders = dbContext.Orders.Where(o => o.ExternalId == null); - int oldTotal = orders.Count(); - int rowUpdated = orders.UpdateFromQuery(o => new Order { ExternalId = Convert.ToString(o.Id) + "Test" }); - int newTotal = orders.Count(); + Assert.IsTrue(oldTotal > 0, "There must be articles in database that match this condition (OutOfStock == true)"); + Assert.IsTrue(rowUpdated == oldTotal, "The number of rows update must match the count of rows that match the condition (OutOfStock == false)"); + Assert.IsTrue(newTotal == 0, "The new count must be 0 to indicate all records were updated"); + } + [TestMethod] + public void With_Concatenating_String() + { + var dbContext = SetupDbContext(true); + var orders = dbContext.Orders.Where(o => o.ExternalId == null); + int oldTotal = orders.Count(); + int rowUpdated = orders.UpdateFromQuery(o => new Order { ExternalId = Convert.ToString(o.Id) + "Test" }); + int newTotal = orders.Count(); - Assert.IsTrue(oldTotal > 0, "There must be orders in database that match this condition (ExternalId == null)"); - Assert.IsTrue(rowUpdated == oldTotal, "The number of rows update must match the count of rows that match the condition (ExternalId == null)"); - Assert.IsTrue(newTotal == 0, "The new count must be 0 to indicate all records were updated"); - } - [TestMethod] - public void With_Concatenating_String_And_Number() - { - var dbContext = SetupDbContext(true); - var orders = dbContext.Orders.Where(o => o.ExternalId == null); - int oldTotal = orders.Count(); - int rowUpdated = orders.UpdateFromQuery(o => new Order { ExternalId = Convert.ToString(o.Id) + "Test" }); - int newTotal = orders.Count(); + Assert.IsTrue(oldTotal > 0, "There must be orders in database that match this condition (ExternalId == null)"); + Assert.IsTrue(rowUpdated == oldTotal, "The number of rows update must match the count of rows that match the condition (ExternalId == null)"); + Assert.IsTrue(newTotal == 0, "The new count must be 0 to indicate all records were updated"); + } + [TestMethod] + public void With_Concatenating_String_And_Number() + { + var dbContext = SetupDbContext(true); + var orders = dbContext.Orders.Where(o => o.ExternalId == null); + int oldTotal = orders.Count(); + int rowUpdated = orders.UpdateFromQuery(o => new Order { ExternalId = Convert.ToString(o.Id) + "Test" }); + int newTotal = orders.Count(); - Assert.IsTrue(oldTotal > 0, "There must be orders in database that match this condition (ExternalId == null)"); - Assert.IsTrue(rowUpdated == oldTotal, "The number of rows update must match the count of rows that match the condition (ExternalId == null)"); - Assert.IsTrue(newTotal == 0, "The new count must be 0 to indicate all records were updated"); - } - [TestMethod] - public void With_DateTime_Value() - { - var dbContext = SetupDbContext(true); - DateTime dateTime = dbContext.Orders.Max(o => o.AddedDateTime).AddDays(-30); - DateTime now = DateTime.UtcNow; + Assert.IsTrue(oldTotal > 0, "There must be orders in database that match this condition (ExternalId == null)"); + Assert.IsTrue(rowUpdated == oldTotal, "The number of rows update must match the count of rows that match the condition (ExternalId == null)"); + Assert.IsTrue(newTotal == 0, "The new count must be 0 to indicate all records were updated"); + } + [TestMethod] + public void With_DateTime_Value() + { + var dbContext = SetupDbContext(true); + DateTime dateTime = dbContext.Orders.Max(o => o.AddedDateTime).AddDays(-30); + DateTime now = DateTime.UtcNow; - int oldTotal = dbContext.Orders.Where(o => o.AddedDateTime >= dateTime).Count(); - int rowUpdated = dbContext.Orders.Where(o => o.AddedDateTime >= dateTime).UpdateFromQuery(o => new Order { ModifiedDateTime = now }); - int newTotal = dbContext.Orders.Where(o => o.ModifiedDateTime == now).Count(); + int oldTotal = dbContext.Orders.Where(o => o.AddedDateTime >= dateTime).Count(); + int rowUpdated = dbContext.Orders.Where(o => o.AddedDateTime >= dateTime).UpdateFromQuery(o => new Order { ModifiedDateTime = now }); + int newTotal = dbContext.Orders.Where(o => o.ModifiedDateTime == now).Count(); - Assert.IsTrue(oldTotal > 0, "There must be orders in database that match this condition (Orders added in last 30 days)"); - Assert.IsTrue(rowUpdated == newTotal, "The number of rows updated should equal the new count of rows that match the condition (Orders added in last 30 days)"); - Assert.IsTrue(oldTotal == newTotal, "The count of rows matching the condition before and after the update should be equal. (Orders added in last 30 days)"); - } - [TestMethod] - public void With_DateTimeOffset_Value() - { - var dbContext = SetupDbContext(true); - DateTime dateTime = dbContext.Orders.Max(o => o.AddedDateTime).AddDays(-30); - DateTimeOffset now = DateTimeOffset.UtcNow; + Assert.IsTrue(oldTotal > 0, "There must be orders in database that match this condition (Orders added in last 30 days)"); + Assert.IsTrue(rowUpdated == newTotal, "The number of rows updated should equal the new count of rows that match the condition (Orders added in last 30 days)"); + Assert.IsTrue(oldTotal == newTotal, "The count of rows matching the condition before and after the update should be equal. (Orders added in last 30 days)"); + } + [TestMethod] + public void With_DateTimeOffset_Value() + { + var dbContext = SetupDbContext(true); + DateTime dateTime = dbContext.Orders.Max(o => o.AddedDateTime).AddDays(-30); + DateTimeOffset now = DateTimeOffset.UtcNow; - int oldTotal = dbContext.Orders.Where(o => o.AddedDateTime >= dateTime).Count(); - int rowUpdated = dbContext.Orders.Where(o => o.AddedDateTime >= dateTime).UpdateFromQuery(o => new Order { ModifiedDateTimeOffset = now }); - int newTotal = dbContext.Orders.Where(o => o.ModifiedDateTimeOffset == now).Count(); + int oldTotal = dbContext.Orders.Where(o => o.AddedDateTime >= dateTime).Count(); + int rowUpdated = dbContext.Orders.Where(o => o.AddedDateTime >= dateTime).UpdateFromQuery(o => new Order { ModifiedDateTimeOffset = now }); + int newTotal = dbContext.Orders.Where(o => o.ModifiedDateTimeOffset == now).Count(); - Assert.IsTrue(oldTotal > 0, "There must be orders in database that match this condition (Orders added in last 30 days)"); - Assert.IsTrue(rowUpdated == newTotal, "The number of rows updated should equal the new count of rows that match the condition (Orders added in last 30 days)"); - Assert.IsTrue(oldTotal == newTotal, "The count of rows matching the condition before and after the update should be equal. (Orders added in last 30 days)"); - } - [TestMethod] - public void With_DateTimeOffset_No_UTC_Value() - { - var dbContext = SetupDbContext(true); - DateTime dateTime = dbContext.Orders.Max(o => o.AddedDateTime).AddDays(-30); - DateTimeOffset now = DateTimeOffset.Parse("2020-06-17T16:00:00+05:00"); + Assert.IsTrue(oldTotal > 0, "There must be orders in database that match this condition (Orders added in last 30 days)"); + Assert.IsTrue(rowUpdated == newTotal, "The number of rows updated should equal the new count of rows that match the condition (Orders added in last 30 days)"); + Assert.IsTrue(oldTotal == newTotal, "The count of rows matching the condition before and after the update should be equal. (Orders added in last 30 days)"); + } + [TestMethod] + public void With_DateTimeOffset_No_UTC_Value() + { + var dbContext = SetupDbContext(true); + DateTime dateTime = dbContext.Orders.Max(o => o.AddedDateTime).AddDays(-30); + DateTimeOffset now = DateTimeOffset.Parse("2020-06-17T16:00:00+05:00"); - int oldTotal = dbContext.Orders.Where(o => o.AddedDateTime >= dateTime).Count(); - int rowUpdated = dbContext.Orders.Where(o => o.AddedDateTime >= dateTime).UpdateFromQuery(o => new Order { ModifiedDateTimeOffset = now }); - int newTotal = dbContext.Orders.Where(o => o.ModifiedDateTimeOffset == now).Count(); + int oldTotal = dbContext.Orders.Where(o => o.AddedDateTime >= dateTime).Count(); + int rowUpdated = dbContext.Orders.Where(o => o.AddedDateTime >= dateTime).UpdateFromQuery(o => new Order { ModifiedDateTimeOffset = now }); + int newTotal = dbContext.Orders.Where(o => o.ModifiedDateTimeOffset == now).Count(); - Assert.IsTrue(oldTotal > 0, "There must be orders in database that match this condition (Orders added in last 30 days)"); - Assert.IsTrue(rowUpdated == newTotal, "The number of rows updated should equal the new count of rows that match the condition (Orders added in last 30 days)"); - Assert.IsTrue(oldTotal == newTotal, "The count of rows matching the condition before and after the update should be equal. (Orders added in last 30 days)"); - } - [TestMethod] - public void With_Decimal_Value() - { - var dbContext = SetupDbContext(true); - var orders = dbContext.Orders.Where(o => o.Price < 10M); - int oldTotal = orders.Count(); - int rowUpdated = orders.UpdateFromQuery(o => new Order { Price = 25.30M }); - int newTotal = orders.Count(); - int matchCount = dbContext.Orders.Where(o => o.Price == 25.30M).Count(); + Assert.IsTrue(oldTotal > 0, "There must be orders in database that match this condition (Orders added in last 30 days)"); + Assert.IsTrue(rowUpdated == newTotal, "The number of rows updated should equal the new count of rows that match the condition (Orders added in last 30 days)"); + Assert.IsTrue(oldTotal == newTotal, "The count of rows matching the condition before and after the update should be equal. (Orders added in last 30 days)"); + } + [TestMethod] + public void With_Decimal_Value() + { + var dbContext = SetupDbContext(true); + var orders = dbContext.Orders.Where(o => o.Price < 10M); + int oldTotal = orders.Count(); + int rowUpdated = orders.UpdateFromQuery(o => new Order { Price = 25.30M }); + int newTotal = orders.Count(); + int matchCount = dbContext.Orders.Where(o => o.Price == 25.30M).Count(); - Assert.IsTrue(oldTotal > 0, "There must be orders in database that match this condition (Price < $10)"); - Assert.IsTrue(rowUpdated == oldTotal, "The number of rows update must match the count of rows that match the condtion (Price < $10)"); - Assert.IsTrue(newTotal == 0, "The new count must be 0 to indicate all records were updated"); - Assert.IsTrue(matchCount == rowUpdated, "The match count must be equal the number of rows updated in the database."); - } - [TestMethod] - public void With_Different_Culture() - { - Thread.CurrentThread.CurrentCulture = CultureInfo.GetCultureInfo("sv-SE"); - var dbContext = SetupDbContext(true); - int oldTotal = dbContext.Orders.Where(o => o.Price < 10M).Count(); - int rowUpdated = dbContext.Orders.Where(o => o.Price < 10M).UpdateFromQuery(o => new Order { Price = 25.30M }); - int newTotal = dbContext.Orders.Where(o => o.Price < 10M).Count(); - int matchCount = dbContext.Orders.Where(o => o.Price == 25.30M).Count(); + Assert.IsTrue(oldTotal > 0, "There must be orders in database that match this condition (Price < $10)"); + Assert.IsTrue(rowUpdated == oldTotal, "The number of rows update must match the count of rows that match the condtion (Price < $10)"); + Assert.IsTrue(newTotal == 0, "The new count must be 0 to indicate all records were updated"); + Assert.IsTrue(matchCount == rowUpdated, "The match count must be equal the number of rows updated in the database."); + } + [TestMethod] + public void With_Different_Culture() + { + Thread.CurrentThread.CurrentCulture = CultureInfo.GetCultureInfo("sv-SE"); + var dbContext = SetupDbContext(true); + int oldTotal = dbContext.Orders.Where(o => o.Price < 10M).Count(); + int rowUpdated = dbContext.Orders.Where(o => o.Price < 10M).UpdateFromQuery(o => new Order { Price = 25.30M }); + int newTotal = dbContext.Orders.Where(o => o.Price < 10M).Count(); + int matchCount = dbContext.Orders.Where(o => o.Price == 25.30M).Count(); - Assert.AreEqual("25,30", Convert.ToString(25.30M)); - Assert.IsTrue(oldTotal > 0, "There must be orders in database that match this condition (Price < $10)"); - Assert.IsTrue(rowUpdated == oldTotal, "The number of rows update must match the count of rows that match the condtion (Price < $10)"); - Assert.IsTrue(newTotal == 0, "The new count must be 0 to indicate all records were updated"); - Assert.IsTrue(matchCount == rowUpdated, "The match count must be equal the number of rows updated in the database."); - } - [TestMethod] - public void With_Enum_Value() - { - var dbContext = SetupDbContext(true); - var products = dbContext.Products.Where(a => a.StatusEnum == ProductStatus.OutOfStock && a.OutOfStock); - int oldTotal = products.Count(); - int rowUpdated = products.UpdateFromQuery(a => new Product { StatusEnum = ProductStatus.InStock }); - int newTotal = products.Count(o => o.StatusEnum == ProductStatus.OutOfStock && o.OutOfStock); - int newTotal2 = dbContext.Products.Count(o => o.StatusEnum == ProductStatus.InStock && o.OutOfStock); + Assert.AreEqual("25,30", Convert.ToString(25.30M)); + Assert.IsTrue(oldTotal > 0, "There must be orders in database that match this condition (Price < $10)"); + Assert.IsTrue(rowUpdated == oldTotal, "The number of rows update must match the count of rows that match the condtion (Price < $10)"); + Assert.IsTrue(newTotal == 0, "The new count must be 0 to indicate all records were updated"); + Assert.IsTrue(matchCount == rowUpdated, "The match count must be equal the number of rows updated in the database."); + } + [TestMethod] + public void With_Enum_Value() + { + var dbContext = SetupDbContext(true); + var products = dbContext.Products.Where(a => a.StatusEnum == ProductStatus.OutOfStock && a.OutOfStock); + int oldTotal = products.Count(); + int rowUpdated = products.UpdateFromQuery(a => new Product { StatusEnum = ProductStatus.InStock }); + int newTotal = products.Count(o => o.StatusEnum == ProductStatus.OutOfStock && o.OutOfStock); + int newTotal2 = dbContext.Products.Count(o => o.StatusEnum == ProductStatus.InStock && o.OutOfStock); - Assert.IsTrue(oldTotal > 0, "There must be articles in database that match this condition (OutOfStock == true)"); - Assert.IsTrue(rowUpdated == oldTotal, "The number of rows update must match the count of rows that match the condition (OutOfStock == false)"); - Assert.IsTrue(newTotal == 0, "The new count must be 0 to indicate all records were updated"); - Assert.IsTrue(newTotal2 == oldTotal, "All rows must have been updated"); - } - [TestMethod] - public void With_Guid_Value() - { - var dbContext = SetupDbContext(true); - var guid = Guid.NewGuid(); - var orders = dbContext.Orders.Where(o => o.Price < 10M); - int oldTotal = orders.Count(); - int rowUpdated = orders.UpdateFromQuery(o => new Order { GlobalId = guid }); - int matchCount = dbContext.Orders.Where(o => o.GlobalId == guid).Count(); + Assert.IsTrue(oldTotal > 0, "There must be articles in database that match this condition (OutOfStock == true)"); + Assert.IsTrue(rowUpdated == oldTotal, "The number of rows update must match the count of rows that match the condition (OutOfStock == false)"); + Assert.IsTrue(newTotal == 0, "The new count must be 0 to indicate all records were updated"); + Assert.IsTrue(newTotal2 == oldTotal, "All rows must have been updated"); + } + [TestMethod] + public void With_Guid_Value() + { + var dbContext = SetupDbContext(true); + var guid = Guid.NewGuid(); + var orders = dbContext.Orders.Where(o => o.Price < 10M); + int oldTotal = orders.Count(); + int rowUpdated = orders.UpdateFromQuery(o => new Order { GlobalId = guid }); + int matchCount = dbContext.Orders.Where(o => o.GlobalId == guid).Count(); - Assert.IsTrue(oldTotal > 0, "There must be orders in database that match this condition (Price < $10)"); - Assert.IsTrue(rowUpdated == oldTotal, $"The number of rows update must match the count of rows that match the condition (GlobalId = '{guid}')"); - Assert.IsTrue(matchCount == rowUpdated, "The match count must be equal the number of rows updated in the database."); - } - [TestMethod] - public void With_Long_List() - { - var dbContext = SetupDbContext(true); - var ids = new List() { 1, 2, 3, 4, 5, 6, 7, 8 }; - var orders = dbContext.Orders.Where(o => ids.Contains(o.Id)); - int oldTotal = orders.Count(); - int rowUpdated = orders.UpdateFromQuery(o => new Order { Price = 25.25M }); - int newTotal = orders.Where(o => o.Price != 25.25M).Count(); - int matchCount = dbContext.Orders.Where(o => ids.Contains(o.Id) && o.Price == 25.25M).Count(); + Assert.IsTrue(oldTotal > 0, "There must be orders in database that match this condition (Price < $10)"); + Assert.IsTrue(rowUpdated == oldTotal, $"The number of rows update must match the count of rows that match the condition (GlobalId = '{guid}')"); + Assert.IsTrue(matchCount == rowUpdated, "The match count must be equal the number of rows updated in the database."); + } + [TestMethod] + public void With_Long_List() + { + var dbContext = SetupDbContext(true); + var ids = new List() { 1, 2, 3, 4, 5, 6, 7, 8 }; + var orders = dbContext.Orders.Where(o => ids.Contains(o.Id)); + int oldTotal = orders.Count(); + int rowUpdated = orders.UpdateFromQuery(o => new Order { Price = 25.25M }); + int newTotal = orders.Where(o => o.Price != 25.25M).Count(); + int matchCount = dbContext.Orders.Where(o => ids.Contains(o.Id) && o.Price == 25.25M).Count(); - Assert.IsTrue(oldTotal > 0, "There must be orders in database that match this condition (Price < $10)"); - Assert.IsTrue(rowUpdated == oldTotal, "The number of rows update must match the count of rows that match the condtion (Price < $10)"); - Assert.IsTrue(newTotal == 0, "The new count must be 0 to indicate all records were updated"); - Assert.IsTrue(matchCount == rowUpdated, "The match count must be equal the number of rows updated in the database."); - } - [TestMethod] - public void With_MethodCall() - { - var dbContext = SetupDbContext(true); + Assert.IsTrue(oldTotal > 0, "There must be orders in database that match this condition (Price < $10)"); + Assert.IsTrue(rowUpdated == oldTotal, "The number of rows update must match the count of rows that match the condtion (Price < $10)"); + Assert.IsTrue(newTotal == 0, "The new count must be 0 to indicate all records were updated"); + Assert.IsTrue(matchCount == rowUpdated, "The match count must be equal the number of rows updated in the database."); + } + [TestMethod] + public void With_MethodCall() + { + var dbContext = SetupDbContext(true); - int oldTotal = dbContext.Orders.Count(a => a.Price < 10); - int rowUpdated = dbContext.Orders.Where(a => a.Price < 10).UpdateFromQuery(o => new Order { Price = Math.Ceiling((o.Price + 10.5M) * 3 / 1) }); - int newTotal = dbContext.Orders.Count(o => o.Price < 10); + int oldTotal = dbContext.Orders.Count(a => a.Price < 10); + int rowUpdated = dbContext.Orders.Where(a => a.Price < 10).UpdateFromQuery(o => new Order { Price = Math.Ceiling((o.Price + 10.5M) * 3 / 1) }); + int newTotal = dbContext.Orders.Count(o => o.Price < 10); - Assert.IsTrue(oldTotal > 0, "There must be order in database that match this condition (Price < 10)"); - Assert.IsTrue(rowUpdated == oldTotal, "The number of rows update must match the count of rows that match the condition (Price < 10)"); - Assert.IsTrue(newTotal == 0, "The new count must be 0 to indicate all records were updated"); - } - [TestMethod] - public void With_Null_Value() - { - var dbContext = SetupDbContext(true); - var orders = dbContext.Orders.Where(o => o.ExternalId != null); - int oldTotal = orders.Count(); - int rowUpdated = orders.UpdateFromQuery(o => new Order { ExternalId = null }); - int newTotal = orders.Count(); + Assert.IsTrue(oldTotal > 0, "There must be order in database that match this condition (Price < 10)"); + Assert.IsTrue(rowUpdated == oldTotal, "The number of rows update must match the count of rows that match the condition (Price < 10)"); + Assert.IsTrue(newTotal == 0, "The new count must be 0 to indicate all records were updated"); + } + [TestMethod] + public void With_Null_Value() + { + var dbContext = SetupDbContext(true); + var orders = dbContext.Orders.Where(o => o.ExternalId != null); + int oldTotal = orders.Count(); + int rowUpdated = orders.UpdateFromQuery(o => new Order { ExternalId = null }); + int newTotal = orders.Count(); - Assert.IsTrue(oldTotal > 0, "There must be orders in database that match this condition (ExternalId != null)"); - Assert.IsTrue(rowUpdated == oldTotal, "The number of rows update must match the count of rows that match the condition (ExternalId != null)"); - Assert.IsTrue(newTotal == 0, "The new count must be 0 to indicate all records were updated"); - } - [TestMethod] - public void With_Schema() - { - var dbContext = SetupDbContext(true, PopulateDataMode.Schema); - var products = dbContext.ProductsWithCustomSchema.Where(o => o.Price < 5M); - int oldTotal = products.Count(); - int rowUpdated = products.UpdateFromQuery(o => new ProductWithCustomSchema { Price = 25.30M }); - int newTotal = products.Count(); - int matchCount = dbContext.ProductsWithCustomSchema.Where(o => o.Price == 25.30M).Count(); + Assert.IsTrue(oldTotal > 0, "There must be orders in database that match this condition (ExternalId != null)"); + Assert.IsTrue(rowUpdated == oldTotal, "The number of rows update must match the count of rows that match the condition (ExternalId != null)"); + Assert.IsTrue(newTotal == 0, "The new count must be 0 to indicate all records were updated"); + } + [TestMethod] + public void With_Schema() + { + var dbContext = SetupDbContext(true, PopulateDataMode.Schema); + var products = dbContext.ProductsWithCustomSchema.Where(o => o.Price < 5M); + int oldTotal = products.Count(); + int rowUpdated = products.UpdateFromQuery(o => new ProductWithCustomSchema { Price = 25.30M }); + int newTotal = products.Count(); + int matchCount = dbContext.ProductsWithCustomSchema.Where(o => o.Price == 25.30M).Count(); - Assert.IsTrue(oldTotal > 0, "There must be products in database that match this condition (Price < 5)"); - Assert.IsTrue(rowUpdated == oldTotal, "The number of rows update must match the count of rows that match the condtion (Price < 5)"); - Assert.IsTrue(newTotal == 0, "The new count must be 0 to indicate all records were updated"); - Assert.IsTrue(matchCount == rowUpdated, "The match count must be equal the number of rows updated in the database."); - } - [TestMethod] - public void With_String_Containing_Apostrophe() - { - var dbContext = SetupDbContext(true); - int oldTotal = dbContext.Orders.Where(o => o.ExternalId == null).Count(); - int rowUpdated = dbContext.Orders.Where(o => o.ExternalId == null).UpdateFromQuery(o => new Order { ExternalId = "inv'alid" }); - int newTotal = dbContext.Orders.Where(o => o.ExternalId == null).Count(); + Assert.IsTrue(oldTotal > 0, "There must be products in database that match this condition (Price < 5)"); + Assert.IsTrue(rowUpdated == oldTotal, "The number of rows update must match the count of rows that match the condtion (Price < 5)"); + Assert.IsTrue(newTotal == 0, "The new count must be 0 to indicate all records were updated"); + Assert.IsTrue(matchCount == rowUpdated, "The match count must be equal the number of rows updated in the database."); + } + [TestMethod] + public void With_String_Containing_Apostrophe() + { + var dbContext = SetupDbContext(true); + int oldTotal = dbContext.Orders.Where(o => o.ExternalId == null).Count(); + int rowUpdated = dbContext.Orders.Where(o => o.ExternalId == null).UpdateFromQuery(o => new Order { ExternalId = "inv'alid" }); + int newTotal = dbContext.Orders.Where(o => o.ExternalId == null).Count(); - Assert.IsTrue(oldTotal > 0, "There must be orders in database that match this condition (ExternalId == null)"); - Assert.IsTrue(rowUpdated == oldTotal, "The number of rows update must match the count of rows that match the condition (ExternalId == null)"); - Assert.IsTrue(newTotal == 0, "The new count must be 0 to indicate all records were updated"); - } - [TestMethod] - public void With_Transaction() + Assert.IsTrue(oldTotal > 0, "There must be orders in database that match this condition (ExternalId == null)"); + Assert.IsTrue(rowUpdated == oldTotal, "The number of rows update must match the count of rows that match the condition (ExternalId == null)"); + Assert.IsTrue(newTotal == 0, "The new count must be 0 to indicate all records were updated"); + } + [TestMethod] + public void With_Transaction() + { + var dbContext = SetupDbContext(true); + int oldTotal = dbContext.Orders.Where(o => o.Price < 10M).Count(); + int rowUpdated; + using (var transaction = dbContext.Database.BeginTransaction()) { - var dbContext = SetupDbContext(true); - int oldTotal = dbContext.Orders.Where(o => o.Price < 10M).Count(); - int rowUpdated; - using (var transaction = dbContext.Database.BeginTransaction()) - { - rowUpdated = dbContext.Orders.Where(o => o.Price < 10M).UpdateFromQuery(o => new Order { Price = 25.30M }); - transaction.Rollback(); - } - int newTotal = dbContext.Orders.Where(o => o.Price < 10M).Count(); - int matchCount = dbContext.Orders.Where(o => o.Price == 25.30M).Count(); - - Assert.IsTrue(oldTotal > 0, "There must be orders in database that match this condition (Price < $10)"); - Assert.IsTrue(rowUpdated == oldTotal, "The number of rows update must match the count of rows that match the condtion (Price < $10)"); - Assert.IsTrue(newTotal == oldTotal, "The new count must match the old count since the transaction was rollbacked"); - Assert.IsTrue(matchCount == 0, "The match count must be equal to 0 since the transaction was rollbacked."); + rowUpdated = dbContext.Orders.Where(o => o.Price < 10M).UpdateFromQuery(o => new Order { Price = 25.30M }); + transaction.Rollback(); } - [TestMethod] - public void With_Variables() - { - var dbContext = SetupDbContext(true); - decimal priceStart = 10M; - decimal priceUpdate = 0.34M; + int newTotal = dbContext.Orders.Where(o => o.Price < 10M).Count(); + int matchCount = dbContext.Orders.Where(o => o.Price == 25.30M).Count(); - int oldTotal = dbContext.Orders.Count(a => a.Price < 10); - int rowUpdated = dbContext.Orders.Where(a => a.Price < 10).UpdateFromQuery(a => new Order { Price = priceStart + priceUpdate }); - int newTotal = dbContext.Orders.Count(o => o.Price < 10); + Assert.IsTrue(oldTotal > 0, "There must be orders in database that match this condition (Price < $10)"); + Assert.IsTrue(rowUpdated == oldTotal, "The number of rows update must match the count of rows that match the condtion (Price < $10)"); + Assert.IsTrue(newTotal == oldTotal, "The new count must match the old count since the transaction was rollbacked"); + Assert.IsTrue(matchCount == 0, "The match count must be equal to 0 since the transaction was rollbacked."); + } + [TestMethod] + public void With_Variables() + { + var dbContext = SetupDbContext(true); + decimal priceStart = 10M; + decimal priceUpdate = 0.34M; - Assert.IsTrue(oldTotal > 0, "There must be orders in database that match this condition (Price < 10)"); - Assert.IsTrue(rowUpdated == oldTotal, "The number of rows update must match the count of rows that match the condition (Price < 10)"); - Assert.IsTrue(newTotal == 0, "The new count must be 0 to indicate all records were updated"); - } - [TestMethod] - public void With_Variable_And_Decimal() - { - var dbContext = SetupDbContext(true); - decimal priceStart = 10M; + int oldTotal = dbContext.Orders.Count(a => a.Price < 10); + int rowUpdated = dbContext.Orders.Where(a => a.Price < 10).UpdateFromQuery(a => new Order { Price = priceStart + priceUpdate }); + int newTotal = dbContext.Orders.Count(o => o.Price < 10); - int oldTotal = dbContext.Orders.Count(a => a.Price < 10); - int rowUpdated = dbContext.Orders.Where(a => a.Price < 10).UpdateFromQuery(a => new Order { Price = priceStart + 7M }); - int newTotal = dbContext.Orders.Count(o => o.Price < 10); + Assert.IsTrue(oldTotal > 0, "There must be orders in database that match this condition (Price < 10)"); + Assert.IsTrue(rowUpdated == oldTotal, "The number of rows update must match the count of rows that match the condition (Price < 10)"); + Assert.IsTrue(newTotal == 0, "The new count must be 0 to indicate all records were updated"); + } + [TestMethod] + public void With_Variable_And_Decimal() + { + var dbContext = SetupDbContext(true); + decimal priceStart = 10M; - Assert.IsTrue(oldTotal > 0, "There must be orders in database that match this condition (Price < 10)"); - Assert.IsTrue(rowUpdated == oldTotal, "The number of rows update must match the count of rows that match the condition (Price < 10)"); - Assert.IsTrue(newTotal == 0, "The new count must be 0 to indicate all records were updated"); - } + int oldTotal = dbContext.Orders.Count(a => a.Price < 10); + int rowUpdated = dbContext.Orders.Where(a => a.Price < 10).UpdateFromQuery(a => new Order { Price = priceStart + 7M }); + int newTotal = dbContext.Orders.Count(o => o.Price < 10); + + Assert.IsTrue(oldTotal > 0, "There must be orders in database that match this condition (Price < 10)"); + Assert.IsTrue(rowUpdated == oldTotal, "The number of rows update must match the count of rows that match the condition (Price < 10)"); + Assert.IsTrue(newTotal == 0, "The new count must be 0 to indicate all records were updated"); } } \ No newline at end of file diff --git a/N.EntityFrameworkCore.Extensions.Test/DbContextExtensions/UpdateFromQueryAsync.cs b/N.EntityFrameworkCore.Extensions.Test/DbContextExtensions/UpdateFromQueryAsync.cs index ba7ca2e..02a8b80 100644 --- a/N.EntityFrameworkCore.Extensions.Test/DbContextExtensions/UpdateFromQueryAsync.cs +++ b/N.EntityFrameworkCore.Extensions.Test/DbContextExtensions/UpdateFromQueryAsync.cs @@ -9,270 +9,269 @@ using N.EntityFrameworkCore.Extensions.Test.Data; using N.EntityFrameworkCore.Extensions.Test.Data.Enums; -namespace N.EntityFrameworkCore.Extensions.Test.DbContextExtensions +namespace N.EntityFrameworkCore.Extensions.Test.DbContextExtensions; + +[TestClass] +public class UpdateFromQueryAsync : DbContextExtensionsBase { - [TestClass] - public class UpdateFromQueryAsync : DbContextExtensionsBase + [TestMethod] + public async Task With_Boolean_Value() { - [TestMethod] - public async Task With_Boolean_Value() - { - var dbContext = SetupDbContext(true); - int oldTotal = dbContext.Products.Count(a => a.OutOfStock); - int rowUpdated = await dbContext.Products.Where(a => a.OutOfStock).UpdateFromQueryAsync(a => new Product { OutOfStock = false }); - int newTotal = dbContext.Products.Count(o => o.OutOfStock); + var dbContext = SetupDbContext(true); + int oldTotal = dbContext.Products.Count(a => a.OutOfStock); + int rowUpdated = await dbContext.Products.Where(a => a.OutOfStock).UpdateFromQueryAsync(a => new Product { OutOfStock = false }); + int newTotal = dbContext.Products.Count(o => o.OutOfStock); - Assert.IsTrue(oldTotal > 0, "There must be articles in database that match this condition (OutOfStock == true)"); - Assert.IsTrue(rowUpdated == oldTotal, "The number of rows update must match the count of rows that match the condition (OutOfStock == false)"); - Assert.IsTrue(newTotal == 0, "The new count must be 0 to indicate all records were updated"); - } - [TestMethod] - public async Task With_Concatenating_String() - { - var dbContext = SetupDbContext(true); - var orders = dbContext.Orders.Where(o => o.ExternalId == null); - int oldTotal = orders.Count(); - int rowUpdated = await orders.UpdateFromQueryAsync(o => new Order { ExternalId = Convert.ToString(o.Id) + "Test" }); - int newTotal = orders.Count(); + Assert.IsTrue(oldTotal > 0, "There must be articles in database that match this condition (OutOfStock == true)"); + Assert.IsTrue(rowUpdated == oldTotal, "The number of rows update must match the count of rows that match the condition (OutOfStock == false)"); + Assert.IsTrue(newTotal == 0, "The new count must be 0 to indicate all records were updated"); + } + [TestMethod] + public async Task With_Concatenating_String() + { + var dbContext = SetupDbContext(true); + var orders = dbContext.Orders.Where(o => o.ExternalId == null); + int oldTotal = orders.Count(); + int rowUpdated = await orders.UpdateFromQueryAsync(o => new Order { ExternalId = Convert.ToString(o.Id) + "Test" }); + int newTotal = orders.Count(); - Assert.IsTrue(oldTotal > 0, "There must be orders in database that match this condition (ExternalId == null)"); - Assert.IsTrue(rowUpdated == oldTotal, "The number of rows update must match the count of rows that match the condition (ExternalId == null)"); - Assert.IsTrue(newTotal == 0, "The new count must be 0 to indicate all records were updated"); - } - [TestMethod] - public async Task With_Concatenating_String_And_Number() - { - var dbContext = SetupDbContext(true); - var orders = dbContext.Orders.Where(o => o.ExternalId == null); - int oldTotal = orders.Count(); - int rowUpdated = await orders.UpdateFromQueryAsync(o => new Order { ExternalId = Convert.ToString(o.Id) + "Test" }); - int newTotal = orders.Count(); + Assert.IsTrue(oldTotal > 0, "There must be orders in database that match this condition (ExternalId == null)"); + Assert.IsTrue(rowUpdated == oldTotal, "The number of rows update must match the count of rows that match the condition (ExternalId == null)"); + Assert.IsTrue(newTotal == 0, "The new count must be 0 to indicate all records were updated"); + } + [TestMethod] + public async Task With_Concatenating_String_And_Number() + { + var dbContext = SetupDbContext(true); + var orders = dbContext.Orders.Where(o => o.ExternalId == null); + int oldTotal = orders.Count(); + int rowUpdated = await orders.UpdateFromQueryAsync(o => new Order { ExternalId = Convert.ToString(o.Id) + "Test" }); + int newTotal = orders.Count(); - Assert.IsTrue(oldTotal > 0, "There must be orders in database that match this condition (ExternalId == null)"); - Assert.IsTrue(rowUpdated == oldTotal, "The number of rows update must match the count of rows that match the condition (ExternalId == null)"); - Assert.IsTrue(newTotal == 0, "The new count must be 0 to indicate all records were updated"); - } - [TestMethod] - public async Task With_DateTime_Value() - { - var dbContext = SetupDbContext(true); - DateTime dateTime = dbContext.Orders.Max(o => o.AddedDateTime).AddDays(-30); - DateTime now = DateTime.UtcNow; + Assert.IsTrue(oldTotal > 0, "There must be orders in database that match this condition (ExternalId == null)"); + Assert.IsTrue(rowUpdated == oldTotal, "The number of rows update must match the count of rows that match the condition (ExternalId == null)"); + Assert.IsTrue(newTotal == 0, "The new count must be 0 to indicate all records were updated"); + } + [TestMethod] + public async Task With_DateTime_Value() + { + var dbContext = SetupDbContext(true); + DateTime dateTime = dbContext.Orders.Max(o => o.AddedDateTime).AddDays(-30); + DateTime now = DateTime.UtcNow; - int oldTotal = dbContext.Orders.Where(o => o.AddedDateTime >= dateTime).Count(); - int rowUpdated = await dbContext.Orders.Where(o => o.AddedDateTime >= dateTime).UpdateFromQueryAsync(o => new Order { ModifiedDateTime = now }); - int newTotal = dbContext.Orders.Where(o => o.ModifiedDateTime == now).Count(); + int oldTotal = dbContext.Orders.Where(o => o.AddedDateTime >= dateTime).Count(); + int rowUpdated = await dbContext.Orders.Where(o => o.AddedDateTime >= dateTime).UpdateFromQueryAsync(o => new Order { ModifiedDateTime = now }); + int newTotal = dbContext.Orders.Where(o => o.ModifiedDateTime == now).Count(); - Assert.IsTrue(oldTotal > 0, "There must be orders in database that match this condition (Orders added in last 30 days)"); - Assert.IsTrue(rowUpdated == newTotal, "The number of rows updated should equal the new count of rows that match the condition (Orders added in last 30 days)"); - Assert.IsTrue(oldTotal == newTotal, "The count of rows matching the condition before and after the update should be equal. (Orders added in last 30 days)"); - } - [TestMethod] - public async Task With_DateTimeOffset_Value() - { - var dbContext = SetupDbContext(true); - DateTime dateTime = dbContext.Orders.Max(o => o.AddedDateTime).AddDays(-30); - DateTimeOffset now = DateTimeOffset.UtcNow; + Assert.IsTrue(oldTotal > 0, "There must be orders in database that match this condition (Orders added in last 30 days)"); + Assert.IsTrue(rowUpdated == newTotal, "The number of rows updated should equal the new count of rows that match the condition (Orders added in last 30 days)"); + Assert.IsTrue(oldTotal == newTotal, "The count of rows matching the condition before and after the update should be equal. (Orders added in last 30 days)"); + } + [TestMethod] + public async Task With_DateTimeOffset_Value() + { + var dbContext = SetupDbContext(true); + DateTime dateTime = dbContext.Orders.Max(o => o.AddedDateTime).AddDays(-30); + DateTimeOffset now = DateTimeOffset.UtcNow; - int oldTotal = dbContext.Orders.Where(o => o.AddedDateTime >= dateTime).Count(); - int rowUpdated = await dbContext.Orders.Where(o => o.AddedDateTime >= dateTime).UpdateFromQueryAsync(o => new Order { ModifiedDateTimeOffset = now }); - int newTotal = dbContext.Orders.Where(o => o.ModifiedDateTimeOffset == now).Count(); + int oldTotal = dbContext.Orders.Where(o => o.AddedDateTime >= dateTime).Count(); + int rowUpdated = await dbContext.Orders.Where(o => o.AddedDateTime >= dateTime).UpdateFromQueryAsync(o => new Order { ModifiedDateTimeOffset = now }); + int newTotal = dbContext.Orders.Where(o => o.ModifiedDateTimeOffset == now).Count(); - Assert.IsTrue(oldTotal > 0, "There must be orders in database that match this condition (Orders added in last 30 days)"); - Assert.IsTrue(rowUpdated == newTotal, "The number of rows updated should equal the new count of rows that match the condition (Orders added in last 30 days)"); - Assert.IsTrue(oldTotal == newTotal, "The count of rows matching the condition before and after the update should be equal. (Orders added in last 30 days)"); - } - [TestMethod] - public async Task With_DateTimeOffset_No_UTC_Value() - { - var dbContext = SetupDbContext(true); - DateTime dateTime = dbContext.Orders.Max(o => o.AddedDateTime).AddDays(-30); - DateTimeOffset now = DateTimeOffset.Parse("2020-06-17T16:00:00+05:00"); + Assert.IsTrue(oldTotal > 0, "There must be orders in database that match this condition (Orders added in last 30 days)"); + Assert.IsTrue(rowUpdated == newTotal, "The number of rows updated should equal the new count of rows that match the condition (Orders added in last 30 days)"); + Assert.IsTrue(oldTotal == newTotal, "The count of rows matching the condition before and after the update should be equal. (Orders added in last 30 days)"); + } + [TestMethod] + public async Task With_DateTimeOffset_No_UTC_Value() + { + var dbContext = SetupDbContext(true); + DateTime dateTime = dbContext.Orders.Max(o => o.AddedDateTime).AddDays(-30); + DateTimeOffset now = DateTimeOffset.Parse("2020-06-17T16:00:00+05:00"); - int oldTotal = dbContext.Orders.Where(o => o.AddedDateTime >= dateTime).Count(); - int rowUpdated = await dbContext.Orders.Where(o => o.AddedDateTime >= dateTime).UpdateFromQueryAsync(o => new Order { ModifiedDateTimeOffset = now }); - int newTotal = dbContext.Orders.Where(o => o.ModifiedDateTimeOffset == now).Count(); + int oldTotal = dbContext.Orders.Where(o => o.AddedDateTime >= dateTime).Count(); + int rowUpdated = await dbContext.Orders.Where(o => o.AddedDateTime >= dateTime).UpdateFromQueryAsync(o => new Order { ModifiedDateTimeOffset = now }); + int newTotal = dbContext.Orders.Where(o => o.ModifiedDateTimeOffset == now).Count(); - Assert.IsTrue(oldTotal > 0, "There must be orders in database that match this condition (Orders added in last 30 days)"); - Assert.IsTrue(rowUpdated == newTotal, "The number of rows updated should equal the new count of rows that match the condition (Orders added in last 30 days)"); - Assert.IsTrue(oldTotal == newTotal, "The count of rows matching the condition before and after the update should be equal. (Orders added in last 30 days)"); - } - [TestMethod] - public async Task With_Decimal_Value() - { - var dbContext = SetupDbContext(true); - var orders = dbContext.Orders.Where(o => o.Price < 10M); - int oldTotal = orders.Count(); - int rowUpdated = await orders.UpdateFromQueryAsync(o => new Order { Price = 25.30M }); - int newTotal = orders.Count(); - int matchCount = dbContext.Orders.Where(o => o.Price == 25.30M).Count(); + Assert.IsTrue(oldTotal > 0, "There must be orders in database that match this condition (Orders added in last 30 days)"); + Assert.IsTrue(rowUpdated == newTotal, "The number of rows updated should equal the new count of rows that match the condition (Orders added in last 30 days)"); + Assert.IsTrue(oldTotal == newTotal, "The count of rows matching the condition before and after the update should be equal. (Orders added in last 30 days)"); + } + [TestMethod] + public async Task With_Decimal_Value() + { + var dbContext = SetupDbContext(true); + var orders = dbContext.Orders.Where(o => o.Price < 10M); + int oldTotal = orders.Count(); + int rowUpdated = await orders.UpdateFromQueryAsync(o => new Order { Price = 25.30M }); + int newTotal = orders.Count(); + int matchCount = dbContext.Orders.Where(o => o.Price == 25.30M).Count(); - Assert.IsTrue(oldTotal > 0, "There must be orders in database that match this condition (Price < $10)"); - Assert.IsTrue(rowUpdated == oldTotal, "The number of rows update must match the count of rows that match the condtion (Price < $10)"); - Assert.IsTrue(newTotal == 0, "The new count must be 0 to indicate all records were updated"); - Assert.IsTrue(matchCount == rowUpdated, "The match count must be equal the number of rows updated in the database."); - } - [TestMethod] - public async Task With_Different_Culture() - { - Thread.CurrentThread.CurrentCulture = CultureInfo.GetCultureInfo("sv-SE"); - var dbContext = SetupDbContext(true); - int oldTotal = dbContext.Orders.Where(o => o.Price < 10M).Count(); - int rowUpdated = await dbContext.Orders.Where(o => o.Price < 10M).UpdateFromQueryAsync(o => new Order { Price = 25.30M }); - int newTotal = dbContext.Orders.Where(o => o.Price < 10M).Count(); - int matchCount = dbContext.Orders.Where(o => o.Price == 25.30M).Count(); + Assert.IsTrue(oldTotal > 0, "There must be orders in database that match this condition (Price < $10)"); + Assert.IsTrue(rowUpdated == oldTotal, "The number of rows update must match the count of rows that match the condtion (Price < $10)"); + Assert.IsTrue(newTotal == 0, "The new count must be 0 to indicate all records were updated"); + Assert.IsTrue(matchCount == rowUpdated, "The match count must be equal the number of rows updated in the database."); + } + [TestMethod] + public async Task With_Different_Culture() + { + Thread.CurrentThread.CurrentCulture = CultureInfo.GetCultureInfo("sv-SE"); + var dbContext = SetupDbContext(true); + int oldTotal = dbContext.Orders.Where(o => o.Price < 10M).Count(); + int rowUpdated = await dbContext.Orders.Where(o => o.Price < 10M).UpdateFromQueryAsync(o => new Order { Price = 25.30M }); + int newTotal = dbContext.Orders.Where(o => o.Price < 10M).Count(); + int matchCount = dbContext.Orders.Where(o => o.Price == 25.30M).Count(); - Assert.AreEqual("25,30", Convert.ToString(25.30M)); - Assert.IsTrue(oldTotal > 0, "There must be orders in database that match this condition (Price < $10)"); - Assert.IsTrue(rowUpdated == oldTotal, "The number of rows update must match the count of rows that match the condtion (Price < $10)"); - Assert.IsTrue(newTotal == 0, "The new count must be 0 to indicate all records were updated"); - Assert.IsTrue(matchCount == rowUpdated, "The match count must be equal the number of rows updated in the database."); - } - [TestMethod] - public async Task With_Enum_Value() - { - var dbContext = SetupDbContext(true); - var products = dbContext.Products.Where(a => a.StatusEnum == ProductStatus.OutOfStock && a.OutOfStock); - int oldTotal = products.Count(); - int rowUpdated = await products.UpdateFromQueryAsync(a => new Product { StatusEnum = ProductStatus.InStock }); - int newTotal = products.Count(o => o.StatusEnum == ProductStatus.OutOfStock && o.OutOfStock); - int newTotal2 = dbContext.Products.Count(o => o.StatusEnum == ProductStatus.InStock && o.OutOfStock); + Assert.AreEqual("25,30", Convert.ToString(25.30M)); + Assert.IsTrue(oldTotal > 0, "There must be orders in database that match this condition (Price < $10)"); + Assert.IsTrue(rowUpdated == oldTotal, "The number of rows update must match the count of rows that match the condtion (Price < $10)"); + Assert.IsTrue(newTotal == 0, "The new count must be 0 to indicate all records were updated"); + Assert.IsTrue(matchCount == rowUpdated, "The match count must be equal the number of rows updated in the database."); + } + [TestMethod] + public async Task With_Enum_Value() + { + var dbContext = SetupDbContext(true); + var products = dbContext.Products.Where(a => a.StatusEnum == ProductStatus.OutOfStock && a.OutOfStock); + int oldTotal = products.Count(); + int rowUpdated = await products.UpdateFromQueryAsync(a => new Product { StatusEnum = ProductStatus.InStock }); + int newTotal = products.Count(o => o.StatusEnum == ProductStatus.OutOfStock && o.OutOfStock); + int newTotal2 = dbContext.Products.Count(o => o.StatusEnum == ProductStatus.InStock && o.OutOfStock); - Assert.IsTrue(oldTotal > 0, "There must be articles in database that match this condition (OutOfStock == true)"); - Assert.IsTrue(rowUpdated == oldTotal, "The number of rows update must match the count of rows that match the condition (OutOfStock == false)"); - Assert.IsTrue(newTotal == 0, "The new count must be 0 to indicate all records were updated"); - Assert.IsTrue(newTotal2 == oldTotal, "All rows must have been updated"); - } - [TestMethod] - public async Task With_Guid_Value() - { - var dbContext = SetupDbContext(true); - var guid = Guid.NewGuid(); - var orders = dbContext.Orders.Where(o => o.Price < 10M); - int oldTotal = await orders.CountAsync(); - int rowUpdated = await orders.UpdateFromQueryAsync(o => new Order { GlobalId = guid }); - int matchCount = await dbContext.Orders.Where(o => o.GlobalId == guid).CountAsync(); + Assert.IsTrue(oldTotal > 0, "There must be articles in database that match this condition (OutOfStock == true)"); + Assert.IsTrue(rowUpdated == oldTotal, "The number of rows update must match the count of rows that match the condition (OutOfStock == false)"); + Assert.IsTrue(newTotal == 0, "The new count must be 0 to indicate all records were updated"); + Assert.IsTrue(newTotal2 == oldTotal, "All rows must have been updated"); + } + [TestMethod] + public async Task With_Guid_Value() + { + var dbContext = SetupDbContext(true); + var guid = Guid.NewGuid(); + var orders = dbContext.Orders.Where(o => o.Price < 10M); + int oldTotal = await orders.CountAsync(); + int rowUpdated = await orders.UpdateFromQueryAsync(o => new Order { GlobalId = guid }); + int matchCount = await dbContext.Orders.Where(o => o.GlobalId == guid).CountAsync(); - Assert.IsTrue(oldTotal > 0, "There must be orders in database that match this condition (Price < $10)"); - Assert.IsTrue(rowUpdated == oldTotal, $"The number of rows update must match the count of rows that match the condition (GlobalId = '{guid}')"); - Assert.IsTrue(matchCount == rowUpdated, "The match count must be equal the number of rows updated in the database."); - } - [TestMethod] - public async Task With_Long_List() - { - var dbContext = SetupDbContext(true); - var ids = new List() { 1, 2, 3, 4, 5, 6, 7, 8 }; - var orders = dbContext.Orders.Where(o => ids.Contains(o.Id)); - int oldTotal = orders.Count(); - int rowUpdated = await orders.UpdateFromQueryAsync(o => new Order { Price = 25.25M }); - int newTotal = orders.Where(o => o.Price != 25.25M).Count(); - int matchCount = dbContext.Orders.Where(o => ids.Contains(o.Id) && o.Price == 25.25M).Count(); + Assert.IsTrue(oldTotal > 0, "There must be orders in database that match this condition (Price < $10)"); + Assert.IsTrue(rowUpdated == oldTotal, $"The number of rows update must match the count of rows that match the condition (GlobalId = '{guid}')"); + Assert.IsTrue(matchCount == rowUpdated, "The match count must be equal the number of rows updated in the database."); + } + [TestMethod] + public async Task With_Long_List() + { + var dbContext = SetupDbContext(true); + var ids = new List() { 1, 2, 3, 4, 5, 6, 7, 8 }; + var orders = dbContext.Orders.Where(o => ids.Contains(o.Id)); + int oldTotal = orders.Count(); + int rowUpdated = await orders.UpdateFromQueryAsync(o => new Order { Price = 25.25M }); + int newTotal = orders.Where(o => o.Price != 25.25M).Count(); + int matchCount = dbContext.Orders.Where(o => ids.Contains(o.Id) && o.Price == 25.25M).Count(); - Assert.IsTrue(oldTotal > 0, "There must be orders in database that match this condition (Price < $10)"); - Assert.IsTrue(rowUpdated == oldTotal, "The number of rows update must match the count of rows that match the condtion (Price < $10)"); - Assert.IsTrue(newTotal == 0, "The new count must be 0 to indicate all records were updated"); - Assert.IsTrue(matchCount == rowUpdated, "The match count must be equal the number of rows updated in the database."); - } - [TestMethod] - public async Task With_MethodCall() - { - var dbContext = SetupDbContext(true); + Assert.IsTrue(oldTotal > 0, "There must be orders in database that match this condition (Price < $10)"); + Assert.IsTrue(rowUpdated == oldTotal, "The number of rows update must match the count of rows that match the condtion (Price < $10)"); + Assert.IsTrue(newTotal == 0, "The new count must be 0 to indicate all records were updated"); + Assert.IsTrue(matchCount == rowUpdated, "The match count must be equal the number of rows updated in the database."); + } + [TestMethod] + public async Task With_MethodCall() + { + var dbContext = SetupDbContext(true); - int oldTotal = dbContext.Orders.Count(a => a.Price < 10); - int rowUpdated = await dbContext.Orders.Where(a => a.Price < 10).UpdateFromQueryAsync(o => new Order { Price = Math.Ceiling((o.Price + 10.5M) * 3 / 1) }); - int newTotal = dbContext.Orders.Count(o => o.Price < 10); + int oldTotal = dbContext.Orders.Count(a => a.Price < 10); + int rowUpdated = await dbContext.Orders.Where(a => a.Price < 10).UpdateFromQueryAsync(o => new Order { Price = Math.Ceiling((o.Price + 10.5M) * 3 / 1) }); + int newTotal = dbContext.Orders.Count(o => o.Price < 10); - Assert.IsTrue(oldTotal > 0, "There must be order in database that match this condition (Price < 10)"); - Assert.IsTrue(rowUpdated == oldTotal, "The number of rows update must match the count of rows that match the condition (Price < 10)"); - Assert.IsTrue(newTotal == 0, "The new count must be 0 to indicate all records were updated"); - } - [TestMethod] - public async Task With_Null_Value() - { - var dbContext = SetupDbContext(true); - var orders = dbContext.Orders.Where(o => o.ExternalId != null); - int oldTotal = orders.Count(); - int rowUpdated = await orders.UpdateFromQueryAsync(o => new Order { ExternalId = null }); - int newTotal = orders.Count(); + Assert.IsTrue(oldTotal > 0, "There must be order in database that match this condition (Price < 10)"); + Assert.IsTrue(rowUpdated == oldTotal, "The number of rows update must match the count of rows that match the condition (Price < 10)"); + Assert.IsTrue(newTotal == 0, "The new count must be 0 to indicate all records were updated"); + } + [TestMethod] + public async Task With_Null_Value() + { + var dbContext = SetupDbContext(true); + var orders = dbContext.Orders.Where(o => o.ExternalId != null); + int oldTotal = orders.Count(); + int rowUpdated = await orders.UpdateFromQueryAsync(o => new Order { ExternalId = null }); + int newTotal = orders.Count(); - Assert.IsTrue(oldTotal > 0, "There must be orders in database that match this condition (ExternalId != null)"); - Assert.IsTrue(rowUpdated == oldTotal, "The number of rows update must match the count of rows that match the condition (ExternalId != null)"); - Assert.IsTrue(newTotal == 0, "The new count must be 0 to indicate all records were updated"); - } - [TestMethod] - public async Task With_Schema() - { - var dbContext = SetupDbContext(true, PopulateDataMode.Schema); - var products = dbContext.ProductsWithCustomSchema.Where(o => o.Price < 5M); - int oldTotal = products.Count(); - int rowUpdated = await products.UpdateFromQueryAsync(o => new ProductWithCustomSchema { Price = 25.30M }); - int newTotal = products.Count(); - int matchCount = dbContext.ProductsWithCustomSchema.Where(o => o.Price == 25.30M).Count(); + Assert.IsTrue(oldTotal > 0, "There must be orders in database that match this condition (ExternalId != null)"); + Assert.IsTrue(rowUpdated == oldTotal, "The number of rows update must match the count of rows that match the condition (ExternalId != null)"); + Assert.IsTrue(newTotal == 0, "The new count must be 0 to indicate all records were updated"); + } + [TestMethod] + public async Task With_Schema() + { + var dbContext = SetupDbContext(true, PopulateDataMode.Schema); + var products = dbContext.ProductsWithCustomSchema.Where(o => o.Price < 5M); + int oldTotal = products.Count(); + int rowUpdated = await products.UpdateFromQueryAsync(o => new ProductWithCustomSchema { Price = 25.30M }); + int newTotal = products.Count(); + int matchCount = dbContext.ProductsWithCustomSchema.Where(o => o.Price == 25.30M).Count(); - Assert.IsTrue(oldTotal > 0, "There must be products in database that match this condition (Price < 5)"); - Assert.IsTrue(rowUpdated == oldTotal, "The number of rows update must match the count of rows that match the condtion (Price < 5)"); - Assert.IsTrue(newTotal == 0, "The new count must be 0 to indicate all records were updated"); - Assert.IsTrue(matchCount == rowUpdated, "The match count must be equal the number of rows updated in the database."); - } - [TestMethod] - public async Task With_String_Containing_Apostrophe() - { - var dbContext = SetupDbContext(true); - int oldTotal = dbContext.Orders.Where(o => o.ExternalId == null).Count(); - int rowUpdated = await dbContext.Orders.Where(o => o.ExternalId == null).UpdateFromQueryAsync(o => new Order { ExternalId = "inv'alid" }); - int newTotal = dbContext.Orders.Where(o => o.ExternalId == null).Count(); + Assert.IsTrue(oldTotal > 0, "There must be products in database that match this condition (Price < 5)"); + Assert.IsTrue(rowUpdated == oldTotal, "The number of rows update must match the count of rows that match the condtion (Price < 5)"); + Assert.IsTrue(newTotal == 0, "The new count must be 0 to indicate all records were updated"); + Assert.IsTrue(matchCount == rowUpdated, "The match count must be equal the number of rows updated in the database."); + } + [TestMethod] + public async Task With_String_Containing_Apostrophe() + { + var dbContext = SetupDbContext(true); + int oldTotal = dbContext.Orders.Where(o => o.ExternalId == null).Count(); + int rowUpdated = await dbContext.Orders.Where(o => o.ExternalId == null).UpdateFromQueryAsync(o => new Order { ExternalId = "inv'alid" }); + int newTotal = dbContext.Orders.Where(o => o.ExternalId == null).Count(); - Assert.IsTrue(oldTotal > 0, "There must be orders in database that match this condition (ExternalId == null)"); - Assert.IsTrue(rowUpdated == oldTotal, "The number of rows update must match the count of rows that match the condition (ExternalId == null)"); - Assert.IsTrue(newTotal == 0, "The new count must be 0 to indicate all records were updated"); - } - [TestMethod] - public async Task With_Transaction() + Assert.IsTrue(oldTotal > 0, "There must be orders in database that match this condition (ExternalId == null)"); + Assert.IsTrue(rowUpdated == oldTotal, "The number of rows update must match the count of rows that match the condition (ExternalId == null)"); + Assert.IsTrue(newTotal == 0, "The new count must be 0 to indicate all records were updated"); + } + [TestMethod] + public async Task With_Transaction() + { + var dbContext = SetupDbContext(true); + int oldTotal = dbContext.Orders.Where(o => o.Price < 10M).Count(); + int rowUpdated; + using (var transaction = dbContext.Database.BeginTransaction()) { - var dbContext = SetupDbContext(true); - int oldTotal = dbContext.Orders.Where(o => o.Price < 10M).Count(); - int rowUpdated; - using (var transaction = dbContext.Database.BeginTransaction()) - { - rowUpdated = await dbContext.Orders.Where(o => o.Price < 10M).UpdateFromQueryAsync(o => new Order { Price = 25.30M }); - transaction.Rollback(); - } - int newTotal = dbContext.Orders.Where(o => o.Price < 10M).Count(); - int matchCount = dbContext.Orders.Where(o => o.Price == 25.30M).Count(); - - Assert.IsTrue(oldTotal > 0, "There must be orders in database that match this condition (Price < $10)"); - Assert.IsTrue(rowUpdated == oldTotal, "The number of rows update must match the count of rows that match the condtion (Price < $10)"); - Assert.IsTrue(newTotal == oldTotal, "The new count must match the old count since the transaction was rollbacked"); - Assert.IsTrue(matchCount == 0, "The match count must be equal to 0 since the transaction was rollbacked."); + rowUpdated = await dbContext.Orders.Where(o => o.Price < 10M).UpdateFromQueryAsync(o => new Order { Price = 25.30M }); + transaction.Rollback(); } - [TestMethod] - public async Task With_Variables() - { - var dbContext = SetupDbContext(true); - decimal priceStart = 10M; - decimal priceUpdate = 0.34M; + int newTotal = dbContext.Orders.Where(o => o.Price < 10M).Count(); + int matchCount = dbContext.Orders.Where(o => o.Price == 25.30M).Count(); - int oldTotal = dbContext.Orders.Count(a => a.Price < 10); - int rowUpdated = await dbContext.Orders.Where(a => a.Price < 10).UpdateFromQueryAsync(a => new Order { Price = priceStart + priceUpdate }); - int newTotal = dbContext.Orders.Count(o => o.Price < 10); + Assert.IsTrue(oldTotal > 0, "There must be orders in database that match this condition (Price < $10)"); + Assert.IsTrue(rowUpdated == oldTotal, "The number of rows update must match the count of rows that match the condtion (Price < $10)"); + Assert.IsTrue(newTotal == oldTotal, "The new count must match the old count since the transaction was rollbacked"); + Assert.IsTrue(matchCount == 0, "The match count must be equal to 0 since the transaction was rollbacked."); + } + [TestMethod] + public async Task With_Variables() + { + var dbContext = SetupDbContext(true); + decimal priceStart = 10M; + decimal priceUpdate = 0.34M; - Assert.IsTrue(oldTotal > 0, "There must be orders in database that match this condition (Price < 10)"); - Assert.IsTrue(rowUpdated == oldTotal, "The number of rows update must match the count of rows that match the condition (Price < 10)"); - Assert.IsTrue(newTotal == 0, "The new count must be 0 to indicate all records were updated"); - } - [TestMethod] - public async Task With_Variable_And_Decimal() - { - var dbContext = SetupDbContext(true); - decimal priceStart = 10M; + int oldTotal = dbContext.Orders.Count(a => a.Price < 10); + int rowUpdated = await dbContext.Orders.Where(a => a.Price < 10).UpdateFromQueryAsync(a => new Order { Price = priceStart + priceUpdate }); + int newTotal = dbContext.Orders.Count(o => o.Price < 10); - int oldTotal = dbContext.Orders.Count(a => a.Price < 10); - int rowUpdated = await dbContext.Orders.Where(a => a.Price < 10).UpdateFromQueryAsync(a => new Order { Price = priceStart + 7M }); - int newTotal = dbContext.Orders.Count(o => o.Price < 10); + Assert.IsTrue(oldTotal > 0, "There must be orders in database that match this condition (Price < 10)"); + Assert.IsTrue(rowUpdated == oldTotal, "The number of rows update must match the count of rows that match the condition (Price < 10)"); + Assert.IsTrue(newTotal == 0, "The new count must be 0 to indicate all records were updated"); + } + [TestMethod] + public async Task With_Variable_And_Decimal() + { + var dbContext = SetupDbContext(true); + decimal priceStart = 10M; - Assert.IsTrue(oldTotal > 0, "There must be orders in database that match this condition (Price < 10)"); - Assert.IsTrue(rowUpdated == oldTotal, "The number of rows update must match the count of rows that match the condition (Price < 10)"); - Assert.IsTrue(newTotal == 0, "The new count must be 0 to indicate all records were updated"); - } + int oldTotal = dbContext.Orders.Count(a => a.Price < 10); + int rowUpdated = await dbContext.Orders.Where(a => a.Price < 10).UpdateFromQueryAsync(a => new Order { Price = priceStart + 7M }); + int newTotal = dbContext.Orders.Count(o => o.Price < 10); + + Assert.IsTrue(oldTotal > 0, "There must be orders in database that match this condition (Price < 10)"); + Assert.IsTrue(rowUpdated == oldTotal, "The number of rows update must match the count of rows that match the condition (Price < 10)"); + Assert.IsTrue(newTotal == 0, "The new count must be 0 to indicate all records were updated"); } } \ No newline at end of file diff --git a/N.EntityFrameworkCore.Extensions.Test/DbSetExtensions/Clear.cs b/N.EntityFrameworkCore.Extensions.Test/DbSetExtensions/Clear.cs index e344c39..91e8537 100644 --- a/N.EntityFrameworkCore.Extensions.Test/DbSetExtensions/Clear.cs +++ b/N.EntityFrameworkCore.Extensions.Test/DbSetExtensions/Clear.cs @@ -3,21 +3,20 @@ using N.EntityFrameworkCore.Extensions.Test.Data; using N.EntityFrameworkCore.Extensions.Test.DbContextExtensions; -namespace N.EntityFrameworkCore.Extensions.Test.DbSetExtensions +namespace N.EntityFrameworkCore.Extensions.Test.DbSetExtensions; + +[TestClass] +public class Clear : DbContextExtensionsBase { - [TestClass] - public class Clear : DbContextExtensionsBase + [TestMethod] + public void Using_Dbset() { - [TestMethod] - public void Using_Dbset() - { - var dbContext = SetupDbContext(true); - int oldOrdersCount = dbContext.Orders.Count(); - dbContext.Orders.Clear(); - int newOrdersCount = dbContext.Orders.Count(); + var dbContext = SetupDbContext(true); + int oldOrdersCount = dbContext.Orders.Count(); + dbContext.Orders.Clear(); + int newOrdersCount = dbContext.Orders.Count(); - Assert.IsTrue(oldOrdersCount > 0, "Orders table should have data"); - Assert.IsTrue(newOrdersCount == 0, "Order table should be empty after truncating"); - } + Assert.IsTrue(oldOrdersCount > 0, "Orders table should have data"); + Assert.IsTrue(newOrdersCount == 0, "Order table should be empty after truncating"); } } \ No newline at end of file diff --git a/N.EntityFrameworkCore.Extensions.Test/DbSetExtensions/ClearAsync.cs b/N.EntityFrameworkCore.Extensions.Test/DbSetExtensions/ClearAsync.cs index 921d654..6cb0097 100644 --- a/N.EntityFrameworkCore.Extensions.Test/DbSetExtensions/ClearAsync.cs +++ b/N.EntityFrameworkCore.Extensions.Test/DbSetExtensions/ClearAsync.cs @@ -4,21 +4,20 @@ using N.EntityFrameworkCore.Extensions.Test.Data; using N.EntityFrameworkCore.Extensions.Test.DbContextExtensions; -namespace N.EntityFrameworkCore.Extensions.Test.DbSetExtensions +namespace N.EntityFrameworkCore.Extensions.Test.DbSetExtensions; + +[TestClass] +public class ClearAsync : DbContextExtensionsBase { - [TestClass] - public class ClearAsync : DbContextExtensionsBase + [TestMethod] + public async Task Using_Dbset() { - [TestMethod] - public async Task Using_Dbset() - { - var dbContext = SetupDbContext(true); - int oldOrdersCount = dbContext.Orders.Count(); - await dbContext.Orders.ClearAsync(); - int newOrdersCount = dbContext.Orders.Count(); + var dbContext = SetupDbContext(true); + int oldOrdersCount = dbContext.Orders.Count(); + await dbContext.Orders.ClearAsync(); + int newOrdersCount = dbContext.Orders.Count(); - Assert.IsTrue(oldOrdersCount > 0, "Orders table should have data"); - Assert.IsTrue(newOrdersCount == 0, "Order table should be empty after truncating"); - } + Assert.IsTrue(oldOrdersCount > 0, "Orders table should have data"); + Assert.IsTrue(newOrdersCount == 0, "Order table should be empty after truncating"); } } \ No newline at end of file diff --git a/N.EntityFrameworkCore.Extensions.Test/DbSetExtensions/Truncate.cs b/N.EntityFrameworkCore.Extensions.Test/DbSetExtensions/Truncate.cs index 9bcdc51..de0a871 100644 --- a/N.EntityFrameworkCore.Extensions.Test/DbSetExtensions/Truncate.cs +++ b/N.EntityFrameworkCore.Extensions.Test/DbSetExtensions/Truncate.cs @@ -3,21 +3,20 @@ using N.EntityFrameworkCore.Extensions.Test.Data; using N.EntityFrameworkCore.Extensions.Test.DbContextExtensions; -namespace N.EntityFrameworkCore.Extensions.Test.DbSetExtensions +namespace N.EntityFrameworkCore.Extensions.Test.DbSetExtensions; + +[TestClass] +public class Truncate : DbContextExtensionsBase { - [TestClass] - public class Truncate : DbContextExtensionsBase + [TestMethod] + public void Using_Dbset() { - [TestMethod] - public void Using_Dbset() - { - var dbContext = SetupDbContext(true); - int oldOrdersCount = dbContext.Orders.Count(); - dbContext.Orders.Truncate(); - int newOrdersCount = dbContext.Orders.Count(); + var dbContext = SetupDbContext(true); + int oldOrdersCount = dbContext.Orders.Count(); + dbContext.Orders.Truncate(); + int newOrdersCount = dbContext.Orders.Count(); - Assert.IsTrue(oldOrdersCount > 0, "Orders table should have data"); - Assert.IsTrue(newOrdersCount == 0, "Order table should be empty after truncating"); - } + Assert.IsTrue(oldOrdersCount > 0, "Orders table should have data"); + Assert.IsTrue(newOrdersCount == 0, "Order table should be empty after truncating"); } } \ No newline at end of file diff --git a/N.EntityFrameworkCore.Extensions.Test/DbSetExtensions/TruncateAsync.cs b/N.EntityFrameworkCore.Extensions.Test/DbSetExtensions/TruncateAsync.cs index 5d3a1ad..6daf4ff 100644 --- a/N.EntityFrameworkCore.Extensions.Test/DbSetExtensions/TruncateAsync.cs +++ b/N.EntityFrameworkCore.Extensions.Test/DbSetExtensions/TruncateAsync.cs @@ -4,21 +4,20 @@ using N.EntityFrameworkCore.Extensions.Test.Data; using N.EntityFrameworkCore.Extensions.Test.DbContextExtensions; -namespace N.EntityFrameworkCore.Extensions.Test.DbSetExtensions +namespace N.EntityFrameworkCore.Extensions.Test.DbSetExtensions; + +[TestClass] +public class TruncateAsync : DbContextExtensionsBase { - [TestClass] - public class TruncateAsync : DbContextExtensionsBase + [TestMethod] + public async Task Using_Dbset() { - [TestMethod] - public async Task Using_Dbset() - { - var dbContext = SetupDbContext(true); - int oldOrdersCount = dbContext.Orders.Count(); - await dbContext.Orders.TruncateAsync(); - int newOrdersCount = dbContext.Orders.Count(); + var dbContext = SetupDbContext(true); + int oldOrdersCount = dbContext.Orders.Count(); + await dbContext.Orders.TruncateAsync(); + int newOrdersCount = dbContext.Orders.Count(); - Assert.IsTrue(oldOrdersCount > 0, "Orders table should have data"); - Assert.IsTrue(newOrdersCount == 0, "Order table should be empty after truncating"); - } + Assert.IsTrue(oldOrdersCount > 0, "Orders table should have data"); + Assert.IsTrue(newOrdersCount == 0, "Order table should be empty after truncating"); } } \ No newline at end of file diff --git a/N.EntityFrameworkCore.Extensions/Common/Constants.cs b/N.EntityFrameworkCore.Extensions/Common/Constants.cs index 45602a0..0c1864d 100644 --- a/N.EntityFrameworkCore.Extensions/Common/Constants.cs +++ b/N.EntityFrameworkCore.Extensions/Common/Constants.cs @@ -4,10 +4,9 @@ using System.Text; using System.Threading.Tasks; -namespace N.EntityFrameworkCore.Extensions.Common +namespace N.EntityFrameworkCore.Extensions.Common; + +public static class Constants { - public static class Constants - { - public readonly static string InternalId_ColumnName = "_be_xx_id"; - } + public readonly static string InternalId_ColumnName = "_be_xx_id"; } \ No newline at end of file diff --git a/N.EntityFrameworkCore.Extensions/Data/BulkDeleteOptions.cs b/N.EntityFrameworkCore.Extensions/Data/BulkDeleteOptions.cs index db00d7f..412d3b4 100644 --- a/N.EntityFrameworkCore.Extensions/Data/BulkDeleteOptions.cs +++ b/N.EntityFrameworkCore.Extensions/Data/BulkDeleteOptions.cs @@ -1,10 +1,9 @@ using System; using System.Linq.Expressions; -namespace N.EntityFrameworkCore.Extensions +namespace N.EntityFrameworkCore.Extensions; + +public class BulkDeleteOptions : BulkOptions { - public class BulkDeleteOptions : BulkOptions - { - public Expression> DeleteOnCondition { get; set; } - } + public Expression> DeleteOnCondition { get; set; } } \ No newline at end of file diff --git a/N.EntityFrameworkCore.Extensions/Data/BulkFetchOptions.cs b/N.EntityFrameworkCore.Extensions/Data/BulkFetchOptions.cs index 684ad2d..a68c181 100644 --- a/N.EntityFrameworkCore.Extensions/Data/BulkFetchOptions.cs +++ b/N.EntityFrameworkCore.Extensions/Data/BulkFetchOptions.cs @@ -6,16 +6,15 @@ using System.Threading.Tasks; using N.EntityFrameworkCore.Extensions.Enums; -namespace N.EntityFrameworkCore.Extensions +namespace N.EntityFrameworkCore.Extensions; + +public class BulkFetchOptions : BulkOptions { - public class BulkFetchOptions : BulkOptions + public Expression> IgnoreColumns { get; set; } + public Expression> InputColumns { get; set; } + public Expression> JoinOnCondition { get; set; } + public BulkFetchOptions() { - public Expression> IgnoreColumns { get; set; } - public Expression> InputColumns { get; set; } - public Expression> JoinOnCondition { get; set; } - public BulkFetchOptions() - { - //this.ConnectionBehavior = ConnectionBehavior.New; - } + //this.ConnectionBehavior = ConnectionBehavior.New; } } \ No newline at end of file diff --git a/N.EntityFrameworkCore.Extensions/Data/BulkInsertOptions.cs b/N.EntityFrameworkCore.Extensions/Data/BulkInsertOptions.cs index da8f863..df9f89d 100644 --- a/N.EntityFrameworkCore.Extensions/Data/BulkInsertOptions.cs +++ b/N.EntityFrameworkCore.Extensions/Data/BulkInsertOptions.cs @@ -3,30 +3,29 @@ using System.Linq; using System.Linq.Expressions; -namespace N.EntityFrameworkCore.Extensions +namespace N.EntityFrameworkCore.Extensions; + +public class BulkInsertOptions : BulkOptions { - public class BulkInsertOptions : BulkOptions - { - public bool AutoMapOutput { get; set; } - public Expression> IgnoreColumns { get; set; } - public Expression> InputColumns { get; set; } - public bool InsertIfNotExists { get; set; } - public Expression> InsertOnCondition { get; set; } - public bool KeepIdentity { get; set; } + public bool AutoMapOutput { get; set; } + public Expression> IgnoreColumns { get; set; } + public Expression> InputColumns { get; set; } + public bool InsertIfNotExists { get; set; } + public Expression> InsertOnCondition { get; set; } + public bool KeepIdentity { get; set; } - public string[] GetInputColumns() - { - return this.InputColumns == null ? null : this.InputColumns.Body.Type.GetProperties().Select(o => o.Name).ToArray(); - } + public string[] GetInputColumns() + { + return this.InputColumns == null ? null : this.InputColumns.Body.Type.GetProperties().Select(o => o.Name).ToArray(); + } - public BulkInsertOptions() - { - this.AutoMapOutput = true; - this.InsertIfNotExists = false; - } - internal BulkInsertOptions(BulkOptions options) - { - this.EntityType = options.EntityType; - } + public BulkInsertOptions() + { + this.AutoMapOutput = true; + this.InsertIfNotExists = false; + } + internal BulkInsertOptions(BulkOptions options) + { + this.EntityType = options.EntityType; } } \ No newline at end of file diff --git a/N.EntityFrameworkCore.Extensions/Data/BulkInsertResult.cs b/N.EntityFrameworkCore.Extensions/Data/BulkInsertResult.cs index 1bd3390..13a24a4 100644 --- a/N.EntityFrameworkCore.Extensions/Data/BulkInsertResult.cs +++ b/N.EntityFrameworkCore.Extensions/Data/BulkInsertResult.cs @@ -1,11 +1,10 @@ using System; using System.Collections.Generic; -namespace N.EntityFrameworkCore.Extensions +namespace N.EntityFrameworkCore.Extensions; + +internal class BulkInsertResult { - internal class BulkInsertResult - { - internal int RowsAffected { get; set; } - internal Dictionary EntityMap { get; set; } - } + internal int RowsAffected { get; set; } + internal Dictionary EntityMap { get; set; } } \ No newline at end of file diff --git a/N.EntityFrameworkCore.Extensions/Data/BulkMergeOption.cs b/N.EntityFrameworkCore.Extensions/Data/BulkMergeOption.cs index e7cc0cd..fec19c4 100644 --- a/N.EntityFrameworkCore.Extensions/Data/BulkMergeOption.cs +++ b/N.EntityFrameworkCore.Extensions/Data/BulkMergeOption.cs @@ -3,30 +3,29 @@ using System.Linq; using System.Linq.Expressions; -namespace N.EntityFrameworkCore.Extensions +namespace N.EntityFrameworkCore.Extensions; + +public class BulkMergeOptions : BulkOptions { - public class BulkMergeOptions : BulkOptions - { - public Expression> MergeOnCondition { get; set; } - //public Func NotMatchedBySourceCondition { get; set; } - //public Func NotMatchedByTargetCondition { get; set; } - //public Func MatchedCondition { get; set; } - public Expression> IgnoreColumnsOnInsert { get; set; } - public Expression> IgnoreColumnsOnUpdate { get; set; } - public bool AutoMapOutput { get; set; } - internal bool DeleteIfNotMatched { get; set; } + public Expression> MergeOnCondition { get; set; } + //public Func NotMatchedBySourceCondition { get; set; } + //public Func NotMatchedByTargetCondition { get; set; } + //public Func MatchedCondition { get; set; } + public Expression> IgnoreColumnsOnInsert { get; set; } + public Expression> IgnoreColumnsOnUpdate { get; set; } + public bool AutoMapOutput { get; set; } + internal bool DeleteIfNotMatched { get; set; } - public BulkMergeOptions() - { + public BulkMergeOptions() + { this.AutoMapOutput = true; } - public List GetIgnoreColumnsOnInsert() - { + public List GetIgnoreColumnsOnInsert() + { return this.IgnoreColumnsOnInsert == null ? new List() : this.IgnoreColumnsOnInsert.Body.Type.GetProperties().Select(o => o.Name).ToList(); } - public List GetIgnoreColumnsOnUpdate() - { + public List GetIgnoreColumnsOnUpdate() + { return this.IgnoreColumnsOnUpdate == null ? new List() : this.IgnoreColumnsOnUpdate.Body.Type.GetProperties().Select(o => o.Name).ToList(); } - } } \ No newline at end of file diff --git a/N.EntityFrameworkCore.Extensions/Data/BulkMergeOutputRow.cs b/N.EntityFrameworkCore.Extensions/Data/BulkMergeOutputRow.cs index 82ca5d9..751b4cf 100644 --- a/N.EntityFrameworkCore.Extensions/Data/BulkMergeOutputRow.cs +++ b/N.EntityFrameworkCore.Extensions/Data/BulkMergeOutputRow.cs @@ -1,12 +1,11 @@ -namespace N.EntityFrameworkCore.Extensions +namespace N.EntityFrameworkCore.Extensions; + +public class BulkMergeOutputRow { - public class BulkMergeOutputRow - { - public string Action { get; set; } + public string Action { get; set; } - public BulkMergeOutputRow(string action) - { + public BulkMergeOutputRow(string action) + { this.Action = action; } - } } \ No newline at end of file diff --git a/N.EntityFrameworkCore.Extensions/Data/BulkMergeResult.cs b/N.EntityFrameworkCore.Extensions/Data/BulkMergeResult.cs index 42e3a9e..6e18d09 100644 --- a/N.EntityFrameworkCore.Extensions/Data/BulkMergeResult.cs +++ b/N.EntityFrameworkCore.Extensions/Data/BulkMergeResult.cs @@ -1,14 +1,13 @@ using System.Collections.Generic; using Microsoft.EntityFrameworkCore.Metadata.Internal; -namespace N.EntityFrameworkCore.Extensions +namespace N.EntityFrameworkCore.Extensions; + +public class BulkMergeResult { - public class BulkMergeResult - { - public IEnumerable> Output { get; set; } - public int RowsAffected { get; set; } - public int RowsDeleted { get; internal set; } - public int RowsInserted { get; internal set; } - public int RowsUpdated { get; internal set; } - } + public IEnumerable> Output { get; set; } + public int RowsAffected { get; set; } + public int RowsDeleted { get; internal set; } + public int RowsInserted { get; internal set; } + public int RowsUpdated { get; internal set; } } \ No newline at end of file diff --git a/N.EntityFrameworkCore.Extensions/Data/BulkOperation.cs b/N.EntityFrameworkCore.Extensions/Data/BulkOperation.cs index 0e4eb4b..325b196 100644 --- a/N.EntityFrameworkCore.Extensions/Data/BulkOperation.cs +++ b/N.EntityFrameworkCore.Extensions/Data/BulkOperation.cs @@ -20,27 +20,27 @@ using N.EntityFrameworkCore.Extensions.Util; using static Microsoft.EntityFrameworkCore.DbLoggerCategory.Database; -namespace N.EntityFrameworkCore.Extensions +namespace N.EntityFrameworkCore.Extensions; + +internal partial class BulkOperation : IDisposable { - internal partial class BulkOperation : IDisposable - { - internal SqlConnection Connection => DbTransactionContext.Connection; - internal DbContext Context { get; } - internal bool StagingTableCreated { get; set; } - internal string StagingTableName { get; } - internal string[] PrimaryKeyColumnNames { get; } - internal BulkOptions Options { get; } - internal Expression> InputColumns { get; } - internal Expression> IgnoreColumns { get; } - internal DbTransactionContext DbTransactionContext { get; } - internal Type EntityType => typeof(T); - internal SqlTransaction Transaction => DbTransactionContext.CurrentTransaction; - internal TableMapping TableMapping { get; } - internal IEnumerable SchemaQualifiedTableNames => TableMapping.GetSchemaQualifiedTableNames(); + internal SqlConnection Connection => DbTransactionContext.Connection; + internal DbContext Context { get; } + internal bool StagingTableCreated { get; set; } + internal string StagingTableName { get; } + internal string[] PrimaryKeyColumnNames { get; } + internal BulkOptions Options { get; } + internal Expression> InputColumns { get; } + internal Expression> IgnoreColumns { get; } + internal DbTransactionContext DbTransactionContext { get; } + internal Type EntityType => typeof(T); + internal SqlTransaction Transaction => DbTransactionContext.CurrentTransaction; + internal TableMapping TableMapping { get; } + internal IEnumerable SchemaQualifiedTableNames => TableMapping.GetSchemaQualifiedTableNames(); - public BulkOperation(DbContext dbContext, BulkOptions options, Expression> inputColumns = null, Expression> ignoreColumns = null) - { + public BulkOperation(DbContext dbContext, BulkOptions options, Expression> inputColumns = null, Expression> ignoreColumns = null) + { Context = dbContext; Options = options; InputColumns = inputColumns; @@ -51,17 +51,17 @@ public BulkOperation(DbContext dbContext, BulkOptions options, Expression BulkInsertStagingData(IEnumerable entities, bool keepIdentity = true, bool useInternalId = false) - { + internal BulkInsertResult BulkInsertStagingData(IEnumerable entities, bool keepIdentity = true, bool useInternalId = false) + { IEnumerable columnsToInsert = GetColumnNames(keepIdentity); string internalIdColumn = useInternalId ? Common.Constants.InternalId_ColumnName : null; Context.Database.CloneTable(SchemaQualifiedTableNames, StagingTableName, TableMapping.GetQualifiedColumnNames(columnsToInsert), internalIdColumn); StagingTableCreated = true; return DbContextExtensions.BulkInsert(entities, Options, TableMapping, Connection, Transaction, StagingTableName, columnsToInsert, SqlBulkCopyOptions.KeepIdentity, useInternalId); } - internal BulkMergeResult ExecuteMerge(Dictionary entityMap, Expression> mergeOnCondition, - bool autoMapOutput, bool keepIdentity, bool insertIfNotExists, bool update = false, bool delete = false) - { + internal BulkMergeResult ExecuteMerge(Dictionary entityMap, Expression> mergeOnCondition, + bool autoMapOutput, bool keepIdentity, bool insertIfNotExists, bool update = false, bool delete = false) + { var rowsInserted = new Dictionary(); var rowsUpdated = new Dictionary(); var rowsDeleted = new Dictionary(); @@ -146,19 +146,19 @@ .. TableMapping.GetEntityProperties(entityType, ValueGenerated.OnAddOrUpdate).To }; } - private IEnumerable GetMergeOutputColumns(IEnumerable autoGeneratedColumns, bool delete = false) - { + private IEnumerable GetMergeOutputColumns(IEnumerable autoGeneratedColumns, bool delete = false) + { List columnsToOutput = new List { "$Action", string.Format("[{0}].[{1}]", "s", Constants.InternalId_ColumnName) }; columnsToOutput.AddRange(autoGeneratedColumns.Select(o => string.Format("[inserted].[{0}]", o))); return columnsToOutput.AsEnumerable(); } - private object[] GetMergeOutputValues(IEnumerable columns, object[] values, IEnumerable properties) - { + private object[] GetMergeOutputValues(IEnumerable columns, object[] values, IEnumerable properties) + { var valuesIndex = properties.Select(o => columns.ToList().IndexOf($"[inserted].[{o.GetColumnName()}]")); return valuesIndex.Select(i => values[i]).ToArray(); } - internal int ExecuteUpdate(IEnumerable entities, Expression> updateOnCondition) - { + internal int ExecuteUpdate(IEnumerable entities, Expression> updateOnCondition) + { int rowsUpdated = 0; foreach (var entityType in TableMapping.EntityTypes) { @@ -171,33 +171,32 @@ internal int ExecuteUpdate(IEnumerable entities, Expression> } return rowsUpdated; } - internal void ValidateBulkMerge(Expression> mergeOnCondition) - { + internal void ValidateBulkMerge(Expression> mergeOnCondition) + { if (PrimaryKeyColumnNames.Length == 0 && mergeOnCondition == null) throw new InvalidDataException("BulkMerge requires that the entity have a primary key"); if (PrimaryKeyColumnNames.Length == 0 && mergeOnCondition == null) throw new InvalidDataException("BulkMerge requires that Options.MergeOnCondition be set"); } - internal void ValidateBulkUpdate(Expression> updateOnCondition) - { + internal void ValidateBulkUpdate(Expression> updateOnCondition) + { if (PrimaryKeyColumnNames.Length == 0 && updateOnCondition == null) throw new InvalidDataException("BulkUpdate requires that the entity have a primary key or the Options.UpdateOnCondition must be set."); } - public void Dispose() - { + public void Dispose() + { if (StagingTableCreated) { Context.Database.DropTable(StagingTableName); } } - internal IEnumerable GetColumnNames(bool includPrimaryKeys = false) - { + internal IEnumerable GetColumnNames(bool includPrimaryKeys = false) + { return GetColumnNames(null, includPrimaryKeys); } - internal IEnumerable GetColumnNames(IEntityType entityType, bool includPrimaryKeys = false) - { + internal IEnumerable GetColumnNames(IEntityType entityType, bool includPrimaryKeys = false) + { return CommonUtil.FilterColumns(TableMapping.GetColumnNames(entityType, includPrimaryKeys), PrimaryKeyColumnNames, InputColumns, IgnoreColumns); } - } } \ No newline at end of file diff --git a/N.EntityFrameworkCore.Extensions/Data/BulkOperationAsync.cs b/N.EntityFrameworkCore.Extensions/Data/BulkOperationAsync.cs index 8e4b704..95a0aed 100644 --- a/N.EntityFrameworkCore.Extensions/Data/BulkOperationAsync.cs +++ b/N.EntityFrameworkCore.Extensions/Data/BulkOperationAsync.cs @@ -10,12 +10,12 @@ using N.EntityFrameworkCore.Extensions.Sql; using N.EntityFrameworkCore.Extensions.Util; -namespace N.EntityFrameworkCore.Extensions +namespace N.EntityFrameworkCore.Extensions; + +internal partial class BulkOperation { - internal partial class BulkOperation + internal async Task> BulkInsertStagingDataAsync(IEnumerable entities, bool keepIdentity = true, bool useInternalId = false, CancellationToken cancellationToken = default) { - internal async Task> BulkInsertStagingDataAsync(IEnumerable entities, bool keepIdentity = true, bool useInternalId = false, CancellationToken cancellationToken = default) - { IEnumerable columnsToInsert = GetColumnNames(keepIdentity); string internalIdColumn = useInternalId ? Common.Constants.InternalId_ColumnName : null; await Context.Database.CloneTableAsync(SchemaQualifiedTableNames, StagingTableName, TableMapping.GetQualifiedColumnNames(columnsToInsert), internalIdColumn, cancellationToken); @@ -23,9 +23,9 @@ internal async Task> BulkInsertStagingDataAsync(IEnumerable< return await DbContextExtensionsAsync.BulkInsertAsync(entities, Options, TableMapping, Connection, Transaction, StagingTableName, columnsToInsert, SqlBulkCopyOptions.KeepIdentity, useInternalId, cancellationToken); } - internal async Task> ExecuteMergeAsync(Dictionary entityMap, Expression> mergeOnCondition, - bool autoMapOutput, bool insertIfNotExists, bool update = false, bool delete = false, CancellationToken cancellationToken = default) - { + internal async Task> ExecuteMergeAsync(Dictionary entityMap, Expression> mergeOnCondition, + bool autoMapOutput, bool insertIfNotExists, bool update = false, bool delete = false, CancellationToken cancellationToken = default) + { var rowsInserted = new Dictionary(); var rowsUpdated = new Dictionary(); var rowsDeleted = new Dictionary(); @@ -108,8 +108,8 @@ .. TableMapping.GetEntityProperties(entityType, ValueGenerated.OnAddOrUpdate).To RowsUpdated = rowsUpdated.Values.LastOrDefault() }; } - internal async Task ExecuteUpdateAsync(IEnumerable entities, Expression> updateOnCondition, CancellationToken cancellationToken = default) - { + internal async Task ExecuteUpdateAsync(IEnumerable entities, Expression> updateOnCondition, CancellationToken cancellationToken = default) + { int rowsUpdated = 0; foreach (var entityType in TableMapping.EntityTypes) { @@ -122,5 +122,4 @@ internal async Task ExecuteUpdateAsync(IEnumerable entities, Expression< } return rowsUpdated; } - } } \ No newline at end of file diff --git a/N.EntityFrameworkCore.Extensions/Data/BulkOptions.cs b/N.EntityFrameworkCore.Extensions/Data/BulkOptions.cs index 69888f8..1b51b85 100644 --- a/N.EntityFrameworkCore.Extensions/Data/BulkOptions.cs +++ b/N.EntityFrameworkCore.Extensions/Data/BulkOptions.cs @@ -7,29 +7,28 @@ using Microsoft.EntityFrameworkCore.Metadata; using N.EntityFrameworkCore.Extensions.Enums; -namespace N.EntityFrameworkCore.Extensions +namespace N.EntityFrameworkCore.Extensions; + +public class BulkOptions { - public class BulkOptions - { - public int BatchSize { get; set; } - public SqlBulkCopyOptions BulkCopyOptions { get; internal set; } - public SqlBulkCopyColumnOrderHintCollection ColumnOrderHints { get; internal set; } - public bool EnableStreaming { get; internal set; } - public int NotifyAfter { get; internal set; } - public bool UsePermanentTable { get; set; } - public int? CommandTimeout { get; set; } - internal ConnectionBehavior ConnectionBehavior { get; set; } - internal IEntityType EntityType { get; set; } + public int BatchSize { get; set; } + public SqlBulkCopyOptions BulkCopyOptions { get; internal set; } + public SqlBulkCopyColumnOrderHintCollection ColumnOrderHints { get; internal set; } + public bool EnableStreaming { get; internal set; } + public int NotifyAfter { get; internal set; } + public bool UsePermanentTable { get; set; } + public int? CommandTimeout { get; set; } + internal ConnectionBehavior ConnectionBehavior { get; set; } + internal IEntityType EntityType { get; set; } - public SqlRowsCopiedEventHandler SqlRowsCopied { get; internal set; } + public SqlRowsCopiedEventHandler SqlRowsCopied { get; internal set; } - public BulkOptions() - { + public BulkOptions() + { this.BulkCopyOptions = SqlBulkCopyOptions.Default; this.ColumnOrderHints = new SqlBulkCopyColumnOrderHintCollection(); this.EnableStreaming = false; this.NotifyAfter = 0; this.ConnectionBehavior = ConnectionBehavior.Default; } - } } \ No newline at end of file diff --git a/N.EntityFrameworkCore.Extensions/Data/BulkQueryResult.cs b/N.EntityFrameworkCore.Extensions/Data/BulkQueryResult.cs index eae2879..267af6f 100644 --- a/N.EntityFrameworkCore.Extensions/Data/BulkQueryResult.cs +++ b/N.EntityFrameworkCore.Extensions/Data/BulkQueryResult.cs @@ -1,11 +1,10 @@ using System.Collections.Generic; -namespace N.EntityFrameworkCore.Extensions +namespace N.EntityFrameworkCore.Extensions; + +public class BulkQueryResult { - public class BulkQueryResult - { - public IEnumerable Results { get; internal set; } - public IEnumerable Columns { get; internal set; } - public int RowsAffected { get; internal set; } - } + public IEnumerable Results { get; internal set; } + public IEnumerable Columns { get; internal set; } + public int RowsAffected { get; internal set; } } \ No newline at end of file diff --git a/N.EntityFrameworkCore.Extensions/Data/BulkSyncOptions.cs b/N.EntityFrameworkCore.Extensions/Data/BulkSyncOptions.cs index 83a1d72..7326f8f 100644 --- a/N.EntityFrameworkCore.Extensions/Data/BulkSyncOptions.cs +++ b/N.EntityFrameworkCore.Extensions/Data/BulkSyncOptions.cs @@ -1,11 +1,10 @@  -namespace N.EntityFrameworkCore.Extensions +namespace N.EntityFrameworkCore.Extensions; + +public class BulkSyncOptions : BulkMergeOptions { - public class BulkSyncOptions : BulkMergeOptions + public BulkSyncOptions() { - public BulkSyncOptions() - { this.DeleteIfNotMatched = true; } - } } \ No newline at end of file diff --git a/N.EntityFrameworkCore.Extensions/Data/BulkSyncResult.cs b/N.EntityFrameworkCore.Extensions/Data/BulkSyncResult.cs index 6c06c30..0e9fbdf 100644 --- a/N.EntityFrameworkCore.Extensions/Data/BulkSyncResult.cs +++ b/N.EntityFrameworkCore.Extensions/Data/BulkSyncResult.cs @@ -1,11 +1,11 @@  -namespace N.EntityFrameworkCore.Extensions +namespace N.EntityFrameworkCore.Extensions; + +public class BulkSyncResult : BulkMergeResult { - public class BulkSyncResult : BulkMergeResult + public new int RowsDeleted { get; set; } + public static BulkSyncResult Map(BulkMergeResult result) { - public new int RowsDeleted { get; set; } - public static BulkSyncResult Map(BulkMergeResult result) - { return new BulkSyncResult() { Output = result.Output, @@ -15,5 +15,4 @@ public static BulkSyncResult Map(BulkMergeResult result) RowsUpdated = result.RowsUpdated }; } - } } \ No newline at end of file diff --git a/N.EntityFrameworkCore.Extensions/Data/BulkUpdateOptions.cs b/N.EntityFrameworkCore.Extensions/Data/BulkUpdateOptions.cs index eb7d395..f71fe82 100644 --- a/N.EntityFrameworkCore.Extensions/Data/BulkUpdateOptions.cs +++ b/N.EntityFrameworkCore.Extensions/Data/BulkUpdateOptions.cs @@ -1,12 +1,11 @@ using System; using System.Linq.Expressions; -namespace N.EntityFrameworkCore.Extensions +namespace N.EntityFrameworkCore.Extensions; + +public class BulkUpdateOptions : BulkOptions { - public class BulkUpdateOptions : BulkOptions - { - public Expression> InputColumns { get; set; } - public Expression> IgnoreColumns { get; set; } - public Expression> UpdateOnCondition { get; set; } - } + public Expression> InputColumns { get; set; } + public Expression> IgnoreColumns { get; set; } + public Expression> UpdateOnCondition { get; set; } } \ No newline at end of file diff --git a/N.EntityFrameworkCore.Extensions/Data/DatabaseFacadeExtensions.cs b/N.EntityFrameworkCore.Extensions/Data/DatabaseFacadeExtensions.cs index 8aae0e3..29ab5d4 100644 --- a/N.EntityFrameworkCore.Extensions/Data/DatabaseFacadeExtensions.cs +++ b/N.EntityFrameworkCore.Extensions/Data/DatabaseFacadeExtensions.cs @@ -13,30 +13,30 @@ using N.EntityFrameworkCore.Extensions.Enums; using N.EntityFrameworkCore.Extensions.Util; -namespace N.EntityFrameworkCore.Extensions +namespace N.EntityFrameworkCore.Extensions; + +public static class DabaseFacadeExtensions { - public static class DabaseFacadeExtensions + public static SqlQuery FromSqlQuery(this DatabaseFacade database, string sqlText, params object[] parameters) { - public static SqlQuery FromSqlQuery(this DatabaseFacade database, string sqlText, params object[] parameters) - { return new SqlQuery(database, sqlText, parameters); } - public static int ClearTable(this DatabaseFacade database, string tableName) - { + public static int ClearTable(this DatabaseFacade database, string tableName) + { return database.ExecuteSqlRaw(string.Format("DELETE FROM {0}", tableName)); } - internal static int CloneTable(this DatabaseFacade database, string sourceTable, string destinationTable, IEnumerable columnNames, string internalIdColumnName = null) - { + internal static int CloneTable(this DatabaseFacade database, string sourceTable, string destinationTable, IEnumerable columnNames, string internalIdColumnName = null) + { return database.CloneTable(new string[] { sourceTable }, destinationTable, columnNames, internalIdColumnName); } - internal static int CloneTable(this DatabaseFacade database, IEnumerable sourceTables, string destinationTable, IEnumerable columnNames, string internalIdColumnName = null) - { + internal static int CloneTable(this DatabaseFacade database, IEnumerable sourceTables, string destinationTable, IEnumerable columnNames, string internalIdColumnName = null) + { string columns = columnNames != null && columnNames.Count() > 0 ? string.Join(",", CommonUtil.FormatColumns(columnNames)) : "*"; columns = !string.IsNullOrEmpty(internalIdColumnName) ? string.Format("{0},CAST( NULL AS INT) AS {1}", columns, internalIdColumnName) : columns; return database.ExecuteSqlRaw(string.Format("SELECT TOP 0 {0} INTO {1} FROM {2}", columns, destinationTable, string.Join(",", sourceTables))); } - internal static DbCommand CreateCommand(this DatabaseFacade database, ConnectionBehavior connectionBehavior = ConnectionBehavior.Default) - { + internal static DbCommand CreateCommand(this DatabaseFacade database, ConnectionBehavior connectionBehavior = ConnectionBehavior.Default) + { var dbConnection = database.GetDbConnection(connectionBehavior); if (dbConnection.State != ConnectionState.Open) dbConnection.Open(); @@ -46,33 +46,33 @@ internal static DbCommand CreateCommand(this DatabaseFacade database, Connection return command; } - public static int DropTable(this DatabaseFacade database, string tableName, bool ifExists = false) - { + public static int DropTable(this DatabaseFacade database, string tableName, bool ifExists = false) + { bool deleteTable = !ifExists || (ifExists && database.TableExists(tableName)) ? true : false; return deleteTable ? database.ExecuteSqlInternal(string.Format("DROP TABLE {0}", tableName), null, ConnectionBehavior.Default) : -1; } - public static void TruncateTable(this DatabaseFacade database, string tableName, bool ifExists = false) - { + public static void TruncateTable(this DatabaseFacade database, string tableName, bool ifExists = false) + { bool truncateTable = !ifExists || (ifExists && database.TableExists(tableName)) ? true : false; if (truncateTable) { database.ExecuteSqlRaw(string.Format("TRUNCATE TABLE {0}", tableName)); } } - public static bool TableExists(this DatabaseFacade database, string tableName) - { + public static bool TableExists(this DatabaseFacade database, string tableName) + { return Convert.ToBoolean(database.ExecuteScalar(string.Format("SELECT CASE WHEN OBJECT_ID(N'{0}', N'U') IS NOT NULL THEN 1 ELSE 0 END", tableName))); } - public static bool TableHasIdentity(this DatabaseFacade database, string tableName) - { + public static bool TableHasIdentity(this DatabaseFacade database, string tableName) + { return Convert.ToBoolean(database.ExecuteScalar($"SELECT ISNULL(OBJECTPROPERTY(OBJECT_ID('{tableName}'), 'TableHasIdentity'), 0)")); } - internal static int ExecuteSqlInternal(this DatabaseFacade database, string sql, int? commandTimeout = null, ConnectionBehavior connectionBehavior = default) - { + internal static int ExecuteSqlInternal(this DatabaseFacade database, string sql, int? commandTimeout = null, ConnectionBehavior connectionBehavior = default) + { return database.ExecuteSql(sql, null, commandTimeout, connectionBehavior); } - internal static int ExecuteSql(this DatabaseFacade database, string sql, object[] parameters = null, int? commandTimeout = null, ConnectionBehavior connectionBehavior = default) - { + internal static int ExecuteSql(this DatabaseFacade database, string sql, object[] parameters = null, int? commandTimeout = null, ConnectionBehavior connectionBehavior = default) + { var command = database.CreateCommand(connectionBehavior); command.CommandText = sql; if (commandTimeout != null) @@ -85,8 +85,8 @@ internal static int ExecuteSql(this DatabaseFacade database, string sql, object[ } return command.ExecuteNonQuery(); } - internal static object ExecuteScalar(this DatabaseFacade database, string query, object[] parameters = null, int? commandTimeout = null) - { + internal static object ExecuteScalar(this DatabaseFacade database, string query, object[] parameters = null, int? commandTimeout = null) + { object value; var dbConnection = database.GetDbConnection() as SqlConnection; using (var sqlCommand = dbConnection.CreateCommand()) @@ -104,8 +104,8 @@ internal static object ExecuteScalar(this DatabaseFacade database, string query, } return value; } - internal static void ToggleIdentityInsert(this DatabaseFacade database, string tableName, bool enable) - { + internal static void ToggleIdentityInsert(this DatabaseFacade database, string tableName, bool enable) + { bool hasIdentity = database.TableHasIdentity(tableName); if (hasIdentity) { @@ -113,9 +113,8 @@ internal static void ToggleIdentityInsert(this DatabaseFacade database, string t database.ExecuteSql($"SET IDENTITY_INSERT {tableName} {boolString}"); } } - internal static DbConnection GetDbConnection(this DatabaseFacade database, ConnectionBehavior connectionBehavior) - { + internal static DbConnection GetDbConnection(this DatabaseFacade database, ConnectionBehavior connectionBehavior) + { return connectionBehavior == ConnectionBehavior.New ? ((ICloneable)database.GetDbConnection()).Clone() as DbConnection : database.GetDbConnection(); } - } } \ No newline at end of file diff --git a/N.EntityFrameworkCore.Extensions/Data/DatabaseFacadeExtensionsAsync.cs b/N.EntityFrameworkCore.Extensions/Data/DatabaseFacadeExtensionsAsync.cs index 7b9ca28..4c9a4ce 100644 --- a/N.EntityFrameworkCore.Extensions/Data/DatabaseFacadeExtensionsAsync.cs +++ b/N.EntityFrameworkCore.Extensions/Data/DatabaseFacadeExtensionsAsync.cs @@ -10,38 +10,38 @@ using Microsoft.EntityFrameworkCore.Storage; using N.EntityFrameworkCore.Extensions.Util; -namespace N.EntityFrameworkCore.Extensions +namespace N.EntityFrameworkCore.Extensions; + +public static class DabaseFacadeExtensionsAsync { - public static class DabaseFacadeExtensionsAsync + public async static Task ClearTableAsync(this DatabaseFacade database, string tableName, CancellationToken cancellationToken = default) { - public async static Task ClearTableAsync(this DatabaseFacade database, string tableName, CancellationToken cancellationToken = default) - { return await database.ExecuteSqlRawAsync(string.Format("DELETE FROM {0}", tableName), cancellationToken); } - internal async static Task CloneTableAsync(this DatabaseFacade database, string sourceTable, string destinationTable, IEnumerable columnNames, string internalIdColumnName = null, CancellationToken cancellationToken = default) - { + internal async static Task CloneTableAsync(this DatabaseFacade database, string sourceTable, string destinationTable, IEnumerable columnNames, string internalIdColumnName = null, CancellationToken cancellationToken = default) + { return await database.CloneTableAsync(new string[] { sourceTable }, destinationTable, columnNames, internalIdColumnName, cancellationToken); } - internal async static Task CloneTableAsync(this DatabaseFacade database, IEnumerable sourceTables, string destinationTable, IEnumerable columnNames, string internalIdColumnName = null, CancellationToken cancellationToken = default) - { + internal async static Task CloneTableAsync(this DatabaseFacade database, IEnumerable sourceTables, string destinationTable, IEnumerable columnNames, string internalIdColumnName = null, CancellationToken cancellationToken = default) + { string columns = columnNames != null && columnNames.Count() > 0 ? string.Join(",", CommonUtil.FormatColumns(columnNames)) : "*"; columns = !string.IsNullOrEmpty(internalIdColumnName) ? string.Format("{0},CAST( NULL AS INT) AS {1}", columns, internalIdColumnName) : columns; return await database.ExecuteSqlRawAsync(string.Format("SELECT TOP 0 {0} INTO {1} FROM {2}", columns, destinationTable, string.Join(",", sourceTables)), cancellationToken); } - public async static Task TruncateTableAsync(this DatabaseFacade database, string tableName, bool ifExists = false, CancellationToken cancellationToken = default) - { + public async static Task TruncateTableAsync(this DatabaseFacade database, string tableName, bool ifExists = false, CancellationToken cancellationToken = default) + { bool truncateTable = !ifExists || (ifExists && database.TableExists(tableName)) ? true : false; if (truncateTable) { await database.ExecuteSqlRawAsync(string.Format("TRUNCATE TABLE {0}", tableName), cancellationToken); } } - internal async static Task ExecuteSqlAsync(this DatabaseFacade database, string sql, int? commandTimeout = null, CancellationToken cancellationToken = default) - { + internal async static Task ExecuteSqlAsync(this DatabaseFacade database, string sql, int? commandTimeout = null, CancellationToken cancellationToken = default) + { return await database.ExecuteSqlAsync(sql, null, commandTimeout, cancellationToken); } - internal async static Task ExecuteSqlAsync(this DatabaseFacade database, string sql, object[] parameters = null, int? commandTimeout = null, CancellationToken cancellationToken = default) - { + internal async static Task ExecuteSqlAsync(this DatabaseFacade database, string sql, object[] parameters = null, int? commandTimeout = null, CancellationToken cancellationToken = default) + { int value = -1; int? origCommandTimeout = database.GetCommandTimeout(); database.SetCommandTimeout(commandTimeout); @@ -52,8 +52,8 @@ internal async static Task ExecuteSqlAsync(this DatabaseFacade database, st database.SetCommandTimeout(origCommandTimeout); return value; } - internal async static Task ExecuteScalarAsync(this DatabaseFacade database, string query, object[] parameters = null, int? commandTimeout = null, CancellationToken cancellationToken = default) - { + internal async static Task ExecuteScalarAsync(this DatabaseFacade database, string query, object[] parameters = null, int? commandTimeout = null, CancellationToken cancellationToken = default) + { object value; var dbConnection = database.GetDbConnection() as SqlConnection; using (var sqlCommand = dbConnection.CreateCommand()) @@ -71,8 +71,8 @@ internal async static Task ExecuteScalarAsync(this DatabaseFacade databa } return value; } - internal async static Task ToggleIdentityInsertAsync(this DatabaseFacade database, string tableName, bool enable) - { + internal async static Task ToggleIdentityInsertAsync(this DatabaseFacade database, string tableName, bool enable) + { bool hasIdentity = database.TableHasIdentity(tableName); if (hasIdentity) { @@ -80,5 +80,4 @@ internal async static Task ToggleIdentityInsertAsync(this DatabaseFacade databas await database.ExecuteSqlAsync($"SET IDENTITY_INSERT {tableName} {boolString}", database.GetCommandTimeout()); } } - } } \ No newline at end of file diff --git a/N.EntityFrameworkCore.Extensions/Data/DbContextExtensions.cs b/N.EntityFrameworkCore.Extensions/Data/DbContextExtensions.cs index 8d9e6d8..fbe69c5 100644 --- a/N.EntityFrameworkCore.Extensions/Data/DbContextExtensions.cs +++ b/N.EntityFrameworkCore.Extensions/Data/DbContextExtensions.cs @@ -29,29 +29,29 @@ using N.EntityFrameworkCore.Extensions.Util; using static Microsoft.EntityFrameworkCore.DbLoggerCategory; -namespace N.EntityFrameworkCore.Extensions +namespace N.EntityFrameworkCore.Extensions; + +public static class DbContextExtensions { - public static class DbContextExtensions + private static readonly EfExtensionsCommandInterceptor efExtensionsCommandInterceptor; + static DbContextExtensions() { - private static readonly EfExtensionsCommandInterceptor efExtensionsCommandInterceptor; - static DbContextExtensions() - { efExtensionsCommandInterceptor = new EfExtensionsCommandInterceptor(); } - public static void SetupEfCoreExtensions(this DbContextOptionsBuilder builder) - { + public static void SetupEfCoreExtensions(this DbContextOptionsBuilder builder) + { builder.AddInterceptors(efExtensionsCommandInterceptor); } - public static int BulkDelete(this DbContext context, IEnumerable entities) - { + public static int BulkDelete(this DbContext context, IEnumerable entities) + { return context.BulkDelete(entities, new BulkDeleteOptions()); } - public static int BulkDelete(this DbContext context, IEnumerable entities, Action> optionsAction) - { + public static int BulkDelete(this DbContext context, IEnumerable entities, Action> optionsAction) + { return context.BulkDelete(entities, optionsAction.Build()); } - public static int BulkDelete(this DbContext context, IEnumerable entities, BulkDeleteOptions options) - { + public static int BulkDelete(this DbContext context, IEnumerable entities, BulkDeleteOptions options) + { var tableMapping = context.GetTableMapping(typeof(T), options.EntityType); using (var dbTransactionContext = new DbTransactionContext(context, options)) @@ -87,16 +87,16 @@ public static int BulkDelete(this DbContext context, IEnumerable entities, return rowsAffected; } } - public static IEnumerable BulkFetch(this DbSet dbSet, IEnumerable entities) where T : class, new() - { + public static IEnumerable BulkFetch(this DbSet dbSet, IEnumerable entities) where T : class, new() + { return dbSet.BulkFetch(entities, new BulkFetchOptions()); } - public static IEnumerable BulkFetch(this DbSet dbSet, IEnumerable entities, Action> optionsAction) where T : class, new() - { + public static IEnumerable BulkFetch(this DbSet dbSet, IEnumerable entities, Action> optionsAction) where T : class, new() + { return dbSet.BulkFetch(entities, optionsAction.Build()); } - public static IEnumerable BulkFetch(this DbSet dbSet, IEnumerable entities, BulkFetchOptions options) where T : class, new() - { + public static IEnumerable BulkFetch(this DbSet dbSet, IEnumerable entities, BulkFetchOptions options) where T : class, new() + { var context = dbSet.GetDbContext(); var tableMapping = context.GetTableMapping(typeof(T)); @@ -138,19 +138,19 @@ public static int BulkDelete(this DbContext context, IEnumerable entities, context.Database.DropTable(stagingTableName); } } - private static void Validate(TableMapping tableMapping) - { + private static void Validate(TableMapping tableMapping) + { if (!tableMapping.GetPrimaryKeyColumns().Any()) { throw new Exception("You must have a primary key on this table to use this function."); } } - public static void Fetch(this IQueryable querable, Action> action, Action> optionsAction) where T : class, new() - { + public static void Fetch(this IQueryable querable, Action> action, Action> optionsAction) where T : class, new() + { Fetch(querable, action, optionsAction.Build()); } - public static void Fetch(this IQueryable querable, Action> action, FetchOptions options) where T : class, new() - { + public static void Fetch(this IQueryable querable, Action> action, FetchOptions options) where T : class, new() + { var dbContext = querable.GetDbContext(); var sqlQuery = SqlBuilder.Parse(querable.ToQueryString()); var tableMapping = dbContext.GetTableMapping(typeof(T)); @@ -193,8 +193,8 @@ private static void Validate(TableMapping tableMapping) reader.Close(); } - private static IEnumerable FetchInternal(this DbContext dbContext, string sqlText, object[] parameters = null) where T : class, new() - { + private static IEnumerable FetchInternal(this DbContext dbContext, string sqlText, object[] parameters = null) where T : class, new() + { using var command = dbContext.Database.CreateCommand(Enums.ConnectionBehavior.New); command.CommandText = sqlText; if (parameters != null) @@ -213,16 +213,16 @@ private static void Validate(TableMapping tableMapping) reader.Close(); } - public static int BulkInsert(this DbContext context, IEnumerable entities) - { + public static int BulkInsert(this DbContext context, IEnumerable entities) + { return context.BulkInsert(entities, new BulkInsertOptions { }); } - public static int BulkInsert(this DbContext context, IEnumerable entities, Action> optionsAction) - { + public static int BulkInsert(this DbContext context, IEnumerable entities, Action> optionsAction) + { return context.BulkInsert(entities, optionsAction.Build()); } - public static int BulkInsert(this DbContext context, IEnumerable entities, BulkInsertOptions options) - { + public static int BulkInsert(this DbContext context, IEnumerable entities, BulkInsertOptions options) + { int rowsAffected = 0; using (var bulkOperation = new BulkOperation(context, options, options.InputColumns, options.IgnoreColumns)) { @@ -243,8 +243,8 @@ public static int BulkInsert(this DbContext context, IEnumerable entities, return rowsAffected; } - internal static void SetStoreGeneratedValues(this DbContext context, T entity, IEnumerable properties, object[] values) - { + internal static void SetStoreGeneratedValues(this DbContext context, T entity, IEnumerable properties, object[] values) + { int index = 0; var updateEntry = entity as InternalEntityEntry; if (updateEntry == null) @@ -280,9 +280,9 @@ internal static void SetStoreGeneratedValues(this DbContext context, T entity } } - internal static BulkInsertResult BulkInsert(IEnumerable entities, BulkOptions options, TableMapping tableMapping, SqlConnection dbConnection, SqlTransaction transaction, string tableName, - IEnumerable inputColumns = null, SqlBulkCopyOptions bulkCopyOptions = SqlBulkCopyOptions.Default, bool useInteralId = false) - { + internal static BulkInsertResult BulkInsert(IEnumerable entities, BulkOptions options, TableMapping tableMapping, SqlConnection dbConnection, SqlTransaction transaction, string tableName, + IEnumerable inputColumns = null, SqlBulkCopyOptions bulkCopyOptions = SqlBulkCopyOptions.Default, bool useInteralId = false) + { using (var dataReader = new EntityDataReader(tableMapping, entities, useInteralId)) { @@ -321,24 +321,24 @@ internal static BulkInsertResult BulkInsert(IEnumerable entities, BulkO }; } } - public static BulkMergeResult BulkMerge(this DbContext context, IEnumerable entities) - { + public static BulkMergeResult BulkMerge(this DbContext context, IEnumerable entities) + { return BulkMerge(context, entities, new BulkMergeOptions()); } - public static BulkMergeResult BulkMerge(this DbContext context, IEnumerable entities, BulkMergeOptions options) - { + public static BulkMergeResult BulkMerge(this DbContext context, IEnumerable entities, BulkMergeOptions options) + { return InternalBulkMerge(context, entities, options); } - public static BulkMergeResult BulkMerge(this DbContext context, IEnumerable entities, Action> optionsAction) - { + public static BulkMergeResult BulkMerge(this DbContext context, IEnumerable entities, Action> optionsAction) + { return BulkMerge(context, entities, optionsAction.Build()); } - public static int BulkSaveChanges(this DbContext dbContext) - { + public static int BulkSaveChanges(this DbContext dbContext) + { return dbContext.BulkSaveChanges(true); } - public static int BulkSaveChanges(this DbContext dbContext, bool acceptAllChangesOnSuccess = true) - { + public static int BulkSaveChanges(this DbContext dbContext, bool acceptAllChangesOnSuccess = true) + { int rowsAffected = 0; var stateManager = dbContext.GetDependencies().StateManager; @@ -369,20 +369,20 @@ public static int BulkSaveChanges(this DbContext dbContext, bool acceptAllChange return rowsAffected; } - public static BulkSyncResult BulkSync(this DbContext context, IEnumerable entities) - { + public static BulkSyncResult BulkSync(this DbContext context, IEnumerable entities) + { return BulkSync(context, entities, new BulkSyncOptions()); } - public static BulkSyncResult BulkSync(this DbContext context, IEnumerable entities, Action> optionsAction) - { + public static BulkSyncResult BulkSync(this DbContext context, IEnumerable entities, Action> optionsAction) + { return BulkSyncResult.Map(InternalBulkMerge(context, entities, optionsAction.Build())); } - public static BulkSyncResult BulkSync(this DbContext context, IEnumerable entities, BulkSyncOptions options) - { + public static BulkSyncResult BulkSync(this DbContext context, IEnumerable entities, BulkSyncOptions options) + { return BulkSyncResult.Map(InternalBulkMerge(context, entities, options)); } - private static BulkMergeResult InternalBulkMerge(this DbContext context, IEnumerable entities, BulkMergeOptions options) - { + private static BulkMergeResult InternalBulkMerge(this DbContext context, IEnumerable entities, BulkMergeOptions options) + { BulkMergeResult bulkMergeResult; using (var bulkOperation = new BulkOperation(context, options)) { @@ -402,16 +402,16 @@ private static BulkMergeResult InternalBulkMerge(this DbContext context, I } return bulkMergeResult; } - public static int BulkUpdate(this DbContext context, IEnumerable entities) - { + public static int BulkUpdate(this DbContext context, IEnumerable entities) + { return BulkUpdate(context, entities, new BulkUpdateOptions()); } - public static int BulkUpdate(this DbContext context, IEnumerable entities, Action> optionsAction) - { + public static int BulkUpdate(this DbContext context, IEnumerable entities, Action> optionsAction) + { return BulkUpdate(context, entities, optionsAction.Build()); } - public static int BulkUpdate(this DbContext context, IEnumerable entities, BulkUpdateOptions options) - { + public static int BulkUpdate(this DbContext context, IEnumerable entities, BulkUpdateOptions options) + { int rowsUpdated = 0; using (var bulkOperation = new BulkOperation(context, options, options.InputColumns, options.IgnoreColumns)) { @@ -431,8 +431,8 @@ public static int BulkUpdate(this DbContext context, IEnumerable entities, return rowsUpdated; } - private static void ClearEntityStateToUnchanged(DbContext dbContext, IEnumerable entities) - { + private static void ClearEntityStateToUnchanged(DbContext dbContext, IEnumerable entities) + { foreach (var entity in entities) { var entry = dbContext.Entry(entity); @@ -441,8 +441,8 @@ private static void ClearEntityStateToUnchanged(DbContext dbContext, IEnumera } } - internal static BulkQueryResult BulkQuery(this DbContext context, string sqlText, BulkOptions options) - { + internal static BulkQueryResult BulkQuery(this DbContext context, string sqlText, BulkOptions options) + { var results = new List(); var columns = new List(); var command = context.Database.CreateCommand(); @@ -480,8 +480,8 @@ internal static BulkQueryResult BulkQuery(this DbContext context, string sqlText RowsAffected = reader.RecordsAffected }; } - public static int DeleteFromQuery(this IQueryable querable, int? commandTimeout = null) where T : class - { + public static int DeleteFromQuery(this IQueryable querable, int? commandTimeout = null) where T : class + { int rowAffected = 0; using (var dbTransactionContext = new DbTransactionContext(querable.GetDbContext(), commandTimeout)) { @@ -502,8 +502,8 @@ public static int DeleteFromQuery(this IQueryable querable, int? commandTi } return rowAffected; } - public static int InsertFromQuery(this IQueryable querable, string tableName, Expression> insertObjectExpression, int? commandTimeout = null) where T : class - { + public static int InsertFromQuery(this IQueryable querable, string tableName, Expression> insertObjectExpression, int? commandTimeout = null) where T : class + { int rowAffected = 0; using (var dbTransactionContext = new DbTransactionContext(querable.GetDbContext(), commandTimeout)) { @@ -534,8 +534,8 @@ public static int InsertFromQuery(this IQueryable querable, string tableNa } return rowAffected; } - public static int UpdateFromQuery(this IQueryable querable, Expression> updateExpression, int? commandTimeout = null) where T : class - { + public static int UpdateFromQuery(this IQueryable querable, Expression> updateExpression, int? commandTimeout = null) where T : class + { int rowAffected = 0; using (var dbTransactionContext = new DbTransactionContext(querable.GetDbContext(), commandTimeout)) { @@ -556,77 +556,77 @@ public static int UpdateFromQuery(this IQueryable querable, Expression(this IQueryable querable, String filePath) where T : class - { + public static QueryToFileResult QueryToCsvFile(this IQueryable querable, String filePath) where T : class + { return QueryToCsvFile(querable, filePath, new QueryToFileOptions()); } - public static QueryToFileResult QueryToCsvFile(this IQueryable querable, Stream stream) where T : class - { + public static QueryToFileResult QueryToCsvFile(this IQueryable querable, Stream stream) where T : class + { return QueryToCsvFile(querable, stream, new QueryToFileOptions()); } - public static QueryToFileResult QueryToCsvFile(this IQueryable querable, String filePath, Action optionsAction) where T : class - { + public static QueryToFileResult QueryToCsvFile(this IQueryable querable, String filePath, Action optionsAction) where T : class + { return QueryToCsvFile(querable, filePath, optionsAction.Build()); } - public static QueryToFileResult QueryToCsvFile(this IQueryable querable, Stream stream, Action optionsAction) where T : class - { + public static QueryToFileResult QueryToCsvFile(this IQueryable querable, Stream stream, Action optionsAction) where T : class + { return QueryToCsvFile(querable, stream, optionsAction.Build()); } - public static QueryToFileResult QueryToCsvFile(this IQueryable querable, String filePath, QueryToFileOptions options) where T : class - { + public static QueryToFileResult QueryToCsvFile(this IQueryable querable, String filePath, QueryToFileOptions options) where T : class + { var fileStream = File.Create(filePath); return QueryToCsvFile(querable, fileStream, options); } - public static QueryToFileResult QueryToCsvFile(this IQueryable querable, Stream stream, QueryToFileOptions options) where T : class - { + public static QueryToFileResult QueryToCsvFile(this IQueryable querable, Stream stream, QueryToFileOptions options) where T : class + { return InternalQueryToFile(querable, stream, options); } - public static QueryToFileResult SqlQueryToCsvFile(this DatabaseFacade database, string filePath, string sqlText, params object[] parameters) - { + public static QueryToFileResult SqlQueryToCsvFile(this DatabaseFacade database, string filePath, string sqlText, params object[] parameters) + { return SqlQueryToCsvFile(database, filePath, new QueryToFileOptions(), sqlText, parameters); } - public static QueryToFileResult SqlQueryToCsvFile(this DatabaseFacade database, Stream stream, string sqlText, params object[] parameters) - { + public static QueryToFileResult SqlQueryToCsvFile(this DatabaseFacade database, Stream stream, string sqlText, params object[] parameters) + { return SqlQueryToCsvFile(database, stream, new QueryToFileOptions(), sqlText, parameters); } - public static QueryToFileResult SqlQueryToCsvFile(this DatabaseFacade database, string filePath, Action optionsAction, string sqlText, params object[] parameters) - { + public static QueryToFileResult SqlQueryToCsvFile(this DatabaseFacade database, string filePath, Action optionsAction, string sqlText, params object[] parameters) + { return SqlQueryToCsvFile(database, filePath, optionsAction.Build(), sqlText, parameters); } - public static QueryToFileResult SqlQueryToCsvFile(this DatabaseFacade database, Stream stream, Action optionsAction, string sqlText, params object[] parameters) - { + public static QueryToFileResult SqlQueryToCsvFile(this DatabaseFacade database, Stream stream, Action optionsAction, string sqlText, params object[] parameters) + { return SqlQueryToCsvFile(database, stream, optionsAction.Build(), sqlText, parameters); } - public static QueryToFileResult SqlQueryToCsvFile(this DatabaseFacade database, string filePath, QueryToFileOptions options, string sqlText, params object[] parameters) - { + public static QueryToFileResult SqlQueryToCsvFile(this DatabaseFacade database, string filePath, QueryToFileOptions options, string sqlText, params object[] parameters) + { var fileStream = File.Create(filePath); return SqlQueryToCsvFile(database, fileStream, options, sqlText, parameters); } - public static QueryToFileResult SqlQueryToCsvFile(this DatabaseFacade database, Stream stream, QueryToFileOptions options, string sqlText, params object[] parameters) - { + public static QueryToFileResult SqlQueryToCsvFile(this DatabaseFacade database, Stream stream, QueryToFileOptions options, string sqlText, params object[] parameters) + { var dbConnection = database.GetDbConnection() as SqlConnection; return InternalQueryToFile(dbConnection, stream, options, sqlText, parameters); } - public static void Clear(this DbSet dbSet) where T : class - { + public static void Clear(this DbSet dbSet) where T : class + { var dbContext = dbSet.GetDbContext(); var tableMapping = dbContext.GetTableMapping(typeof(T)); dbContext.Database.ClearTable(tableMapping.FullQualifedTableName); } - public static void Truncate(this DbSet dbSet) where T : class - { + public static void Truncate(this DbSet dbSet) where T : class + { var dbContext = dbSet.GetDbContext(); var tableMapping = dbContext.GetTableMapping(typeof(T)); dbContext.Database.TruncateTable(tableMapping.FullQualifedTableName); } - private static QueryToFileResult InternalQueryToFile(this IQueryable querable, Stream stream, QueryToFileOptions options) where T : class - { + private static QueryToFileResult InternalQueryToFile(this IQueryable querable, Stream stream, QueryToFileOptions options) where T : class + { var dbContext = querable.GetDbContext(); var dbConnection = dbContext.GetSqlConnection(); return InternalQueryToFile(dbConnection, stream, options, querable.ToQueryString()); } - private static QueryToFileResult InternalQueryToFile(SqlConnection dbConnection, Stream stream, QueryToFileOptions options, string sqlText, object[] parameters = null) - { + private static QueryToFileResult InternalQueryToFile(SqlConnection dbConnection, Stream stream, QueryToFileOptions options, string sqlText, object[] parameters = null) + { int dataRowCount = 0; int totalRowCount = 0; long bytesWritten = 0; @@ -694,8 +694,8 @@ private static QueryToFileResult InternalQueryToFile(SqlConnection dbConnection, TotalRowCount = totalRowCount }; } - public static IQueryable UsingTable(this IQueryable querable, string tableName) where T : class - { + public static IQueryable UsingTable(this IQueryable querable, string tableName) where T : class + { var dbContext = querable.GetDbContext(); var tableMapping = dbContext.GetTableMapping(typeof(T)); efExtensionsCommandInterceptor.AddCommand(Guid.NewGuid(), @@ -708,8 +708,8 @@ public static IQueryable UsingTable(this IQueryable querable, string ta }); return querable; } - internal static DbContext GetDbContext(this IQueryable querable) where T : class - { + internal static DbContext GetDbContext(this IQueryable querable) where T : class + { DbContext dbContext; try { @@ -735,15 +735,14 @@ internal static DbContext GetDbContext(this IQueryable querable) where T : } return dbContext; } - internal static SqlConnection GetSqlConnection(this DbContext context, ConnectionBehavior connectionBehavior = ConnectionBehavior.Default) - { + internal static SqlConnection GetSqlConnection(this DbContext context, ConnectionBehavior connectionBehavior = ConnectionBehavior.Default) + { var dbConnection = context.Database.GetDbConnection(); return connectionBehavior == ConnectionBehavior.New ? ((ICloneable)dbConnection).Clone() as SqlConnection : dbConnection as SqlConnection; } - public static TableMapping GetTableMapping(this DbContext dbContext, Type type, IEntityType entityType = null) - { + public static TableMapping GetTableMapping(this DbContext dbContext, Type type, IEntityType entityType = null) + { entityType = entityType != null ? entityType : dbContext.Model.FindEntityType(type); return new TableMapping(dbContext, entityType); } - } } \ No newline at end of file diff --git a/N.EntityFrameworkCore.Extensions/Data/DbContextExtensionsAsync.cs b/N.EntityFrameworkCore.Extensions/Data/DbContextExtensionsAsync.cs index 017f451..ef60e9b 100644 --- a/N.EntityFrameworkCore.Extensions/Data/DbContextExtensionsAsync.cs +++ b/N.EntityFrameworkCore.Extensions/Data/DbContextExtensionsAsync.cs @@ -20,20 +20,20 @@ using N.EntityFrameworkCore.Extensions.Sql; using N.EntityFrameworkCore.Extensions.Util; -namespace N.EntityFrameworkCore.Extensions +namespace N.EntityFrameworkCore.Extensions; + +public static class DbContextExtensionsAsync { - public static class DbContextExtensionsAsync + public async static Task BulkDeleteAsync(this DbContext context, IEnumerable entities, CancellationToken cancellationToken = default) { - public async static Task BulkDeleteAsync(this DbContext context, IEnumerable entities, CancellationToken cancellationToken = default) - { return await context.BulkDeleteAsync(entities, new BulkDeleteOptions(), cancellationToken); } - public async static Task BulkDeleteAsync(this DbContext context, IEnumerable entities, Action> optionsAction, CancellationToken cancellationToken = default) - { + public async static Task BulkDeleteAsync(this DbContext context, IEnumerable entities, Action> optionsAction, CancellationToken cancellationToken = default) + { return await context.BulkDeleteAsync(entities, optionsAction.Build(), cancellationToken); } - public async static Task BulkDeleteAsync(this DbContext context, IEnumerable entities, BulkDeleteOptions options, CancellationToken cancellationToken = default) - { + public async static Task BulkDeleteAsync(this DbContext context, IEnumerable entities, BulkDeleteOptions options, CancellationToken cancellationToken = default) + { int rowsAffected = 0; var tableMapping = context.GetTableMapping(typeof(T), options.EntityType); @@ -68,12 +68,12 @@ await BulkInsertAsync(entities, options, tableMapping, dbConnection, transaction return rowsAffected; } } - public async static Task FetchAsync(this IQueryable querable, Func, Task> action, Action> optionsAction, CancellationToken cancellationToken = default) where T : class, new() - { + public async static Task FetchAsync(this IQueryable querable, Func, Task> action, Action> optionsAction, CancellationToken cancellationToken = default) where T : class, new() + { await FetchAsync(querable, action, optionsAction.Build(), cancellationToken); } - public async static Task FetchAsync(this IQueryable querable, Func, Task> action, FetchOptions options, CancellationToken cancellationToken = default) where T : class, new() - { + public async static Task FetchAsync(this IQueryable querable, Func, Task> action, FetchOptions options, CancellationToken cancellationToken = default) where T : class, new() + { var dbContext = querable.GetDbContext(); var sqlQuery = SqlBuilder.Parse(querable.ToQueryString()); var tableMapping = dbContext.GetTableMapping(typeof(T)); @@ -117,16 +117,16 @@ await BulkInsertAsync(entities, options, tableMapping, dbConnection, transaction await reader.CloseAsync(); } - public async static Task BulkInsertAsync(this DbContext context, IEnumerable entities, CancellationToken cancellationToken = default) - { + public async static Task BulkInsertAsync(this DbContext context, IEnumerable entities, CancellationToken cancellationToken = default) + { return await context.BulkInsertAsync(entities, new BulkInsertOptions { }, cancellationToken); } - public async static Task BulkInsertAsync(this DbContext context, IEnumerable entities, Action> optionsAction, CancellationToken cancellationToken = default) - { + public async static Task BulkInsertAsync(this DbContext context, IEnumerable entities, Action> optionsAction, CancellationToken cancellationToken = default) + { return await context.BulkInsertAsync(entities, optionsAction.Build(), cancellationToken); } - public async static Task BulkInsertAsync(this DbContext context, IEnumerable entities, BulkInsertOptions options, CancellationToken cancellationToken = default) - { + public async static Task BulkInsertAsync(this DbContext context, IEnumerable entities, BulkInsertOptions options, CancellationToken cancellationToken = default) + { int rowsAffected = 0; using (var bulkOperation = new BulkOperation(context, options, options.InputColumns, options.IgnoreColumns)) { @@ -146,9 +146,9 @@ public async static Task BulkInsertAsync(this DbContext context, IEnumer } return rowsAffected; } - internal async static Task> BulkInsertAsync(IEnumerable entities, BulkOptions options, TableMapping tableMapping, SqlConnection dbConnection, SqlTransaction transaction, string tableName, - IEnumerable inputColumns = null, SqlBulkCopyOptions bulkCopyOptions = SqlBulkCopyOptions.Default, bool useInteralId = false, CancellationToken cancellationToken = default) - { + internal async static Task> BulkInsertAsync(IEnumerable entities, BulkOptions options, TableMapping tableMapping, SqlConnection dbConnection, SqlTransaction transaction, string tableName, + IEnumerable inputColumns = null, SqlBulkCopyOptions bulkCopyOptions = SqlBulkCopyOptions.Default, bool useInteralId = false, CancellationToken cancellationToken = default) + { var dataReader = new EntityDataReader(tableMapping, entities, useInteralId); var sqlBulkCopy = new SqlBulkCopy(dbConnection, bulkCopyOptions, transaction) @@ -178,24 +178,24 @@ internal async static Task> BulkInsertAsync(IEnumerable> BulkMergeAsync(this DbContext context, IEnumerable entities, CancellationToken cancellationToken = default) - { + public async static Task> BulkMergeAsync(this DbContext context, IEnumerable entities, CancellationToken cancellationToken = default) + { return await BulkMergeAsync(context, entities, new BulkMergeOptions(), cancellationToken); } - public async static Task> BulkMergeAsync(this DbContext context, IEnumerable entities, BulkMergeOptions options, CancellationToken cancellationToken = default) - { + public async static Task> BulkMergeAsync(this DbContext context, IEnumerable entities, BulkMergeOptions options, CancellationToken cancellationToken = default) + { return await InternalBulkMergeAsync(context, entities, options, cancellationToken); } - public async static Task> BulkMergeAsync(this DbContext context, IEnumerable entities, Action> optionsAction, CancellationToken cancellationToken = default) - { + public async static Task> BulkMergeAsync(this DbContext context, IEnumerable entities, Action> optionsAction, CancellationToken cancellationToken = default) + { return await BulkMergeAsync(context, entities, optionsAction.Build(), cancellationToken); } - public async static Task BulkSaveChangesAsync(this DbContext dbContext) - { + public async static Task BulkSaveChangesAsync(this DbContext dbContext) + { return await dbContext.BulkSaveChangesAsync(true); } - public async static Task BulkSaveChangesAsync(this DbContext dbContext, bool acceptAllChangesOnSuccess = true) - { + public async static Task BulkSaveChangesAsync(this DbContext dbContext, bool acceptAllChangesOnSuccess = true) + { int rowsAffected = 0; var stateManager = dbContext.GetDependencies().StateManager; @@ -226,20 +226,20 @@ public async static Task BulkSaveChangesAsync(this DbContext dbContext, boo return rowsAffected; } - public async static Task> BulkSyncAsync(this DbContext context, IEnumerable entities, CancellationToken cancellationToken = default) - { + public async static Task> BulkSyncAsync(this DbContext context, IEnumerable entities, CancellationToken cancellationToken = default) + { return await BulkSyncAsync(context, entities, new BulkSyncOptions(), cancellationToken); } - public async static Task> BulkSyncAsync(this DbContext context, IEnumerable entities, Action> optionsAction, CancellationToken cancellationToken = default) - { + public async static Task> BulkSyncAsync(this DbContext context, IEnumerable entities, Action> optionsAction, CancellationToken cancellationToken = default) + { return BulkSyncResult.Map(await InternalBulkMergeAsync(context, entities, optionsAction.Build(), cancellationToken)); } - public async static Task> BulkSyncAsync(this DbContext context, IEnumerable entities, BulkSyncOptions options, CancellationToken cancellationToken = default) - { + public async static Task> BulkSyncAsync(this DbContext context, IEnumerable entities, BulkSyncOptions options, CancellationToken cancellationToken = default) + { return BulkSyncResult.Map(await InternalBulkMergeAsync(context, entities, options, cancellationToken)); } - private async static Task> InternalBulkMergeAsync(this DbContext context, IEnumerable entities, BulkMergeOptions options, CancellationToken cancellationToken = default) - { + private async static Task> InternalBulkMergeAsync(this DbContext context, IEnumerable entities, BulkMergeOptions options, CancellationToken cancellationToken = default) + { BulkMergeResult bulkMergeResult; using (var bulkOperation = new BulkOperation(context, options)) { @@ -259,16 +259,16 @@ private async static Task> InternalBulkMergeAsync(this DbC } return bulkMergeResult; } - public async static Task BulkUpdateAsync(this DbContext context, IEnumerable entities, CancellationToken cancellationToken = default) - { + public async static Task BulkUpdateAsync(this DbContext context, IEnumerable entities, CancellationToken cancellationToken = default) + { return await BulkUpdateAsync(context, entities, new BulkUpdateOptions(), cancellationToken); } - public async static Task BulkUpdateAsync(this DbContext context, IEnumerable entities, Action> optionsAction, CancellationToken cancellationToken = default) - { + public async static Task BulkUpdateAsync(this DbContext context, IEnumerable entities, Action> optionsAction, CancellationToken cancellationToken = default) + { return await BulkUpdateAsync(context, entities, optionsAction.Build(), cancellationToken); } - public async static Task BulkUpdateAsync(this DbContext context, IEnumerable entities, BulkUpdateOptions options, CancellationToken cancellationToken = default) - { + public async static Task BulkUpdateAsync(this DbContext context, IEnumerable entities, BulkUpdateOptions options, CancellationToken cancellationToken = default) + { int rowsUpdated = 0; using (var bulkOperation = new BulkOperation(context, options, options.InputColumns, options.IgnoreColumns)) { @@ -287,8 +287,8 @@ public async static Task BulkUpdateAsync(this DbContext context, IEnumer } return rowsUpdated; } - internal async static Task BulkQueryAsync(this DbContext context, string sqlText, SqlConnection dbConnection, SqlTransaction transaction, BulkOptions options, CancellationToken cancellationToken = default) - { + internal async static Task BulkQueryAsync(this DbContext context, string sqlText, SqlConnection dbConnection, SqlTransaction transaction, BulkOptions options, CancellationToken cancellationToken = default) + { var results = new List(); var columns = new List(); var command = new SqlCommand(sqlText, dbConnection, transaction); @@ -325,8 +325,8 @@ internal async static Task BulkQueryAsync(this DbContext contex RowsAffected = reader.RecordsAffected }; } - public async static Task DeleteFromQueryAsync(this IQueryable querable, int? commandTimeout = null, CancellationToken cancellationToken = default) where T : class - { + public async static Task DeleteFromQueryAsync(this IQueryable querable, int? commandTimeout = null, CancellationToken cancellationToken = default) where T : class + { int rowAffected = 0; var dbContext = querable.GetDbContext(); using (var dbTransactionContext = new DbTransactionContext(dbContext, commandTimeout)) @@ -349,9 +349,9 @@ public async static Task DeleteFromQueryAsync(this IQueryable querabl } return rowAffected; } - public async static Task InsertFromQueryAsync(this IQueryable querable, string tableName, Expression> insertObjectExpression, int? commandTimeout = null, - CancellationToken cancellationToken = default) where T : class - { + public async static Task InsertFromQueryAsync(this IQueryable querable, string tableName, Expression> insertObjectExpression, int? commandTimeout = null, + CancellationToken cancellationToken = default) where T : class + { int rowAffected = 0; var dbContext = querable.GetDbContext(); using (var dbTransactionContext = new DbTransactionContext(dbContext, commandTimeout)) @@ -384,9 +384,9 @@ public async static Task InsertFromQueryAsync(this IQueryable querabl } return rowAffected; } - public async static Task UpdateFromQueryAsync(this IQueryable querable, Expression> updateExpression, int? commandTimeout = null, - CancellationToken cancellationToken = default) where T : class - { + public async static Task UpdateFromQueryAsync(this IQueryable querable, Expression> updateExpression, int? commandTimeout = null, + CancellationToken cancellationToken = default) where T : class + { int rowAffected = 0; var dbContext = querable.GetDbContext(); using (var dbTransactionContext = new DbTransactionContext(dbContext, commandTimeout)) @@ -409,89 +409,89 @@ public async static Task UpdateFromQueryAsync(this IQueryable querabl } return rowAffected; } - public async static Task QueryToCsvFileAsync(this IQueryable querable, String filePath, CancellationToken cancellationToken = default) where T : class - { + public async static Task QueryToCsvFileAsync(this IQueryable querable, String filePath, CancellationToken cancellationToken = default) where T : class + { return await QueryToCsvFileAsync(querable, filePath, new QueryToFileOptions(), cancellationToken); } - public async static Task QueryToCsvFileAsync(this IQueryable querable, Stream stream, CancellationToken cancellationToken = default) where T : class - { + public async static Task QueryToCsvFileAsync(this IQueryable querable, Stream stream, CancellationToken cancellationToken = default) where T : class + { return await QueryToCsvFileAsync(querable, stream, new QueryToFileOptions(), cancellationToken); } - public async static Task QueryToCsvFileAsync(this IQueryable querable, String filePath, Action optionsAction, - CancellationToken cancellationToken = default) where T : class - { + public async static Task QueryToCsvFileAsync(this IQueryable querable, String filePath, Action optionsAction, + CancellationToken cancellationToken = default) where T : class + { return await QueryToCsvFileAsync(querable, filePath, optionsAction.Build(), cancellationToken); } - public async static Task QueryToCsvFileAsync(this IQueryable querable, Stream stream, Action optionsAction, - CancellationToken cancellationToken = default) where T : class - { + public async static Task QueryToCsvFileAsync(this IQueryable querable, Stream stream, Action optionsAction, + CancellationToken cancellationToken = default) where T : class + { return await QueryToCsvFileAsync(querable, stream, optionsAction.Build(), cancellationToken); } - public async static Task QueryToCsvFileAsync(this IQueryable querable, String filePath, QueryToFileOptions options, - CancellationToken cancellationToken = default) where T : class - { + public async static Task QueryToCsvFileAsync(this IQueryable querable, String filePath, QueryToFileOptions options, + CancellationToken cancellationToken = default) where T : class + { var fileStream = File.Create(filePath); return await QueryToCsvFileAsync(querable, fileStream, options, cancellationToken); } - public async static Task QueryToCsvFileAsync(this IQueryable querable, Stream stream, QueryToFileOptions options, - CancellationToken cancellationToken = default) where T : class - { + public async static Task QueryToCsvFileAsync(this IQueryable querable, Stream stream, QueryToFileOptions options, + CancellationToken cancellationToken = default) where T : class + { return await InternalQueryToFileAsync(querable, stream, options, cancellationToken); } - public async static Task SqlQueryToCsvFileAsync(this DatabaseFacade database, string filePath, string sqlText, object[] parameters, - CancellationToken cancellationToken = default) - { + public async static Task SqlQueryToCsvFileAsync(this DatabaseFacade database, string filePath, string sqlText, object[] parameters, + CancellationToken cancellationToken = default) + { return await SqlQueryToCsvFileAsync(database, filePath, new QueryToFileOptions(), sqlText, parameters, cancellationToken); } - public async static Task SqlQueryToCsvFileAsync(this DatabaseFacade database, Stream stream, string sqlText, object[] parameters, - CancellationToken cancellationToken = default) - { + public async static Task SqlQueryToCsvFileAsync(this DatabaseFacade database, Stream stream, string sqlText, object[] parameters, + CancellationToken cancellationToken = default) + { return await SqlQueryToCsvFileAsync(database, stream, new QueryToFileOptions(), sqlText, parameters, cancellationToken); } - public async static Task SqlQueryToCsvFileAsync(this DatabaseFacade database, string filePath, Action optionsAction, string sqlText, object[] parameters, - CancellationToken cancellationToken = default) - { + public async static Task SqlQueryToCsvFileAsync(this DatabaseFacade database, string filePath, Action optionsAction, string sqlText, object[] parameters, + CancellationToken cancellationToken = default) + { return await SqlQueryToCsvFileAsync(database, filePath, optionsAction.Build(), sqlText, parameters, cancellationToken); } - public async static Task SqlQueryToCsvFileAsync(this DatabaseFacade database, Stream stream, Action optionsAction, string sqlText, object[] parameters, - CancellationToken cancellationToken = default) - { + public async static Task SqlQueryToCsvFileAsync(this DatabaseFacade database, Stream stream, Action optionsAction, string sqlText, object[] parameters, + CancellationToken cancellationToken = default) + { return await SqlQueryToCsvFileAsync(database, stream, optionsAction.Build(), sqlText, parameters, cancellationToken); } - public async static Task SqlQueryToCsvFileAsync(this DatabaseFacade database, string filePath, QueryToFileOptions options, string sqlText, object[] parameters, - CancellationToken cancellationToken = default) - { + public async static Task SqlQueryToCsvFileAsync(this DatabaseFacade database, string filePath, QueryToFileOptions options, string sqlText, object[] parameters, + CancellationToken cancellationToken = default) + { var fileStream = File.Create(filePath); return await SqlQueryToCsvFileAsync(database, fileStream, options, sqlText, parameters, cancellationToken); } - public async static Task SqlQueryToCsvFileAsync(this DatabaseFacade database, Stream stream, QueryToFileOptions options, string sqlText, object[] parameters, - CancellationToken cancellationToken = default) - { + public async static Task SqlQueryToCsvFileAsync(this DatabaseFacade database, Stream stream, QueryToFileOptions options, string sqlText, object[] parameters, + CancellationToken cancellationToken = default) + { var dbConnection = database.GetDbConnection() as SqlConnection; return await InternalQueryToFileAsync(dbConnection, stream, options, sqlText, parameters, cancellationToken); } - public async static Task ClearAsync(this DbSet dbSet, CancellationToken cancellationToken = default) where T : class - { + public async static Task ClearAsync(this DbSet dbSet, CancellationToken cancellationToken = default) where T : class + { var dbContext = dbSet.GetDbContext(); var tableMapping = dbContext.GetTableMapping(typeof(T)); await dbContext.Database.ClearTableAsync(tableMapping.FullQualifedTableName, cancellationToken); } - public async static Task TruncateAsync(this DbSet dbSet, CancellationToken cancellationToken = default) where T : class - { + public async static Task TruncateAsync(this DbSet dbSet, CancellationToken cancellationToken = default) where T : class + { var dbContext = dbSet.GetDbContext(); var tableMapping = dbContext.GetTableMapping(typeof(T)); await dbContext.Database.TruncateTableAsync(tableMapping.FullQualifedTableName, false, cancellationToken); } - private async static Task InternalQueryToFileAsync(this IQueryable querable, Stream stream, QueryToFileOptions options, - CancellationToken cancellationToken = default) where T : class - { + private async static Task InternalQueryToFileAsync(this IQueryable querable, Stream stream, QueryToFileOptions options, + CancellationToken cancellationToken = default) where T : class + { var dbContext = querable.GetDbContext(); var dbConnection = dbContext.GetSqlConnection(); return await InternalQueryToFileAsync(dbConnection, stream, options, querable.ToQueryString(), null, cancellationToken); } - private async static Task InternalQueryToFileAsync(SqlConnection dbConnection, Stream stream, QueryToFileOptions options, string sqlText, object[] parameters = null, - CancellationToken cancellationToken = default) - { + private async static Task InternalQueryToFileAsync(SqlConnection dbConnection, Stream stream, QueryToFileOptions options, string sqlText, object[] parameters = null, + CancellationToken cancellationToken = default) + { int dataRowCount = 0; int totalRowCount = 0; long bytesWritten = 0; @@ -559,5 +559,4 @@ private async static Task InternalQueryToFileAsync(SqlConnect TotalRowCount = totalRowCount }; } - } } \ No newline at end of file diff --git a/N.EntityFrameworkCore.Extensions/Data/DbTransactionContext.cs b/N.EntityFrameworkCore.Extensions/Data/DbTransactionContext.cs index 49f3668..fb9f388 100644 --- a/N.EntityFrameworkCore.Extensions/Data/DbTransactionContext.cs +++ b/N.EntityFrameworkCore.Extensions/Data/DbTransactionContext.cs @@ -5,26 +5,26 @@ using N.EntityFrameworkCore.Extensions.Enums; -namespace N.EntityFrameworkCore.Extensions +namespace N.EntityFrameworkCore.Extensions; + +internal class DbTransactionContext : IDisposable { - internal class DbTransactionContext : IDisposable - { - private bool closeConnection; - private bool ownsTransaction; - private int? defaultCommandTimeout; - private DbContext context; - private IDbContextTransaction transaction; + private bool closeConnection; + private bool ownsTransaction; + private int? defaultCommandTimeout; + private DbContext context; + private IDbContextTransaction transaction; - public SqlConnection Connection { get; internal set; } - public SqlTransaction CurrentTransaction { get; private set; } - public DbContext DbContext => context; + public SqlConnection Connection { get; internal set; } + public SqlTransaction CurrentTransaction { get; private set; } + public DbContext DbContext => context; - public DbTransactionContext(DbContext context, BulkOptions bulkOptions, bool openConnection = true) : this(context, bulkOptions.CommandTimeout, bulkOptions.ConnectionBehavior, openConnection) - { + public DbTransactionContext(DbContext context, BulkOptions bulkOptions, bool openConnection = true) : this(context, bulkOptions.CommandTimeout, bulkOptions.ConnectionBehavior, openConnection) + { } - public DbTransactionContext(DbContext context, int? commandTimeout = null, ConnectionBehavior connectionBehavior = ConnectionBehavior.Default, bool openConnection = true) - { + public DbTransactionContext(DbContext context, int? commandTimeout = null, ConnectionBehavior connectionBehavior = ConnectionBehavior.Default, bool openConnection = true) + { this.context = context; this.Connection = context.GetSqlConnection(connectionBehavior); if (openConnection) @@ -51,8 +51,8 @@ public DbTransactionContext(DbContext context, int? commandTimeout = null, Conne context.Database.SetCommandTimeout(commandTimeout); } - public void Dispose() - { + public void Dispose() + { context.Database.SetCommandTimeout(defaultCommandTimeout); if (closeConnection) { @@ -60,15 +60,14 @@ public void Dispose() } } - internal void Commit() - { + internal void Commit() + { if (this.ownsTransaction && this.transaction != null) transaction.Commit(); } - internal void Rollback() - { + internal void Rollback() + { if (this.transaction != null) transaction.Rollback(); } - } } \ No newline at end of file diff --git a/N.EntityFrameworkCore.Extensions/Data/EfExtensionsCommand.cs b/N.EntityFrameworkCore.Extensions/Data/EfExtensionsCommand.cs index da513e8..6f05c45 100644 --- a/N.EntityFrameworkCore.Extensions/Data/EfExtensionsCommand.cs +++ b/N.EntityFrameworkCore.Extensions/Data/EfExtensionsCommand.cs @@ -2,17 +2,17 @@ using Microsoft.Data.SqlClient; using Microsoft.EntityFrameworkCore.Diagnostics; -namespace N.EntityFrameworkCore.Extensions +namespace N.EntityFrameworkCore.Extensions; + +class EfExtensionsCommand { - class EfExtensionsCommand - { - public EfExtensionsCommandType CommandType { get; set; } - public string OldValue { get; set; } - public string NewValue { get; set; } - public SqlConnection Connection { get; internal set; } + public EfExtensionsCommandType CommandType { get; set; } + public string OldValue { get; set; } + public string NewValue { get; set; } + public SqlConnection Connection { get; internal set; } - internal bool Execute(DbCommand command, CommandEventData eventData, InterceptionResult result) - { + internal bool Execute(DbCommand command, CommandEventData eventData, InterceptionResult result) + { if (CommandType == EfExtensionsCommandType.ChangeTableName) { command.CommandText = command.CommandText.Replace(OldValue, NewValue); @@ -20,5 +20,4 @@ internal bool Execute(DbCommand command, CommandEventData eventData, Interceptio return true; } - } } \ No newline at end of file diff --git a/N.EntityFrameworkCore.Extensions/Data/EfExtensionsCommandInterceptor.cs b/N.EntityFrameworkCore.Extensions/Data/EfExtensionsCommandInterceptor.cs index 4d09301..3980f9e 100644 --- a/N.EntityFrameworkCore.Extensions/Data/EfExtensionsCommandInterceptor.cs +++ b/N.EntityFrameworkCore.Extensions/Data/EfExtensionsCommandInterceptor.cs @@ -5,13 +5,13 @@ using System.Threading.Tasks; using Microsoft.EntityFrameworkCore.Diagnostics; -namespace N.EntityFrameworkCore.Extensions +namespace N.EntityFrameworkCore.Extensions; + +public class EfExtensionsCommandInterceptor : DbCommandInterceptor { - public class EfExtensionsCommandInterceptor : DbCommandInterceptor + private ConcurrentDictionary extensionCommands = new ConcurrentDictionary(); + public override InterceptionResult ReaderExecuting(DbCommand command, CommandEventData eventData, InterceptionResult result) { - private ConcurrentDictionary extensionCommands = new ConcurrentDictionary(); - public override InterceptionResult ReaderExecuting(DbCommand command, CommandEventData eventData, InterceptionResult result) - { foreach (var extensionCommand in extensionCommands) { if (extensionCommand.Value.Connection == command.Connection) @@ -22,9 +22,8 @@ public override InterceptionResult ReaderExecuting(DbCommand comma } return result; } - internal void AddCommand(Guid clientConnectionId, EfExtensionsCommand efExtensionsCommand) - { + internal void AddCommand(Guid clientConnectionId, EfExtensionsCommand efExtensionsCommand) + { extensionCommands.TryAdd(clientConnectionId, efExtensionsCommand); } - } } \ No newline at end of file diff --git a/N.EntityFrameworkCore.Extensions/Data/EntityDataReader.cs b/N.EntityFrameworkCore.Extensions/Data/EntityDataReader.cs index 27c62f8..10d4dfb 100644 --- a/N.EntityFrameworkCore.Extensions/Data/EntityDataReader.cs +++ b/N.EntityFrameworkCore.Extensions/Data/EntityDataReader.cs @@ -13,22 +13,22 @@ using N.EntityFrameworkCore.Extensions.Common; using N.EntityFrameworkCore.Extensions.Extensions; -namespace N.EntityFrameworkCore.Extensions +namespace N.EntityFrameworkCore.Extensions; + +internal class EntityDataReader : IDataReader { - internal class EntityDataReader : IDataReader + public TableMapping TableMapping { get; set; } + public Dictionary EntityMap { get; set; } + private Dictionary columnIndexes; + private int currentId; + private bool useInternalId; + private int tableFieldCount; + private IEnumerable entities; + private IEnumerator enumerator; + private Dictionary> selectors; + + public EntityDataReader(TableMapping tableMapping, IEnumerable entities, bool useInternalId) { - public TableMapping TableMapping { get; set; } - public Dictionary EntityMap { get; set; } - private Dictionary columnIndexes; - private int currentId; - private bool useInternalId; - private int tableFieldCount; - private IEnumerable entities; - private IEnumerator enumerator; - private Dictionary> selectors; - - public EntityDataReader(TableMapping tableMapping, IEnumerable entities, bool useInternalId) - { this.columnIndexes = new Dictionary(); this.currentId = 0; this.useInternalId = useInternalId; @@ -55,8 +55,8 @@ public EntityDataReader(TableMapping tableMapping, IEnumerable entities, bool columnIndexes[Constants.InternalId_ColumnName] = i; } } - private Func GetValueSelector(IProperty property) - { + private Func GetValueSelector(IProperty property) + { Func selector; var valueGeneratorFactory = property.GetValueGeneratorFactory(); if (valueGeneratorFactory != null) @@ -85,131 +85,131 @@ private Func GetValueSelector(IProperty property) } return selector; } - public object this[int i] => throw new NotImplementedException(); + public object this[int i] => throw new NotImplementedException(); - public object this[string name] => throw new NotImplementedException(); + public object this[string name] => throw new NotImplementedException(); - public int Depth { get; set; } + public int Depth { get; set; } - public bool IsClosed => throw new NotImplementedException(); + public bool IsClosed => throw new NotImplementedException(); - public int RecordsAffected => throw new NotImplementedException(); + public int RecordsAffected => throw new NotImplementedException(); - public int FieldCount { get; set; } + public int FieldCount { get; set; } - public void Close() - { + public void Close() + { throw new NotImplementedException(); } - public void Dispose() - { + public void Dispose() + { selectors = null; enumerator.Dispose(); } - public bool GetBoolean(int i) - { + public bool GetBoolean(int i) + { throw new NotImplementedException(); } - public byte GetByte(int i) - { + public byte GetByte(int i) + { throw new NotImplementedException(); } - public long GetBytes(int i, long fieldOffset, byte[] buffer, int bufferoffset, int length) - { + public long GetBytes(int i, long fieldOffset, byte[] buffer, int bufferoffset, int length) + { throw new NotImplementedException(); } - public char GetChar(int i) - { + public char GetChar(int i) + { throw new NotImplementedException(); } - public long GetChars(int i, long fieldoffset, char[] buffer, int bufferoffset, int length) - { + public long GetChars(int i, long fieldoffset, char[] buffer, int bufferoffset, int length) + { throw new NotImplementedException(); } - public IDataReader GetData(int i) - { + public IDataReader GetData(int i) + { throw new NotImplementedException(); } - public string GetDataTypeName(int i) - { + public string GetDataTypeName(int i) + { throw new NotImplementedException(); } - public DateTime GetDateTime(int i) - { + public DateTime GetDateTime(int i) + { throw new NotImplementedException(); } - public decimal GetDecimal(int i) - { + public decimal GetDecimal(int i) + { throw new NotImplementedException(); } - public double GetDouble(int i) - { + public double GetDouble(int i) + { throw new NotImplementedException(); } - public Type GetFieldType(int i) - { + public Type GetFieldType(int i) + { throw new NotImplementedException(); } - public float GetFloat(int i) - { + public float GetFloat(int i) + { throw new NotImplementedException(); } - public Guid GetGuid(int i) - { + public Guid GetGuid(int i) + { throw new NotImplementedException(); } - public short GetInt16(int i) - { + public short GetInt16(int i) + { throw new NotImplementedException(); } - public int GetInt32(int i) - { + public int GetInt32(int i) + { throw new NotImplementedException(); } - public long GetInt64(int i) - { + public long GetInt64(int i) + { throw new NotImplementedException(); } - public string GetName(int i) - { + public string GetName(int i) + { throw new NotImplementedException(); } - public int GetOrdinal(string name) - { + public int GetOrdinal(string name) + { return columnIndexes[name]; } - public DataTable GetSchemaTable() - { + public DataTable GetSchemaTable() + { throw new NotImplementedException(); } - public string GetString(int i) - { + public string GetString(int i) + { throw new NotImplementedException(); } - public object GetValue(int i) - { + public object GetValue(int i) + { if (i == tableFieldCount) { return this.currentId; @@ -221,28 +221,28 @@ public object GetValue(int i) } - private EntityEntry FindEntry(object entity) - { + private EntityEntry FindEntry(object entity) + { return entity is InternalEntityEntry ? ((InternalEntityEntry)entity).ToEntityEntry() : this.TableMapping.DbContext.Entry(entity); } - public int GetValues(object[] values) - { + public int GetValues(object[] values) + { throw new NotImplementedException(); } - public bool IsDBNull(int i) - { + public bool IsDBNull(int i) + { throw new NotImplementedException(); } - public bool NextResult() - { + public bool NextResult() + { throw new NotImplementedException(); } - public bool Read() - { + public bool Read() + { bool moveNext = enumerator.MoveNext(); if (moveNext && this.useInternalId) @@ -252,5 +252,4 @@ public bool Read() } return moveNext; } - } } \ No newline at end of file diff --git a/N.EntityFrameworkCore.Extensions/Data/FetchOptions.cs b/N.EntityFrameworkCore.Extensions/Data/FetchOptions.cs index f01d7e0..6d773ac 100644 --- a/N.EntityFrameworkCore.Extensions/Data/FetchOptions.cs +++ b/N.EntityFrameworkCore.Extensions/Data/FetchOptions.cs @@ -5,12 +5,11 @@ using System.Text; using System.Threading.Tasks; -namespace N.EntityFrameworkCore.Extensions +namespace N.EntityFrameworkCore.Extensions; + +public class FetchOptions { - public class FetchOptions - { - public Expression> IgnoreColumns { get; set; } - public Expression> InputColumns { get; set; } - public int BatchSize { get; set; } - } + public Expression> IgnoreColumns { get; set; } + public Expression> InputColumns { get; set; } + public int BatchSize { get; set; } } \ No newline at end of file diff --git a/N.EntityFrameworkCore.Extensions/Data/FetchResult.cs b/N.EntityFrameworkCore.Extensions/Data/FetchResult.cs index c4ba7cb..b179906 100644 --- a/N.EntityFrameworkCore.Extensions/Data/FetchResult.cs +++ b/N.EntityFrameworkCore.Extensions/Data/FetchResult.cs @@ -1,11 +1,10 @@ using System; using System.Collections.Generic; -namespace N.EntityFrameworkCore.Extensions +namespace N.EntityFrameworkCore.Extensions; + +public class FetchResult { - public class FetchResult - { - public List Results { get; set; } - public int Batch { get; set; } - } + public List Results { get; set; } + public int Batch { get; set; } } \ No newline at end of file diff --git a/N.EntityFrameworkCore.Extensions/Data/QueryToFileOptions.cs b/N.EntityFrameworkCore.Extensions/Data/QueryToFileOptions.cs index e7e3f13..f846265 100644 --- a/N.EntityFrameworkCore.Extensions/Data/QueryToFileOptions.cs +++ b/N.EntityFrameworkCore.Extensions/Data/QueryToFileOptions.cs @@ -2,22 +2,21 @@ using System.Collections.Generic; using System.Text; -namespace N.EntityFrameworkCore.Extensions +namespace N.EntityFrameworkCore.Extensions; + +public class QueryToFileOptions { - public class QueryToFileOptions - { - public string ColumnDelimiter { get; set; } - public int? CommandTimeout { get; set; } - public bool IncludeHeaderRow { get; set; } - public string RowDelimiter { get; set; } - public string TextQualifer { get; set; } + public string ColumnDelimiter { get; set; } + public int? CommandTimeout { get; set; } + public bool IncludeHeaderRow { get; set; } + public string RowDelimiter { get; set; } + public string TextQualifer { get; set; } - public QueryToFileOptions() - { + public QueryToFileOptions() + { ColumnDelimiter = ","; IncludeHeaderRow = true; RowDelimiter = "\r\n"; TextQualifer = ""; } - } } \ No newline at end of file diff --git a/N.EntityFrameworkCore.Extensions/Data/QueryToFileResult.cs b/N.EntityFrameworkCore.Extensions/Data/QueryToFileResult.cs index 9f0aaf3..03269e5 100644 --- a/N.EntityFrameworkCore.Extensions/Data/QueryToFileResult.cs +++ b/N.EntityFrameworkCore.Extensions/Data/QueryToFileResult.cs @@ -2,12 +2,11 @@ using System.Collections.Generic; using System.Text; -namespace N.EntityFrameworkCore.Extensions +namespace N.EntityFrameworkCore.Extensions; + +public class QueryToFileResult { - public class QueryToFileResult - { - public long BytesWritten { get; set; } - public int DataRowCount { get; internal set; } - public int TotalRowCount { get; internal set; } - } + public long BytesWritten { get; set; } + public int DataRowCount { get; internal set; } + public int TotalRowCount { get; internal set; } } \ No newline at end of file diff --git a/N.EntityFrameworkCore.Extensions/Data/SqlMergeAction.cs b/N.EntityFrameworkCore.Extensions/Data/SqlMergeAction.cs index bfa75c0..17c885c 100644 --- a/N.EntityFrameworkCore.Extensions/Data/SqlMergeAction.cs +++ b/N.EntityFrameworkCore.Extensions/Data/SqlMergeAction.cs @@ -4,12 +4,11 @@ using System.Text; using System.Threading.Tasks; -namespace N.EntityFrameworkCore.Extensions +namespace N.EntityFrameworkCore.Extensions; + +internal static class SqlMergeAction { - internal static class SqlMergeAction - { - public static string Insert = "INSERT"; - public static string Update = "UPDATE"; - public static string Delete = "DELETE"; - } + public static string Insert = "INSERT"; + public static string Update = "UPDATE"; + public static string Delete = "DELETE"; } \ No newline at end of file diff --git a/N.EntityFrameworkCore.Extensions/Data/SqlQuery.cs b/N.EntityFrameworkCore.Extensions/Data/SqlQuery.cs index 3a75155..0dae8f9 100644 --- a/N.EntityFrameworkCore.Extensions/Data/SqlQuery.cs +++ b/N.EntityFrameworkCore.Extensions/Data/SqlQuery.cs @@ -4,34 +4,33 @@ using Microsoft.EntityFrameworkCore.Infrastructure; using N.EntityFrameworkCore.Extensions.Sql; -namespace N.EntityFrameworkCore.Extensions +namespace N.EntityFrameworkCore.Extensions; + +public class SqlQuery { - public class SqlQuery - { - private DatabaseFacade database; - public string SqlText { get; private set; } - public object[] Parameters { get; private set; } + private DatabaseFacade database; + public string SqlText { get; private set; } + public object[] Parameters { get; private set; } - public SqlQuery(DatabaseFacade database, String sqlText, params object[] parameters) - { + public SqlQuery(DatabaseFacade database, String sqlText, params object[] parameters) + { this.database = database; this.SqlText = sqlText; this.Parameters = parameters; } - public int Count() - { + public int Count() + { string countSqlText = SqlBuilder.Parse(this.SqlText).Count(); return (int)database.ExecuteScalar(countSqlText, this.Parameters); } - public async Task CountAsync(CancellationToken cancellationToken = default) - { + public async Task CountAsync(CancellationToken cancellationToken = default) + { string countSqlText = SqlBuilder.Parse(this.SqlText).Count(); return (int)await database.ExecuteScalarAsync(countSqlText, this.Parameters, null, cancellationToken); } - public int ExecuteNonQuery() - { + public int ExecuteNonQuery() + { return database.ExecuteSql(this.SqlText, this.Parameters); } - } } \ No newline at end of file diff --git a/N.EntityFrameworkCore.Extensions/Data/TableMapping.cs b/N.EntityFrameworkCore.Extensions/Data/TableMapping.cs index 11d3611..5f4ff55 100644 --- a/N.EntityFrameworkCore.Extensions/Data/TableMapping.cs +++ b/N.EntityFrameworkCore.Extensions/Data/TableMapping.cs @@ -8,27 +8,27 @@ using Microsoft.EntityFrameworkCore.Metadata.Internal; using N.EntityFrameworkCore.Extensions.Extensions; -namespace N.EntityFrameworkCore.Extensions +namespace N.EntityFrameworkCore.Extensions; + +public class TableMapping { - public class TableMapping - { - public DbContext DbContext { get; private set; } - public IEntityType EntityType { get; set; } - public IProperty[] Properties { get; } - public string Schema { get; } - public string TableName { get; } - public IEnumerable EntityTypes { get; } + public DbContext DbContext { get; private set; } + public IEntityType EntityType { get; set; } + public IProperty[] Properties { get; } + public string Schema { get; } + public string TableName { get; } + public IEnumerable EntityTypes { get; } - public bool HasIdentityColumn => EntityType.FindPrimaryKey().Properties.Any(o => o.ValueGenerated != ValueGenerated.Never); - public StoreObjectIdentifier StoreObjectIdentifier => StoreObjectIdentifier.Table(TableName, EntityType.GetSchema()); - private Dictionary ColumnMap { get; set; } - public string FullQualifedTableName - { - get { return string.Format("[{0}].[{1}]", this.Schema, this.TableName); } - } + public bool HasIdentityColumn => EntityType.FindPrimaryKey().Properties.Any(o => o.ValueGenerated != ValueGenerated.Never); + public StoreObjectIdentifier StoreObjectIdentifier => StoreObjectIdentifier.Table(TableName, EntityType.GetSchema()); + private Dictionary ColumnMap { get; set; } + public string FullQualifedTableName + { + get { return string.Format("[{0}].[{1}]", this.Schema, this.TableName); } + } - public TableMapping(DbContext dbContext, IEntityType entityType) - { + public TableMapping(DbContext dbContext, IEntityType entityType) + { DbContext = dbContext; EntityType = entityType; Properties = GetProperties(entityType); @@ -37,30 +37,30 @@ public TableMapping(DbContext dbContext, IEntityType entityType) TableName = entityType.GetTableName(); EntityTypes = EntityType.GetAllBaseTypesInclusive().Where(o => !o.IsAbstract()); } - public IProperty GetPropertyFromColumnName(string columnName) - { + public IProperty GetPropertyFromColumnName(string columnName) + { return ColumnMap[columnName]; } - private static IProperty[] GetProperties(IEntityType entityType) - { + private static IProperty[] GetProperties(IEntityType entityType) + { var properties = entityType.GetProperties().ToList(); properties.AddRange(entityType.GetComplexProperties().SelectMany(p => p.ComplexType.GetProperties())); return properties.ToArray(); } - public IEnumerable GetQualifiedColumnNames(IEnumerable columnNames, IEntityType entityType = null) - { + public IEnumerable GetQualifiedColumnNames(IEnumerable columnNames, IEntityType entityType = null) + { return Properties.Where(o => entityType == null || o.GetDeclaringEntityType() == entityType) .Select(o => FindColumn(o)) .Where(o => columnNames == null || columnNames.Contains(o.Name)) .Select(o => $"[{o.Table.Name}].[{o.Name}]").ToList(); } - public string GetColumnName(IProperty property) - { + public string GetColumnName(IProperty property) + { return FindColumn(property).Name; } - private IColumnBase FindColumn(IProperty property) - { + private IColumnBase FindColumn(IProperty property) + { var entityType = property.GetDeclaringEntityType(); if (entityType == null || entityType.IsAbstract()) entityType = EntityType; @@ -68,12 +68,12 @@ private IColumnBase FindColumn(IProperty property) return property.FindColumn(storeObjectIdentifier); } - private string FindTableName(IEntityType declaringEntityType, IEntityType entityType) - { + private string FindTableName(IEntityType declaringEntityType, IEntityType entityType) + { return declaringEntityType != null && declaringEntityType.IsAbstract() ? declaringEntityType.GetTableName() : entityType.GetTableName(); } - public IEnumerable GetColumnNames(IEntityType entityType, bool primaryKeyColumns) - { + public IEnumerable GetColumnNames(IEntityType entityType, bool primaryKeyColumns) + { List columns; if (entityType != null) { @@ -98,8 +98,8 @@ public IEnumerable GetColumnNames(IEntityType entityType, bool primaryKe } return columns.Distinct(); } - public IEnumerable GetColumns(bool includePrimaryKeyColumns = false) - { + public IEnumerable GetColumns(bool includePrimaryKeyColumns = false) + { var columns = new List(); foreach (var entityType in EntityTypes) { @@ -115,25 +115,25 @@ public IEnumerable GetColumns(bool includePrimaryKeyColumns = false) } return columns.Where(o => o != null).Distinct(); } - public IEnumerable GetPrimaryKeyColumns() - { + public IEnumerable GetPrimaryKeyColumns() + { return EntityType.FindPrimaryKey().Properties.Select(o => o.GetColumnName(this.StoreObjectIdentifier)); } - internal IEnumerable GetAutoGeneratedColumns(IEntityType entityType = null) - { + internal IEnumerable GetAutoGeneratedColumns(IEntityType entityType = null) + { entityType = entityType ?? this.EntityType; return entityType.GetProperties().Where(o => o.ValueGenerated != ValueGenerated.Never) .Select(o => o.GetColumnName(this.StoreObjectIdentifier)); } - internal IEnumerable GetEntityProperties(IEntityType entityType = null, ValueGenerated? valueGenerated = null) - { + internal IEnumerable GetEntityProperties(IEntityType entityType = null, ValueGenerated? valueGenerated = null) + { entityType = entityType ?? this.EntityType; return entityType.GetProperties().Where(o => valueGenerated == null || o.ValueGenerated == valueGenerated).AsEnumerable(); } - internal Func GetValueFromProvider(IProperty property) - { + internal Func GetValueFromProvider(IProperty property) + { var valueConverter = property.GetTypeMapping().Converter; if (valueConverter != null) { @@ -144,8 +144,8 @@ internal Func GetValueFromProvider(IProperty property) return value => value; } } - internal IEnumerable> GetValuesFromProvider() - { + internal IEnumerable> GetValuesFromProvider() + { var propertyGetters = new List>(); foreach (var property in this.Properties) { @@ -154,10 +154,9 @@ internal IEnumerable> GetValuesFromProvider() return propertyGetters.AsEnumerable(); } - internal IEnumerable GetSchemaQualifiedTableNames() - { + internal IEnumerable GetSchemaQualifiedTableNames() + { return EntityTypes .Select(o => $"[{o.GetSchema() ?? "dbo"}].[{o.GetTableName()}]").Distinct(); } - } } \ No newline at end of file diff --git a/N.EntityFrameworkCore.Extensions/Enums/ConnectionBehavior.cs b/N.EntityFrameworkCore.Extensions/Enums/ConnectionBehavior.cs index b9b2563..a5a476a 100644 --- a/N.EntityFrameworkCore.Extensions/Enums/ConnectionBehavior.cs +++ b/N.EntityFrameworkCore.Extensions/Enums/ConnectionBehavior.cs @@ -4,11 +4,10 @@ using System.Text; using System.Threading.Tasks; -namespace N.EntityFrameworkCore.Extensions.Enums +namespace N.EntityFrameworkCore.Extensions.Enums; + +internal enum ConnectionBehavior { - internal enum ConnectionBehavior - { - Default, - New - } + Default, + New } \ No newline at end of file diff --git a/N.EntityFrameworkCore.Extensions/Enums/EfExtensionsCommandType.cs b/N.EntityFrameworkCore.Extensions/Enums/EfExtensionsCommandType.cs index 3b53e1a..597fcdb 100644 --- a/N.EntityFrameworkCore.Extensions/Enums/EfExtensionsCommandType.cs +++ b/N.EntityFrameworkCore.Extensions/Enums/EfExtensionsCommandType.cs @@ -4,10 +4,9 @@ using System.Text; using System.Threading.Tasks; -namespace N.EntityFrameworkCore.Extensions +namespace N.EntityFrameworkCore.Extensions; + +enum EfExtensionsCommandType { - enum EfExtensionsCommandType - { - ChangeTableName - } + ChangeTableName } \ No newline at end of file diff --git a/N.EntityFrameworkCore.Extensions/Extensions/CommonExtensions.cs b/N.EntityFrameworkCore.Extensions/Extensions/CommonExtensions.cs index bb03e58..6632887 100644 --- a/N.EntityFrameworkCore.Extensions/Extensions/CommonExtensions.cs +++ b/N.EntityFrameworkCore.Extensions/Extensions/CommonExtensions.cs @@ -2,15 +2,14 @@ using System.Collections.Generic; using System.Text; -namespace N.EntityFrameworkCore.Extensions.Extensions +namespace N.EntityFrameworkCore.Extensions.Extensions; + +internal static class CommonExtensions { - internal static class CommonExtensions + internal static T Build(this Action buildAction) where T : new() { - internal static T Build(this Action buildAction) where T : new() - { var parameter = new T(); buildAction(parameter); return parameter; } - } } \ No newline at end of file diff --git a/N.EntityFrameworkCore.Extensions/Extensions/IPropertyExtensions.cs b/N.EntityFrameworkCore.Extensions/Extensions/IPropertyExtensions.cs index 05eb13d..860e9c1 100644 --- a/N.EntityFrameworkCore.Extensions/Extensions/IPropertyExtensions.cs +++ b/N.EntityFrameworkCore.Extensions/Extensions/IPropertyExtensions.cs @@ -7,13 +7,12 @@ using Microsoft.EntityFrameworkCore.Metadata; using Microsoft.EntityFrameworkCore.Metadata.Internal; -namespace N.EntityFrameworkCore.Extensions.Extensions +namespace N.EntityFrameworkCore.Extensions.Extensions; + +public static class IPropertyExtensions { - public static class IPropertyExtensions + public static IEntityType GetDeclaringEntityType(this IProperty property) { - public static IEntityType GetDeclaringEntityType(this IProperty property) - { return property.DeclaringType as IEntityType; } - } } \ No newline at end of file diff --git a/N.EntityFrameworkCore.Extensions/Extensions/LinqExtensions.cs b/N.EntityFrameworkCore.Extensions/Extensions/LinqExtensions.cs index 7e8b8ae..8d4d14c 100644 --- a/N.EntityFrameworkCore.Extensions/Extensions/LinqExtensions.cs +++ b/N.EntityFrameworkCore.Extensions/Extensions/LinqExtensions.cs @@ -10,24 +10,24 @@ using System.Threading.Tasks; using Microsoft.IdentityModel.Protocols; -namespace N.EntityFrameworkCore.Extensions +namespace N.EntityFrameworkCore.Extensions; + +static class LinqExtensions { - static class LinqExtensions + static Dictionary sqlExpressionTypes = new() { - static Dictionary sqlExpressionTypes = new() - { - { ExpressionType.AndAlso, "AND" }, - { ExpressionType.Or, "OR" }, - { ExpressionType.Add, "+" }, - { ExpressionType.Subtract, "-" }, - { ExpressionType.Multiply, "*" }, - { ExpressionType.Divide, "/" }, - { ExpressionType.Modulo, "%" }, - { ExpressionType.Equal, "=" } - }; + { ExpressionType.AndAlso, "AND" }, + { ExpressionType.Or, "OR" }, + { ExpressionType.Add, "+" }, + { ExpressionType.Subtract, "-" }, + { ExpressionType.Multiply, "*" }, + { ExpressionType.Divide, "/" }, + { ExpressionType.Modulo, "%" }, + { ExpressionType.Equal, "=" } + }; - internal static string ToSql(this MemberBinding binding) - { + internal static string ToSql(this MemberBinding binding) + { if (binding is MemberAssignment memberAssingment) { return GetExpressionValueAsString(memberAssingment.Expression); @@ -37,8 +37,8 @@ internal static string ToSql(this MemberBinding binding) throw new NotSupportedException(); } } - internal static string GetExpressionValueAsString(Expression expression) - { + internal static string GetExpressionValueAsString(Expression expression) + { if (expression is ConstantExpression constantExpression) { return ConvertToSqlValue(constantExpression.Value); @@ -89,8 +89,8 @@ internal static string GetExpressionValueAsString(Expression expression) } } - private static string ConvertToSqlValue(object value) - { + private static string ConvertToSqlValue(object value) + { if (value == null) return "NULL"; if (value is string str) @@ -111,8 +111,8 @@ private static string ConvertToSqlValue(object value) throw new NotImplementedException("Unhandled data type."); } - public static List GetObjectProperties(this Expression> expression) - { + public static List GetObjectProperties(this Expression> expression) + { if (expression == null) { return new List(); @@ -134,8 +134,8 @@ public static List GetObjectProperties(this Expression(this Expression expression, params string[] parameters) - { + internal static string ToSqlPredicate2(this Expression expression, params string[] parameters) + { var sql = ToSqlString(expression.Body); for (var i = 0; i < parameters.Length; i++) @@ -144,8 +144,8 @@ internal static string ToSqlPredicate2(this Expression expression, params return sql; } - static string ToSqlString(Expression expression, string sql = null) - { + static string ToSqlString(Expression expression, string sql = null) + { sql ??= ""; if (expression is not BinaryExpression b) return sql; @@ -171,14 +171,14 @@ static string ToSqlString(Expression expression, string sql = null) var right = ToSqlString(b.Right, sql); return left + " AND " + right; } - internal static string ToSql(this ExpressionType expressionType) - { + internal static string ToSql(this ExpressionType expressionType) + { string value = string.Empty; sqlExpressionTypes.TryGetValue(expressionType, out value); return value; } - internal static string ToSql(this Expression expression) - { + internal static string ToSql(this Expression expression) + { var sb = new StringBuilder(); if (expression is BinaryExpression binaryExpression) { @@ -196,8 +196,8 @@ internal static string ToSql(this Expression expression) } return sb.ToString(); } - internal static string ToSqlPredicate(this Expression expression, params string[] parameters) - { + internal static string ToSqlPredicate(this Expression expression, params string[] parameters) + { var stringBuilder = new StringBuilder((string)expression.Body.GetPrivateFieldValue("DebugView")); int i = 0; foreach (var expressionParam in expression.Parameters) @@ -212,8 +212,8 @@ internal static string ToSqlPredicate(this Expression expression, params s stringBuilder.Replace("(System.Int32)", ""); return stringBuilder.ToString(); } - internal static string ToSqlUpdateSetExpression(this Expression expression, string tableName) - { + internal static string ToSqlUpdateSetExpression(this Expression expression, string tableName) + { List setValues = new List(); var memberInitExpression = expression.Body as MemberInitExpression; foreach (var binding in memberInitExpression.Bindings) @@ -224,5 +224,4 @@ internal static string ToSqlUpdateSetExpression(this Expression expression } return string.Join(",", setValues); } - } } \ No newline at end of file diff --git a/N.EntityFrameworkCore.Extensions/Extensions/ObjectExtensions.cs b/N.EntityFrameworkCore.Extensions/Extensions/ObjectExtensions.cs index 4496d83..e87d3c2 100644 --- a/N.EntityFrameworkCore.Extensions/Extensions/ObjectExtensions.cs +++ b/N.EntityFrameworkCore.Extensions/Extensions/ObjectExtensions.cs @@ -2,12 +2,12 @@ using System.Linq.Expressions; using System.Reflection; -namespace N.EntityFrameworkCore.Extensions +namespace N.EntityFrameworkCore.Extensions; + +internal static class ObjectExtensions { - internal static class ObjectExtensions + public static object GetPrivateFieldValue(this object obj, string propName) { - public static object GetPrivateFieldValue(this object obj, string propName) - { if (obj == null) throw new ArgumentNullException(nameof(obj)); Type t = obj.GetType(); FieldInfo fieldInfo = null; @@ -30,5 +30,4 @@ public static object GetPrivateFieldValue(this object obj, string propName) return propertyInfo.GetValue(obj, null); } - } } \ No newline at end of file diff --git a/N.EntityFrameworkCore.Extensions/Extensions/SqlStatementExtensions.cs b/N.EntityFrameworkCore.Extensions/Extensions/SqlStatementExtensions.cs index 9d8460a..5df629f 100644 --- a/N.EntityFrameworkCore.Extensions/Extensions/SqlStatementExtensions.cs +++ b/N.EntityFrameworkCore.Extensions/Extensions/SqlStatementExtensions.cs @@ -5,14 +5,13 @@ using System.Threading.Tasks; using N.EntityFrameworkCore.Extensions.Sql; -namespace N.EntityFrameworkCore.Extensions.Extensions +namespace N.EntityFrameworkCore.Extensions.Extensions; + +internal static class SqlStatementExtensions { - internal static class SqlStatementExtensions + internal static void WriteInsert(this SqlStatement statement, IEnumerable insertColumns) { - internal static void WriteInsert(this SqlStatement statement, IEnumerable insertColumns) - { statement.CreatePart(SqlKeyword.Insert, SqlExpression.Columns(insertColumns)); statement.CreatePart(SqlKeyword.Values, SqlExpression.Columns(insertColumns)); } - } } \ No newline at end of file diff --git a/N.EntityFrameworkCore.Extensions/Sql/SqlBuilder.cs b/N.EntityFrameworkCore.Extensions/Sql/SqlBuilder.cs index 8ef901e..f58386b 100644 --- a/N.EntityFrameworkCore.Extensions/Sql/SqlBuilder.cs +++ b/N.EntityFrameworkCore.Extensions/Sql/SqlBuilder.cs @@ -5,26 +5,26 @@ using System.Linq.Expressions; using Microsoft.Data.SqlClient; -namespace N.EntityFrameworkCore.Extensions.Sql +namespace N.EntityFrameworkCore.Extensions.Sql; + +class SqlBuilder { - class SqlBuilder + private static IEnumerable keywords = new string[] { "DECLARE", "SELECT", "FROM", "WHERE", "GROUP BY", "ORDER BY" }; + public string Sql + { + get { return this.ToString(); } + } + public List Clauses { get; private set; } + public List Parameters { get; private set; } + private SqlBuilder(string sql) { - private static IEnumerable keywords = new string[] { "DECLARE", "SELECT", "FROM", "WHERE", "GROUP BY", "ORDER BY" }; - public string Sql - { - get { return this.ToString(); } - } - public List Clauses { get; private set; } - public List Parameters { get; private set; } - private SqlBuilder(string sql) - { Clauses = new List(); Parameters = new List(); Initialize(sql); } - private void Initialize(string sqlText) - { + private void Initialize(string sqlText) + { string curClause = string.Empty; int curClauseIndex = 0; for (int i = 0; i < sqlText.Length;) @@ -69,8 +69,8 @@ private void Initialize(string sqlText) Clauses.Add(SqlClause.Parse(curClause, sqlText.Substring(curClauseIndex))); } - private string GetDeclareValue(string value) - { + private string GetDeclareValue(string value) + { if (value.StartsWith("'")) { return value.Substring(1, value.Length - 2); @@ -85,16 +85,16 @@ private string GetDeclareValue(string value) } } - public string Count() - { + public string Count() + { return string.Format("SELECT COUNT(*) FROM ({0}) s", string.Join("\r\n", Clauses.Where(o => o.Name != "ORDER BY").Select(o => o.ToString()))); } - public override string ToString() - { + public override string ToString() + { return string.Join("\r\n", Clauses.Select(o => o.ToString())); } - private static string StartsWithString(string textToSearch, IEnumerable valuesToFind, StringComparison stringComparison) - { + private static string StartsWithString(string textToSearch, IEnumerable valuesToFind, StringComparison stringComparison) + { string value = null; foreach (var valueToFind in valuesToFind) { @@ -107,18 +107,18 @@ private static string StartsWithString(string textToSearch, IEnumerable return value; } - public static SqlBuilder Parse(string sql) - { + public static SqlBuilder Parse(string sql) + { return new SqlBuilder(sql); } - public String GetTableAlias() - { + public String GetTableAlias() + { var sqlFromClause = Clauses.First(o => o.Name == "FROM"); var startIndex = sqlFromClause.InputText.LastIndexOf(" AS "); return startIndex > 0 ? sqlFromClause.InputText.Substring(startIndex + 4) : ""; } - public void ChangeToDelete() - { + public void ChangeToDelete() + { Validate(); var sqlClause = Clauses.FirstOrDefault(); var sqlFromClause = Clauses.First(o => o.Name == "FROM"); @@ -130,8 +130,8 @@ public void ChangeToDelete() sqlClause.InputText = sqlFromClause.InputText.Substring(aliasStartIndex, aliasLength); } } - public void ChangeToUpdate(string updateExpression, string setExpression) - { + public void ChangeToUpdate(string updateExpression, string setExpression) + { Validate(); var sqlClause = Clauses.FirstOrDefault(); if (sqlClause != null) @@ -141,8 +141,8 @@ public void ChangeToUpdate(string updateExpression, string setExpression) Clauses.Insert(1, new SqlClause { Name = "SET", InputText = setExpression }); } } - internal void ChangeToInsert(string tableName, Expression> insertObjectExpression) - { + internal void ChangeToInsert(string tableName, Expression> insertObjectExpression) + { Validate(); var sqlSelectClause = Clauses.FirstOrDefault(); string columnsToInsert = string.Join(",", insertObjectExpression.GetObjectProperties()); @@ -151,8 +151,8 @@ internal void ChangeToInsert(string tableName, Expression> in sqlSelectClause.InputText = columnsToInsert; } - internal void SelectColumns(IEnumerable columns) - { + internal void SelectColumns(IEnumerable columns) + { var tableAlias = GetTableAlias(); var sqlClause = Clauses.FirstOrDefault(); if (sqlClause.Name == "SELECT") @@ -160,12 +160,11 @@ internal void SelectColumns(IEnumerable columns) sqlClause.InputText = string.Join(",", columns.Select(c => string.Format("{0}.{1}", tableAlias, c))); } } - private void Validate() - { + private void Validate() + { if (Clauses.Count == 0) { throw new Exception("You must parse a valid sql statement before you can use this function."); } } - } } \ No newline at end of file diff --git a/N.EntityFrameworkCore.Extensions/Sql/SqlClause.cs b/N.EntityFrameworkCore.Extensions/Sql/SqlClause.cs index 8b84dc5..1fed72c 100644 --- a/N.EntityFrameworkCore.Extensions/Sql/SqlClause.cs +++ b/N.EntityFrameworkCore.Extensions/Sql/SqlClause.cs @@ -4,24 +4,23 @@ using System.Text; using System.Threading.Tasks; -namespace N.EntityFrameworkCore.Extensions.Sql +namespace N.EntityFrameworkCore.Extensions.Sql; + +class SqlClause { - class SqlClause + internal string Name { get; set; } + internal string InputText { get; set; } + public string Sql + { + get { return this.ToString(); } + } + public static SqlClause Parse(string name, string inputText) { - internal string Name { get; set; } - internal string InputText { get; set; } - public string Sql - { - get { return this.ToString(); } - } - public static SqlClause Parse(string name, string inputText) - { string cleanText = inputText.Replace("\r\n", "").Trim(); return new SqlClause { Name = name, InputText = cleanText }; } - public override string ToString() - { + public override string ToString() + { return string.Format("{0} {1}", Name, InputText); } - } } \ No newline at end of file diff --git a/N.EntityFrameworkCore.Extensions/Sql/SqlExpression.cs b/N.EntityFrameworkCore.Extensions/Sql/SqlExpression.cs index 9ad34b1..5b39862 100644 --- a/N.EntityFrameworkCore.Extensions/Sql/SqlExpression.cs +++ b/N.EntityFrameworkCore.Extensions/Sql/SqlExpression.cs @@ -9,18 +9,18 @@ using Microsoft.EntityFrameworkCore.Storage.ValueConversion; using N.EntityFrameworkCore.Extensions.Util; -namespace N.EntityFrameworkCore.Extensions.Sql +namespace N.EntityFrameworkCore.Extensions.Sql; + +internal class SqlExpression { - internal class SqlExpression - { - internal SqlExpressionType ExpressionType { get; } - List Items { get; set; } - internal string Sql => ToSql(); - string Alias { get; } - public bool IsEmpty => Items.Count == 0; + internal SqlExpressionType ExpressionType { get; } + List Items { get; set; } + internal string Sql => ToSql(); + string Alias { get; } + public bool IsEmpty => Items.Count == 0; - SqlExpression(SqlExpressionType expressionType, object item, string alias = null) - { + SqlExpression(SqlExpressionType expressionType, object item, string alias = null) + { ExpressionType = expressionType; Items = new List(); if (item is IEnumerable values) @@ -33,35 +33,35 @@ internal class SqlExpression } Alias = alias; } - SqlExpression(SqlExpressionType expressionType, object[] items, string alias = null) - { + SqlExpression(SqlExpressionType expressionType, object[] items, string alias = null) + { ExpressionType = expressionType; Items = new List(); Items.AddRange(items); Alias = alias; } - internal static SqlExpression Columns(IEnumerable columns) - { + internal static SqlExpression Columns(IEnumerable columns) + { return new SqlExpression(SqlExpressionType.Columns, columns); } - internal static SqlExpression Set(IEnumerable columns) - { + internal static SqlExpression Set(IEnumerable columns) + { return new SqlExpression(SqlExpressionType.Set, columns); } - internal static SqlExpression String(string joinOnCondition) - { + internal static SqlExpression String(string joinOnCondition) + { return new SqlExpression(SqlExpressionType.String, joinOnCondition); } - internal static SqlExpression Table(string tableName, string alias = null) - { + internal static SqlExpression Table(string tableName, string alias = null) + { return new SqlExpression(SqlExpressionType.Table, Util.CommonUtil.FormatTableName(tableName), alias); } - private string ToSql() - { + private string ToSql() + { var values = Items.Select(o => o.ToString()).ToArray(); StringBuilder sbSql = new StringBuilder(); if (ExpressionType == SqlExpressionType.Columns) @@ -82,5 +82,4 @@ private string ToSql() //var test = Items.Select(o => o.ToString()).ToArray(); return sbSql.ToString(); } - } } \ No newline at end of file diff --git a/N.EntityFrameworkCore.Extensions/Sql/SqlExpressionType.cs b/N.EntityFrameworkCore.Extensions/Sql/SqlExpressionType.cs index 5ad6646..42ac83f 100644 --- a/N.EntityFrameworkCore.Extensions/Sql/SqlExpressionType.cs +++ b/N.EntityFrameworkCore.Extensions/Sql/SqlExpressionType.cs @@ -1,10 +1,9 @@ -namespace N.EntityFrameworkCore.Extensions.Sql +namespace N.EntityFrameworkCore.Extensions.Sql; + +public enum SqlExpressionType { - public enum SqlExpressionType - { - String, - Table, - Columns, - Set - } + String, + Table, + Columns, + Set } \ No newline at end of file diff --git a/N.EntityFrameworkCore.Extensions/Sql/SqlKeyword.cs b/N.EntityFrameworkCore.Extensions/Sql/SqlKeyword.cs index 9418968..3a68992 100644 --- a/N.EntityFrameworkCore.Extensions/Sql/SqlKeyword.cs +++ b/N.EntityFrameworkCore.Extensions/Sql/SqlKeyword.cs @@ -4,33 +4,32 @@ using System.Text; using System.Threading.Tasks; -namespace N.EntityFrameworkCore.Extensions.Sql +namespace N.EntityFrameworkCore.Extensions.Sql; + +public enum SqlKeyword { - public enum SqlKeyword - { - Select, - Delete, - Insert, - Values, - Update, - Set, - Merge, - Into, - From, - On, - Where, - Using, - When, - Then, - Matched, - Not, - Output, - As, - By, - Source, - Target, - Off, - Identity_Insert, - Semicolon, - } + Select, + Delete, + Insert, + Values, + Update, + Set, + Merge, + Into, + From, + On, + Where, + Using, + When, + Then, + Matched, + Not, + Output, + As, + By, + Source, + Target, + Off, + Identity_Insert, + Semicolon, } \ No newline at end of file diff --git a/N.EntityFrameworkCore.Extensions/Sql/SqlPart.cs b/N.EntityFrameworkCore.Extensions/Sql/SqlPart.cs index 0c1669e..79e3c80 100644 --- a/N.EntityFrameworkCore.Extensions/Sql/SqlPart.cs +++ b/N.EntityFrameworkCore.Extensions/Sql/SqlPart.cs @@ -7,20 +7,20 @@ using Microsoft.EntityFrameworkCore.Query.SqlExpressions; using Microsoft.Identity.Client; -namespace N.EntityFrameworkCore.Extensions.Sql +namespace N.EntityFrameworkCore.Extensions.Sql; + +internal class SqlPart { - internal class SqlPart + internal SqlKeyword Keyword { get; } + internal SqlExpression Expression { get; } + internal bool IgnoreOutput => GetIgnoreOutput(); + public SqlPart(SqlKeyword keyword, SqlExpression expression) { - internal SqlKeyword Keyword { get; } - internal SqlExpression Expression { get; } - internal bool IgnoreOutput => GetIgnoreOutput(); - public SqlPart(SqlKeyword keyword, SqlExpression expression) - { Keyword = keyword; Expression = expression; } - private bool GetIgnoreOutput() - { + private bool GetIgnoreOutput() + { if (Keyword == SqlKeyword.Output && (Expression == null || Expression.IsEmpty)) return true; else @@ -28,5 +28,4 @@ private bool GetIgnoreOutput() } - } } \ No newline at end of file diff --git a/N.EntityFrameworkCore.Extensions/Sql/SqlStatement.cs b/N.EntityFrameworkCore.Extensions/Sql/SqlStatement.cs index 5a22915..be63114 100644 --- a/N.EntityFrameworkCore.Extensions/Sql/SqlStatement.cs +++ b/N.EntityFrameworkCore.Extensions/Sql/SqlStatement.cs @@ -9,34 +9,34 @@ using N.EntityFrameworkCore.Extensions.Extensions; using N.EntityFrameworkCore.Extensions.Util; -namespace N.EntityFrameworkCore.Extensions.Sql +namespace N.EntityFrameworkCore.Extensions.Sql; + +internal class SqlStatement { - internal class SqlStatement + internal string Sql => ToSql(); + List SqlParts { get; } + SqlStatement() { - internal string Sql => ToSql(); - List SqlParts { get; } - SqlStatement() - { SqlParts = new List(); } - //static SqlStatement CreateSelectInto(TableMapping souceTableMapping, string targetTable, string[] columns) - //{ - // foreach(var property in souceTableMapping.Properties) - // { - // var t = property; - // } - // var statement = new SqlStatement(); - // statement.CreatePart(SqlKeyword.Select, SqlPartExpression.Columns("column1","column2")); - // statement.CreatePart(SqlKeyword.Into, SqlPartExpression.Table(targetTable)); - // statement.CreatePart(SqlKeyword.From, SqlPartExpression.Table("Table")); - // return null; - //} - internal void CreatePart(SqlKeyword keyword, SqlExpression expression = null) - { + //static SqlStatement CreateSelectInto(TableMapping souceTableMapping, string targetTable, string[] columns) + //{ + // foreach(var property in souceTableMapping.Properties) + // { + // var t = property; + // } + // var statement = new SqlStatement(); + // statement.CreatePart(SqlKeyword.Select, SqlPartExpression.Columns("column1","column2")); + // statement.CreatePart(SqlKeyword.Into, SqlPartExpression.Table(targetTable)); + // statement.CreatePart(SqlKeyword.From, SqlPartExpression.Table("Table")); + // return null; + //} + internal void CreatePart(SqlKeyword keyword, SqlExpression expression = null) + { SqlParts.Add(new SqlPart(keyword, expression)); } - internal void SetIdentityInsert(string tableName, bool enable) - { + internal void SetIdentityInsert(string tableName, bool enable) + { this.CreatePart(SqlKeyword.Set); this.CreatePart(SqlKeyword.Identity_Insert, SqlExpression.Table(tableName)); if (enable) @@ -45,15 +45,15 @@ internal void SetIdentityInsert(string tableName, bool enable) this.CreatePart(SqlKeyword.Off); this.CreatePart(SqlKeyword.Semicolon); } - //internal static SqlStatement CreateMergeInsert(string sourceTableName, string targetTableName, string mergeOnCondition, - // IEnumerable insertColumns, IEnumerable outputColumns, bool deleteIfNotMatched = false) - //{ + //internal static SqlStatement CreateMergeInsert(string sourceTableName, string targetTableName, string mergeOnCondition, + // IEnumerable insertColumns, IEnumerable outputColumns, bool deleteIfNotMatched = false) + //{ - //} - internal static SqlStatement CreateMerge(string sourceTableName, string targetTableName, string joinOnCondition, - IEnumerable insertColumns, IEnumerable updateColumns, IEnumerable outputColumns, - bool deleteIfNotMatched = false, bool hasIdentityColumn = false) - { + //} + internal static SqlStatement CreateMerge(string sourceTableName, string targetTableName, string joinOnCondition, + IEnumerable insertColumns, IEnumerable updateColumns, IEnumerable outputColumns, + bool deleteIfNotMatched = false, bool hasIdentityColumn = false) + { var statement = new SqlStatement(); if (hasIdentityColumn) statement.SetIdentityInsert(targetTableName, true); @@ -93,8 +93,8 @@ internal static SqlStatement CreateMerge(string sourceTableName, string targetTa return statement; } - private string ToSql() - { + private string ToSql() + { StringBuilder sbSql = new StringBuilder(); foreach (var part in SqlParts) { @@ -132,5 +132,4 @@ private string ToSql() //} return sbSql.ToString(); } - } } \ No newline at end of file diff --git a/N.EntityFrameworkCore.Extensions/Util/CommonUtil.cs b/N.EntityFrameworkCore.Extensions/Util/CommonUtil.cs index 0e2f55a..9b55466 100644 --- a/N.EntityFrameworkCore.Extensions/Util/CommonUtil.cs +++ b/N.EntityFrameworkCore.Extensions/Util/CommonUtil.cs @@ -6,12 +6,12 @@ using System.Text; using Microsoft.Data.SqlClient; -namespace N.EntityFrameworkCore.Extensions.Util +namespace N.EntityFrameworkCore.Extensions.Util; + +internal static class CommonUtil { - internal static class CommonUtil + internal static string GetStagingTableName(TableMapping tableMapping, bool usePermanentTable, SqlConnection sqlConnection) { - internal static string GetStagingTableName(TableMapping tableMapping, bool usePermanentTable, SqlConnection sqlConnection) - { string tableName = string.Empty; if (usePermanentTable) tableName = string.Format("[{0}].[tmp_be_xx_{1}_{2}]", tableMapping.Schema, tableMapping.TableName, sqlConnection.ClientConnectionId.ToString()); @@ -19,21 +19,21 @@ internal static string GetStagingTableName(TableMapping tableMapping, bool usePe tableName = string.Format("[{0}].[#tmp_be_xx_{1}]", tableMapping.Schema, tableMapping.TableName); return tableName; } - private static string FormatColumn(string column) - { + private static string FormatColumn(string column) + { var parts = column.Split('.'); return string.Join(".", parts.Select(p => p.StartsWith("$") || (p.StartsWith("[") && p.EndsWith("]")) ? p : $"[{p}]")); } - internal static IEnumerable FormatColumns(IEnumerable columns) - { + internal static IEnumerable FormatColumns(IEnumerable columns) + { return columns.Select(s => FormatColumn(s)); } - internal static IEnumerable FormatColumns(string tableAlias, IEnumerable columns) - { + internal static IEnumerable FormatColumns(string tableAlias, IEnumerable columns) + { return columns.Select(s => s.StartsWith("[") && s.EndsWith("]") ? string.Format("[{0}].{1}", tableAlias, s) : string.Format("[{0}].[{1}]", tableAlias, s)); } - internal static IEnumerable FilterColumns(IEnumerable columnNames, string[] primaryKeyColumnNames, Expression> inputColumns, Expression> ignoreColumns) - { + internal static IEnumerable FilterColumns(IEnumerable columnNames, string[] primaryKeyColumnNames, Expression> inputColumns, Expression> ignoreColumns) + { var filteredColumnNames = columnNames; if (inputColumns != null) { @@ -55,20 +55,20 @@ internal static IEnumerable FilterColumns(IEnumerable columnN return filteredColumnNames; } - internal static string FormatTableName(string tableName) - { + internal static string FormatTableName(string tableName) + { return string.Join(".", tableName.Split('.').Select(s => $"[{RemoveQualifier(s)}]")); } - private static string RemoveQualifier(string name) - { + private static string RemoveQualifier(string name) + { return name.TrimStart('[').TrimEnd(']'); } - } - internal static class CommonUtil +} +internal static class CommonUtil +{ + internal static string[] GetColumns(Expression> expression, string[] tableNames) { - internal static string[] GetColumns(Expression> expression, string[] tableNames) - { List foundColumns = new List(); string sqlText = (string)expression.Body.GetPrivateFieldValue("DebugView"); @@ -87,8 +87,8 @@ internal static string[] GetColumns(Expression> expression, str return foundColumns.ToArray(); } - internal static string GetJoinConditionSql(Expression> joinKeyExpression, string[] storeGeneratedColumnNames, string sourceTableName = "s", string targetTableName = "t") - { + internal static string GetJoinConditionSql(Expression> joinKeyExpression, string[] storeGeneratedColumnNames, string sourceTableName = "s", string targetTableName = "t") + { string joinConditionSql = string.Empty; if (joinKeyExpression != null) { @@ -105,5 +105,4 @@ internal static string GetJoinConditionSql(Expression> joinKeyE } return joinConditionSql; } - } } \ No newline at end of file diff --git a/N.EntityFrameworkCore.Extensions/Util/SqlUtil.cs b/N.EntityFrameworkCore.Extensions/Util/SqlUtil.cs index 4863d7a..ebc8a65 100644 --- a/N.EntityFrameworkCore.Extensions/Util/SqlUtil.cs +++ b/N.EntityFrameworkCore.Extensions/Util/SqlUtil.cs @@ -6,13 +6,12 @@ using Microsoft.Data.SqlClient; using N.EntityFrameworkCore.Extensions.Util; -namespace N.EntityFrameworkCore.Extensions +namespace N.EntityFrameworkCore.Extensions; + +internal static class SqlUtil { - internal static class SqlUtil + internal static string ConvertToColumnString(IEnumerable columnNames) { - internal static string ConvertToColumnString(IEnumerable columnNames) - { - return string.Join(",", columnNames); - } + return string.Join(",", columnNames); } } \ No newline at end of file From bd62c2b3e4cd829e9ac80c0c3ddb692d7e1a876f Mon Sep 17 00:00:00 2001 From: Rikard Andersson Date: Tue, 11 Jun 2024 20:57:53 +0200 Subject: [PATCH 3/4] Ignore rider auto generated files --- .gitignore | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/.gitignore b/.gitignore index 3e16852..a5b0bb9 100644 --- a/.gitignore +++ b/.gitignore @@ -1,3 +1,4 @@ bin/ obj/ -.vs/ \ No newline at end of file +.vs/ +/.idea/.idea** From 055e1c6666187f1c3764169c22460fb51b2a62d2 Mon Sep 17 00:00:00 2001 From: Rikard Andersson Date: Wed, 12 Jun 2024 20:51:10 +0200 Subject: [PATCH 4/4] Remove unused usings --- .editorconfig | 2 +- .../Common/Config.cs | 5 +---- .../Data/Enums/ProductStatus.cs | 8 +------- .../Data/Position.cs | 8 +------- N.EntityFrameworkCore.Extensions.Test/Data/Product.cs | 2 -- .../Data/ProductCategory.cs | 10 +--------- .../Data/ProductWithComplexKey.cs | 4 ---- .../Data/ProductWithCustomSchema.cs | 6 +----- .../Data/ProductWithTrigger.cs | 6 +----- .../Data/TestDbContext.cs | 3 --- .../DatabaseExtensions/DatabaseExtensionsBase.cs | 3 --- .../DatabaseExtensions/SqlQueryToCsvFile.cs | 6 +----- .../DatabaseExtensions/SqlQueryToCsvFileAsync.cs | 5 +---- .../DatabaseExtensions/TableExists.cs | 6 +----- .../DatabaseExtensions/TruncateTable.cs | 6 +----- .../DatabaseExtensions/TruncateTableAsync.cs | 5 +---- .../DbContextExtensions/BulkDelete.cs | 1 - .../DbContextExtensions/BulkFetch.cs | 6 +----- .../DbContextExtensions/BulkSaveChanges.cs | 3 --- .../DbContextExtensions/BulkSaveChangesAsync.cs | 1 - .../DbContextExtensions/BulkUpdate.cs | 5 +---- .../DbContextExtensions/BulkUpdateAsync.cs | 4 +--- .../DbContextExtensions/DbContextExtensionsBase.cs | 1 - .../DbContextExtensions/DeleteFromQuery.cs | 1 - .../DbContextExtensions/DeleteFromQueryAsync.cs | 1 - .../DbContextExtensions/InsertFromQueryAsync.cs | 1 - .../DbContextExtensions/UpdateFromQuery.cs | 1 - .../DbSetExtensions/Clear.cs | 1 - .../DbSetExtensions/ClearAsync.cs | 1 - .../DbSetExtensions/Truncate.cs | 1 - .../DbSetExtensions/TruncateAsync.cs | 1 - N.EntityFrameworkCore.Extensions/Common/Constants.cs | 8 +------- .../Data/BulkFetchOptions.cs | 5 ----- .../Data/BulkInsertOptions.cs | 1 - .../Data/BulkInsertResult.cs | 3 +-- .../Data/BulkMergeResult.cs | 1 - .../Data/BulkOperation.cs | 10 ---------- N.EntityFrameworkCore.Extensions/Data/BulkOptions.cs | 7 +------ .../Data/DatabaseFacadeExtensions.cs | 3 --- .../Data/DatabaseFacadeExtensionsAsync.cs | 3 +-- .../Data/DbContextExtensions.cs | 11 ----------- .../Data/DbContextExtensionsAsync.cs | 4 ---- .../Data/EfExtensionsCommandInterceptor.cs | 2 -- .../Data/EntityDataReader.cs | 7 ------- N.EntityFrameworkCore.Extensions/Data/FetchOptions.cs | 4 ---- N.EntityFrameworkCore.Extensions/Data/FetchResult.cs | 3 +-- .../Data/QueryToFileOptions.cs | 6 +----- .../Data/QueryToFileResult.cs | 6 +----- .../Data/SqlMergeAction.cs | 8 +------- N.EntityFrameworkCore.Extensions/Data/TableMapping.cs | 2 -- .../Enums/ConnectionBehavior.cs | 8 +------- .../Enums/EfExtensionsCommandType.cs | 8 +------- .../Extensions/CommonExtensions.cs | 2 -- .../Extensions/DbDataReaderExtensions.cs | 6 ------ .../Extensions/IPropertyExtensions.cs | 9 +-------- .../Extensions/LinqExtensions.cs | 4 ---- .../Extensions/ObjectExtensions.cs | 1 - .../Extensions/SqlStatementExtensions.cs | 6 +----- N.EntityFrameworkCore.Extensions/Sql/SqlClause.cs | 8 +------- N.EntityFrameworkCore.Extensions/Sql/SqlExpression.cs | 8 +------- N.EntityFrameworkCore.Extensions/Sql/SqlKeyword.cs | 8 +------- N.EntityFrameworkCore.Extensions/Sql/SqlPart.cs | 11 +---------- N.EntityFrameworkCore.Extensions/Sql/SqlStatement.cs | 8 +------- N.EntityFrameworkCore.Extensions/Util/CommonUtil.cs | 1 - N.EntityFrameworkCore.Extensions/Util/SqlUtil.cs | 8 +------- 65 files changed, 33 insertions(+), 271 deletions(-) diff --git a/.editorconfig b/.editorconfig index 99aa104..69b7d5c 100644 --- a/.editorconfig +++ b/.editorconfig @@ -112,7 +112,7 @@ csharp_style_prefer_readonly_struct_member = true # Code-block preferences csharp_prefer_braces = true csharp_prefer_simple_using_statement = true -csharp_style_namespace_declarations = block_scoped +csharp_style_namespace_declarations = file_scoped csharp_style_prefer_method_group_conversion = true csharp_style_prefer_primary_constructors = true csharp_style_prefer_top_level_statements = true diff --git a/N.EntityFrameworkCore.Extensions.Test/Common/Config.cs b/N.EntityFrameworkCore.Extensions.Test/Common/Config.cs index 9c35b08..94b61d8 100644 --- a/N.EntityFrameworkCore.Extensions.Test/Common/Config.cs +++ b/N.EntityFrameworkCore.Extensions.Test/Common/Config.cs @@ -1,7 +1,4 @@ -using System; -using System.Collections.Generic; -using System.Text; -using Microsoft.Extensions.Configuration; +using Microsoft.Extensions.Configuration; namespace N.EntityFrameworkCore.Extensions.Test.Common; diff --git a/N.EntityFrameworkCore.Extensions.Test/Data/Enums/ProductStatus.cs b/N.EntityFrameworkCore.Extensions.Test/Data/Enums/ProductStatus.cs index e3b5c8c..91a250d 100644 --- a/N.EntityFrameworkCore.Extensions.Test/Data/Enums/ProductStatus.cs +++ b/N.EntityFrameworkCore.Extensions.Test/Data/Enums/ProductStatus.cs @@ -1,10 +1,4 @@ -using System; -using System.Collections.Generic; -using System.Linq; -using System.Text; -using System.Threading.Tasks; - -namespace N.EntityFrameworkCore.Extensions.Test.Data.Enums; +namespace N.EntityFrameworkCore.Extensions.Test.Data.Enums; public enum ProductStatus { diff --git a/N.EntityFrameworkCore.Extensions.Test/Data/Position.cs b/N.EntityFrameworkCore.Extensions.Test/Data/Position.cs index d4c162c..95ec3e4 100644 --- a/N.EntityFrameworkCore.Extensions.Test/Data/Position.cs +++ b/N.EntityFrameworkCore.Extensions.Test/Data/Position.cs @@ -1,10 +1,4 @@ -using System; -using System.Collections.Generic; -using System.Linq; -using System.Text; -using System.Threading.Tasks; - -namespace N.EntityFrameworkCore.Extensions.Test.Data; +namespace N.EntityFrameworkCore.Extensions.Test.Data; public class Position { diff --git a/N.EntityFrameworkCore.Extensions.Test/Data/Product.cs b/N.EntityFrameworkCore.Extensions.Test/Data/Product.cs index 384d185..84fcc0f 100644 --- a/N.EntityFrameworkCore.Extensions.Test/Data/Product.cs +++ b/N.EntityFrameworkCore.Extensions.Test/Data/Product.cs @@ -1,8 +1,6 @@ using System; -using System.Collections.Generic; using System.ComponentModel.DataAnnotations; using System.ComponentModel.DataAnnotations.Schema; -using System.Text; using N.EntityFrameworkCore.Extensions.Test.Data.Enums; namespace N.EntityFrameworkCore.Extensions.Test.Data; diff --git a/N.EntityFrameworkCore.Extensions.Test/Data/ProductCategory.cs b/N.EntityFrameworkCore.Extensions.Test/Data/ProductCategory.cs index 83bd84d..168263b 100644 --- a/N.EntityFrameworkCore.Extensions.Test/Data/ProductCategory.cs +++ b/N.EntityFrameworkCore.Extensions.Test/Data/ProductCategory.cs @@ -1,12 +1,4 @@ -using System; -using System.Collections.Generic; -using System.Linq; -using System.Text; -using System.Threading.Tasks; -using Microsoft.VisualStudio.TestTools.UnitTesting; -using N.EntityFrameworkCore.Extensions.Test.Data.Enums; - -namespace N.EntityFrameworkCore.Extensions.Test.Data; +namespace N.EntityFrameworkCore.Extensions.Test.Data; public class ProductCategory { diff --git a/N.EntityFrameworkCore.Extensions.Test/Data/ProductWithComplexKey.cs b/N.EntityFrameworkCore.Extensions.Test/Data/ProductWithComplexKey.cs index 12ef54b..d7ebe4e 100644 --- a/N.EntityFrameworkCore.Extensions.Test/Data/ProductWithComplexKey.cs +++ b/N.EntityFrameworkCore.Extensions.Test/Data/ProductWithComplexKey.cs @@ -1,10 +1,6 @@ using System; -using System.Collections.Generic; using System.ComponentModel.DataAnnotations; using System.ComponentModel.DataAnnotations.Schema; -using System.Linq; -using System.Text; -using System.Threading.Tasks; namespace N.EntityFrameworkCore.Extensions.Test.Data; diff --git a/N.EntityFrameworkCore.Extensions.Test/Data/ProductWithCustomSchema.cs b/N.EntityFrameworkCore.Extensions.Test/Data/ProductWithCustomSchema.cs index a9306a5..dead561 100644 --- a/N.EntityFrameworkCore.Extensions.Test/Data/ProductWithCustomSchema.cs +++ b/N.EntityFrameworkCore.Extensions.Test/Data/ProductWithCustomSchema.cs @@ -1,9 +1,5 @@ -using System; -using System.Collections.Generic; -using System.ComponentModel.DataAnnotations; +using System.ComponentModel.DataAnnotations; using System.ComponentModel.DataAnnotations.Schema; -using System.Text; -using N.EntityFrameworkCore.Extensions.Test.Data.Enums; namespace N.EntityFrameworkCore.Extensions.Test.Data; diff --git a/N.EntityFrameworkCore.Extensions.Test/Data/ProductWithTrigger.cs b/N.EntityFrameworkCore.Extensions.Test/Data/ProductWithTrigger.cs index 137b8b9..d3c9302 100644 --- a/N.EntityFrameworkCore.Extensions.Test/Data/ProductWithTrigger.cs +++ b/N.EntityFrameworkCore.Extensions.Test/Data/ProductWithTrigger.cs @@ -1,9 +1,5 @@ -using System; -using System.Collections.Generic; -using System.ComponentModel.DataAnnotations; +using System.ComponentModel.DataAnnotations; using System.ComponentModel.DataAnnotations.Schema; -using System.Text; -using N.EntityFrameworkCore.Extensions.Test.Data.Enums; namespace N.EntityFrameworkCore.Extensions.Test.Data; diff --git a/N.EntityFrameworkCore.Extensions.Test/Data/TestDbContext.cs b/N.EntityFrameworkCore.Extensions.Test/Data/TestDbContext.cs index 4299def..cfb22a1 100644 --- a/N.EntityFrameworkCore.Extensions.Test/Data/TestDbContext.cs +++ b/N.EntityFrameworkCore.Extensions.Test/Data/TestDbContext.cs @@ -1,8 +1,5 @@ using System; -using System.ComponentModel.DataAnnotations.Schema; using System.Drawing; -using System.Reflection.Metadata; -using System.Runtime.ConstrainedExecution; using Microsoft.EntityFrameworkCore; using N.EntityFrameworkCore.Extensions.Test.Common; diff --git a/N.EntityFrameworkCore.Extensions.Test/DatabaseExtensions/DatabaseExtensionsBase.cs b/N.EntityFrameworkCore.Extensions.Test/DatabaseExtensions/DatabaseExtensionsBase.cs index 9831c8e..4cb3506 100644 --- a/N.EntityFrameworkCore.Extensions.Test/DatabaseExtensions/DatabaseExtensionsBase.cs +++ b/N.EntityFrameworkCore.Extensions.Test/DatabaseExtensions/DatabaseExtensionsBase.cs @@ -1,9 +1,6 @@ using System; using System.Collections.Generic; using System.Diagnostics; -using System.Linq; -using System.Text; -using System.Threading.Tasks; using N.EntityFrameworkCore.Extensions.Test.Data; namespace N.EntityFrameworkCore.Extensions.Test.DatabaseExtensions; diff --git a/N.EntityFrameworkCore.Extensions.Test/DatabaseExtensions/SqlQueryToCsvFile.cs b/N.EntityFrameworkCore.Extensions.Test/DatabaseExtensions/SqlQueryToCsvFile.cs index 2817d71..89dad2f 100644 --- a/N.EntityFrameworkCore.Extensions.Test/DatabaseExtensions/SqlQueryToCsvFile.cs +++ b/N.EntityFrameworkCore.Extensions.Test/DatabaseExtensions/SqlQueryToCsvFile.cs @@ -1,8 +1,4 @@ -using System; -using System.Collections.Generic; -using System.Linq; -using System.Text; -using System.Threading.Tasks; +using System.Linq; using Microsoft.Data.SqlClient; using Microsoft.VisualStudio.TestTools.UnitTesting; diff --git a/N.EntityFrameworkCore.Extensions.Test/DatabaseExtensions/SqlQueryToCsvFileAsync.cs b/N.EntityFrameworkCore.Extensions.Test/DatabaseExtensions/SqlQueryToCsvFileAsync.cs index faf8dac..1cd6cec 100644 --- a/N.EntityFrameworkCore.Extensions.Test/DatabaseExtensions/SqlQueryToCsvFileAsync.cs +++ b/N.EntityFrameworkCore.Extensions.Test/DatabaseExtensions/SqlQueryToCsvFileAsync.cs @@ -1,7 +1,4 @@ -using System; -using System.Collections.Generic; -using System.Linq; -using System.Text; +using System.Linq; using System.Threading.Tasks; using Microsoft.Data.SqlClient; using Microsoft.VisualStudio.TestTools.UnitTesting; diff --git a/N.EntityFrameworkCore.Extensions.Test/DatabaseExtensions/TableExists.cs b/N.EntityFrameworkCore.Extensions.Test/DatabaseExtensions/TableExists.cs index 878b142..d7aac54 100644 --- a/N.EntityFrameworkCore.Extensions.Test/DatabaseExtensions/TableExists.cs +++ b/N.EntityFrameworkCore.Extensions.Test/DatabaseExtensions/TableExists.cs @@ -1,8 +1,4 @@ -using System; -using System.Collections.Generic; -using System.Linq; -using System.Text; -using System.Threading.Tasks; +using System.Linq; using Microsoft.VisualStudio.TestTools.UnitTesting; namespace N.EntityFrameworkCore.Extensions.Test.DatabaseExtensions; diff --git a/N.EntityFrameworkCore.Extensions.Test/DatabaseExtensions/TruncateTable.cs b/N.EntityFrameworkCore.Extensions.Test/DatabaseExtensions/TruncateTable.cs index c9cdcd7..b1e3e52 100644 --- a/N.EntityFrameworkCore.Extensions.Test/DatabaseExtensions/TruncateTable.cs +++ b/N.EntityFrameworkCore.Extensions.Test/DatabaseExtensions/TruncateTable.cs @@ -1,8 +1,4 @@ -using System; -using System.Collections.Generic; -using System.Linq; -using System.Text; -using System.Threading.Tasks; +using System.Linq; using Microsoft.VisualStudio.TestTools.UnitTesting; namespace N.EntityFrameworkCore.Extensions.Test.DatabaseExtensions; diff --git a/N.EntityFrameworkCore.Extensions.Test/DatabaseExtensions/TruncateTableAsync.cs b/N.EntityFrameworkCore.Extensions.Test/DatabaseExtensions/TruncateTableAsync.cs index 3e9d674..d5f2dee 100644 --- a/N.EntityFrameworkCore.Extensions.Test/DatabaseExtensions/TruncateTableAsync.cs +++ b/N.EntityFrameworkCore.Extensions.Test/DatabaseExtensions/TruncateTableAsync.cs @@ -1,7 +1,4 @@ -using System; -using System.Collections.Generic; -using System.Linq; -using System.Text; +using System.Linq; using System.Threading.Tasks; using Microsoft.VisualStudio.TestTools.UnitTesting; diff --git a/N.EntityFrameworkCore.Extensions.Test/DbContextExtensions/BulkDelete.cs b/N.EntityFrameworkCore.Extensions.Test/DbContextExtensions/BulkDelete.cs index 82412dc..ca13154 100644 --- a/N.EntityFrameworkCore.Extensions.Test/DbContextExtensions/BulkDelete.cs +++ b/N.EntityFrameworkCore.Extensions.Test/DbContextExtensions/BulkDelete.cs @@ -1,5 +1,4 @@ using System.Linq; -using System.Threading.Tasks; using Microsoft.VisualStudio.TestTools.UnitTesting; using N.EntityFrameworkCore.Extensions.Test.Data; diff --git a/N.EntityFrameworkCore.Extensions.Test/DbContextExtensions/BulkFetch.cs b/N.EntityFrameworkCore.Extensions.Test/DbContextExtensions/BulkFetch.cs index 9b4d300..fe34879 100644 --- a/N.EntityFrameworkCore.Extensions.Test/DbContextExtensions/BulkFetch.cs +++ b/N.EntityFrameworkCore.Extensions.Test/DbContextExtensions/BulkFetch.cs @@ -1,8 +1,4 @@ -using System; -using System.Collections.Generic; -using System.Linq; -using System.Text; -using System.Threading.Tasks; +using System.Linq; using Microsoft.VisualStudio.TestTools.UnitTesting; namespace N.EntityFrameworkCore.Extensions.Test.DbContextExtensions; diff --git a/N.EntityFrameworkCore.Extensions.Test/DbContextExtensions/BulkSaveChanges.cs b/N.EntityFrameworkCore.Extensions.Test/DbContextExtensions/BulkSaveChanges.cs index c290166..19562ea 100644 --- a/N.EntityFrameworkCore.Extensions.Test/DbContextExtensions/BulkSaveChanges.cs +++ b/N.EntityFrameworkCore.Extensions.Test/DbContextExtensions/BulkSaveChanges.cs @@ -1,9 +1,6 @@ using System; using System.Collections.Generic; using System.Linq; -using System.Text; -using System.Threading.Tasks; -using System.Threading.Tasks.Dataflow; using Microsoft.VisualStudio.TestTools.UnitTesting; using N.EntityFrameworkCore.Extensions.Test.Data; diff --git a/N.EntityFrameworkCore.Extensions.Test/DbContextExtensions/BulkSaveChangesAsync.cs b/N.EntityFrameworkCore.Extensions.Test/DbContextExtensions/BulkSaveChangesAsync.cs index 713deea..9bb39b9 100644 --- a/N.EntityFrameworkCore.Extensions.Test/DbContextExtensions/BulkSaveChangesAsync.cs +++ b/N.EntityFrameworkCore.Extensions.Test/DbContextExtensions/BulkSaveChangesAsync.cs @@ -1,7 +1,6 @@ using System; using System.Collections.Generic; using System.Linq; -using System.Text; using System.Threading.Tasks; using Microsoft.EntityFrameworkCore; using Microsoft.VisualStudio.TestTools.UnitTesting; diff --git a/N.EntityFrameworkCore.Extensions.Test/DbContextExtensions/BulkUpdate.cs b/N.EntityFrameworkCore.Extensions.Test/DbContextExtensions/BulkUpdate.cs index fbcd228..20481e8 100644 --- a/N.EntityFrameworkCore.Extensions.Test/DbContextExtensions/BulkUpdate.cs +++ b/N.EntityFrameworkCore.Extensions.Test/DbContextExtensions/BulkUpdate.cs @@ -1,8 +1,5 @@ -using System; -using System.Collections.Generic; -using System.Linq; +using System.Linq; using Microsoft.EntityFrameworkCore; -using Microsoft.Extensions.Options; using Microsoft.VisualStudio.TestTools.UnitTesting; using N.EntityFrameworkCore.Extensions.Test.Data; diff --git a/N.EntityFrameworkCore.Extensions.Test/DbContextExtensions/BulkUpdateAsync.cs b/N.EntityFrameworkCore.Extensions.Test/DbContextExtensions/BulkUpdateAsync.cs index 2db7a94..054c67b 100644 --- a/N.EntityFrameworkCore.Extensions.Test/DbContextExtensions/BulkUpdateAsync.cs +++ b/N.EntityFrameworkCore.Extensions.Test/DbContextExtensions/BulkUpdateAsync.cs @@ -1,6 +1,4 @@ -using System; -using System.Collections.Generic; -using System.Linq; +using System.Linq; using System.Threading.Tasks; using Microsoft.EntityFrameworkCore; using Microsoft.VisualStudio.TestTools.UnitTesting; diff --git a/N.EntityFrameworkCore.Extensions.Test/DbContextExtensions/DbContextExtensionsBase.cs b/N.EntityFrameworkCore.Extensions.Test/DbContextExtensions/DbContextExtensionsBase.cs index a34be60..169fcf8 100644 --- a/N.EntityFrameworkCore.Extensions.Test/DbContextExtensions/DbContextExtensionsBase.cs +++ b/N.EntityFrameworkCore.Extensions.Test/DbContextExtensions/DbContextExtensionsBase.cs @@ -2,7 +2,6 @@ using System.Collections.Generic; using System.Diagnostics; using System.Drawing; -using System.Linq; using Microsoft.VisualStudio.TestTools.UnitTesting; using N.EntityFrameworkCore.Extensions.Test.Data; using N.EntityFrameworkCore.Extensions.Test.Data.Enums; diff --git a/N.EntityFrameworkCore.Extensions.Test/DbContextExtensions/DeleteFromQuery.cs b/N.EntityFrameworkCore.Extensions.Test/DbContextExtensions/DeleteFromQuery.cs index 86514d9..0b95e62 100644 --- a/N.EntityFrameworkCore.Extensions.Test/DbContextExtensions/DeleteFromQuery.cs +++ b/N.EntityFrameworkCore.Extensions.Test/DbContextExtensions/DeleteFromQuery.cs @@ -1,6 +1,5 @@ using System; using System.Linq; -using System.Threading.Tasks; using Microsoft.VisualStudio.TestTools.UnitTesting; namespace N.EntityFrameworkCore.Extensions.Test.DbContextExtensions; diff --git a/N.EntityFrameworkCore.Extensions.Test/DbContextExtensions/DeleteFromQueryAsync.cs b/N.EntityFrameworkCore.Extensions.Test/DbContextExtensions/DeleteFromQueryAsync.cs index 81505c2..11b88ce 100644 --- a/N.EntityFrameworkCore.Extensions.Test/DbContextExtensions/DeleteFromQueryAsync.cs +++ b/N.EntityFrameworkCore.Extensions.Test/DbContextExtensions/DeleteFromQueryAsync.cs @@ -1,6 +1,5 @@ using System; using System.Linq; -using System.Runtime.CompilerServices; using System.Threading.Tasks; using Microsoft.VisualStudio.TestTools.UnitTesting; diff --git a/N.EntityFrameworkCore.Extensions.Test/DbContextExtensions/InsertFromQueryAsync.cs b/N.EntityFrameworkCore.Extensions.Test/DbContextExtensions/InsertFromQueryAsync.cs index 7c7071a..bd83fcf 100644 --- a/N.EntityFrameworkCore.Extensions.Test/DbContextExtensions/InsertFromQueryAsync.cs +++ b/N.EntityFrameworkCore.Extensions.Test/DbContextExtensions/InsertFromQueryAsync.cs @@ -1,7 +1,6 @@ using System; using System.Linq; using System.Threading.Tasks; -using Microsoft.EntityFrameworkCore; using Microsoft.VisualStudio.TestTools.UnitTesting; namespace N.EntityFrameworkCore.Extensions.Test.DbContextExtensions; diff --git a/N.EntityFrameworkCore.Extensions.Test/DbContextExtensions/UpdateFromQuery.cs b/N.EntityFrameworkCore.Extensions.Test/DbContextExtensions/UpdateFromQuery.cs index b278b62..ab9006e 100644 --- a/N.EntityFrameworkCore.Extensions.Test/DbContextExtensions/UpdateFromQuery.cs +++ b/N.EntityFrameworkCore.Extensions.Test/DbContextExtensions/UpdateFromQuery.cs @@ -3,7 +3,6 @@ using System.Globalization; using System.Linq; using System.Threading; -using System.Threading.Tasks; using Microsoft.VisualStudio.TestTools.UnitTesting; using N.EntityFrameworkCore.Extensions.Test.Data; using N.EntityFrameworkCore.Extensions.Test.Data.Enums; diff --git a/N.EntityFrameworkCore.Extensions.Test/DbSetExtensions/Clear.cs b/N.EntityFrameworkCore.Extensions.Test/DbSetExtensions/Clear.cs index 91e8537..998cf97 100644 --- a/N.EntityFrameworkCore.Extensions.Test/DbSetExtensions/Clear.cs +++ b/N.EntityFrameworkCore.Extensions.Test/DbSetExtensions/Clear.cs @@ -1,6 +1,5 @@ using System.Linq; using Microsoft.VisualStudio.TestTools.UnitTesting; -using N.EntityFrameworkCore.Extensions.Test.Data; using N.EntityFrameworkCore.Extensions.Test.DbContextExtensions; namespace N.EntityFrameworkCore.Extensions.Test.DbSetExtensions; diff --git a/N.EntityFrameworkCore.Extensions.Test/DbSetExtensions/ClearAsync.cs b/N.EntityFrameworkCore.Extensions.Test/DbSetExtensions/ClearAsync.cs index 6cb0097..ee209c7 100644 --- a/N.EntityFrameworkCore.Extensions.Test/DbSetExtensions/ClearAsync.cs +++ b/N.EntityFrameworkCore.Extensions.Test/DbSetExtensions/ClearAsync.cs @@ -1,7 +1,6 @@ using System.Linq; using System.Threading.Tasks; using Microsoft.VisualStudio.TestTools.UnitTesting; -using N.EntityFrameworkCore.Extensions.Test.Data; using N.EntityFrameworkCore.Extensions.Test.DbContextExtensions; namespace N.EntityFrameworkCore.Extensions.Test.DbSetExtensions; diff --git a/N.EntityFrameworkCore.Extensions.Test/DbSetExtensions/Truncate.cs b/N.EntityFrameworkCore.Extensions.Test/DbSetExtensions/Truncate.cs index de0a871..03b999e 100644 --- a/N.EntityFrameworkCore.Extensions.Test/DbSetExtensions/Truncate.cs +++ b/N.EntityFrameworkCore.Extensions.Test/DbSetExtensions/Truncate.cs @@ -1,6 +1,5 @@ using System.Linq; using Microsoft.VisualStudio.TestTools.UnitTesting; -using N.EntityFrameworkCore.Extensions.Test.Data; using N.EntityFrameworkCore.Extensions.Test.DbContextExtensions; namespace N.EntityFrameworkCore.Extensions.Test.DbSetExtensions; diff --git a/N.EntityFrameworkCore.Extensions.Test/DbSetExtensions/TruncateAsync.cs b/N.EntityFrameworkCore.Extensions.Test/DbSetExtensions/TruncateAsync.cs index 6daf4ff..838547e 100644 --- a/N.EntityFrameworkCore.Extensions.Test/DbSetExtensions/TruncateAsync.cs +++ b/N.EntityFrameworkCore.Extensions.Test/DbSetExtensions/TruncateAsync.cs @@ -1,7 +1,6 @@ using System.Linq; using System.Threading.Tasks; using Microsoft.VisualStudio.TestTools.UnitTesting; -using N.EntityFrameworkCore.Extensions.Test.Data; using N.EntityFrameworkCore.Extensions.Test.DbContextExtensions; namespace N.EntityFrameworkCore.Extensions.Test.DbSetExtensions; diff --git a/N.EntityFrameworkCore.Extensions/Common/Constants.cs b/N.EntityFrameworkCore.Extensions/Common/Constants.cs index 0c1864d..6e4eb17 100644 --- a/N.EntityFrameworkCore.Extensions/Common/Constants.cs +++ b/N.EntityFrameworkCore.Extensions/Common/Constants.cs @@ -1,10 +1,4 @@ -using System; -using System.Collections.Generic; -using System.Linq; -using System.Text; -using System.Threading.Tasks; - -namespace N.EntityFrameworkCore.Extensions.Common; +namespace N.EntityFrameworkCore.Extensions.Common; public static class Constants { diff --git a/N.EntityFrameworkCore.Extensions/Data/BulkFetchOptions.cs b/N.EntityFrameworkCore.Extensions/Data/BulkFetchOptions.cs index a68c181..60bbdec 100644 --- a/N.EntityFrameworkCore.Extensions/Data/BulkFetchOptions.cs +++ b/N.EntityFrameworkCore.Extensions/Data/BulkFetchOptions.cs @@ -1,10 +1,5 @@ using System; -using System.Collections.Generic; -using System.Linq; using System.Linq.Expressions; -using System.Text; -using System.Threading.Tasks; -using N.EntityFrameworkCore.Extensions.Enums; namespace N.EntityFrameworkCore.Extensions; diff --git a/N.EntityFrameworkCore.Extensions/Data/BulkInsertOptions.cs b/N.EntityFrameworkCore.Extensions/Data/BulkInsertOptions.cs index df9f89d..445e462 100644 --- a/N.EntityFrameworkCore.Extensions/Data/BulkInsertOptions.cs +++ b/N.EntityFrameworkCore.Extensions/Data/BulkInsertOptions.cs @@ -1,5 +1,4 @@ using System; -using System.Collections.Generic; using System.Linq; using System.Linq.Expressions; diff --git a/N.EntityFrameworkCore.Extensions/Data/BulkInsertResult.cs b/N.EntityFrameworkCore.Extensions/Data/BulkInsertResult.cs index 13a24a4..cf64815 100644 --- a/N.EntityFrameworkCore.Extensions/Data/BulkInsertResult.cs +++ b/N.EntityFrameworkCore.Extensions/Data/BulkInsertResult.cs @@ -1,5 +1,4 @@ -using System; -using System.Collections.Generic; +using System.Collections.Generic; namespace N.EntityFrameworkCore.Extensions; diff --git a/N.EntityFrameworkCore.Extensions/Data/BulkMergeResult.cs b/N.EntityFrameworkCore.Extensions/Data/BulkMergeResult.cs index 6e18d09..b28592e 100644 --- a/N.EntityFrameworkCore.Extensions/Data/BulkMergeResult.cs +++ b/N.EntityFrameworkCore.Extensions/Data/BulkMergeResult.cs @@ -1,5 +1,4 @@ using System.Collections.Generic; -using Microsoft.EntityFrameworkCore.Metadata.Internal; namespace N.EntityFrameworkCore.Extensions; diff --git a/N.EntityFrameworkCore.Extensions/Data/BulkOperation.cs b/N.EntityFrameworkCore.Extensions/Data/BulkOperation.cs index 325b196..042ad51 100644 --- a/N.EntityFrameworkCore.Extensions/Data/BulkOperation.cs +++ b/N.EntityFrameworkCore.Extensions/Data/BulkOperation.cs @@ -1,24 +1,14 @@ using System; -using System.Collections; using System.Collections.Generic; -using System.ComponentModel.Design; -using System.Data; -using System.Data.Common; using System.IO; using System.Linq; using System.Linq.Expressions; -using System.Reflection; -using System.Transactions; using Microsoft.Data.SqlClient; using Microsoft.EntityFrameworkCore; using Microsoft.EntityFrameworkCore.Metadata; -using Microsoft.EntityFrameworkCore.Metadata.Conventions; -using Microsoft.EntityFrameworkCore.Metadata.Internal; -using Microsoft.Extensions.Options; using N.EntityFrameworkCore.Extensions.Common; using N.EntityFrameworkCore.Extensions.Sql; using N.EntityFrameworkCore.Extensions.Util; -using static Microsoft.EntityFrameworkCore.DbLoggerCategory.Database; namespace N.EntityFrameworkCore.Extensions; diff --git a/N.EntityFrameworkCore.Extensions/Data/BulkOptions.cs b/N.EntityFrameworkCore.Extensions/Data/BulkOptions.cs index 1b51b85..d51e903 100644 --- a/N.EntityFrameworkCore.Extensions/Data/BulkOptions.cs +++ b/N.EntityFrameworkCore.Extensions/Data/BulkOptions.cs @@ -1,9 +1,4 @@ -using System; -using System.Collections.Generic; -using System.Linq; -using System.Text; -using System.Threading.Tasks; -using Microsoft.Data.SqlClient; +using Microsoft.Data.SqlClient; using Microsoft.EntityFrameworkCore.Metadata; using N.EntityFrameworkCore.Extensions.Enums; diff --git a/N.EntityFrameworkCore.Extensions/Data/DatabaseFacadeExtensions.cs b/N.EntityFrameworkCore.Extensions/Data/DatabaseFacadeExtensions.cs index 29ab5d4..6194c3f 100644 --- a/N.EntityFrameworkCore.Extensions/Data/DatabaseFacadeExtensions.cs +++ b/N.EntityFrameworkCore.Extensions/Data/DatabaseFacadeExtensions.cs @@ -3,12 +3,9 @@ using System.Data; using System.Data.Common; using System.Linq; -using System.Threading.Tasks; -using System.Transactions; using Microsoft.Data.SqlClient; using Microsoft.EntityFrameworkCore; using Microsoft.EntityFrameworkCore.Infrastructure; -using Microsoft.EntityFrameworkCore.Scaffolding.Metadata; using Microsoft.EntityFrameworkCore.Storage; using N.EntityFrameworkCore.Extensions.Enums; using N.EntityFrameworkCore.Extensions.Util; diff --git a/N.EntityFrameworkCore.Extensions/Data/DatabaseFacadeExtensionsAsync.cs b/N.EntityFrameworkCore.Extensions/Data/DatabaseFacadeExtensionsAsync.cs index 4c9a4ce..e4de828 100644 --- a/N.EntityFrameworkCore.Extensions/Data/DatabaseFacadeExtensionsAsync.cs +++ b/N.EntityFrameworkCore.Extensions/Data/DatabaseFacadeExtensionsAsync.cs @@ -1,5 +1,4 @@ -using System; -using System.Collections.Generic; +using System.Collections.Generic; using System.Data; using System.Linq; using System.Threading; diff --git a/N.EntityFrameworkCore.Extensions/Data/DbContextExtensions.cs b/N.EntityFrameworkCore.Extensions/Data/DbContextExtensions.cs index fbe69c5..255f9f6 100644 --- a/N.EntityFrameworkCore.Extensions/Data/DbContextExtensions.cs +++ b/N.EntityFrameworkCore.Extensions/Data/DbContextExtensions.cs @@ -1,33 +1,22 @@ using System; using System.Collections.Generic; -using System.ComponentModel; using System.Data; -using System.Data.Common; using System.IO; using System.Linq; using System.Linq.Expressions; -using System.Reflection; -using System.Runtime.CompilerServices; -using System.Text; using Microsoft.Data.SqlClient; using Microsoft.EntityFrameworkCore; using Microsoft.EntityFrameworkCore.ChangeTracking.Internal; -using Microsoft.EntityFrameworkCore.Diagnostics; using Microsoft.EntityFrameworkCore.Infrastructure; using Microsoft.EntityFrameworkCore.Internal; using Microsoft.EntityFrameworkCore.Metadata; -using Microsoft.EntityFrameworkCore.Metadata.Conventions; -using Microsoft.EntityFrameworkCore.Metadata.Internal; using Microsoft.EntityFrameworkCore.Query; using Microsoft.EntityFrameworkCore.Query.Internal; -using Microsoft.EntityFrameworkCore.Storage; -using Microsoft.EntityFrameworkCore.Update; using N.EntityFrameworkCore.Extensions.Common; using N.EntityFrameworkCore.Extensions.Enums; using N.EntityFrameworkCore.Extensions.Extensions; using N.EntityFrameworkCore.Extensions.Sql; using N.EntityFrameworkCore.Extensions.Util; -using static Microsoft.EntityFrameworkCore.DbLoggerCategory; namespace N.EntityFrameworkCore.Extensions; diff --git a/N.EntityFrameworkCore.Extensions/Data/DbContextExtensionsAsync.cs b/N.EntityFrameworkCore.Extensions/Data/DbContextExtensionsAsync.cs index ef60e9b..1d0c4b8 100644 --- a/N.EntityFrameworkCore.Extensions/Data/DbContextExtensionsAsync.cs +++ b/N.EntityFrameworkCore.Extensions/Data/DbContextExtensionsAsync.cs @@ -4,16 +4,12 @@ using System.IO; using System.Linq; using System.Linq.Expressions; -using System.Reflection; using System.Threading; using System.Threading.Tasks; using Microsoft.Data.SqlClient; using Microsoft.EntityFrameworkCore; -using Microsoft.EntityFrameworkCore.ChangeTracking.Internal; using Microsoft.EntityFrameworkCore.Infrastructure; using Microsoft.EntityFrameworkCore.Internal; -using Microsoft.EntityFrameworkCore.Metadata; -using Microsoft.EntityFrameworkCore.Migrations.Operations; using N.EntityFrameworkCore.Extensions.Common; using N.EntityFrameworkCore.Extensions.Enums; using N.EntityFrameworkCore.Extensions.Extensions; diff --git a/N.EntityFrameworkCore.Extensions/Data/EfExtensionsCommandInterceptor.cs b/N.EntityFrameworkCore.Extensions/Data/EfExtensionsCommandInterceptor.cs index 3980f9e..7fbea61 100644 --- a/N.EntityFrameworkCore.Extensions/Data/EfExtensionsCommandInterceptor.cs +++ b/N.EntityFrameworkCore.Extensions/Data/EfExtensionsCommandInterceptor.cs @@ -1,8 +1,6 @@ using System; using System.Collections.Concurrent; using System.Data.Common; -using System.Threading; -using System.Threading.Tasks; using Microsoft.EntityFrameworkCore.Diagnostics; namespace N.EntityFrameworkCore.Extensions; diff --git a/N.EntityFrameworkCore.Extensions/Data/EntityDataReader.cs b/N.EntityFrameworkCore.Extensions/Data/EntityDataReader.cs index 10d4dfb..521eef8 100644 --- a/N.EntityFrameworkCore.Extensions/Data/EntityDataReader.cs +++ b/N.EntityFrameworkCore.Extensions/Data/EntityDataReader.cs @@ -1,17 +1,10 @@ using System; using System.Collections.Generic; using System.Data; -using System.Linq; -using System.Linq.Expressions; -using Microsoft.EntityFrameworkCore; using Microsoft.EntityFrameworkCore.ChangeTracking; using Microsoft.EntityFrameworkCore.ChangeTracking.Internal; using Microsoft.EntityFrameworkCore.Metadata; -using Microsoft.EntityFrameworkCore.Metadata.Internal; -using Microsoft.EntityFrameworkCore.Update; -using Microsoft.EntityFrameworkCore.ValueGeneration; using N.EntityFrameworkCore.Extensions.Common; -using N.EntityFrameworkCore.Extensions.Extensions; namespace N.EntityFrameworkCore.Extensions; diff --git a/N.EntityFrameworkCore.Extensions/Data/FetchOptions.cs b/N.EntityFrameworkCore.Extensions/Data/FetchOptions.cs index 6d773ac..1d00787 100644 --- a/N.EntityFrameworkCore.Extensions/Data/FetchOptions.cs +++ b/N.EntityFrameworkCore.Extensions/Data/FetchOptions.cs @@ -1,9 +1,5 @@ using System; -using System.Collections.Generic; -using System.Linq; using System.Linq.Expressions; -using System.Text; -using System.Threading.Tasks; namespace N.EntityFrameworkCore.Extensions; diff --git a/N.EntityFrameworkCore.Extensions/Data/FetchResult.cs b/N.EntityFrameworkCore.Extensions/Data/FetchResult.cs index b179906..1b579ec 100644 --- a/N.EntityFrameworkCore.Extensions/Data/FetchResult.cs +++ b/N.EntityFrameworkCore.Extensions/Data/FetchResult.cs @@ -1,5 +1,4 @@ -using System; -using System.Collections.Generic; +using System.Collections.Generic; namespace N.EntityFrameworkCore.Extensions; diff --git a/N.EntityFrameworkCore.Extensions/Data/QueryToFileOptions.cs b/N.EntityFrameworkCore.Extensions/Data/QueryToFileOptions.cs index f846265..75f68bd 100644 --- a/N.EntityFrameworkCore.Extensions/Data/QueryToFileOptions.cs +++ b/N.EntityFrameworkCore.Extensions/Data/QueryToFileOptions.cs @@ -1,8 +1,4 @@ -using System; -using System.Collections.Generic; -using System.Text; - -namespace N.EntityFrameworkCore.Extensions; +namespace N.EntityFrameworkCore.Extensions; public class QueryToFileOptions { diff --git a/N.EntityFrameworkCore.Extensions/Data/QueryToFileResult.cs b/N.EntityFrameworkCore.Extensions/Data/QueryToFileResult.cs index 03269e5..174615e 100644 --- a/N.EntityFrameworkCore.Extensions/Data/QueryToFileResult.cs +++ b/N.EntityFrameworkCore.Extensions/Data/QueryToFileResult.cs @@ -1,8 +1,4 @@ -using System; -using System.Collections.Generic; -using System.Text; - -namespace N.EntityFrameworkCore.Extensions; +namespace N.EntityFrameworkCore.Extensions; public class QueryToFileResult { diff --git a/N.EntityFrameworkCore.Extensions/Data/SqlMergeAction.cs b/N.EntityFrameworkCore.Extensions/Data/SqlMergeAction.cs index 17c885c..0fd407e 100644 --- a/N.EntityFrameworkCore.Extensions/Data/SqlMergeAction.cs +++ b/N.EntityFrameworkCore.Extensions/Data/SqlMergeAction.cs @@ -1,10 +1,4 @@ -using System; -using System.Collections.Generic; -using System.Linq; -using System.Text; -using System.Threading.Tasks; - -namespace N.EntityFrameworkCore.Extensions; +namespace N.EntityFrameworkCore.Extensions; internal static class SqlMergeAction { diff --git a/N.EntityFrameworkCore.Extensions/Data/TableMapping.cs b/N.EntityFrameworkCore.Extensions/Data/TableMapping.cs index 5f4ff55..f395986 100644 --- a/N.EntityFrameworkCore.Extensions/Data/TableMapping.cs +++ b/N.EntityFrameworkCore.Extensions/Data/TableMapping.cs @@ -2,8 +2,6 @@ using System.Collections.Generic; using System.Linq; using Microsoft.EntityFrameworkCore; -using Microsoft.EntityFrameworkCore.ChangeTracking; -using Microsoft.EntityFrameworkCore.ChangeTracking.Internal; using Microsoft.EntityFrameworkCore.Metadata; using Microsoft.EntityFrameworkCore.Metadata.Internal; using N.EntityFrameworkCore.Extensions.Extensions; diff --git a/N.EntityFrameworkCore.Extensions/Enums/ConnectionBehavior.cs b/N.EntityFrameworkCore.Extensions/Enums/ConnectionBehavior.cs index a5a476a..3e12ad4 100644 --- a/N.EntityFrameworkCore.Extensions/Enums/ConnectionBehavior.cs +++ b/N.EntityFrameworkCore.Extensions/Enums/ConnectionBehavior.cs @@ -1,10 +1,4 @@ -using System; -using System.Collections.Generic; -using System.Linq; -using System.Text; -using System.Threading.Tasks; - -namespace N.EntityFrameworkCore.Extensions.Enums; +namespace N.EntityFrameworkCore.Extensions.Enums; internal enum ConnectionBehavior { diff --git a/N.EntityFrameworkCore.Extensions/Enums/EfExtensionsCommandType.cs b/N.EntityFrameworkCore.Extensions/Enums/EfExtensionsCommandType.cs index 597fcdb..bc0c115 100644 --- a/N.EntityFrameworkCore.Extensions/Enums/EfExtensionsCommandType.cs +++ b/N.EntityFrameworkCore.Extensions/Enums/EfExtensionsCommandType.cs @@ -1,10 +1,4 @@ -using System; -using System.Collections.Generic; -using System.Linq; -using System.Text; -using System.Threading.Tasks; - -namespace N.EntityFrameworkCore.Extensions; +namespace N.EntityFrameworkCore.Extensions; enum EfExtensionsCommandType { diff --git a/N.EntityFrameworkCore.Extensions/Extensions/CommonExtensions.cs b/N.EntityFrameworkCore.Extensions/Extensions/CommonExtensions.cs index 6632887..11d7303 100644 --- a/N.EntityFrameworkCore.Extensions/Extensions/CommonExtensions.cs +++ b/N.EntityFrameworkCore.Extensions/Extensions/CommonExtensions.cs @@ -1,6 +1,4 @@ using System; -using System.Collections.Generic; -using System.Text; namespace N.EntityFrameworkCore.Extensions.Extensions; diff --git a/N.EntityFrameworkCore.Extensions/Extensions/DbDataReaderExtensions.cs b/N.EntityFrameworkCore.Extensions/Extensions/DbDataReaderExtensions.cs index 4166106..3793892 100644 --- a/N.EntityFrameworkCore.Extensions/Extensions/DbDataReaderExtensions.cs +++ b/N.EntityFrameworkCore.Extensions/Extensions/DbDataReaderExtensions.cs @@ -1,14 +1,8 @@ using System; using System.Collections.Generic; using System.Data.Common; -using System.Linq; -using System.Reflection; using Microsoft.EntityFrameworkCore; -using Microsoft.EntityFrameworkCore.ChangeTracking; -using Microsoft.EntityFrameworkCore.ChangeTracking.Internal; -using Microsoft.EntityFrameworkCore.Infrastructure; using Microsoft.EntityFrameworkCore.Metadata; -using Microsoft.EntityFrameworkCore.Metadata.Internal; namespace N.EntityFrameworkCore.Extensions.Extensions; diff --git a/N.EntityFrameworkCore.Extensions/Extensions/IPropertyExtensions.cs b/N.EntityFrameworkCore.Extensions/Extensions/IPropertyExtensions.cs index 860e9c1..90b2cd6 100644 --- a/N.EntityFrameworkCore.Extensions/Extensions/IPropertyExtensions.cs +++ b/N.EntityFrameworkCore.Extensions/Extensions/IPropertyExtensions.cs @@ -1,11 +1,4 @@ -using System; -using System.Collections.Generic; -using System.Linq; -using System.Runtime.CompilerServices; -using System.Text; -using System.Threading.Tasks; -using Microsoft.EntityFrameworkCore.Metadata; -using Microsoft.EntityFrameworkCore.Metadata.Internal; +using Microsoft.EntityFrameworkCore.Metadata; namespace N.EntityFrameworkCore.Extensions.Extensions; diff --git a/N.EntityFrameworkCore.Extensions/Extensions/LinqExtensions.cs b/N.EntityFrameworkCore.Extensions/Extensions/LinqExtensions.cs index 8d4d14c..becfffc 100644 --- a/N.EntityFrameworkCore.Extensions/Extensions/LinqExtensions.cs +++ b/N.EntityFrameworkCore.Extensions/Extensions/LinqExtensions.cs @@ -3,12 +3,8 @@ using System.Globalization; using System.Linq; using System.Linq.Expressions; -using System.Net.NetworkInformation; using System.Reflection; using System.Text; -using System.Text.Json.Nodes; -using System.Threading.Tasks; -using Microsoft.IdentityModel.Protocols; namespace N.EntityFrameworkCore.Extensions; diff --git a/N.EntityFrameworkCore.Extensions/Extensions/ObjectExtensions.cs b/N.EntityFrameworkCore.Extensions/Extensions/ObjectExtensions.cs index e87d3c2..bdc099e 100644 --- a/N.EntityFrameworkCore.Extensions/Extensions/ObjectExtensions.cs +++ b/N.EntityFrameworkCore.Extensions/Extensions/ObjectExtensions.cs @@ -1,5 +1,4 @@ using System; -using System.Linq.Expressions; using System.Reflection; namespace N.EntityFrameworkCore.Extensions; diff --git a/N.EntityFrameworkCore.Extensions/Extensions/SqlStatementExtensions.cs b/N.EntityFrameworkCore.Extensions/Extensions/SqlStatementExtensions.cs index 5df629f..c7f4055 100644 --- a/N.EntityFrameworkCore.Extensions/Extensions/SqlStatementExtensions.cs +++ b/N.EntityFrameworkCore.Extensions/Extensions/SqlStatementExtensions.cs @@ -1,8 +1,4 @@ -using System; -using System.Collections.Generic; -using System.Linq; -using System.Text; -using System.Threading.Tasks; +using System.Collections.Generic; using N.EntityFrameworkCore.Extensions.Sql; namespace N.EntityFrameworkCore.Extensions.Extensions; diff --git a/N.EntityFrameworkCore.Extensions/Sql/SqlClause.cs b/N.EntityFrameworkCore.Extensions/Sql/SqlClause.cs index 1fed72c..637cb3b 100644 --- a/N.EntityFrameworkCore.Extensions/Sql/SqlClause.cs +++ b/N.EntityFrameworkCore.Extensions/Sql/SqlClause.cs @@ -1,10 +1,4 @@ -using System; -using System.Collections.Generic; -using System.Linq; -using System.Text; -using System.Threading.Tasks; - -namespace N.EntityFrameworkCore.Extensions.Sql; +namespace N.EntityFrameworkCore.Extensions.Sql; class SqlClause { diff --git a/N.EntityFrameworkCore.Extensions/Sql/SqlExpression.cs b/N.EntityFrameworkCore.Extensions/Sql/SqlExpression.cs index 5b39862..889fef7 100644 --- a/N.EntityFrameworkCore.Extensions/Sql/SqlExpression.cs +++ b/N.EntityFrameworkCore.Extensions/Sql/SqlExpression.cs @@ -1,12 +1,6 @@ -using System; -using System.Collections.Generic; +using System.Collections.Generic; using System.Linq; -using System.Linq.Expressions; -using System.Runtime.InteropServices.ObjectiveC; using System.Text; -using System.Threading.Tasks; -using Microsoft.EntityFrameworkCore.Metadata.Internal; -using Microsoft.EntityFrameworkCore.Storage.ValueConversion; using N.EntityFrameworkCore.Extensions.Util; namespace N.EntityFrameworkCore.Extensions.Sql; diff --git a/N.EntityFrameworkCore.Extensions/Sql/SqlKeyword.cs b/N.EntityFrameworkCore.Extensions/Sql/SqlKeyword.cs index 3a68992..0e28202 100644 --- a/N.EntityFrameworkCore.Extensions/Sql/SqlKeyword.cs +++ b/N.EntityFrameworkCore.Extensions/Sql/SqlKeyword.cs @@ -1,10 +1,4 @@ -using System; -using System.Collections.Generic; -using System.Linq; -using System.Text; -using System.Threading.Tasks; - -namespace N.EntityFrameworkCore.Extensions.Sql; +namespace N.EntityFrameworkCore.Extensions.Sql; public enum SqlKeyword { diff --git a/N.EntityFrameworkCore.Extensions/Sql/SqlPart.cs b/N.EntityFrameworkCore.Extensions/Sql/SqlPart.cs index 79e3c80..b015d4c 100644 --- a/N.EntityFrameworkCore.Extensions/Sql/SqlPart.cs +++ b/N.EntityFrameworkCore.Extensions/Sql/SqlPart.cs @@ -1,13 +1,4 @@ -using System; -using System.Collections.Generic; -using System.Linq; -using System.Linq.Expressions; -using System.Text; -using System.Threading.Tasks; -using Microsoft.EntityFrameworkCore.Query.SqlExpressions; -using Microsoft.Identity.Client; - -namespace N.EntityFrameworkCore.Extensions.Sql; +namespace N.EntityFrameworkCore.Extensions.Sql; internal class SqlPart { diff --git a/N.EntityFrameworkCore.Extensions/Sql/SqlStatement.cs b/N.EntityFrameworkCore.Extensions/Sql/SqlStatement.cs index be63114..7f13b7c 100644 --- a/N.EntityFrameworkCore.Extensions/Sql/SqlStatement.cs +++ b/N.EntityFrameworkCore.Extensions/Sql/SqlStatement.cs @@ -1,13 +1,7 @@ -using System; -using System.Collections.Generic; -using System.Data.SqlTypes; +using System.Collections.Generic; using System.Linq; -using System.Runtime.CompilerServices; using System.Text; -using System.Threading.Tasks; -using Microsoft.Extensions.Options; using N.EntityFrameworkCore.Extensions.Extensions; -using N.EntityFrameworkCore.Extensions.Util; namespace N.EntityFrameworkCore.Extensions.Sql; diff --git a/N.EntityFrameworkCore.Extensions/Util/CommonUtil.cs b/N.EntityFrameworkCore.Extensions/Util/CommonUtil.cs index 9b55466..ab4b9e2 100644 --- a/N.EntityFrameworkCore.Extensions/Util/CommonUtil.cs +++ b/N.EntityFrameworkCore.Extensions/Util/CommonUtil.cs @@ -3,7 +3,6 @@ using System.IO; using System.Linq; using System.Linq.Expressions; -using System.Text; using Microsoft.Data.SqlClient; namespace N.EntityFrameworkCore.Extensions.Util; diff --git a/N.EntityFrameworkCore.Extensions/Util/SqlUtil.cs b/N.EntityFrameworkCore.Extensions/Util/SqlUtil.cs index ebc8a65..de42c71 100644 --- a/N.EntityFrameworkCore.Extensions/Util/SqlUtil.cs +++ b/N.EntityFrameworkCore.Extensions/Util/SqlUtil.cs @@ -1,10 +1,4 @@ -using System; -using System.Collections.Generic; -using System.Data; -using System.Data.Common; -using System.Linq; -using Microsoft.Data.SqlClient; -using N.EntityFrameworkCore.Extensions.Util; +using System.Collections.Generic; namespace N.EntityFrameworkCore.Extensions;