From a0b3bd487a71e0e182d1662c7d733cad87488359 Mon Sep 17 00:00:00 2001 From: Dave Whiffin Date: Wed, 4 Mar 2020 17:25:00 +0000 Subject: [PATCH 01/27] Applying DB Column Sizes --- .../Entities/BasketAggregate/BasketQueries.cs | 20 + .../Entities/QuoteAggregate/QuoteQueries.cs | 15 + .../Interfaces/IAsyncRepository.cs | 2 - .../ApplicationCore/Services/BasketService.cs | 40 +- .../ApplicationCore/Services/OrderService.cs | 26 +- .../Services/PurchaseOrderService.cs | 14 +- .../ApplicationCore/Services/QuoteService.cs | 22 +- .../Infrastructure/Data/CatalogContext.cs | 2 - .../Data/Config/BasketConfiguration.cs | 6 +- .../Data/Config/CatalogItemConfiguration.cs | 13 + .../Data/Config/CatalogItemExcerptBuilder.cs | 22 + .../Data/Config/EntityBuilderExtensions.cs | 26 +- .../Data/Config/OrderConfiguration.cs | 3 + .../Data/Config/OrderItemConfiguration.cs | 11 +- .../Data/Config/QuoteConfiguration.cs | 8 +- .../Data/Config/QuoteItemConfiguration.cs | 6 +- .../Infrastructure/Data/EfRepository.cs | 2 - .../20200304170042_ResizeColumns.Designer.cs | 948 +++++++++++++++++ .../20200304170042_ResizeColumns.cs | 319 ++++++ ...200304171630_SetGtinColumnSize.Designer.cs | 950 ++++++++++++++++++ .../20200304171630_SetGtinColumnSize.cs | 49 + .../Migrations/CatalogContextModelSnapshot.cs | 59 +- src/Web/.config/dotnet-tools.json | 2 +- src/Web/GenerateDbCreationScripts.bat | 4 + src/Web/Program.cs | 1 + src/Web/Web.csproj | 1 + src/WebJobs/Functions.cs | 2 +- src/WebJobs/Jobs/CreateFakePurchaseOrders.cs | 12 +- .../JsonFileBlockProgressRepository.cs | 12 +- src/WebJobs/Program.cs | 27 +- src/WebJobs/appsettings.json | 2 +- .../appsettings.json | 2 +- 32 files changed, 2494 insertions(+), 134 deletions(-) create mode 100644 src/Nethereum.eShop/ApplicationCore/Entities/BasketAggregate/BasketQueries.cs create mode 100644 src/Nethereum.eShop/ApplicationCore/Entities/QuoteAggregate/QuoteQueries.cs create mode 100644 src/Nethereum.eShop/Infrastructure/Data/Config/CatalogItemExcerptBuilder.cs create mode 100644 src/Nethereum.eShop/Infrastructure/Data/Migrations/20200304170042_ResizeColumns.Designer.cs create mode 100644 src/Nethereum.eShop/Infrastructure/Data/Migrations/20200304170042_ResizeColumns.cs create mode 100644 src/Nethereum.eShop/Infrastructure/Data/Migrations/20200304171630_SetGtinColumnSize.Designer.cs create mode 100644 src/Nethereum.eShop/Infrastructure/Data/Migrations/20200304171630_SetGtinColumnSize.cs create mode 100644 src/Web/GenerateDbCreationScripts.bat diff --git a/src/Nethereum.eShop/ApplicationCore/Entities/BasketAggregate/BasketQueries.cs b/src/Nethereum.eShop/ApplicationCore/Entities/BasketAggregate/BasketQueries.cs new file mode 100644 index 0000000..93c2a76 --- /dev/null +++ b/src/Nethereum.eShop/ApplicationCore/Entities/BasketAggregate/BasketQueries.cs @@ -0,0 +1,20 @@ +using Microsoft.EntityFrameworkCore; +using Nethereum.eShop.Infrastructure.Data; +using System.Linq; +using System.Threading.Tasks; + +namespace Nethereum.eShop.ApplicationCore.Entities.BasketAggregate +{ + public static class BasketQueries + { + public static Task GetBasketWithItemsOrDefault(this CatalogContext context, int basketId) + { + return context.Baskets.Include(b => b.Items).Where(b => b.Id == basketId).FirstOrDefaultAsync(); + } + + public static Task GetBasketWithItemsOrDefault(this CatalogContext context, string buyerId) + { + return context.Baskets.Include(b => b.Items).Where(b => b.BuyerId == buyerId).FirstOrDefaultAsync(); + } + } +} diff --git a/src/Nethereum.eShop/ApplicationCore/Entities/QuoteAggregate/QuoteQueries.cs b/src/Nethereum.eShop/ApplicationCore/Entities/QuoteAggregate/QuoteQueries.cs new file mode 100644 index 0000000..91f12e4 --- /dev/null +++ b/src/Nethereum.eShop/ApplicationCore/Entities/QuoteAggregate/QuoteQueries.cs @@ -0,0 +1,15 @@ +using Microsoft.EntityFrameworkCore; +using Nethereum.eShop.Infrastructure.Data; +using System.Linq; +using System.Threading.Tasks; + +namespace Nethereum.eShop.ApplicationCore.Entities.QuoteAggregate +{ + public static class QuoteQueries + { + public static Task GetQuoteWithItemsOrDefault(this CatalogContext context, int quoteId) + { + return context.Quotes.Include(b => b.QuoteItems).Where(b => b.Id == quoteId).FirstOrDefaultAsync(); + } + } +} diff --git a/src/Nethereum.eShop/ApplicationCore/Interfaces/IAsyncRepository.cs b/src/Nethereum.eShop/ApplicationCore/Interfaces/IAsyncRepository.cs index a2cef6d..e5395fb 100644 --- a/src/Nethereum.eShop/ApplicationCore/Interfaces/IAsyncRepository.cs +++ b/src/Nethereum.eShop/ApplicationCore/Interfaces/IAsyncRepository.cs @@ -14,7 +14,5 @@ public interface IAsyncRepository where T : BaseEntity, IAggregateRoot Task UpdateAsync(T entity); Task DeleteAsync(T entity); Task CountAsync(ISpecification spec); - - DbSet DbSet { get; } } } diff --git a/src/Nethereum.eShop/ApplicationCore/Services/BasketService.cs b/src/Nethereum.eShop/ApplicationCore/Services/BasketService.cs index 3a8b15e..6a8e312 100644 --- a/src/Nethereum.eShop/ApplicationCore/Services/BasketService.cs +++ b/src/Nethereum.eShop/ApplicationCore/Services/BasketService.cs @@ -1,45 +1,42 @@ -using Nethereum.eShop.ApplicationCore.Interfaces; -using System.Threading.Tasks; +using Ardalis.GuardClauses; +using Microsoft.EntityFrameworkCore; +using Nethereum.eShop.ApplicationCore.Entities.BasketAggregate; +using Nethereum.eShop.ApplicationCore.Interfaces; +using Nethereum.eShop.Infrastructure.Data; using System.Collections.Generic; -using Nethereum.eShop.ApplicationCore.Specifications; using System.Linq; -using Ardalis.GuardClauses; -using Nethereum.eShop.ApplicationCore.Entities.BasketAggregate; +using System.Threading.Tasks; namespace Nethereum.eShop.ApplicationCore.Services { public class BasketService : IBasketService { - private readonly IAsyncRepository _basketRepository; + private readonly CatalogContext _dbContext; private readonly IAppLogger _logger; - public BasketService(IAsyncRepository basketRepository, - IAppLogger logger) + public BasketService(CatalogContext dbContext, IAppLogger logger) { - _basketRepository = basketRepository; + _dbContext = dbContext; _logger = logger; } public async Task AddItemToBasket(int basketId, int catalogItemId, decimal price, int quantity = 1) { - var basket = await _basketRepository.GetByIdAsync(basketId); - + var basket = await _dbContext.GetBasketWithItemsOrDefault(basketId).ConfigureAwait(false); basket.AddItem(catalogItemId, price, quantity); - - await _basketRepository.UpdateAsync(basket); + await _dbContext.SaveChangesAsync().ConfigureAwait(false); } public async Task DeleteBasketAsync(int basketId) { - var basket = await _basketRepository.GetByIdAsync(basketId); - await _basketRepository.DeleteAsync(basket); + _dbContext.Entry(new Basket { Id = basketId }).State = EntityState.Deleted; + await _dbContext.SaveChangesAsync().ConfigureAwait(false); } public async Task GetBasketItemCountAsync(string userName) { Guard.Against.NullOrEmpty(userName, nameof(userName)); - var basketSpec = new BasketWithItemsSpecification(userName); - var basket = (await _basketRepository.ListAsync(basketSpec)).FirstOrDefault(); + var basket = await _dbContext.GetBasketWithItemsOrDefault(userName).ConfigureAwait(false); if (basket == null) { _logger.LogInformation($"No basket found for {userName}"); @@ -53,7 +50,7 @@ public async Task GetBasketItemCountAsync(string userName) public async Task SetQuantities(int basketId, Dictionary quantities) { Guard.Against.Null(quantities, nameof(quantities)); - var basket = await _basketRepository.GetByIdAsync(basketId); + var basket = await _dbContext.GetBasketWithItemsOrDefault(basketId).ConfigureAwait(false); Guard.Against.NullBasket(basketId, basket); foreach (var item in basket.Items) { @@ -64,20 +61,19 @@ public async Task SetQuantities(int basketId, Dictionary quantities } } basket.RemoveEmptyItems(); - await _basketRepository.UpdateAsync(basket); + await _dbContext.SaveChangesAsync().ConfigureAwait(false); } public async Task TransferBasketAsync(string anonymousId, string userName) { Guard.Against.NullOrEmpty(anonymousId, nameof(anonymousId)); Guard.Against.NullOrEmpty(userName, nameof(userName)); - var basketSpec = new BasketWithItemsSpecification(anonymousId); - var basket = (await _basketRepository.ListAsync(basketSpec)).FirstOrDefault(); + var basket = await _dbContext.GetBasketWithItemsOrDefault(anonymousId).ConfigureAwait(false); if (basket == null) return; basket.BuyerId = userName; // TODO: populate from buyer entity basket.BuyerAddress = ""; - await _basketRepository.UpdateAsync(basket); + await _dbContext.SaveChangesAsync().ConfigureAwait(false); } } } diff --git a/src/Nethereum.eShop/ApplicationCore/Services/OrderService.cs b/src/Nethereum.eShop/ApplicationCore/Services/OrderService.cs index 59a8f38..31a85e2 100644 --- a/src/Nethereum.eShop/ApplicationCore/Services/OrderService.cs +++ b/src/Nethereum.eShop/ApplicationCore/Services/OrderService.cs @@ -1,10 +1,9 @@ using Ardalis.GuardClauses; using Nethereum.Commerce.Contracts.Purchasing.ContractDefinition; -using Nethereum.eShop.ApplicationCore.Entities; using Nethereum.eShop.ApplicationCore.Entities.OrderAggregate; using Nethereum.eShop.ApplicationCore.Entities.QuoteAggregate; using Nethereum.eShop.ApplicationCore.Interfaces; -using Nethereum.eShop.ApplicationCore.Specifications; +using Nethereum.eShop.Infrastructure.Data; using System; using System.Collections.Generic; using System.Linq; @@ -14,17 +13,11 @@ namespace Nethereum.eShop.ApplicationCore.Services { public class OrderService : IOrderService { - private readonly IAsyncRepository _orderRepository; - private readonly IAsyncRepository _quoteRepository; - private readonly IAsyncRepository _itemRepository; + private readonly CatalogContext _dbContext; - public OrderService(IAsyncRepository quoteRepository, - IAsyncRepository itemRepository, - IAsyncRepository orderRepository) + public OrderService(CatalogContext catalogContext) { - _orderRepository = orderRepository; - _quoteRepository = quoteRepository; - _itemRepository = itemRepository; + _dbContext = catalogContext; } public async Task CreateOrderAsync(string transactionHash, Po purchaseOrder) @@ -34,10 +27,7 @@ public async Task CreateOrderAsync(string transactionHash, Po purchaseOrder) int quoteId = (int)purchaseOrder.QuoteId; - var spec = new QuoteWithItemsSpecification(quoteId); - - var quotes = await _quoteRepository.ListAsync(spec); - var quote = quotes.FirstOrDefault(); + var quote = await _dbContext.GetQuoteWithItemsOrDefault(quoteId); Guard.Against.NullQuote(quoteId, quote); var items = new List(); @@ -78,11 +68,13 @@ public async Task CreateOrderAsync(string transactionHash, Po purchaseOrder) orderItem.EscrowReleaseDate = DateTimeOffset.FromUnixTimeSeconds((long)poItem.PlannedEscrowReleaseDate); } - await _orderRepository.AddAsync(order); quote.TransactionHash = transactionHash; quote.PoNumber = (long)purchaseOrder.PoNumber; quote.Status = QuoteStatus.Complete; - await _quoteRepository.UpdateAsync(quote); + + _dbContext.Orders.Add(order); + + await _dbContext.SaveChangesAsync(); } } } diff --git a/src/Nethereum.eShop/ApplicationCore/Services/PurchaseOrderService.cs b/src/Nethereum.eShop/ApplicationCore/Services/PurchaseOrderService.cs index 6436513..b25445a 100644 --- a/src/Nethereum.eShop/ApplicationCore/Services/PurchaseOrderService.cs +++ b/src/Nethereum.eShop/ApplicationCore/Services/PurchaseOrderService.cs @@ -1,8 +1,8 @@ using Ardalis.GuardClauses; using Nethereum.eShop.ApplicationCore.Entities; using Nethereum.eShop.ApplicationCore.Entities.BasketAggregate; -using Nethereum.eShop.ApplicationCore.Entities.OrderAggregate; using Nethereum.eShop.ApplicationCore.Interfaces; +using Nethereum.eShop.Infrastructure.Data; using System; using System.Threading.Tasks; @@ -10,15 +10,11 @@ namespace Nethereum.eShop.ApplicationCore.Services { public class PurchaseOrderService : IPurchaseOrderService { - private readonly IAsyncRepository _basketRepository; - private readonly IAsyncRepository _itemRepository; + private readonly CatalogContext _dbContext; - public PurchaseOrderService( - IAsyncRepository basketRepository, - IAsyncRepository itemRepository) + public PurchaseOrderService(CatalogContext catalogContext) { - _basketRepository = basketRepository; - _itemRepository = itemRepository; + _dbContext = catalogContext; } public async Task CreateOrderAsync(int basketId, PostalAddress billingAddress, PostalAddress shippingAddress) @@ -29,7 +25,7 @@ public async Task CreateOrderAsync(int basketId, PostalAddress billingAddress, P // using basket to populate // we need the buyer nonce - var basket = await _basketRepository.GetByIdAsync(basketId); + var basket = await _dbContext.GetBasketWithItemsOrDefault(basketId).ConfigureAwait(false); Guard.Against.NullBasket(basketId, basket); throw new NotImplementedException(); diff --git a/src/Nethereum.eShop/ApplicationCore/Services/QuoteService.cs b/src/Nethereum.eShop/ApplicationCore/Services/QuoteService.cs index fab1f3b..a096272 100644 --- a/src/Nethereum.eShop/ApplicationCore/Services/QuoteService.cs +++ b/src/Nethereum.eShop/ApplicationCore/Services/QuoteService.cs @@ -2,9 +2,9 @@ using Nethereum.eShop.ApplicationCore.Entities; using Nethereum.eShop.ApplicationCore.Entities.BasketAggregate; using Nethereum.eShop.ApplicationCore.Entities.QuoteAggregate; -using Nethereum.eShop.ApplicationCore.Entities.RulesEngine; using Nethereum.eShop.ApplicationCore.Exceptions; using Nethereum.eShop.ApplicationCore.Interfaces; +using Nethereum.eShop.Infrastructure.Data; using System; using System.Collections.Generic; using System.Threading.Tasks; @@ -13,20 +13,14 @@ namespace Nethereum.eShop.ApplicationCore.Services { public class QuoteService : IQuoteService { - private readonly IAsyncRepository _quoteRepository; - private readonly IAsyncRepository _basketRepository; - private readonly IAsyncRepository _itemRepository; + private readonly CatalogContext _dbContext; private readonly IRulesEngineService _rulesEngineService; public QuoteService( - IAsyncRepository basketRepository, - IAsyncRepository itemRepository, - IAsyncRepository orderRepository, + CatalogContext catalogContext, IRulesEngineService rulesEngineService = null) { - _quoteRepository = orderRepository; - _basketRepository = basketRepository; - _itemRepository = itemRepository; + _dbContext = catalogContext; _rulesEngineService = rulesEngineService; } @@ -40,7 +34,7 @@ public async Task CreateQuoteAsync(int basketId) // Create purchase order // reserve stock? - var basket = await _basketRepository.GetByIdAsync(basketId); + var basket = await _dbContext.GetBasketWithItemsOrDefault(basketId).ConfigureAwait(false); Guard.Against.NullBasket(basketId, basket); var quoteItems = await MapAsync(basket); @@ -70,7 +64,9 @@ public async Task CreateQuoteAsync(int basketId) } } - await _quoteRepository.AddAsync(quote); + _dbContext.Quotes.Add(quote); + + await _dbContext.SaveChangesAsync().ConfigureAwait(false); } private async Task> MapAsync(Basket basket) @@ -78,7 +74,7 @@ private async Task> MapAsync(Basket basket) var items = new List(); foreach (var item in basket.Items) { - var catalogItem = await _itemRepository.GetByIdAsync(item.CatalogItemId); + var catalogItem = await _dbContext.CatalogItems.FindAsync(item.CatalogItemId).ConfigureAwait(false); var itemOrdered = new CatalogItemExcerpt( catalogItem.Id, catalogItem.Gtin, catalogItem.GtinRegistryId, catalogItem.Name, catalogItem.PictureUri); diff --git a/src/Nethereum.eShop/Infrastructure/Data/CatalogContext.cs b/src/Nethereum.eShop/Infrastructure/Data/CatalogContext.cs index 23af718..0f69557 100644 --- a/src/Nethereum.eShop/Infrastructure/Data/CatalogContext.cs +++ b/src/Nethereum.eShop/Infrastructure/Data/CatalogContext.cs @@ -37,7 +37,5 @@ protected override void OnModelCreating(ModelBuilder builder) base.OnModelCreating(builder); builder.ApplyConfigurationsFromAssembly(Assembly.GetExecutingAssembly()); } - - } } diff --git a/src/Nethereum.eShop/Infrastructure/Data/Config/BasketConfiguration.cs b/src/Nethereum.eShop/Infrastructure/Data/Config/BasketConfiguration.cs index 3062c19..324a36f 100644 --- a/src/Nethereum.eShop/Infrastructure/Data/Config/BasketConfiguration.cs +++ b/src/Nethereum.eShop/Infrastructure/Data/Config/BasketConfiguration.cs @@ -19,8 +19,7 @@ public void Configure(EntityTypeBuilder builder) .HasMaxLength(256) .IsRequired(); - builder.HasIndex(b => b.BuyerId); - builder.HasIndex(b => b.BuyerAddress); + builder.Property(b => b.TransactionHash).IsHash(); builder.OwnsOne(o => o.ShipTo, a => { @@ -31,6 +30,9 @@ public void Configure(EntityTypeBuilder builder) { a.ConfigureAddress(); }); + + builder.HasIndex(b => b.BuyerId); + builder.HasIndex(b => b.BuyerAddress); } } } diff --git a/src/Nethereum.eShop/Infrastructure/Data/Config/CatalogItemConfiguration.cs b/src/Nethereum.eShop/Infrastructure/Data/Config/CatalogItemConfiguration.cs index a4fe342..80f303c 100644 --- a/src/Nethereum.eShop/Infrastructure/Data/Config/CatalogItemConfiguration.cs +++ b/src/Nethereum.eShop/Infrastructure/Data/Config/CatalogItemConfiguration.cs @@ -27,6 +27,19 @@ public void Configure(EntityTypeBuilder builder) .IsPrice(); builder.Property(ci => ci.PictureUri) + .IsUri() + .IsRequired(false); + + builder.Property(ci => ci.PictureSmallUri) + .IsUri() + .IsRequired(false); + + builder.Property(ci => ci.PictureMediumUri) + .IsUri() + .IsRequired(false); + + builder.Property(ci => ci.PictureLargeUri) + .IsUri() .IsRequired(false); builder.HasOne(ci => ci.CatalogBrand) diff --git a/src/Nethereum.eShop/Infrastructure/Data/Config/CatalogItemExcerptBuilder.cs b/src/Nethereum.eShop/Infrastructure/Data/Config/CatalogItemExcerptBuilder.cs new file mode 100644 index 0000000..bc32ae1 --- /dev/null +++ b/src/Nethereum.eShop/Infrastructure/Data/Config/CatalogItemExcerptBuilder.cs @@ -0,0 +1,22 @@ +using Microsoft.EntityFrameworkCore.Metadata.Builders; +using Nethereum.eShop.ApplicationCore.Entities; + +namespace Nethereum.eShop.Infrastructure.Data.Config +{ + public static class CatalogItemExcerptBuilder + { + public static void ConfigureCatalogItemExcerpt(this OwnedNavigationBuilder a) where TParentEntity : class{ + a.WithOwner(); + a.WithOwner(); + + a.Property(cio => cio.ProductName) + .HasMaxLength(50) + .IsRequired(); + + a.Property(cio => cio.PictureUri).IsUri(); + + a.Property(cio => cio.Gtin).IsGtin(); + } + + } +} diff --git a/src/Nethereum.eShop/Infrastructure/Data/Config/EntityBuilderExtensions.cs b/src/Nethereum.eShop/Infrastructure/Data/Config/EntityBuilderExtensions.cs index 67b156b..17eee97 100644 --- a/src/Nethereum.eShop/Infrastructure/Data/Config/EntityBuilderExtensions.cs +++ b/src/Nethereum.eShop/Infrastructure/Data/Config/EntityBuilderExtensions.cs @@ -5,9 +5,12 @@ namespace Nethereum.eShop.Infrastructure.Data.Config { public static class EntityBuilderExtensions { - private const int Hash = 67; - private const int Address = 43; + private const int HashLength = 67; + private const int AddressLength = 43; private const int BigIntegerLength = 100; + private const int Bytes32Length = 32; + private const int UriLength = 512; + private const int GtinLength = 14; public static PropertyBuilder IsPrice(this PropertyBuilder prop) { @@ -16,17 +19,32 @@ public static PropertyBuilder IsPrice(this PropertyBuilder pro public static PropertyBuilder IsHash(this PropertyBuilder prop) { - return prop.HasMaxLength(Hash); + return prop.HasMaxLength(HashLength); } public static PropertyBuilder IsAddress(this PropertyBuilder prop) { - return prop.HasMaxLength(Address); + return prop.HasMaxLength(AddressLength); } public static PropertyBuilder IsBigInteger(this PropertyBuilder prop) { return prop.HasMaxLength(BigIntegerLength); } + + public static PropertyBuilder IsBytes32(this PropertyBuilder prop) + { + return prop.HasMaxLength(Bytes32Length); + } + + public static PropertyBuilder IsUri(this PropertyBuilder prop) + { + return prop.HasMaxLength(UriLength); + } + + public static PropertyBuilder IsGtin(this PropertyBuilder prop) + { + return prop.HasMaxLength(GtinLength); + } } } diff --git a/src/Nethereum.eShop/Infrastructure/Data/Config/OrderConfiguration.cs b/src/Nethereum.eShop/Infrastructure/Data/Config/OrderConfiguration.cs index 39f48d6..d3ce6f8 100644 --- a/src/Nethereum.eShop/Infrastructure/Data/Config/OrderConfiguration.cs +++ b/src/Nethereum.eShop/Infrastructure/Data/Config/OrderConfiguration.cs @@ -31,6 +31,9 @@ public void Configure(EntityTypeBuilder builder) builder.Property(o => o.ApproverAddress).IsAddress(); builder.Property(o => o.BuyerWalletAddress).IsAddress(); builder.Property(o => o.TransactionHash).IsHash(); + builder.Property(o => o.CurrencyAddress).IsAddress(); + builder.Property(o => o.CurrencySymbol).IsBytes32(); + builder.Property(o => o.SellerId).IsBytes32(); } } } diff --git a/src/Nethereum.eShop/Infrastructure/Data/Config/OrderItemConfiguration.cs b/src/Nethereum.eShop/Infrastructure/Data/Config/OrderItemConfiguration.cs index a1e65d4..f02d8c1 100644 --- a/src/Nethereum.eShop/Infrastructure/Data/Config/OrderItemConfiguration.cs +++ b/src/Nethereum.eShop/Infrastructure/Data/Config/OrderItemConfiguration.cs @@ -10,16 +10,17 @@ public void Configure(EntityTypeBuilder builder) { builder.OwnsOne(i => i.ItemOrdered, io => { - io.WithOwner(); - - io.Property(cio => cio.ProductName) - .HasMaxLength(50) - .IsRequired(); + io.ConfigureCatalogItemExcerpt(); }); builder.Property(oi => oi.UnitPrice) .IsRequired(true) .IsPrice(); + + builder.Property(i => i.Unit).HasMaxLength(50); + builder.Property(i => i.QuantityAddress).IsAddress(); + builder.Property(i => i.QuantitySymbol).IsBytes32(); + builder.Property(i => i.CurrencyValue).IsBigInteger(); } } } diff --git a/src/Nethereum.eShop/Infrastructure/Data/Config/QuoteConfiguration.cs b/src/Nethereum.eShop/Infrastructure/Data/Config/QuoteConfiguration.cs index 07b0576..645e7d8 100644 --- a/src/Nethereum.eShop/Infrastructure/Data/Config/QuoteConfiguration.cs +++ b/src/Nethereum.eShop/Infrastructure/Data/Config/QuoteConfiguration.cs @@ -12,9 +12,6 @@ public void Configure(EntityTypeBuilder builder) navigation.SetPropertyAccessMode(PropertyAccessMode.Field); - builder.HasIndex(b => b.BuyerId); - builder.HasIndex(b => b.BuyerAddress); - builder.OwnsOne(o => o.ShipTo, a => { a.ConfigureAddress(); @@ -30,6 +27,11 @@ public void Configure(EntityTypeBuilder builder) builder.Property(o => o.ApproverAddress).IsAddress(); builder.Property(o => o.BuyerWalletAddress).IsAddress(); builder.Property(o => o.TransactionHash).IsHash(); + builder.Property(o => o.CurrencyAddress).IsAddress(); + builder.Property(o => o.CurrencySymbol).IsBytes32(); + builder.Property(o => o.SellerId).IsBytes32(); + builder.HasIndex(b => b.BuyerId); + builder.HasIndex(b => b.BuyerAddress); } } } diff --git a/src/Nethereum.eShop/Infrastructure/Data/Config/QuoteItemConfiguration.cs b/src/Nethereum.eShop/Infrastructure/Data/Config/QuoteItemConfiguration.cs index b289a40..97b37a0 100644 --- a/src/Nethereum.eShop/Infrastructure/Data/Config/QuoteItemConfiguration.cs +++ b/src/Nethereum.eShop/Infrastructure/Data/Config/QuoteItemConfiguration.cs @@ -10,11 +10,7 @@ public void Configure(EntityTypeBuilder builder) { builder.OwnsOne(i => i.ItemOrdered, io => { - io.WithOwner(); - - io.Property(cio => cio.ProductName) - .HasMaxLength(50) - .IsRequired(); + io.ConfigureCatalogItemExcerpt(); }); builder.Property(oi => oi.UnitPrice) diff --git a/src/Nethereum.eShop/Infrastructure/Data/EfRepository.cs b/src/Nethereum.eShop/Infrastructure/Data/EfRepository.cs index d81d321..64c68ba 100644 --- a/src/Nethereum.eShop/Infrastructure/Data/EfRepository.cs +++ b/src/Nethereum.eShop/Infrastructure/Data/EfRepository.cs @@ -16,8 +16,6 @@ public class EfRepository : IAsyncRepository where T : BaseEntity, IAggreg { protected readonly CatalogContext _dbContext; - public DbSet DbSet => _dbContext.Set(); - public EfRepository(CatalogContext dbContext) { _dbContext = dbContext; diff --git a/src/Nethereum.eShop/Infrastructure/Data/Migrations/20200304170042_ResizeColumns.Designer.cs b/src/Nethereum.eShop/Infrastructure/Data/Migrations/20200304170042_ResizeColumns.Designer.cs new file mode 100644 index 0000000..e807db1 --- /dev/null +++ b/src/Nethereum.eShop/Infrastructure/Data/Migrations/20200304170042_ResizeColumns.Designer.cs @@ -0,0 +1,948 @@ +// +using System; +using Microsoft.EntityFrameworkCore; +using Microsoft.EntityFrameworkCore.Infrastructure; +using Microsoft.EntityFrameworkCore.Metadata; +using Microsoft.EntityFrameworkCore.Migrations; +using Microsoft.EntityFrameworkCore.Storage.ValueConversion; +using Nethereum.eShop.Infrastructure.Data; + +namespace Nethereum.eShop.Infrastructure.Data.Migrations +{ + [DbContext(typeof(CatalogContext))] + [Migration("20200304170042_ResizeColumns")] + partial class ResizeColumns + { + protected override void BuildTargetModel(ModelBuilder modelBuilder) + { +#pragma warning disable 612, 618 + modelBuilder + .HasAnnotation("ProductVersion", "3.1.2") + .HasAnnotation("Relational:MaxIdentifierLength", 128) + .HasAnnotation("Relational:Sequence:.catalog_brand_hilo", "'catalog_brand_hilo', '', '1', '10', '', '', 'Int64', 'False'") + .HasAnnotation("Relational:Sequence:.catalog_hilo", "'catalog_hilo', '', '1', '10', '', '', 'Int64', 'False'") + .HasAnnotation("Relational:Sequence:.catalog_type_hilo", "'catalog_type_hilo', '', '1', '10', '', '', 'Int64', 'False'") + .HasAnnotation("Relational:Sequence:.stock_hilo", "'stock_hilo', '', '1', '10', '', '', 'Int64', 'False'") + .HasAnnotation("SqlServer:ValueGenerationStrategy", SqlServerValueGenerationStrategy.IdentityColumn); + + modelBuilder.Entity("Nethereum.eShop.ApplicationCore.Entities.BasketAggregate.Basket", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("int") + .HasAnnotation("SqlServer:ValueGenerationStrategy", SqlServerValueGenerationStrategy.IdentityColumn); + + b.Property("BuyerAddress") + .IsRequired() + .HasColumnType("nvarchar(43)") + .HasMaxLength(43); + + b.Property("BuyerId") + .IsRequired() + .HasColumnType("nvarchar(256)") + .HasMaxLength(256); + + b.Property("TransactionHash") + .HasColumnType("nvarchar(67)") + .HasMaxLength(67); + + b.HasKey("Id"); + + b.HasIndex("BuyerAddress"); + + b.HasIndex("BuyerId"); + + b.ToTable("Baskets"); + }); + + modelBuilder.Entity("Nethereum.eShop.ApplicationCore.Entities.BasketAggregate.BasketItem", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("int") + .HasAnnotation("SqlServer:ValueGenerationStrategy", SqlServerValueGenerationStrategy.IdentityColumn); + + b.Property("BasketId") + .HasColumnType("int"); + + b.Property("CatalogItemId") + .HasColumnType("int"); + + b.Property("Quantity") + .HasColumnType("int"); + + b.Property("UnitPrice") + .HasColumnType("decimal(18,2)"); + + b.HasKey("Id"); + + b.HasIndex("BasketId"); + + b.ToTable("BasketItems"); + }); + + modelBuilder.Entity("Nethereum.eShop.ApplicationCore.Entities.BuyerAggregate.Buyer", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("int") + .HasAnnotation("SqlServer:ValueGenerationStrategy", SqlServerValueGenerationStrategy.IdentityColumn); + + b.Property("BuyerAddress") + .HasColumnType("nvarchar(43)") + .HasMaxLength(43); + + b.Property("BuyerId") + .IsRequired() + .HasColumnType("nvarchar(256)") + .HasMaxLength(256); + + b.HasKey("Id"); + + b.HasIndex("BuyerAddress") + .IsUnique() + .HasFilter("[BuyerAddress] IS NOT NULL"); + + b.HasIndex("BuyerId") + .IsUnique(); + + b.ToTable("Buyers"); + }); + + modelBuilder.Entity("Nethereum.eShop.ApplicationCore.Entities.BuyerAggregate.BuyerPostalAddress", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("int") + .HasAnnotation("SqlServer:ValueGenerationStrategy", SqlServerValueGenerationStrategy.IdentityColumn); + + b.Property("BuyerId") + .HasColumnType("int"); + + b.Property("Name") + .HasColumnType("nvarchar(max)"); + + b.HasKey("Id"); + + b.HasIndex("BuyerId"); + + b.ToTable("BuyerPostalAddress"); + }); + + modelBuilder.Entity("Nethereum.eShop.ApplicationCore.Entities.CatalogBrand", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("int") + .HasAnnotation("SqlServer:HiLoSequenceName", "catalog_brand_hilo") + .HasAnnotation("SqlServer:ValueGenerationStrategy", SqlServerValueGenerationStrategy.SequenceHiLo); + + b.Property("Brand") + .IsRequired() + .HasColumnType("nvarchar(100)") + .HasMaxLength(100); + + b.HasKey("Id"); + + b.ToTable("CatalogBrands"); + }); + + modelBuilder.Entity("Nethereum.eShop.ApplicationCore.Entities.CatalogItem", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("int") + .HasAnnotation("SqlServer:HiLoSequenceName", "catalog_hilo") + .HasAnnotation("SqlServer:ValueGenerationStrategy", SqlServerValueGenerationStrategy.SequenceHiLo); + + b.Property("AttributeJson") + .HasColumnType("nvarchar(max)"); + + b.Property("CatalogBrandId") + .HasColumnType("int"); + + b.Property("CatalogTypeId") + .HasColumnType("int"); + + b.Property("Depth") + .HasColumnType("int"); + + b.Property("Description") + .HasColumnType("nvarchar(max)"); + + b.Property("Gtin") + .IsRequired() + .HasColumnType("nvarchar(14)") + .HasMaxLength(14); + + b.Property("GtinRegistryId") + .HasColumnType("int"); + + b.Property("Height") + .HasColumnType("int"); + + b.Property("Name") + .IsRequired() + .HasColumnType("nvarchar(50)") + .HasMaxLength(50); + + b.Property("PictureLargeUri") + .HasColumnType("nvarchar(512)") + .HasMaxLength(512); + + b.Property("PictureMediumUri") + .HasColumnType("nvarchar(512)") + .HasMaxLength(512); + + b.Property("PictureSmallUri") + .HasColumnType("nvarchar(512)") + .HasMaxLength(512); + + b.Property("PictureUri") + .HasColumnType("nvarchar(512)") + .HasMaxLength(512); + + b.Property("Price") + .HasColumnType("decimal(18,2)"); + + b.Property("Rank") + .HasColumnType("int"); + + b.Property("Status") + .HasColumnType("int"); + + b.Property("Unit") + .HasColumnType("nvarchar(8)") + .HasMaxLength(8); + + b.Property("Weight") + .HasColumnType("int"); + + b.Property("Width") + .HasColumnType("int"); + + b.HasKey("Id"); + + b.HasIndex("CatalogBrandId"); + + b.HasIndex("CatalogTypeId"); + + b.ToTable("Catalog"); + }); + + modelBuilder.Entity("Nethereum.eShop.ApplicationCore.Entities.CatalogType", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("int") + .HasAnnotation("SqlServer:HiLoSequenceName", "catalog_type_hilo") + .HasAnnotation("SqlServer:ValueGenerationStrategy", SqlServerValueGenerationStrategy.SequenceHiLo); + + b.Property("Type") + .IsRequired() + .HasColumnType("nvarchar(100)") + .HasMaxLength(100); + + b.HasKey("Id"); + + b.ToTable("CatalogTypes"); + }); + + modelBuilder.Entity("Nethereum.eShop.ApplicationCore.Entities.OrderAggregate.Order", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("int") + .HasAnnotation("SqlServer:ValueGenerationStrategy", SqlServerValueGenerationStrategy.IdentityColumn); + + b.Property("ApproverAddress") + .HasColumnType("nvarchar(43)") + .HasMaxLength(43); + + b.Property("BuyerAddress") + .HasColumnType("nvarchar(43)") + .HasMaxLength(43); + + b.Property("BuyerId") + .IsRequired() + .HasColumnType("nvarchar(256)") + .HasMaxLength(256); + + b.Property("BuyerWalletAddress") + .HasColumnType("nvarchar(43)") + .HasMaxLength(43); + + b.Property("CurrencyAddress") + .HasColumnType("nvarchar(43)") + .HasMaxLength(43); + + b.Property("CurrencySymbol") + .HasColumnType("nvarchar(32)") + .HasMaxLength(32); + + b.Property("OrderDate") + .HasColumnType("datetimeoffset"); + + b.Property("PoDate") + .HasColumnType("datetimeoffset"); + + b.Property("PoNumber") + .HasColumnType("bigint"); + + b.Property("PoType") + .HasColumnType("int"); + + b.Property("QuoteId") + .HasColumnType("int"); + + b.Property("SellerId") + .HasColumnType("nvarchar(32)") + .HasMaxLength(32); + + b.Property("Status") + .HasColumnType("int"); + + b.Property("TransactionHash") + .HasColumnType("nvarchar(67)") + .HasMaxLength(67); + + b.HasKey("Id"); + + b.HasIndex("BuyerAddress"); + + b.HasIndex("BuyerId"); + + b.ToTable("Orders"); + }); + + modelBuilder.Entity("Nethereum.eShop.ApplicationCore.Entities.OrderAggregate.OrderItem", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("int") + .HasAnnotation("SqlServer:ValueGenerationStrategy", SqlServerValueGenerationStrategy.IdentityColumn); + + b.Property("ActualEscrowReleaseDate") + .HasColumnType("datetimeoffset"); + + b.Property("CurrencyValue") + .HasColumnType("nvarchar(100)") + .HasMaxLength(100); + + b.Property("GoodsIssueDate") + .HasColumnType("datetimeoffset"); + + b.Property("IsEscrowReleased") + .HasColumnType("bit"); + + b.Property("OrderId") + .HasColumnType("int"); + + b.Property("PlannedEscrowReleaseDate") + .HasColumnType("datetimeoffset"); + + b.Property("PoItemNumber") + .HasColumnType("int"); + + b.Property("PoItemStatus") + .HasColumnType("int"); + + b.Property("Quantity") + .HasColumnType("int"); + + b.Property("QuantityAddress") + .HasColumnType("nvarchar(43)") + .HasMaxLength(43); + + b.Property("QuantitySymbol") + .HasColumnType("nvarchar(32)") + .HasMaxLength(32); + + b.Property("Status") + .HasColumnType("int"); + + b.Property("Unit") + .HasColumnType("nvarchar(50)") + .HasMaxLength(50); + + b.Property("UnitPrice") + .HasColumnType("decimal(18,2)"); + + b.HasKey("Id"); + + b.HasIndex("OrderId"); + + b.ToTable("OrderItems"); + }); + + modelBuilder.Entity("Nethereum.eShop.ApplicationCore.Entities.QuoteAggregate.Quote", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("int") + .HasAnnotation("SqlServer:ValueGenerationStrategy", SqlServerValueGenerationStrategy.IdentityColumn); + + b.Property("ApproverAddress") + .HasColumnType("nvarchar(43)") + .HasMaxLength(43); + + b.Property("BuyerAddress") + .HasColumnType("nvarchar(43)") + .HasMaxLength(43); + + b.Property("BuyerId") + .IsRequired() + .HasColumnType("nvarchar(256)") + .HasMaxLength(256); + + b.Property("BuyerWalletAddress") + .HasColumnType("nvarchar(43)") + .HasMaxLength(43); + + b.Property("CurrencyAddress") + .HasColumnType("nvarchar(43)") + .HasMaxLength(43); + + b.Property("CurrencySymbol") + .HasColumnType("nvarchar(32)") + .HasMaxLength(32); + + b.Property("Date") + .HasColumnType("datetimeoffset"); + + b.Property("Expiry") + .HasColumnType("datetimeoffset"); + + b.Property("PoNumber") + .HasColumnType("bigint"); + + b.Property("PoType") + .HasColumnType("int"); + + b.Property("SellerId") + .HasColumnType("nvarchar(32)") + .HasMaxLength(32); + + b.Property("Status") + .HasColumnType("int"); + + b.Property("TransactionHash") + .HasColumnType("nvarchar(67)") + .HasMaxLength(67); + + b.HasKey("Id"); + + b.HasIndex("BuyerAddress"); + + b.HasIndex("BuyerId"); + + b.ToTable("Quotes"); + }); + + modelBuilder.Entity("Nethereum.eShop.ApplicationCore.Entities.QuoteAggregate.QuoteItem", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("int") + .HasAnnotation("SqlServer:ValueGenerationStrategy", SqlServerValueGenerationStrategy.IdentityColumn); + + b.Property("CurrencyValue") + .HasColumnType("nvarchar(max)"); + + b.Property("EscrowReleaseDate") + .HasColumnType("datetimeoffset"); + + b.Property("PoItemNumber") + .HasColumnType("int"); + + b.Property("Quantity") + .HasColumnType("int"); + + b.Property("QuantityAddress") + .HasColumnType("nvarchar(max)"); + + b.Property("QuantitySymbol") + .HasColumnType("nvarchar(max)"); + + b.Property("QuoteId") + .HasColumnType("int"); + + b.Property("Unit") + .HasColumnType("nvarchar(max)"); + + b.Property("UnitPrice") + .HasColumnType("decimal(18,2)"); + + b.HasKey("Id"); + + b.HasIndex("QuoteId"); + + b.ToTable("QuoteItems"); + }); + + modelBuilder.Entity("Nethereum.eShop.ApplicationCore.Entities.StockItem", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("int") + .HasAnnotation("SqlServer:HiLoSequenceName", "stock_hilo") + .HasAnnotation("SqlServer:ValueGenerationStrategy", SqlServerValueGenerationStrategy.SequenceHiLo); + + b.Property("CatalogItemId") + .HasColumnType("int"); + + b.Property("Location") + .IsRequired() + .HasColumnType("nvarchar(50)") + .HasMaxLength(50); + + b.Property("Quantity") + .HasColumnType("int"); + + b.HasKey("Id"); + + b.HasIndex("CatalogItemId"); + + b.ToTable("Stock"); + }); + + modelBuilder.Entity("Nethereum.eShop.ApplicationCore.Entities.BasketAggregate.Basket", b => + { + b.OwnsOne("Nethereum.eShop.ApplicationCore.Entities.PostalAddress", "BillTo", b1 => + { + b1.Property("BasketId") + .ValueGeneratedOnAdd() + .HasColumnType("int") + .HasAnnotation("SqlServer:ValueGenerationStrategy", SqlServerValueGenerationStrategy.IdentityColumn); + + b1.Property("City") + .IsRequired() + .HasColumnType("nvarchar(100)") + .HasMaxLength(100); + + b1.Property("Country") + .IsRequired() + .HasColumnType("nvarchar(90)") + .HasMaxLength(90); + + b1.Property("RecipientName") + .IsRequired() + .HasColumnType("nvarchar(255)") + .HasMaxLength(255); + + b1.Property("State") + .HasColumnType("nvarchar(60)") + .HasMaxLength(60); + + b1.Property("Street") + .IsRequired() + .HasColumnType("nvarchar(180)") + .HasMaxLength(180); + + b1.Property("ZipCode") + .IsRequired() + .HasColumnType("nvarchar(18)") + .HasMaxLength(18); + + b1.HasKey("BasketId"); + + b1.ToTable("Baskets"); + + b1.WithOwner() + .HasForeignKey("BasketId"); + }); + + b.OwnsOne("Nethereum.eShop.ApplicationCore.Entities.PostalAddress", "ShipTo", b1 => + { + b1.Property("BasketId") + .ValueGeneratedOnAdd() + .HasColumnType("int") + .HasAnnotation("SqlServer:ValueGenerationStrategy", SqlServerValueGenerationStrategy.IdentityColumn); + + b1.Property("City") + .IsRequired() + .HasColumnType("nvarchar(100)") + .HasMaxLength(100); + + b1.Property("Country") + .IsRequired() + .HasColumnType("nvarchar(90)") + .HasMaxLength(90); + + b1.Property("RecipientName") + .IsRequired() + .HasColumnType("nvarchar(255)") + .HasMaxLength(255); + + b1.Property("State") + .HasColumnType("nvarchar(60)") + .HasMaxLength(60); + + b1.Property("Street") + .IsRequired() + .HasColumnType("nvarchar(180)") + .HasMaxLength(180); + + b1.Property("ZipCode") + .IsRequired() + .HasColumnType("nvarchar(18)") + .HasMaxLength(18); + + b1.HasKey("BasketId"); + + b1.ToTable("Baskets"); + + b1.WithOwner() + .HasForeignKey("BasketId"); + }); + }); + + modelBuilder.Entity("Nethereum.eShop.ApplicationCore.Entities.BasketAggregate.BasketItem", b => + { + b.HasOne("Nethereum.eShop.ApplicationCore.Entities.BasketAggregate.Basket", null) + .WithMany("Items") + .HasForeignKey("BasketId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + }); + + modelBuilder.Entity("Nethereum.eShop.ApplicationCore.Entities.BuyerAggregate.BuyerPostalAddress", b => + { + b.HasOne("Nethereum.eShop.ApplicationCore.Entities.BuyerAggregate.Buyer", null) + .WithMany("PostalAddresses") + .HasForeignKey("BuyerId"); + + b.OwnsOne("Nethereum.eShop.ApplicationCore.Entities.PostalAddress", "PostalAddress", b1 => + { + b1.Property("BuyerPostalAddressId") + .ValueGeneratedOnAdd() + .HasColumnType("int") + .HasAnnotation("SqlServer:ValueGenerationStrategy", SqlServerValueGenerationStrategy.IdentityColumn); + + b1.Property("City") + .IsRequired() + .HasColumnType("nvarchar(100)") + .HasMaxLength(100); + + b1.Property("Country") + .IsRequired() + .HasColumnType("nvarchar(90)") + .HasMaxLength(90); + + b1.Property("RecipientName") + .IsRequired() + .HasColumnType("nvarchar(255)") + .HasMaxLength(255); + + b1.Property("State") + .HasColumnType("nvarchar(60)") + .HasMaxLength(60); + + b1.Property("Street") + .IsRequired() + .HasColumnType("nvarchar(180)") + .HasMaxLength(180); + + b1.Property("ZipCode") + .IsRequired() + .HasColumnType("nvarchar(18)") + .HasMaxLength(18); + + b1.HasKey("BuyerPostalAddressId"); + + b1.ToTable("BuyerPostalAddress"); + + b1.WithOwner() + .HasForeignKey("BuyerPostalAddressId"); + }); + }); + + modelBuilder.Entity("Nethereum.eShop.ApplicationCore.Entities.CatalogItem", b => + { + b.HasOne("Nethereum.eShop.ApplicationCore.Entities.CatalogBrand", "CatalogBrand") + .WithMany() + .HasForeignKey("CatalogBrandId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.HasOne("Nethereum.eShop.ApplicationCore.Entities.CatalogType", "CatalogType") + .WithMany() + .HasForeignKey("CatalogTypeId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + }); + + modelBuilder.Entity("Nethereum.eShop.ApplicationCore.Entities.OrderAggregate.Order", b => + { + b.OwnsOne("Nethereum.eShop.ApplicationCore.Entities.PostalAddress", "BillTo", b1 => + { + b1.Property("OrderId") + .ValueGeneratedOnAdd() + .HasColumnType("int") + .HasAnnotation("SqlServer:ValueGenerationStrategy", SqlServerValueGenerationStrategy.IdentityColumn); + + b1.Property("City") + .IsRequired() + .HasColumnType("nvarchar(100)") + .HasMaxLength(100); + + b1.Property("Country") + .IsRequired() + .HasColumnType("nvarchar(90)") + .HasMaxLength(90); + + b1.Property("RecipientName") + .IsRequired() + .HasColumnType("nvarchar(255)") + .HasMaxLength(255); + + b1.Property("State") + .HasColumnType("nvarchar(60)") + .HasMaxLength(60); + + b1.Property("Street") + .IsRequired() + .HasColumnType("nvarchar(180)") + .HasMaxLength(180); + + b1.Property("ZipCode") + .IsRequired() + .HasColumnType("nvarchar(18)") + .HasMaxLength(18); + + b1.HasKey("OrderId"); + + b1.ToTable("Orders"); + + b1.WithOwner() + .HasForeignKey("OrderId"); + }); + + b.OwnsOne("Nethereum.eShop.ApplicationCore.Entities.PostalAddress", "ShipTo", b1 => + { + b1.Property("OrderId") + .ValueGeneratedOnAdd() + .HasColumnType("int") + .HasAnnotation("SqlServer:ValueGenerationStrategy", SqlServerValueGenerationStrategy.IdentityColumn); + + b1.Property("City") + .IsRequired() + .HasColumnType("nvarchar(100)") + .HasMaxLength(100); + + b1.Property("Country") + .IsRequired() + .HasColumnType("nvarchar(90)") + .HasMaxLength(90); + + b1.Property("RecipientName") + .IsRequired() + .HasColumnType("nvarchar(255)") + .HasMaxLength(255); + + b1.Property("State") + .HasColumnType("nvarchar(60)") + .HasMaxLength(60); + + b1.Property("Street") + .IsRequired() + .HasColumnType("nvarchar(180)") + .HasMaxLength(180); + + b1.Property("ZipCode") + .IsRequired() + .HasColumnType("nvarchar(18)") + .HasMaxLength(18); + + b1.HasKey("OrderId"); + + b1.ToTable("Orders"); + + b1.WithOwner() + .HasForeignKey("OrderId"); + }); + }); + + modelBuilder.Entity("Nethereum.eShop.ApplicationCore.Entities.OrderAggregate.OrderItem", b => + { + b.HasOne("Nethereum.eShop.ApplicationCore.Entities.OrderAggregate.Order", null) + .WithMany("OrderItems") + .HasForeignKey("OrderId"); + + b.OwnsOne("Nethereum.eShop.ApplicationCore.Entities.CatalogItemExcerpt", "ItemOrdered", b1 => + { + b1.Property("OrderItemId") + .ValueGeneratedOnAdd() + .HasColumnType("int") + .HasAnnotation("SqlServer:ValueGenerationStrategy", SqlServerValueGenerationStrategy.IdentityColumn); + + b1.Property("CatalogItemId") + .HasColumnType("int"); + + b1.Property("Gtin") + .HasColumnType("nvarchar(max)"); + + b1.Property("GtinRegistryId") + .HasColumnType("int"); + + b1.Property("PictureUri") + .HasColumnType("nvarchar(512)") + .HasMaxLength(512); + + b1.Property("ProductName") + .IsRequired() + .HasColumnType("nvarchar(50)") + .HasMaxLength(50); + + b1.HasKey("OrderItemId"); + + b1.ToTable("OrderItems"); + + b1.WithOwner() + .HasForeignKey("OrderItemId"); + }); + }); + + modelBuilder.Entity("Nethereum.eShop.ApplicationCore.Entities.QuoteAggregate.Quote", b => + { + b.OwnsOne("Nethereum.eShop.ApplicationCore.Entities.PostalAddress", "BillTo", b1 => + { + b1.Property("QuoteId") + .ValueGeneratedOnAdd() + .HasColumnType("int") + .HasAnnotation("SqlServer:ValueGenerationStrategy", SqlServerValueGenerationStrategy.IdentityColumn); + + b1.Property("City") + .IsRequired() + .HasColumnType("nvarchar(100)") + .HasMaxLength(100); + + b1.Property("Country") + .IsRequired() + .HasColumnType("nvarchar(90)") + .HasMaxLength(90); + + b1.Property("RecipientName") + .IsRequired() + .HasColumnType("nvarchar(255)") + .HasMaxLength(255); + + b1.Property("State") + .HasColumnType("nvarchar(60)") + .HasMaxLength(60); + + b1.Property("Street") + .IsRequired() + .HasColumnType("nvarchar(180)") + .HasMaxLength(180); + + b1.Property("ZipCode") + .IsRequired() + .HasColumnType("nvarchar(18)") + .HasMaxLength(18); + + b1.HasKey("QuoteId"); + + b1.ToTable("Quotes"); + + b1.WithOwner() + .HasForeignKey("QuoteId"); + }); + + b.OwnsOne("Nethereum.eShop.ApplicationCore.Entities.PostalAddress", "ShipTo", b1 => + { + b1.Property("QuoteId") + .ValueGeneratedOnAdd() + .HasColumnType("int") + .HasAnnotation("SqlServer:ValueGenerationStrategy", SqlServerValueGenerationStrategy.IdentityColumn); + + b1.Property("City") + .IsRequired() + .HasColumnType("nvarchar(100)") + .HasMaxLength(100); + + b1.Property("Country") + .IsRequired() + .HasColumnType("nvarchar(90)") + .HasMaxLength(90); + + b1.Property("RecipientName") + .IsRequired() + .HasColumnType("nvarchar(255)") + .HasMaxLength(255); + + b1.Property("State") + .HasColumnType("nvarchar(60)") + .HasMaxLength(60); + + b1.Property("Street") + .IsRequired() + .HasColumnType("nvarchar(180)") + .HasMaxLength(180); + + b1.Property("ZipCode") + .IsRequired() + .HasColumnType("nvarchar(18)") + .HasMaxLength(18); + + b1.HasKey("QuoteId"); + + b1.ToTable("Quotes"); + + b1.WithOwner() + .HasForeignKey("QuoteId"); + }); + }); + + modelBuilder.Entity("Nethereum.eShop.ApplicationCore.Entities.QuoteAggregate.QuoteItem", b => + { + b.HasOne("Nethereum.eShop.ApplicationCore.Entities.QuoteAggregate.Quote", null) + .WithMany("QuoteItems") + .HasForeignKey("QuoteId"); + + b.OwnsOne("Nethereum.eShop.ApplicationCore.Entities.CatalogItemExcerpt", "ItemOrdered", b1 => + { + b1.Property("QuoteItemId") + .ValueGeneratedOnAdd() + .HasColumnType("int") + .HasAnnotation("SqlServer:ValueGenerationStrategy", SqlServerValueGenerationStrategy.IdentityColumn); + + b1.Property("CatalogItemId") + .HasColumnType("int"); + + b1.Property("Gtin") + .HasColumnType("nvarchar(max)"); + + b1.Property("GtinRegistryId") + .HasColumnType("int"); + + b1.Property("PictureUri") + .HasColumnType("nvarchar(512)") + .HasMaxLength(512); + + b1.Property("ProductName") + .IsRequired() + .HasColumnType("nvarchar(50)") + .HasMaxLength(50); + + b1.HasKey("QuoteItemId"); + + b1.ToTable("QuoteItems"); + + b1.WithOwner() + .HasForeignKey("QuoteItemId"); + }); + }); + + modelBuilder.Entity("Nethereum.eShop.ApplicationCore.Entities.StockItem", b => + { + b.HasOne("Nethereum.eShop.ApplicationCore.Entities.CatalogItem", "CatalogItem") + .WithMany() + .HasForeignKey("CatalogItemId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + }); +#pragma warning restore 612, 618 + } + } +} diff --git a/src/Nethereum.eShop/Infrastructure/Data/Migrations/20200304170042_ResizeColumns.cs b/src/Nethereum.eShop/Infrastructure/Data/Migrations/20200304170042_ResizeColumns.cs new file mode 100644 index 0000000..2f4d2a8 --- /dev/null +++ b/src/Nethereum.eShop/Infrastructure/Data/Migrations/20200304170042_ResizeColumns.cs @@ -0,0 +1,319 @@ +using Microsoft.EntityFrameworkCore.Migrations; + +namespace Nethereum.eShop.Infrastructure.Data.Migrations +{ + public partial class ResizeColumns : Migration + { + protected override void Up(MigrationBuilder migrationBuilder) + { + migrationBuilder.AlterColumn( + name: "SellerId", + table: "Quotes", + maxLength: 32, + nullable: true, + oldClrType: typeof(string), + oldType: "nvarchar(max)", + oldNullable: true); + + migrationBuilder.AlterColumn( + name: "CurrencySymbol", + table: "Quotes", + maxLength: 32, + nullable: true, + oldClrType: typeof(string), + oldType: "nvarchar(max)", + oldNullable: true); + + migrationBuilder.AlterColumn( + name: "CurrencyAddress", + table: "Quotes", + maxLength: 43, + nullable: true, + oldClrType: typeof(string), + oldType: "nvarchar(max)", + oldNullable: true); + + migrationBuilder.AlterColumn( + name: "ItemOrdered_PictureUri", + table: "QuoteItems", + maxLength: 512, + nullable: true, + oldClrType: typeof(string), + oldType: "nvarchar(max)", + oldNullable: true); + + migrationBuilder.AlterColumn( + name: "SellerId", + table: "Orders", + maxLength: 32, + nullable: true, + oldClrType: typeof(string), + oldType: "nvarchar(max)", + oldNullable: true); + + migrationBuilder.AlterColumn( + name: "CurrencySymbol", + table: "Orders", + maxLength: 32, + nullable: true, + oldClrType: typeof(string), + oldType: "nvarchar(max)", + oldNullable: true); + + migrationBuilder.AlterColumn( + name: "CurrencyAddress", + table: "Orders", + maxLength: 43, + nullable: true, + oldClrType: typeof(string), + oldType: "nvarchar(max)", + oldNullable: true); + + migrationBuilder.AlterColumn( + name: "ItemOrdered_PictureUri", + table: "OrderItems", + maxLength: 512, + nullable: true, + oldClrType: typeof(string), + oldType: "nvarchar(max)", + oldNullable: true); + + migrationBuilder.AlterColumn( + name: "Unit", + table: "OrderItems", + maxLength: 50, + nullable: true, + oldClrType: typeof(string), + oldType: "nvarchar(max)", + oldNullable: true); + + migrationBuilder.AlterColumn( + name: "QuantitySymbol", + table: "OrderItems", + maxLength: 32, + nullable: true, + oldClrType: typeof(string), + oldType: "nvarchar(max)", + oldNullable: true); + + migrationBuilder.AlterColumn( + name: "QuantityAddress", + table: "OrderItems", + maxLength: 43, + nullable: true, + oldClrType: typeof(string), + oldType: "nvarchar(max)", + oldNullable: true); + + migrationBuilder.AlterColumn( + name: "CurrencyValue", + table: "OrderItems", + maxLength: 100, + nullable: true, + oldClrType: typeof(string), + oldType: "nvarchar(max)", + oldNullable: true); + + migrationBuilder.AlterColumn( + name: "PictureUri", + table: "Catalog", + maxLength: 512, + nullable: true, + oldClrType: typeof(string), + oldType: "nvarchar(max)", + oldNullable: true); + + migrationBuilder.AlterColumn( + name: "PictureSmallUri", + table: "Catalog", + maxLength: 512, + nullable: true, + oldClrType: typeof(string), + oldType: "nvarchar(max)", + oldNullable: true); + + migrationBuilder.AlterColumn( + name: "PictureMediumUri", + table: "Catalog", + maxLength: 512, + nullable: true, + oldClrType: typeof(string), + oldType: "nvarchar(max)", + oldNullable: true); + + migrationBuilder.AlterColumn( + name: "PictureLargeUri", + table: "Catalog", + maxLength: 512, + nullable: true, + oldClrType: typeof(string), + oldType: "nvarchar(max)", + oldNullable: true); + + migrationBuilder.AlterColumn( + name: "TransactionHash", + table: "Baskets", + maxLength: 67, + nullable: true, + oldClrType: typeof(string), + oldType: "nvarchar(max)", + oldNullable: true); + } + + protected override void Down(MigrationBuilder migrationBuilder) + { + migrationBuilder.AlterColumn( + name: "SellerId", + table: "Quotes", + type: "nvarchar(max)", + nullable: true, + oldClrType: typeof(string), + oldMaxLength: 32, + oldNullable: true); + + migrationBuilder.AlterColumn( + name: "CurrencySymbol", + table: "Quotes", + type: "nvarchar(max)", + nullable: true, + oldClrType: typeof(string), + oldMaxLength: 32, + oldNullable: true); + + migrationBuilder.AlterColumn( + name: "CurrencyAddress", + table: "Quotes", + type: "nvarchar(max)", + nullable: true, + oldClrType: typeof(string), + oldMaxLength: 43, + oldNullable: true); + + migrationBuilder.AlterColumn( + name: "ItemOrdered_PictureUri", + table: "QuoteItems", + type: "nvarchar(max)", + nullable: true, + oldClrType: typeof(string), + oldMaxLength: 512, + oldNullable: true); + + migrationBuilder.AlterColumn( + name: "SellerId", + table: "Orders", + type: "nvarchar(max)", + nullable: true, + oldClrType: typeof(string), + oldMaxLength: 32, + oldNullable: true); + + migrationBuilder.AlterColumn( + name: "CurrencySymbol", + table: "Orders", + type: "nvarchar(max)", + nullable: true, + oldClrType: typeof(string), + oldMaxLength: 32, + oldNullable: true); + + migrationBuilder.AlterColumn( + name: "CurrencyAddress", + table: "Orders", + type: "nvarchar(max)", + nullable: true, + oldClrType: typeof(string), + oldMaxLength: 43, + oldNullable: true); + + migrationBuilder.AlterColumn( + name: "ItemOrdered_PictureUri", + table: "OrderItems", + type: "nvarchar(max)", + nullable: true, + oldClrType: typeof(string), + oldMaxLength: 512, + oldNullable: true); + + migrationBuilder.AlterColumn( + name: "Unit", + table: "OrderItems", + type: "nvarchar(max)", + nullable: true, + oldClrType: typeof(string), + oldMaxLength: 50, + oldNullable: true); + + migrationBuilder.AlterColumn( + name: "QuantitySymbol", + table: "OrderItems", + type: "nvarchar(max)", + nullable: true, + oldClrType: typeof(string), + oldMaxLength: 32, + oldNullable: true); + + migrationBuilder.AlterColumn( + name: "QuantityAddress", + table: "OrderItems", + type: "nvarchar(max)", + nullable: true, + oldClrType: typeof(string), + oldMaxLength: 43, + oldNullable: true); + + migrationBuilder.AlterColumn( + name: "CurrencyValue", + table: "OrderItems", + type: "nvarchar(max)", + nullable: true, + oldClrType: typeof(string), + oldMaxLength: 100, + oldNullable: true); + + migrationBuilder.AlterColumn( + name: "PictureUri", + table: "Catalog", + type: "nvarchar(max)", + nullable: true, + oldClrType: typeof(string), + oldMaxLength: 512, + oldNullable: true); + + migrationBuilder.AlterColumn( + name: "PictureSmallUri", + table: "Catalog", + type: "nvarchar(max)", + nullable: true, + oldClrType: typeof(string), + oldMaxLength: 512, + oldNullable: true); + + migrationBuilder.AlterColumn( + name: "PictureMediumUri", + table: "Catalog", + type: "nvarchar(max)", + nullable: true, + oldClrType: typeof(string), + oldMaxLength: 512, + oldNullable: true); + + migrationBuilder.AlterColumn( + name: "PictureLargeUri", + table: "Catalog", + type: "nvarchar(max)", + nullable: true, + oldClrType: typeof(string), + oldMaxLength: 512, + oldNullable: true); + + migrationBuilder.AlterColumn( + name: "TransactionHash", + table: "Baskets", + type: "nvarchar(max)", + nullable: true, + oldClrType: typeof(string), + oldMaxLength: 67, + oldNullable: true); + } + } +} diff --git a/src/Nethereum.eShop/Infrastructure/Data/Migrations/20200304171630_SetGtinColumnSize.Designer.cs b/src/Nethereum.eShop/Infrastructure/Data/Migrations/20200304171630_SetGtinColumnSize.Designer.cs new file mode 100644 index 0000000..01bc531 --- /dev/null +++ b/src/Nethereum.eShop/Infrastructure/Data/Migrations/20200304171630_SetGtinColumnSize.Designer.cs @@ -0,0 +1,950 @@ +// +using System; +using Microsoft.EntityFrameworkCore; +using Microsoft.EntityFrameworkCore.Infrastructure; +using Microsoft.EntityFrameworkCore.Metadata; +using Microsoft.EntityFrameworkCore.Migrations; +using Microsoft.EntityFrameworkCore.Storage.ValueConversion; +using Nethereum.eShop.Infrastructure.Data; + +namespace Nethereum.eShop.Infrastructure.Data.Migrations +{ + [DbContext(typeof(CatalogContext))] + [Migration("20200304171630_SetGtinColumnSize")] + partial class SetGtinColumnSize + { + protected override void BuildTargetModel(ModelBuilder modelBuilder) + { +#pragma warning disable 612, 618 + modelBuilder + .HasAnnotation("ProductVersion", "3.1.2") + .HasAnnotation("Relational:MaxIdentifierLength", 128) + .HasAnnotation("Relational:Sequence:.catalog_brand_hilo", "'catalog_brand_hilo', '', '1', '10', '', '', 'Int64', 'False'") + .HasAnnotation("Relational:Sequence:.catalog_hilo", "'catalog_hilo', '', '1', '10', '', '', 'Int64', 'False'") + .HasAnnotation("Relational:Sequence:.catalog_type_hilo", "'catalog_type_hilo', '', '1', '10', '', '', 'Int64', 'False'") + .HasAnnotation("Relational:Sequence:.stock_hilo", "'stock_hilo', '', '1', '10', '', '', 'Int64', 'False'") + .HasAnnotation("SqlServer:ValueGenerationStrategy", SqlServerValueGenerationStrategy.IdentityColumn); + + modelBuilder.Entity("Nethereum.eShop.ApplicationCore.Entities.BasketAggregate.Basket", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("int") + .HasAnnotation("SqlServer:ValueGenerationStrategy", SqlServerValueGenerationStrategy.IdentityColumn); + + b.Property("BuyerAddress") + .IsRequired() + .HasColumnType("nvarchar(43)") + .HasMaxLength(43); + + b.Property("BuyerId") + .IsRequired() + .HasColumnType("nvarchar(256)") + .HasMaxLength(256); + + b.Property("TransactionHash") + .HasColumnType("nvarchar(67)") + .HasMaxLength(67); + + b.HasKey("Id"); + + b.HasIndex("BuyerAddress"); + + b.HasIndex("BuyerId"); + + b.ToTable("Baskets"); + }); + + modelBuilder.Entity("Nethereum.eShop.ApplicationCore.Entities.BasketAggregate.BasketItem", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("int") + .HasAnnotation("SqlServer:ValueGenerationStrategy", SqlServerValueGenerationStrategy.IdentityColumn); + + b.Property("BasketId") + .HasColumnType("int"); + + b.Property("CatalogItemId") + .HasColumnType("int"); + + b.Property("Quantity") + .HasColumnType("int"); + + b.Property("UnitPrice") + .HasColumnType("decimal(18,2)"); + + b.HasKey("Id"); + + b.HasIndex("BasketId"); + + b.ToTable("BasketItems"); + }); + + modelBuilder.Entity("Nethereum.eShop.ApplicationCore.Entities.BuyerAggregate.Buyer", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("int") + .HasAnnotation("SqlServer:ValueGenerationStrategy", SqlServerValueGenerationStrategy.IdentityColumn); + + b.Property("BuyerAddress") + .HasColumnType("nvarchar(43)") + .HasMaxLength(43); + + b.Property("BuyerId") + .IsRequired() + .HasColumnType("nvarchar(256)") + .HasMaxLength(256); + + b.HasKey("Id"); + + b.HasIndex("BuyerAddress") + .IsUnique() + .HasFilter("[BuyerAddress] IS NOT NULL"); + + b.HasIndex("BuyerId") + .IsUnique(); + + b.ToTable("Buyers"); + }); + + modelBuilder.Entity("Nethereum.eShop.ApplicationCore.Entities.BuyerAggregate.BuyerPostalAddress", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("int") + .HasAnnotation("SqlServer:ValueGenerationStrategy", SqlServerValueGenerationStrategy.IdentityColumn); + + b.Property("BuyerId") + .HasColumnType("int"); + + b.Property("Name") + .HasColumnType("nvarchar(max)"); + + b.HasKey("Id"); + + b.HasIndex("BuyerId"); + + b.ToTable("BuyerPostalAddress"); + }); + + modelBuilder.Entity("Nethereum.eShop.ApplicationCore.Entities.CatalogBrand", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("int") + .HasAnnotation("SqlServer:HiLoSequenceName", "catalog_brand_hilo") + .HasAnnotation("SqlServer:ValueGenerationStrategy", SqlServerValueGenerationStrategy.SequenceHiLo); + + b.Property("Brand") + .IsRequired() + .HasColumnType("nvarchar(100)") + .HasMaxLength(100); + + b.HasKey("Id"); + + b.ToTable("CatalogBrands"); + }); + + modelBuilder.Entity("Nethereum.eShop.ApplicationCore.Entities.CatalogItem", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("int") + .HasAnnotation("SqlServer:HiLoSequenceName", "catalog_hilo") + .HasAnnotation("SqlServer:ValueGenerationStrategy", SqlServerValueGenerationStrategy.SequenceHiLo); + + b.Property("AttributeJson") + .HasColumnType("nvarchar(max)"); + + b.Property("CatalogBrandId") + .HasColumnType("int"); + + b.Property("CatalogTypeId") + .HasColumnType("int"); + + b.Property("Depth") + .HasColumnType("int"); + + b.Property("Description") + .HasColumnType("nvarchar(max)"); + + b.Property("Gtin") + .IsRequired() + .HasColumnType("nvarchar(14)") + .HasMaxLength(14); + + b.Property("GtinRegistryId") + .HasColumnType("int"); + + b.Property("Height") + .HasColumnType("int"); + + b.Property("Name") + .IsRequired() + .HasColumnType("nvarchar(50)") + .HasMaxLength(50); + + b.Property("PictureLargeUri") + .HasColumnType("nvarchar(512)") + .HasMaxLength(512); + + b.Property("PictureMediumUri") + .HasColumnType("nvarchar(512)") + .HasMaxLength(512); + + b.Property("PictureSmallUri") + .HasColumnType("nvarchar(512)") + .HasMaxLength(512); + + b.Property("PictureUri") + .HasColumnType("nvarchar(512)") + .HasMaxLength(512); + + b.Property("Price") + .HasColumnType("decimal(18,2)"); + + b.Property("Rank") + .HasColumnType("int"); + + b.Property("Status") + .HasColumnType("int"); + + b.Property("Unit") + .HasColumnType("nvarchar(8)") + .HasMaxLength(8); + + b.Property("Weight") + .HasColumnType("int"); + + b.Property("Width") + .HasColumnType("int"); + + b.HasKey("Id"); + + b.HasIndex("CatalogBrandId"); + + b.HasIndex("CatalogTypeId"); + + b.ToTable("Catalog"); + }); + + modelBuilder.Entity("Nethereum.eShop.ApplicationCore.Entities.CatalogType", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("int") + .HasAnnotation("SqlServer:HiLoSequenceName", "catalog_type_hilo") + .HasAnnotation("SqlServer:ValueGenerationStrategy", SqlServerValueGenerationStrategy.SequenceHiLo); + + b.Property("Type") + .IsRequired() + .HasColumnType("nvarchar(100)") + .HasMaxLength(100); + + b.HasKey("Id"); + + b.ToTable("CatalogTypes"); + }); + + modelBuilder.Entity("Nethereum.eShop.ApplicationCore.Entities.OrderAggregate.Order", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("int") + .HasAnnotation("SqlServer:ValueGenerationStrategy", SqlServerValueGenerationStrategy.IdentityColumn); + + b.Property("ApproverAddress") + .HasColumnType("nvarchar(43)") + .HasMaxLength(43); + + b.Property("BuyerAddress") + .HasColumnType("nvarchar(43)") + .HasMaxLength(43); + + b.Property("BuyerId") + .IsRequired() + .HasColumnType("nvarchar(256)") + .HasMaxLength(256); + + b.Property("BuyerWalletAddress") + .HasColumnType("nvarchar(43)") + .HasMaxLength(43); + + b.Property("CurrencyAddress") + .HasColumnType("nvarchar(43)") + .HasMaxLength(43); + + b.Property("CurrencySymbol") + .HasColumnType("nvarchar(32)") + .HasMaxLength(32); + + b.Property("OrderDate") + .HasColumnType("datetimeoffset"); + + b.Property("PoDate") + .HasColumnType("datetimeoffset"); + + b.Property("PoNumber") + .HasColumnType("bigint"); + + b.Property("PoType") + .HasColumnType("int"); + + b.Property("QuoteId") + .HasColumnType("int"); + + b.Property("SellerId") + .HasColumnType("nvarchar(32)") + .HasMaxLength(32); + + b.Property("Status") + .HasColumnType("int"); + + b.Property("TransactionHash") + .HasColumnType("nvarchar(67)") + .HasMaxLength(67); + + b.HasKey("Id"); + + b.HasIndex("BuyerAddress"); + + b.HasIndex("BuyerId"); + + b.ToTable("Orders"); + }); + + modelBuilder.Entity("Nethereum.eShop.ApplicationCore.Entities.OrderAggregate.OrderItem", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("int") + .HasAnnotation("SqlServer:ValueGenerationStrategy", SqlServerValueGenerationStrategy.IdentityColumn); + + b.Property("ActualEscrowReleaseDate") + .HasColumnType("datetimeoffset"); + + b.Property("CurrencyValue") + .HasColumnType("nvarchar(100)") + .HasMaxLength(100); + + b.Property("GoodsIssueDate") + .HasColumnType("datetimeoffset"); + + b.Property("IsEscrowReleased") + .HasColumnType("bit"); + + b.Property("OrderId") + .HasColumnType("int"); + + b.Property("PlannedEscrowReleaseDate") + .HasColumnType("datetimeoffset"); + + b.Property("PoItemNumber") + .HasColumnType("int"); + + b.Property("PoItemStatus") + .HasColumnType("int"); + + b.Property("Quantity") + .HasColumnType("int"); + + b.Property("QuantityAddress") + .HasColumnType("nvarchar(43)") + .HasMaxLength(43); + + b.Property("QuantitySymbol") + .HasColumnType("nvarchar(32)") + .HasMaxLength(32); + + b.Property("Status") + .HasColumnType("int"); + + b.Property("Unit") + .HasColumnType("nvarchar(50)") + .HasMaxLength(50); + + b.Property("UnitPrice") + .HasColumnType("decimal(18,2)"); + + b.HasKey("Id"); + + b.HasIndex("OrderId"); + + b.ToTable("OrderItems"); + }); + + modelBuilder.Entity("Nethereum.eShop.ApplicationCore.Entities.QuoteAggregate.Quote", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("int") + .HasAnnotation("SqlServer:ValueGenerationStrategy", SqlServerValueGenerationStrategy.IdentityColumn); + + b.Property("ApproverAddress") + .HasColumnType("nvarchar(43)") + .HasMaxLength(43); + + b.Property("BuyerAddress") + .HasColumnType("nvarchar(43)") + .HasMaxLength(43); + + b.Property("BuyerId") + .IsRequired() + .HasColumnType("nvarchar(256)") + .HasMaxLength(256); + + b.Property("BuyerWalletAddress") + .HasColumnType("nvarchar(43)") + .HasMaxLength(43); + + b.Property("CurrencyAddress") + .HasColumnType("nvarchar(43)") + .HasMaxLength(43); + + b.Property("CurrencySymbol") + .HasColumnType("nvarchar(32)") + .HasMaxLength(32); + + b.Property("Date") + .HasColumnType("datetimeoffset"); + + b.Property("Expiry") + .HasColumnType("datetimeoffset"); + + b.Property("PoNumber") + .HasColumnType("bigint"); + + b.Property("PoType") + .HasColumnType("int"); + + b.Property("SellerId") + .HasColumnType("nvarchar(32)") + .HasMaxLength(32); + + b.Property("Status") + .HasColumnType("int"); + + b.Property("TransactionHash") + .HasColumnType("nvarchar(67)") + .HasMaxLength(67); + + b.HasKey("Id"); + + b.HasIndex("BuyerAddress"); + + b.HasIndex("BuyerId"); + + b.ToTable("Quotes"); + }); + + modelBuilder.Entity("Nethereum.eShop.ApplicationCore.Entities.QuoteAggregate.QuoteItem", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("int") + .HasAnnotation("SqlServer:ValueGenerationStrategy", SqlServerValueGenerationStrategy.IdentityColumn); + + b.Property("CurrencyValue") + .HasColumnType("nvarchar(max)"); + + b.Property("EscrowReleaseDate") + .HasColumnType("datetimeoffset"); + + b.Property("PoItemNumber") + .HasColumnType("int"); + + b.Property("Quantity") + .HasColumnType("int"); + + b.Property("QuantityAddress") + .HasColumnType("nvarchar(max)"); + + b.Property("QuantitySymbol") + .HasColumnType("nvarchar(max)"); + + b.Property("QuoteId") + .HasColumnType("int"); + + b.Property("Unit") + .HasColumnType("nvarchar(max)"); + + b.Property("UnitPrice") + .HasColumnType("decimal(18,2)"); + + b.HasKey("Id"); + + b.HasIndex("QuoteId"); + + b.ToTable("QuoteItems"); + }); + + modelBuilder.Entity("Nethereum.eShop.ApplicationCore.Entities.StockItem", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("int") + .HasAnnotation("SqlServer:HiLoSequenceName", "stock_hilo") + .HasAnnotation("SqlServer:ValueGenerationStrategy", SqlServerValueGenerationStrategy.SequenceHiLo); + + b.Property("CatalogItemId") + .HasColumnType("int"); + + b.Property("Location") + .IsRequired() + .HasColumnType("nvarchar(50)") + .HasMaxLength(50); + + b.Property("Quantity") + .HasColumnType("int"); + + b.HasKey("Id"); + + b.HasIndex("CatalogItemId"); + + b.ToTable("Stock"); + }); + + modelBuilder.Entity("Nethereum.eShop.ApplicationCore.Entities.BasketAggregate.Basket", b => + { + b.OwnsOne("Nethereum.eShop.ApplicationCore.Entities.PostalAddress", "BillTo", b1 => + { + b1.Property("BasketId") + .ValueGeneratedOnAdd() + .HasColumnType("int") + .HasAnnotation("SqlServer:ValueGenerationStrategy", SqlServerValueGenerationStrategy.IdentityColumn); + + b1.Property("City") + .IsRequired() + .HasColumnType("nvarchar(100)") + .HasMaxLength(100); + + b1.Property("Country") + .IsRequired() + .HasColumnType("nvarchar(90)") + .HasMaxLength(90); + + b1.Property("RecipientName") + .IsRequired() + .HasColumnType("nvarchar(255)") + .HasMaxLength(255); + + b1.Property("State") + .HasColumnType("nvarchar(60)") + .HasMaxLength(60); + + b1.Property("Street") + .IsRequired() + .HasColumnType("nvarchar(180)") + .HasMaxLength(180); + + b1.Property("ZipCode") + .IsRequired() + .HasColumnType("nvarchar(18)") + .HasMaxLength(18); + + b1.HasKey("BasketId"); + + b1.ToTable("Baskets"); + + b1.WithOwner() + .HasForeignKey("BasketId"); + }); + + b.OwnsOne("Nethereum.eShop.ApplicationCore.Entities.PostalAddress", "ShipTo", b1 => + { + b1.Property("BasketId") + .ValueGeneratedOnAdd() + .HasColumnType("int") + .HasAnnotation("SqlServer:ValueGenerationStrategy", SqlServerValueGenerationStrategy.IdentityColumn); + + b1.Property("City") + .IsRequired() + .HasColumnType("nvarchar(100)") + .HasMaxLength(100); + + b1.Property("Country") + .IsRequired() + .HasColumnType("nvarchar(90)") + .HasMaxLength(90); + + b1.Property("RecipientName") + .IsRequired() + .HasColumnType("nvarchar(255)") + .HasMaxLength(255); + + b1.Property("State") + .HasColumnType("nvarchar(60)") + .HasMaxLength(60); + + b1.Property("Street") + .IsRequired() + .HasColumnType("nvarchar(180)") + .HasMaxLength(180); + + b1.Property("ZipCode") + .IsRequired() + .HasColumnType("nvarchar(18)") + .HasMaxLength(18); + + b1.HasKey("BasketId"); + + b1.ToTable("Baskets"); + + b1.WithOwner() + .HasForeignKey("BasketId"); + }); + }); + + modelBuilder.Entity("Nethereum.eShop.ApplicationCore.Entities.BasketAggregate.BasketItem", b => + { + b.HasOne("Nethereum.eShop.ApplicationCore.Entities.BasketAggregate.Basket", null) + .WithMany("Items") + .HasForeignKey("BasketId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + }); + + modelBuilder.Entity("Nethereum.eShop.ApplicationCore.Entities.BuyerAggregate.BuyerPostalAddress", b => + { + b.HasOne("Nethereum.eShop.ApplicationCore.Entities.BuyerAggregate.Buyer", null) + .WithMany("PostalAddresses") + .HasForeignKey("BuyerId"); + + b.OwnsOne("Nethereum.eShop.ApplicationCore.Entities.PostalAddress", "PostalAddress", b1 => + { + b1.Property("BuyerPostalAddressId") + .ValueGeneratedOnAdd() + .HasColumnType("int") + .HasAnnotation("SqlServer:ValueGenerationStrategy", SqlServerValueGenerationStrategy.IdentityColumn); + + b1.Property("City") + .IsRequired() + .HasColumnType("nvarchar(100)") + .HasMaxLength(100); + + b1.Property("Country") + .IsRequired() + .HasColumnType("nvarchar(90)") + .HasMaxLength(90); + + b1.Property("RecipientName") + .IsRequired() + .HasColumnType("nvarchar(255)") + .HasMaxLength(255); + + b1.Property("State") + .HasColumnType("nvarchar(60)") + .HasMaxLength(60); + + b1.Property("Street") + .IsRequired() + .HasColumnType("nvarchar(180)") + .HasMaxLength(180); + + b1.Property("ZipCode") + .IsRequired() + .HasColumnType("nvarchar(18)") + .HasMaxLength(18); + + b1.HasKey("BuyerPostalAddressId"); + + b1.ToTable("BuyerPostalAddress"); + + b1.WithOwner() + .HasForeignKey("BuyerPostalAddressId"); + }); + }); + + modelBuilder.Entity("Nethereum.eShop.ApplicationCore.Entities.CatalogItem", b => + { + b.HasOne("Nethereum.eShop.ApplicationCore.Entities.CatalogBrand", "CatalogBrand") + .WithMany() + .HasForeignKey("CatalogBrandId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.HasOne("Nethereum.eShop.ApplicationCore.Entities.CatalogType", "CatalogType") + .WithMany() + .HasForeignKey("CatalogTypeId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + }); + + modelBuilder.Entity("Nethereum.eShop.ApplicationCore.Entities.OrderAggregate.Order", b => + { + b.OwnsOne("Nethereum.eShop.ApplicationCore.Entities.PostalAddress", "BillTo", b1 => + { + b1.Property("OrderId") + .ValueGeneratedOnAdd() + .HasColumnType("int") + .HasAnnotation("SqlServer:ValueGenerationStrategy", SqlServerValueGenerationStrategy.IdentityColumn); + + b1.Property("City") + .IsRequired() + .HasColumnType("nvarchar(100)") + .HasMaxLength(100); + + b1.Property("Country") + .IsRequired() + .HasColumnType("nvarchar(90)") + .HasMaxLength(90); + + b1.Property("RecipientName") + .IsRequired() + .HasColumnType("nvarchar(255)") + .HasMaxLength(255); + + b1.Property("State") + .HasColumnType("nvarchar(60)") + .HasMaxLength(60); + + b1.Property("Street") + .IsRequired() + .HasColumnType("nvarchar(180)") + .HasMaxLength(180); + + b1.Property("ZipCode") + .IsRequired() + .HasColumnType("nvarchar(18)") + .HasMaxLength(18); + + b1.HasKey("OrderId"); + + b1.ToTable("Orders"); + + b1.WithOwner() + .HasForeignKey("OrderId"); + }); + + b.OwnsOne("Nethereum.eShop.ApplicationCore.Entities.PostalAddress", "ShipTo", b1 => + { + b1.Property("OrderId") + .ValueGeneratedOnAdd() + .HasColumnType("int") + .HasAnnotation("SqlServer:ValueGenerationStrategy", SqlServerValueGenerationStrategy.IdentityColumn); + + b1.Property("City") + .IsRequired() + .HasColumnType("nvarchar(100)") + .HasMaxLength(100); + + b1.Property("Country") + .IsRequired() + .HasColumnType("nvarchar(90)") + .HasMaxLength(90); + + b1.Property("RecipientName") + .IsRequired() + .HasColumnType("nvarchar(255)") + .HasMaxLength(255); + + b1.Property("State") + .HasColumnType("nvarchar(60)") + .HasMaxLength(60); + + b1.Property("Street") + .IsRequired() + .HasColumnType("nvarchar(180)") + .HasMaxLength(180); + + b1.Property("ZipCode") + .IsRequired() + .HasColumnType("nvarchar(18)") + .HasMaxLength(18); + + b1.HasKey("OrderId"); + + b1.ToTable("Orders"); + + b1.WithOwner() + .HasForeignKey("OrderId"); + }); + }); + + modelBuilder.Entity("Nethereum.eShop.ApplicationCore.Entities.OrderAggregate.OrderItem", b => + { + b.HasOne("Nethereum.eShop.ApplicationCore.Entities.OrderAggregate.Order", null) + .WithMany("OrderItems") + .HasForeignKey("OrderId"); + + b.OwnsOne("Nethereum.eShop.ApplicationCore.Entities.CatalogItemExcerpt", "ItemOrdered", b1 => + { + b1.Property("OrderItemId") + .ValueGeneratedOnAdd() + .HasColumnType("int") + .HasAnnotation("SqlServer:ValueGenerationStrategy", SqlServerValueGenerationStrategy.IdentityColumn); + + b1.Property("CatalogItemId") + .HasColumnType("int"); + + b1.Property("Gtin") + .HasColumnType("nvarchar(14)") + .HasMaxLength(14); + + b1.Property("GtinRegistryId") + .HasColumnType("int"); + + b1.Property("PictureUri") + .HasColumnType("nvarchar(512)") + .HasMaxLength(512); + + b1.Property("ProductName") + .IsRequired() + .HasColumnType("nvarchar(50)") + .HasMaxLength(50); + + b1.HasKey("OrderItemId"); + + b1.ToTable("OrderItems"); + + b1.WithOwner() + .HasForeignKey("OrderItemId"); + }); + }); + + modelBuilder.Entity("Nethereum.eShop.ApplicationCore.Entities.QuoteAggregate.Quote", b => + { + b.OwnsOne("Nethereum.eShop.ApplicationCore.Entities.PostalAddress", "BillTo", b1 => + { + b1.Property("QuoteId") + .ValueGeneratedOnAdd() + .HasColumnType("int") + .HasAnnotation("SqlServer:ValueGenerationStrategy", SqlServerValueGenerationStrategy.IdentityColumn); + + b1.Property("City") + .IsRequired() + .HasColumnType("nvarchar(100)") + .HasMaxLength(100); + + b1.Property("Country") + .IsRequired() + .HasColumnType("nvarchar(90)") + .HasMaxLength(90); + + b1.Property("RecipientName") + .IsRequired() + .HasColumnType("nvarchar(255)") + .HasMaxLength(255); + + b1.Property("State") + .HasColumnType("nvarchar(60)") + .HasMaxLength(60); + + b1.Property("Street") + .IsRequired() + .HasColumnType("nvarchar(180)") + .HasMaxLength(180); + + b1.Property("ZipCode") + .IsRequired() + .HasColumnType("nvarchar(18)") + .HasMaxLength(18); + + b1.HasKey("QuoteId"); + + b1.ToTable("Quotes"); + + b1.WithOwner() + .HasForeignKey("QuoteId"); + }); + + b.OwnsOne("Nethereum.eShop.ApplicationCore.Entities.PostalAddress", "ShipTo", b1 => + { + b1.Property("QuoteId") + .ValueGeneratedOnAdd() + .HasColumnType("int") + .HasAnnotation("SqlServer:ValueGenerationStrategy", SqlServerValueGenerationStrategy.IdentityColumn); + + b1.Property("City") + .IsRequired() + .HasColumnType("nvarchar(100)") + .HasMaxLength(100); + + b1.Property("Country") + .IsRequired() + .HasColumnType("nvarchar(90)") + .HasMaxLength(90); + + b1.Property("RecipientName") + .IsRequired() + .HasColumnType("nvarchar(255)") + .HasMaxLength(255); + + b1.Property("State") + .HasColumnType("nvarchar(60)") + .HasMaxLength(60); + + b1.Property("Street") + .IsRequired() + .HasColumnType("nvarchar(180)") + .HasMaxLength(180); + + b1.Property("ZipCode") + .IsRequired() + .HasColumnType("nvarchar(18)") + .HasMaxLength(18); + + b1.HasKey("QuoteId"); + + b1.ToTable("Quotes"); + + b1.WithOwner() + .HasForeignKey("QuoteId"); + }); + }); + + modelBuilder.Entity("Nethereum.eShop.ApplicationCore.Entities.QuoteAggregate.QuoteItem", b => + { + b.HasOne("Nethereum.eShop.ApplicationCore.Entities.QuoteAggregate.Quote", null) + .WithMany("QuoteItems") + .HasForeignKey("QuoteId"); + + b.OwnsOne("Nethereum.eShop.ApplicationCore.Entities.CatalogItemExcerpt", "ItemOrdered", b1 => + { + b1.Property("QuoteItemId") + .ValueGeneratedOnAdd() + .HasColumnType("int") + .HasAnnotation("SqlServer:ValueGenerationStrategy", SqlServerValueGenerationStrategy.IdentityColumn); + + b1.Property("CatalogItemId") + .HasColumnType("int"); + + b1.Property("Gtin") + .HasColumnType("nvarchar(14)") + .HasMaxLength(14); + + b1.Property("GtinRegistryId") + .HasColumnType("int"); + + b1.Property("PictureUri") + .HasColumnType("nvarchar(512)") + .HasMaxLength(512); + + b1.Property("ProductName") + .IsRequired() + .HasColumnType("nvarchar(50)") + .HasMaxLength(50); + + b1.HasKey("QuoteItemId"); + + b1.ToTable("QuoteItems"); + + b1.WithOwner() + .HasForeignKey("QuoteItemId"); + }); + }); + + modelBuilder.Entity("Nethereum.eShop.ApplicationCore.Entities.StockItem", b => + { + b.HasOne("Nethereum.eShop.ApplicationCore.Entities.CatalogItem", "CatalogItem") + .WithMany() + .HasForeignKey("CatalogItemId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + }); +#pragma warning restore 612, 618 + } + } +} diff --git a/src/Nethereum.eShop/Infrastructure/Data/Migrations/20200304171630_SetGtinColumnSize.cs b/src/Nethereum.eShop/Infrastructure/Data/Migrations/20200304171630_SetGtinColumnSize.cs new file mode 100644 index 0000000..c4382f2 --- /dev/null +++ b/src/Nethereum.eShop/Infrastructure/Data/Migrations/20200304171630_SetGtinColumnSize.cs @@ -0,0 +1,49 @@ +using Microsoft.EntityFrameworkCore.Migrations; + +namespace Nethereum.eShop.Infrastructure.Data.Migrations +{ + public partial class SetGtinColumnSize : Migration + { + protected override void Up(MigrationBuilder migrationBuilder) + { + migrationBuilder.AlterColumn( + name: "ItemOrdered_Gtin", + table: "QuoteItems", + maxLength: 14, + nullable: true, + oldClrType: typeof(string), + oldType: "nvarchar(max)", + oldNullable: true); + + migrationBuilder.AlterColumn( + name: "ItemOrdered_Gtin", + table: "OrderItems", + maxLength: 14, + nullable: true, + oldClrType: typeof(string), + oldType: "nvarchar(max)", + oldNullable: true); + } + + protected override void Down(MigrationBuilder migrationBuilder) + { + migrationBuilder.AlterColumn( + name: "ItemOrdered_Gtin", + table: "QuoteItems", + type: "nvarchar(max)", + nullable: true, + oldClrType: typeof(string), + oldMaxLength: 14, + oldNullable: true); + + migrationBuilder.AlterColumn( + name: "ItemOrdered_Gtin", + table: "OrderItems", + type: "nvarchar(max)", + nullable: true, + oldClrType: typeof(string), + oldMaxLength: 14, + oldNullable: true); + } + } +} diff --git a/src/Nethereum.eShop/Infrastructure/Data/Migrations/CatalogContextModelSnapshot.cs b/src/Nethereum.eShop/Infrastructure/Data/Migrations/CatalogContextModelSnapshot.cs index b5cb66d..3275bce 100644 --- a/src/Nethereum.eShop/Infrastructure/Data/Migrations/CatalogContextModelSnapshot.cs +++ b/src/Nethereum.eShop/Infrastructure/Data/Migrations/CatalogContextModelSnapshot.cs @@ -15,7 +15,7 @@ protected override void BuildModel(ModelBuilder modelBuilder) { #pragma warning disable 612, 618 modelBuilder - .HasAnnotation("ProductVersion", "3.1.1") + .HasAnnotation("ProductVersion", "3.1.2") .HasAnnotation("Relational:MaxIdentifierLength", 128) .HasAnnotation("Relational:Sequence:.catalog_brand_hilo", "'catalog_brand_hilo', '', '1', '10', '', '', 'Int64', 'False'") .HasAnnotation("Relational:Sequence:.catalog_hilo", "'catalog_hilo', '', '1', '10', '', '', 'Int64', 'False'") @@ -41,7 +41,8 @@ protected override void BuildModel(ModelBuilder modelBuilder) .HasMaxLength(256); b.Property("TransactionHash") - .HasColumnType("nvarchar(max)"); + .HasColumnType("nvarchar(67)") + .HasMaxLength(67); b.HasKey("Id"); @@ -184,16 +185,20 @@ protected override void BuildModel(ModelBuilder modelBuilder) .HasMaxLength(50); b.Property("PictureLargeUri") - .HasColumnType("nvarchar(max)"); + .HasColumnType("nvarchar(512)") + .HasMaxLength(512); b.Property("PictureMediumUri") - .HasColumnType("nvarchar(max)"); + .HasColumnType("nvarchar(512)") + .HasMaxLength(512); b.Property("PictureSmallUri") - .HasColumnType("nvarchar(max)"); + .HasColumnType("nvarchar(512)") + .HasMaxLength(512); b.Property("PictureUri") - .HasColumnType("nvarchar(max)"); + .HasColumnType("nvarchar(512)") + .HasMaxLength(512); b.Property("Price") .HasColumnType("decimal(18,2)"); @@ -266,10 +271,12 @@ protected override void BuildModel(ModelBuilder modelBuilder) .HasMaxLength(43); b.Property("CurrencyAddress") - .HasColumnType("nvarchar(max)"); + .HasColumnType("nvarchar(43)") + .HasMaxLength(43); b.Property("CurrencySymbol") - .HasColumnType("nvarchar(max)"); + .HasColumnType("nvarchar(32)") + .HasMaxLength(32); b.Property("OrderDate") .HasColumnType("datetimeoffset"); @@ -287,7 +294,8 @@ protected override void BuildModel(ModelBuilder modelBuilder) .HasColumnType("int"); b.Property("SellerId") - .HasColumnType("nvarchar(max)"); + .HasColumnType("nvarchar(32)") + .HasMaxLength(32); b.Property("Status") .HasColumnType("int"); @@ -316,7 +324,8 @@ protected override void BuildModel(ModelBuilder modelBuilder) .HasColumnType("datetimeoffset"); b.Property("CurrencyValue") - .HasColumnType("nvarchar(max)"); + .HasColumnType("nvarchar(100)") + .HasMaxLength(100); b.Property("GoodsIssueDate") .HasColumnType("datetimeoffset"); @@ -340,16 +349,19 @@ protected override void BuildModel(ModelBuilder modelBuilder) .HasColumnType("int"); b.Property("QuantityAddress") - .HasColumnType("nvarchar(max)"); + .HasColumnType("nvarchar(43)") + .HasMaxLength(43); b.Property("QuantitySymbol") - .HasColumnType("nvarchar(max)"); + .HasColumnType("nvarchar(32)") + .HasMaxLength(32); b.Property("Status") .HasColumnType("int"); b.Property("Unit") - .HasColumnType("nvarchar(max)"); + .HasColumnType("nvarchar(50)") + .HasMaxLength(50); b.Property("UnitPrice") .HasColumnType("decimal(18,2)"); @@ -386,10 +398,12 @@ protected override void BuildModel(ModelBuilder modelBuilder) .HasMaxLength(43); b.Property("CurrencyAddress") - .HasColumnType("nvarchar(max)"); + .HasColumnType("nvarchar(43)") + .HasMaxLength(43); b.Property("CurrencySymbol") - .HasColumnType("nvarchar(max)"); + .HasColumnType("nvarchar(32)") + .HasMaxLength(32); b.Property("Date") .HasColumnType("datetimeoffset"); @@ -404,7 +418,8 @@ protected override void BuildModel(ModelBuilder modelBuilder) .HasColumnType("int"); b.Property("SellerId") - .HasColumnType("nvarchar(max)"); + .HasColumnType("nvarchar(32)") + .HasMaxLength(32); b.Property("Status") .HasColumnType("int"); @@ -763,13 +778,15 @@ protected override void BuildModel(ModelBuilder modelBuilder) .HasColumnType("int"); b1.Property("Gtin") - .HasColumnType("nvarchar(max)"); + .HasColumnType("nvarchar(14)") + .HasMaxLength(14); b1.Property("GtinRegistryId") .HasColumnType("int"); b1.Property("PictureUri") - .HasColumnType("nvarchar(max)"); + .HasColumnType("nvarchar(512)") + .HasMaxLength(512); b1.Property("ProductName") .IsRequired() @@ -893,13 +910,15 @@ protected override void BuildModel(ModelBuilder modelBuilder) .HasColumnType("int"); b1.Property("Gtin") - .HasColumnType("nvarchar(max)"); + .HasColumnType("nvarchar(14)") + .HasMaxLength(14); b1.Property("GtinRegistryId") .HasColumnType("int"); b1.Property("PictureUri") - .HasColumnType("nvarchar(max)"); + .HasColumnType("nvarchar(512)") + .HasMaxLength(512); b1.Property("ProductName") .IsRequired() diff --git a/src/Web/.config/dotnet-tools.json b/src/Web/.config/dotnet-tools.json index f2de671..56e0950 100644 --- a/src/Web/.config/dotnet-tools.json +++ b/src/Web/.config/dotnet-tools.json @@ -3,7 +3,7 @@ "isRoot": true, "tools": { "dotnet-ef": { - "version": "3.1.1", + "version": "3.1.2", "commands": [ "dotnet-ef" ] diff --git a/src/Web/GenerateDbCreationScripts.bat b/src/Web/GenerateDbCreationScripts.bat new file mode 100644 index 0000000..59432d1 --- /dev/null +++ b/src/Web/GenerateDbCreationScripts.bat @@ -0,0 +1,4 @@ +rem Create First Migration aka InitialCreate +dotnet build +dotnet-ef migrations script -o c:\temp\CreateCatalogDb.sql --project ..\Nethereum.eShop --context Nethereum.eShop.Infrastructure.Data.CatalogContext --no-build +dotnet ef migrations script -o c:\temp\CreateAppIdentityContextDb.sql --project ..\Nethereum.eShop --context Nethereum.eShop.Infrastructure.Identity.AppIdentityDbContext --no-build \ No newline at end of file diff --git a/src/Web/Program.cs b/src/Web/Program.cs index 93cc851..5dcb5e8 100644 --- a/src/Web/Program.cs +++ b/src/Web/Program.cs @@ -20,6 +20,7 @@ public async static Task Main(string[] args) using (var scope = host.Services.CreateScope()) { var services = scope.ServiceProvider; + var loggerFactory = services.GetRequiredService(); try { diff --git a/src/Web/Web.csproj b/src/Web/Web.csproj index eef855e..3802e6c 100644 --- a/src/Web/Web.csproj +++ b/src/Web/Web.csproj @@ -19,6 +19,7 @@ + diff --git a/src/WebJobs/Functions.cs b/src/WebJobs/Functions.cs index 34c48ee..49212a1 100644 --- a/src/WebJobs/Functions.cs +++ b/src/WebJobs/Functions.cs @@ -33,7 +33,7 @@ public async Task CreateFakePurchaseOrders([TimerTrigger("00:00:05")] TimerInfo // the hack below works locally using the same app instance // but will most likely fail on Azure // where a new instance of the app will probably be instantiated on each interval - static bool _processing = false; + private static bool _processing = false; // [Singleton] public async Task ProcessBlockchainEvents([TimerTrigger("00:00:05")] TimerInfo timer, ILogger logger) diff --git a/src/WebJobs/Jobs/CreateFakePurchaseOrders.cs b/src/WebJobs/Jobs/CreateFakePurchaseOrders.cs index d85d39f..a34fc11 100644 --- a/src/WebJobs/Jobs/CreateFakePurchaseOrders.cs +++ b/src/WebJobs/Jobs/CreateFakePurchaseOrders.cs @@ -69,7 +69,7 @@ private async Task CreatePoForQuote(ILogger logger, WalletBuyerService walletBuy return; } - var po = CreateDummyPoForPurchasingCreate(quote).ToBuyerPo(); + var po = CreateDummyPoForPurchasingCreate(quote, walletBuyerService.ContractHandler.ContractAddress).ToBuyerPo(); var receipt = await walletBuyerService.CreatePurchaseOrderRequestAndWaitForReceiptAsync(po); var createdEvent = receipt.DecodeAllEvents().FirstOrDefault(); @@ -88,16 +88,16 @@ private async Task CreatePoForQuote(ILogger logger, WalletBuyerService walletBuy } } - public Storage.Po CreateDummyPoForPurchasingCreate(Quote quote) + public Storage.Po CreateDummyPoForPurchasingCreate(Quote quote, string buyerWalletAddress) { var po = new Storage.Po() { // PoNumber assigned by contract - BuyerAddress = "0x37ed4f49ec2c7bdcce8631b1a7b54ed5d4aa9610", - ReceiverAddress = "0x36ed4f49ec2c7bdcce8631b1a7b54ed5d4aa9610", - BuyerWalletAddress = "0x39ed4f49ec2c7bdcce8631b1a7b54ed5d4aa9610", + BuyerAddress = "0x94618601fe6cb8912b274e5a00453949a57f8c1e", + ReceiverAddress = "0x94618601fe6cb8912b274e5a00453949a57f8c1e", + BuyerWalletAddress = buyerWalletAddress, CurrencySymbol = "DAI", - CurrencyAddress = "0x41ed4f49ec2c7bdcce8631b1a7b54ed5d4aa9610", + CurrencyAddress = "0xef76bcb4216fbbbd4d6e88082d5654def9b6fe2f", QuoteId = quote.Id, QuoteExpiryDate = DateTimeOffset.UtcNow.AddMonths(1).ToUnixTimeSeconds(), ApproverAddress = string.Empty, // assigned by contract diff --git a/src/WebJobs/JsonFileBlockProgressRepository.cs b/src/WebJobs/JsonFileBlockProgressRepository.cs index 3ce1615..08451d8 100644 --- a/src/WebJobs/JsonFileBlockProgressRepository.cs +++ b/src/WebJobs/JsonFileBlockProgressRepository.cs @@ -1,18 +1,16 @@ using Nethereum.BlockchainProcessing.ProgressRepositories; -using System; -using System.Collections.Generic; +using Nethereum.eShop.WebJobs.Configuration; using System.IO; -using System.Text; using System.Threading.Tasks; namespace Nethereum.eShop.WebJobs { public class JsonFileBlockProgressRepository: JsonBlockProgressRepository { - public JsonFileBlockProgressRepository(string jsonFile):base( - () => Task.FromResult(File.Exists(jsonFile)), - async (json) => await File.WriteAllTextAsync(jsonFile, json), - async () => await File.ReadAllTextAsync(jsonFile)) + public JsonFileBlockProgressRepository(EshopConfiguration eshopConfiguration):base( + () => Task.FromResult(File.Exists(eshopConfiguration.PurchaseOrderEventLogConfiguration.BlockProgressJsonFile)), + async (json) => await File.WriteAllTextAsync(eshopConfiguration.PurchaseOrderEventLogConfiguration.BlockProgressJsonFile, json), + async () => await File.ReadAllTextAsync(eshopConfiguration.PurchaseOrderEventLogConfiguration.BlockProgressJsonFile)) { } diff --git a/src/WebJobs/Program.cs b/src/WebJobs/Program.cs index 899883f..10cc038 100644 --- a/src/WebJobs/Program.cs +++ b/src/WebJobs/Program.cs @@ -21,7 +21,7 @@ class Program { static void Main(string[] args) { - IConfigurationRoot config = null; + IConfiguration config = null; EshopConfiguration eShopConfig = null; var hostBuilder = Host.CreateDefaultBuilder(args); @@ -39,19 +39,24 @@ static void Main(string[] args) c.AddScoped(); c.AddScoped(); + // TODO: There's a bug in the BlockProgressRepo + // It's using string ordering instead of numeric ordering to get the last block processed + // so 997 is considered higher than 2061 + // this has been fixed but is awaiting a PR merge and nuget release (probably 3.7.2) + // blockchain event log progress db - var progressDbConnectionString = config.GetConnectionString("BlockchainProcessingProgressDb"); - IBlockchainDbContextFactory blockchainDbContextFactory = - new SqlServerCoreBlockchainDbContextFactory( - progressDbConnectionString, DbSchemaNames.dbo); + //var progressDbConnectionString = config.GetConnectionString("BlockchainProcessingProgressDb"); + //IBlockchainDbContextFactory blockchainDbContextFactory = + // new SqlServerCoreBlockchainDbContextFactory( + // progressDbConnectionString, DbSchemaNames.dbo); - using (var progressContext = blockchainDbContextFactory.CreateContext()) - { - progressContext.Database.EnsureCreated(); - } + //using (var progressContext = blockchainDbContextFactory.CreateContext()) + //{ + // progressContext.Database.EnsureCreated(); + //} - IBlockProgressRepository progressRepo = new BlockProgressRepository(blockchainDbContextFactory); - c.AddSingleton(progressRepo); + //IBlockProgressRepository progressRepo = new BlockProgressRepository(blockchainDbContextFactory); + c.AddSingleton(); // jobs c.AddScoped(); diff --git a/src/WebJobs/appsettings.json b/src/WebJobs/appsettings.json index 906556c..c6bb43b 100644 --- a/src/WebJobs/appsettings.json +++ b/src/WebJobs/appsettings.json @@ -17,7 +17,7 @@ "PurchaseOrderEventLogConfiguration": { "Enabled": true, "BlockProgressJsonFile": "c:/temp/po_blockprogress.json", - "MinimumStartingBlock": 3200, + "MinimumStartingBlock": 0, "NumberOfBlocksPerBatch": 100, "MinimumBlockConfirmations": 12, "TimeoutMs": 3600000 diff --git a/src/contracts/Nethereum.Commerce.ContractDeployments.IntegrationTests/appsettings.json b/src/contracts/Nethereum.Commerce.ContractDeployments.IntegrationTests/appsettings.json index bc19ea8..3331f9b 100644 --- a/src/contracts/Nethereum.Commerce.ContractDeployments.IntegrationTests/appsettings.json +++ b/src/contracts/Nethereum.Commerce.ContractDeployments.IntegrationTests/appsettings.json @@ -1,6 +1,6 @@ { "NewDeployments": { - "BlockchainUrl": "http://testchain.nethereum.com:8545", + "BlockchainUrl": "http://localhost:8545", "EShopSellerId": "Nethereum.eShop", "EShopDescription": "Satoshi's Books", "EShopApproverAddress": "0x32a555f2328e85e489f9a5f03669dc820ce7ebe9", From 1bab6b241965d60adf440fdca327bcab68cd3785 Mon Sep 17 00:00:00 2001 From: Dave Whiffin Date: Fri, 6 Mar 2020 11:41:04 +0000 Subject: [PATCH 02/27] QuoteQueries --- .../ApplicationCore/Entities/BaseEntity.cs | 89 ++++++++++++++++++- .../Entities/BasketAggregate/Basket.cs | 5 ++ .../Entities/RulesEngine/RuleTreeSeed.cs | 3 +- .../Interfaces/IBasketRepository.cs | 17 ++++ .../Interfaces/ICatalogItemRepository.cs | 2 - .../Interfaces/IOrderRepository.cs | 5 +- .../Interfaces/IQuoteRepository.cs | 6 +- .../ApplicationCore/Queries/Paginated.cs | 23 +++++ .../Queries/Quotes/IQuoteQueries.cs | 9 ++ .../Queries/Quotes/QuoteQueries.cs | 71 +++++++++++++++ .../Queries/Quotes/QuoteQueryDtos.cs | 33 +++++++ .../ApplicationCore/Services/BasketService.cs | 27 +++--- .../ApplicationCore/Services/OrderService.cs | 15 ++-- .../Services/PurchaseOrderService.cs | 47 ---------- .../ApplicationCore/Services/QuoteService.cs | 30 ++++--- .../Services/RulesEngineService.cs | 4 +- .../Infrastructure/Data/BasketRepository.cs | 28 ++++++ .../Infrastructure/Data/CatalogContext.cs | 84 ++++++++++++++++- .../Infrastructure/Data/IRepository.cs | 7 ++ .../Infrastructure/Data/MediatorExtension.cs | 28 ++++++ .../Infrastructure/Data/OrderRepository.cs | 63 +++++++++++++ .../Infrastructure/Data/QuoteRepository.cs | 15 ++-- .../Infrastructure/IUnitOfWork.cs | 12 +++ src/Nethereum.eShop/Nethereum.eShop.csproj | 2 + src/Web/Controllers/QuoteController.cs | 1 - src/Web/Features/MyQuotes/GetMyQuotes.cs | 2 +- .../Features/MyQuotes/GetMyQuotesHandler.cs | 54 ++++++----- src/Web/GenerateDbCreationScripts.bat | 2 +- src/Web/Startup.cs | 7 +- src/Web/ViewModels/QuoteViewModel.cs | 25 ++++++ src/Web/Views/Quote/MyQuotes.cshtml | 2 +- src/Web/Web.csproj | 1 + 32 files changed, 582 insertions(+), 137 deletions(-) create mode 100644 src/Nethereum.eShop/ApplicationCore/Interfaces/IBasketRepository.cs create mode 100644 src/Nethereum.eShop/ApplicationCore/Queries/Paginated.cs create mode 100644 src/Nethereum.eShop/ApplicationCore/Queries/Quotes/IQuoteQueries.cs create mode 100644 src/Nethereum.eShop/ApplicationCore/Queries/Quotes/QuoteQueries.cs create mode 100644 src/Nethereum.eShop/ApplicationCore/Queries/Quotes/QuoteQueryDtos.cs delete mode 100644 src/Nethereum.eShop/ApplicationCore/Services/PurchaseOrderService.cs create mode 100644 src/Nethereum.eShop/Infrastructure/Data/BasketRepository.cs create mode 100644 src/Nethereum.eShop/Infrastructure/Data/IRepository.cs create mode 100644 src/Nethereum.eShop/Infrastructure/Data/MediatorExtension.cs create mode 100644 src/Nethereum.eShop/Infrastructure/IUnitOfWork.cs diff --git a/src/Nethereum.eShop/ApplicationCore/Entities/BaseEntity.cs b/src/Nethereum.eShop/ApplicationCore/Entities/BaseEntity.cs index 25e352a..30a4af9 100644 --- a/src/Nethereum.eShop/ApplicationCore/Entities/BaseEntity.cs +++ b/src/Nethereum.eShop/ApplicationCore/Entities/BaseEntity.cs @@ -1,9 +1,94 @@ -namespace Nethereum.eShop.ApplicationCore.Entities +using MediatR; +using System; +using System.Collections.Generic; + +namespace Nethereum.eShop.ApplicationCore.Entities { // This can easily be modified to be BaseEntity and public T Id to support different key types. // Using non-generic integer types for simplicity and to ease caching logic public class BaseEntity { - public int Id { get; set; } + int? _requestedHashCode; + int _Id; + public virtual int Id + { + get + { + return _Id; + } + protected set + { + _Id = value; + } + } + + private List _domainEvents; + public IReadOnlyCollection DomainEvents => _domainEvents?.AsReadOnly(); + + public void AddDomainEvent(INotification eventItem) + { + _domainEvents = _domainEvents ?? new List(); + _domainEvents.Add(eventItem); + } + + public void RemoveDomainEvent(INotification eventItem) + { + _domainEvents?.Remove(eventItem); + } + + public void ClearDomainEvents() + { + _domainEvents?.Clear(); + } + + public bool IsTransient() + { + return this.Id == default(Int32); + } + + public override bool Equals(object obj) + { + if (obj == null || !(obj is BaseEntity)) + return false; + + if (Object.ReferenceEquals(this, obj)) + return true; + + if (this.GetType() != obj.GetType()) + return false; + + BaseEntity item = (BaseEntity)obj; + + if (item.IsTransient() || this.IsTransient()) + return false; + else + return item.Id == this.Id; + } + + public override int GetHashCode() + { + if (!IsTransient()) + { + if (!_requestedHashCode.HasValue) + _requestedHashCode = this.Id.GetHashCode() ^ 31; // XOR for random distribution (http://blogs.msdn.com/b/ericlippert/archive/2011/02/28/guidelines-and-rules-for-gethashcode.aspx) + + return _requestedHashCode.Value; + } + else + return base.GetHashCode(); + + } + public static bool operator ==(BaseEntity left, BaseEntity right) + { + if (Object.Equals(left, null)) + return (Object.Equals(right, null)) ? true : false; + else + return left.Equals(right); + } + + public static bool operator !=(BaseEntity left, BaseEntity right) + { + return !(left == right); + } } } diff --git a/src/Nethereum.eShop/ApplicationCore/Entities/BasketAggregate/Basket.cs b/src/Nethereum.eShop/ApplicationCore/Entities/BasketAggregate/Basket.cs index 68b9e29..8513bf0 100644 --- a/src/Nethereum.eShop/ApplicationCore/Entities/BasketAggregate/Basket.cs +++ b/src/Nethereum.eShop/ApplicationCore/Entities/BasketAggregate/Basket.cs @@ -6,6 +6,11 @@ namespace Nethereum.eShop.ApplicationCore.Entities.BasketAggregate { public class Basket : BaseEntity, IAggregateRoot { + public static Basket CreateForDeletion(int basketId) + { + return new Basket { Id = basketId }; + } + public string BuyerId { get; set; } /// diff --git a/src/Nethereum.eShop/ApplicationCore/Entities/RulesEngine/RuleTreeSeed.cs b/src/Nethereum.eShop/ApplicationCore/Entities/RulesEngine/RuleTreeSeed.cs index c265d75..6624f03 100644 --- a/src/Nethereum.eShop/ApplicationCore/Entities/RulesEngine/RuleTreeSeed.cs +++ b/src/Nethereum.eShop/ApplicationCore/Entities/RulesEngine/RuleTreeSeed.cs @@ -11,8 +11,9 @@ public RuleTreeSeed() Owner = null; } - public RuleTreeSeed(string psRuleTreeId, string psOriginUrl, string psOwner) + public RuleTreeSeed(int id, string psRuleTreeId, string psOriginUrl, string psOwner) { + Id = id; RuleTreeId = psRuleTreeId; RuleTreeOriginUrl = psOriginUrl; Owner = psOwner; diff --git a/src/Nethereum.eShop/ApplicationCore/Interfaces/IBasketRepository.cs b/src/Nethereum.eShop/ApplicationCore/Interfaces/IBasketRepository.cs new file mode 100644 index 0000000..6e30df8 --- /dev/null +++ b/src/Nethereum.eShop/ApplicationCore/Interfaces/IBasketRepository.cs @@ -0,0 +1,17 @@ +using Nethereum.eShop.ApplicationCore.Entities.BasketAggregate; +using Nethereum.eShop.Infrastructure.Data; +using System.Threading.Tasks; + +namespace Nethereum.eShop.ApplicationCore.Interfaces +{ + public interface IBasketRepository : IRepository + { + Basket Add(Basket basket); + Basket Update(Basket basket); + void Delete(Basket basket); + void Delete(int basketId); + Task GetByIdWithItemsAsync(int id); + + Task GetByBuyerIdWithItemsAsync(string userName); + } +} diff --git a/src/Nethereum.eShop/ApplicationCore/Interfaces/ICatalogItemRepository.cs b/src/Nethereum.eShop/ApplicationCore/Interfaces/ICatalogItemRepository.cs index 2c1eaf6..09f7bd6 100644 --- a/src/Nethereum.eShop/ApplicationCore/Interfaces/ICatalogItemRepository.cs +++ b/src/Nethereum.eShop/ApplicationCore/Interfaces/ICatalogItemRepository.cs @@ -1,6 +1,4 @@ using Nethereum.eShop.ApplicationCore.Entities; -using System.Collections.Generic; -using System.Threading.Tasks; namespace Nethereum.eShop.ApplicationCore.Interfaces { diff --git a/src/Nethereum.eShop/ApplicationCore/Interfaces/IOrderRepository.cs b/src/Nethereum.eShop/ApplicationCore/Interfaces/IOrderRepository.cs index 8faa284..6523427 100644 --- a/src/Nethereum.eShop/ApplicationCore/Interfaces/IOrderRepository.cs +++ b/src/Nethereum.eShop/ApplicationCore/Interfaces/IOrderRepository.cs @@ -1,11 +1,14 @@ using Nethereum.eShop.ApplicationCore.Entities.OrderAggregate; +using Nethereum.eShop.Infrastructure.Data; using System.Threading.Tasks; namespace Nethereum.eShop.ApplicationCore.Interfaces { - public interface IOrderRepository : IAsyncRepository + public interface IOrderRepository : IAsyncRepository, IRepository { + Order Add(Order order); + Order Update(Order order); Task GetByIdWithItemsAsync(int id); } } diff --git a/src/Nethereum.eShop/ApplicationCore/Interfaces/IQuoteRepository.cs b/src/Nethereum.eShop/ApplicationCore/Interfaces/IQuoteRepository.cs index d6bdcdb..f502fd4 100644 --- a/src/Nethereum.eShop/ApplicationCore/Interfaces/IQuoteRepository.cs +++ b/src/Nethereum.eShop/ApplicationCore/Interfaces/IQuoteRepository.cs @@ -1,10 +1,14 @@ using Nethereum.eShop.ApplicationCore.Entities.QuoteAggregate; +using Nethereum.eShop.Infrastructure.Data; using System.Threading.Tasks; namespace Nethereum.eShop.ApplicationCore.Interfaces { - public interface IQuoteRepository : IAsyncRepository + public interface IQuoteRepository : IAsyncRepository, IRepository { + Quote Add(Quote quote); + Quote Update(Quote quote); + Task GetByIdWithItemsAsync(int id); } } diff --git a/src/Nethereum.eShop/ApplicationCore/Queries/Paginated.cs b/src/Nethereum.eShop/ApplicationCore/Queries/Paginated.cs new file mode 100644 index 0000000..20131b8 --- /dev/null +++ b/src/Nethereum.eShop/ApplicationCore/Queries/Paginated.cs @@ -0,0 +1,23 @@ +using System.Collections.Generic; + +namespace Nethereum.eShop.ApplicationCore.Queries +{ + public class Paginated where TModel : class + { + public int Offset { get; private set; } + + public int Fetch { get; private set; } + + public long TotalCount { get; private set; } + + public IEnumerable Data { get; private set; } + + public Paginated(int offset, int fetch, long totalCount, IEnumerable data) + { + Offset = offset; + Fetch = fetch; + TotalCount = totalCount; + Data = data; + } + } +} diff --git a/src/Nethereum.eShop/ApplicationCore/Queries/Quotes/IQuoteQueries.cs b/src/Nethereum.eShop/ApplicationCore/Queries/Quotes/IQuoteQueries.cs new file mode 100644 index 0000000..fbe01e4 --- /dev/null +++ b/src/Nethereum.eShop/ApplicationCore/Queries/Quotes/IQuoteQueries.cs @@ -0,0 +1,9 @@ +using System.Threading.Tasks; + +namespace Nethereum.eShop.ApplicationCore.Queries.Quotes +{ + public interface IQuoteQueries + { + Task> GetByBuyerIdAsync(string buyerId, string sortBy = null, int offset = 0, int fetch = 50); + } +} diff --git a/src/Nethereum.eShop/ApplicationCore/Queries/Quotes/QuoteQueries.cs b/src/Nethereum.eShop/ApplicationCore/Queries/Quotes/QuoteQueries.cs new file mode 100644 index 0000000..2e6668c --- /dev/null +++ b/src/Nethereum.eShop/ApplicationCore/Queries/Quotes/QuoteQueries.cs @@ -0,0 +1,71 @@ +using Dapper; +using Microsoft.Data.SqlClient; +using System; +using System.Data; +using System.Linq; +using System.Threading.Tasks; + +namespace Nethereum.eShop.ApplicationCore.Queries.Quotes +{ + public class QuoteQueries: IQuoteQueries + { + private readonly string _connectionString; + + public QuoteQueries(string connectionString) + { + _connectionString = connectionString ?? throw new ArgumentNullException(nameof(connectionString)); + } + + private static string[] SortByColumns = new[] { "Id", "Status" }; + + public async Task> GetByBuyerIdAsync(string buyerId, string sortBy = null, int offset = 0, int fetch = 50) + { + sortBy = sortBy ?? "Id"; + + if (!SortByColumns.Contains(sortBy)) throw new ArgumentException(nameof(sortBy)); + + using (var connection = new SqlConnection(_connectionString)) + { + connection.Open(); + + var parameters = new DynamicParameters(); + parameters.Add("@buyerId", buyerId); + parameters.Add("@offset", offset); + parameters.Add("@fetch", fetch); + parameters.Add("@totalCount", dbType: DbType.Int32, direction: ParameterDirection.Output); + + var rows = await connection.QueryAsync( +@$" +SELECT @totalCount = COUNT(1) FROM Quotes as q WHERE q.BuyerId = @buyerId; +SELECT + q.Id as QuoteId, + q.BuyerAddress, + q.BuyerId, + q.TransactionHash, + q.Date, + q.Status, + q.PoNumber, + q.PoType, + q.CurrencySymbol, + q.Expiry, + q.[BillTo_RecipientName], + q.[BillTo_ZipCode], + q.[ShipTo_RecipientName], + q.[ShipTo_ZipCode], + (select sum(qi.Quantity * qi.UnitPrice) from QuoteItems qi where qi.QuoteId = q.Id) as Total, + (select count(1) from QuoteItems qi where qi.QuoteId = q.Id) as ItemCount +FROM Quotes as q +WHERE q.BuyerId = @buyerId +ORDER BY [{sortBy}] +OFFSET @offset ROWS +FETCH NEXT @fetch ROWS ONLY; +" + , parameters + ); + + return new Paginated(offset, fetch, parameters.Get("@totalCount"), rows); + } + } + + } +} diff --git a/src/Nethereum.eShop/ApplicationCore/Queries/Quotes/QuoteQueryDtos.cs b/src/Nethereum.eShop/ApplicationCore/Queries/Quotes/QuoteQueryDtos.cs new file mode 100644 index 0000000..2834992 --- /dev/null +++ b/src/Nethereum.eShop/ApplicationCore/Queries/Quotes/QuoteQueryDtos.cs @@ -0,0 +1,33 @@ +using System; + +namespace Nethereum.eShop.ApplicationCore.Queries.Quotes +{ + public class QuoteExcerpt + { + public int QuoteId { get; set; } + public string TransactionHash { get; set; } + + public string PoNumber { get; set; } + + public string PoType { get; set; } + public string CurrencySymbol { get; set; } + + public string BuyerId { get; set; } + public string BuyerAddress { get; set; } + public DateTimeOffset QuoteDate { get; set; } + + public DateTimeOffset? Expiry { get; set; } + public decimal Total { get; set; } + public int ItemCount { get; set; } + public string Status { get; set; } + + public String ShipTo_RecipientName { get; set; } + public String ShipTo_ZipCode { get; set; } + public String BillTo_RecipientName { get; set; } + public String BillTo_ZipCode { get; set; } + } + + + + +} diff --git a/src/Nethereum.eShop/ApplicationCore/Services/BasketService.cs b/src/Nethereum.eShop/ApplicationCore/Services/BasketService.cs index 6a8e312..b5029e5 100644 --- a/src/Nethereum.eShop/ApplicationCore/Services/BasketService.cs +++ b/src/Nethereum.eShop/ApplicationCore/Services/BasketService.cs @@ -1,8 +1,5 @@ using Ardalis.GuardClauses; -using Microsoft.EntityFrameworkCore; -using Nethereum.eShop.ApplicationCore.Entities.BasketAggregate; using Nethereum.eShop.ApplicationCore.Interfaces; -using Nethereum.eShop.Infrastructure.Data; using System.Collections.Generic; using System.Linq; using System.Threading.Tasks; @@ -11,32 +8,32 @@ namespace Nethereum.eShop.ApplicationCore.Services { public class BasketService : IBasketService { - private readonly CatalogContext _dbContext; + private readonly IBasketRepository _basketRepository; private readonly IAppLogger _logger; - public BasketService(CatalogContext dbContext, IAppLogger logger) + public BasketService(IBasketRepository basketRepository, IAppLogger logger) { - _dbContext = dbContext; + _basketRepository = basketRepository ?? throw new System.ArgumentNullException(nameof(basketRepository)); _logger = logger; } public async Task AddItemToBasket(int basketId, int catalogItemId, decimal price, int quantity = 1) { - var basket = await _dbContext.GetBasketWithItemsOrDefault(basketId).ConfigureAwait(false); + var basket = await _basketRepository.GetByIdWithItemsAsync(basketId).ConfigureAwait(false); basket.AddItem(catalogItemId, price, quantity); - await _dbContext.SaveChangesAsync().ConfigureAwait(false); + await _basketRepository.UnitOfWork.SaveEntitiesAsync().ConfigureAwait(false); } public async Task DeleteBasketAsync(int basketId) { - _dbContext.Entry(new Basket { Id = basketId }).State = EntityState.Deleted; - await _dbContext.SaveChangesAsync().ConfigureAwait(false); + _basketRepository.Delete(basketId); + await _basketRepository.UnitOfWork.SaveEntitiesAsync().ConfigureAwait(false); } public async Task GetBasketItemCountAsync(string userName) { Guard.Against.NullOrEmpty(userName, nameof(userName)); - var basket = await _dbContext.GetBasketWithItemsOrDefault(userName).ConfigureAwait(false); + var basket = await _basketRepository.GetByBuyerIdWithItemsAsync(userName).ConfigureAwait(false); if (basket == null) { _logger.LogInformation($"No basket found for {userName}"); @@ -50,7 +47,7 @@ public async Task GetBasketItemCountAsync(string userName) public async Task SetQuantities(int basketId, Dictionary quantities) { Guard.Against.Null(quantities, nameof(quantities)); - var basket = await _dbContext.GetBasketWithItemsOrDefault(basketId).ConfigureAwait(false); + var basket = await _basketRepository.GetByIdWithItemsAsync(basketId).ConfigureAwait(false); Guard.Against.NullBasket(basketId, basket); foreach (var item in basket.Items) { @@ -61,19 +58,19 @@ public async Task SetQuantities(int basketId, Dictionary quantities } } basket.RemoveEmptyItems(); - await _dbContext.SaveChangesAsync().ConfigureAwait(false); + await _basketRepository.UnitOfWork.SaveEntitiesAsync().ConfigureAwait(false); } public async Task TransferBasketAsync(string anonymousId, string userName) { Guard.Against.NullOrEmpty(anonymousId, nameof(anonymousId)); Guard.Against.NullOrEmpty(userName, nameof(userName)); - var basket = await _dbContext.GetBasketWithItemsOrDefault(anonymousId).ConfigureAwait(false); + var basket = await _basketRepository.GetByBuyerIdWithItemsAsync(anonymousId).ConfigureAwait(false); if (basket == null) return; basket.BuyerId = userName; // TODO: populate from buyer entity basket.BuyerAddress = ""; - await _dbContext.SaveChangesAsync().ConfigureAwait(false); + await _basketRepository.UnitOfWork.SaveEntitiesAsync().ConfigureAwait(false); } } } diff --git a/src/Nethereum.eShop/ApplicationCore/Services/OrderService.cs b/src/Nethereum.eShop/ApplicationCore/Services/OrderService.cs index 31a85e2..dd2333a 100644 --- a/src/Nethereum.eShop/ApplicationCore/Services/OrderService.cs +++ b/src/Nethereum.eShop/ApplicationCore/Services/OrderService.cs @@ -3,7 +3,6 @@ using Nethereum.eShop.ApplicationCore.Entities.OrderAggregate; using Nethereum.eShop.ApplicationCore.Entities.QuoteAggregate; using Nethereum.eShop.ApplicationCore.Interfaces; -using Nethereum.eShop.Infrastructure.Data; using System; using System.Collections.Generic; using System.Linq; @@ -13,11 +12,13 @@ namespace Nethereum.eShop.ApplicationCore.Services { public class OrderService : IOrderService { - private readonly CatalogContext _dbContext; + private readonly IOrderRepository _orderRepository; + private readonly IQuoteRepository _quoteRepository; - public OrderService(CatalogContext catalogContext) + public OrderService(IOrderRepository orderRepository, IQuoteRepository quoteRepository) { - _dbContext = catalogContext; + _orderRepository = orderRepository ?? throw new ArgumentNullException(nameof(orderRepository)); + _quoteRepository = quoteRepository ?? throw new ArgumentNullException(nameof(quoteRepository)); } public async Task CreateOrderAsync(string transactionHash, Po purchaseOrder) @@ -27,7 +28,7 @@ public async Task CreateOrderAsync(string transactionHash, Po purchaseOrder) int quoteId = (int)purchaseOrder.QuoteId; - var quote = await _dbContext.GetQuoteWithItemsOrDefault(quoteId); + var quote = await _quoteRepository.GetByIdWithItemsAsync(quoteId).ConfigureAwait(false); Guard.Against.NullQuote(quoteId, quote); var items = new List(); @@ -72,9 +73,9 @@ public async Task CreateOrderAsync(string transactionHash, Po purchaseOrder) quote.PoNumber = (long)purchaseOrder.PoNumber; quote.Status = QuoteStatus.Complete; - _dbContext.Orders.Add(order); + _orderRepository.Add(order); - await _dbContext.SaveChangesAsync(); + await _orderRepository.UnitOfWork.SaveChangesAsync().ConfigureAwait(false); } } } diff --git a/src/Nethereum.eShop/ApplicationCore/Services/PurchaseOrderService.cs b/src/Nethereum.eShop/ApplicationCore/Services/PurchaseOrderService.cs deleted file mode 100644 index b25445a..0000000 --- a/src/Nethereum.eShop/ApplicationCore/Services/PurchaseOrderService.cs +++ /dev/null @@ -1,47 +0,0 @@ -using Ardalis.GuardClauses; -using Nethereum.eShop.ApplicationCore.Entities; -using Nethereum.eShop.ApplicationCore.Entities.BasketAggregate; -using Nethereum.eShop.ApplicationCore.Interfaces; -using Nethereum.eShop.Infrastructure.Data; -using System; -using System.Threading.Tasks; - -namespace Nethereum.eShop.ApplicationCore.Services -{ - public class PurchaseOrderService : IPurchaseOrderService - { - private readonly CatalogContext _dbContext; - - public PurchaseOrderService(CatalogContext catalogContext) - { - _dbContext = catalogContext; - } - - public async Task CreateOrderAsync(int basketId, PostalAddress billingAddress, PostalAddress shippingAddress) - { - // TODO: - // write address to buyer, to be looked up on po creation - // Create purchase order on chain - // using basket to populate - // we need the buyer nonce - - var basket = await _dbContext.GetBasketWithItemsOrDefault(basketId).ConfigureAwait(false); - Guard.Against.NullBasket(basketId, basket); - - throw new NotImplementedException(); - //var items = new List(); - //foreach (var item in basket.Items) - //{ - - - // var catalogItem = await _itemRepository.GetByIdAsync(item.CatalogItemId); - // var itemOrdered = new CatalogItemOrdered(catalogItem.Id, catalogItem.Name, catalogItem.PictureUri); - // var orderItem = new OrderItem(itemOrdered, item.UnitPrice, item.Quantity); - // items.Add(orderItem); - //} - //var order = new Order(basket.BuyerId, billingAddress, shippingAddress, items); - - //await _orderRepository.AddAsync(order); - } - } -} diff --git a/src/Nethereum.eShop/ApplicationCore/Services/QuoteService.cs b/src/Nethereum.eShop/ApplicationCore/Services/QuoteService.cs index 5ad1087..272ed98 100644 --- a/src/Nethereum.eShop/ApplicationCore/Services/QuoteService.cs +++ b/src/Nethereum.eShop/ApplicationCore/Services/QuoteService.cs @@ -2,9 +2,9 @@ using Nethereum.eShop.ApplicationCore.Entities; using Nethereum.eShop.ApplicationCore.Entities.BasketAggregate; using Nethereum.eShop.ApplicationCore.Entities.QuoteAggregate; +using Nethereum.eShop.ApplicationCore.Entities.RulesEngine; using Nethereum.eShop.ApplicationCore.Exceptions; using Nethereum.eShop.ApplicationCore.Interfaces; -using Nethereum.eShop.Infrastructure.Data; using System; using System.Collections.Generic; using System.Threading.Tasks; @@ -13,17 +13,21 @@ namespace Nethereum.eShop.ApplicationCore.Services { public class QuoteService : IQuoteService { - private readonly CatalogContext _dbContext; + private readonly IBasketRepository _basketRepository; + private readonly ICatalogItemRepository _itemRepository; + private readonly IQuoteRepository _quoteRepository; private readonly IRulesEngineService _rulesEngineService; public QuoteService( - IAsyncRepository basketRepository, - IAsyncRepository itemRepository, - IAsyncRepository orderRepository, + IBasketRepository basketRepository, + ICatalogItemRepository itemRepository, + IQuoteRepository quoteRepository, IRulesEngineService rulesEngineService) { - _dbContext = catalogContext; - _rulesEngineService = rulesEngineService; + _basketRepository = basketRepository ?? throw new ArgumentNullException(nameof(basketRepository)); + _itemRepository = itemRepository ?? throw new ArgumentNullException(nameof(itemRepository)); + _quoteRepository = quoteRepository ?? throw new ArgumentNullException(nameof(quoteRepository)); + _rulesEngineService = rulesEngineService ?? throw new ArgumentNullException(nameof(rulesEngineService)); } public async Task CreateQuoteAsync(int basketId) @@ -36,7 +40,7 @@ public async Task CreateQuoteAsync(int basketId) // Create purchase order // reserve stock? - var basket = await _dbContext.GetBasketWithItemsOrDefault(basketId).ConfigureAwait(false); + var basket = await _basketRepository.GetByIdWithItemsAsync(basketId).ConfigureAwait(false); Guard.Against.NullBasket(basketId, basket); var quoteItems = await MapAsync(basket); @@ -65,7 +69,9 @@ public async Task CreateQuoteAsync(int basketId) // NOTE: Should we redirect the user to an error page? } - await _quoteRepository.AddAsync(quote); + _quoteRepository.Add(quote); + + await _quoteRepository.UnitOfWork.SaveChangesAsync().ConfigureAwait(false); } private async Task> ExecuteRules(Quote targetQuote) @@ -110,9 +116,7 @@ private async Task> ExecuteRules(Quote targetQuote) } } - _dbContext.Quotes.Add(quote); - - await _dbContext.SaveChangesAsync().ConfigureAwait(false); + return ReportsWithWarnings; } private async Task> MapAsync(Basket basket) @@ -120,7 +124,7 @@ private async Task> MapAsync(Basket basket) var items = new List(); foreach (var item in basket.Items) { - var catalogItem = await _dbContext.CatalogItems.FindAsync(item.CatalogItemId).ConfigureAwait(false); + var catalogItem = await _itemRepository.GetByIdAsync(item.CatalogItemId).ConfigureAwait(false); var itemOrdered = new CatalogItemExcerpt( catalogItem.Id, catalogItem.Gtin, catalogItem.GtinRegistryId, catalogItem.Name, catalogItem.PictureUri); diff --git a/src/Nethereum.eShop/ApplicationCore/Services/RulesEngineService.cs b/src/Nethereum.eShop/ApplicationCore/Services/RulesEngineService.cs index d1ae04d..80bfed9 100644 --- a/src/Nethereum.eShop/ApplicationCore/Services/RulesEngineService.cs +++ b/src/Nethereum.eShop/ApplicationCore/Services/RulesEngineService.cs @@ -53,7 +53,7 @@ public async Task GetQuoteRuleTree() var sBizRulesUrl = _rulesEngineInitializer.GetQuoteBizRulesFileUrl(); RuleTreeSeed quoteTreeSeed = - new RuleTreeSeed("QuoteTree", sBizRulesUrl, "default") { Id = 1 }; + new RuleTreeSeed(1, "QuoteTree", sBizRulesUrl, "default"); var RuleTreeIsCached = await _ruleTreeRepository.ContainsAsync(quoteTreeSeed.Id).ConfigureAwait(false); @@ -74,7 +74,7 @@ public async Task GetQuoteItemRuleTree() var sBizRulesUrl = _rulesEngineInitializer.GetQuoteItemBizRulesFileUrl(); RuleTreeSeed quoteItemTreeSeed = - new RuleTreeSeed("QuoteItemTree", sBizRulesUrl, "default") { Id = 2 }; + new RuleTreeSeed(2, "QuoteItemTree", sBizRulesUrl, "default"); var RuleTreeIsCached = await _ruleTreeRepository.ContainsAsync(quoteItemTreeSeed.Id).ConfigureAwait(false); diff --git a/src/Nethereum.eShop/Infrastructure/Data/BasketRepository.cs b/src/Nethereum.eShop/Infrastructure/Data/BasketRepository.cs new file mode 100644 index 0000000..0d4dcfa --- /dev/null +++ b/src/Nethereum.eShop/Infrastructure/Data/BasketRepository.cs @@ -0,0 +1,28 @@ +using Nethereum.eShop.ApplicationCore.Entities.BasketAggregate; +using Nethereum.eShop.ApplicationCore.Interfaces; +using System.Threading.Tasks; + +namespace Nethereum.eShop.Infrastructure.Data +{ + public class BasketRepository : EfRepository, IBasketRepository + { + public BasketRepository(CatalogContext dbContext) : base(dbContext) { } + + public IUnitOfWork UnitOfWork => _dbContext; + public Basket Add(Basket basket) => _dbContext.Baskets.Add(basket).Entity; + public Basket Update(Basket basket) => _dbContext.Baskets.Update(basket).Entity; + public Task GetByIdWithItemsAsync(int id) => _dbContext.GetBasketWithItemsOrDefault(id); + + public Task GetByBuyerIdWithItemsAsync(string buyerId) => _dbContext.GetBasketWithItemsOrDefault(buyerId); + + public void Delete(Basket basket) + { + _dbContext.Baskets.Remove(basket); + } + + public void Delete(int basketId) + { + _dbContext.Entry(Basket.CreateForDeletion(basketId)).State = Microsoft.EntityFrameworkCore.EntityState.Deleted; + } + } +} diff --git a/src/Nethereum.eShop/Infrastructure/Data/CatalogContext.cs b/src/Nethereum.eShop/Infrastructure/Data/CatalogContext.cs index 0f69557..f97fa33 100644 --- a/src/Nethereum.eShop/Infrastructure/Data/CatalogContext.cs +++ b/src/Nethereum.eShop/Infrastructure/Data/CatalogContext.cs @@ -1,18 +1,28 @@ -using Microsoft.EntityFrameworkCore; +using MediatR; +using Microsoft.EntityFrameworkCore; +using Microsoft.EntityFrameworkCore.Storage; using Nethereum.eShop.ApplicationCore.Entities; using Nethereum.eShop.ApplicationCore.Entities.BasketAggregate; using Nethereum.eShop.ApplicationCore.Entities.BuyerAggregate; using Nethereum.eShop.ApplicationCore.Entities.OrderAggregate; using Nethereum.eShop.ApplicationCore.Entities.QuoteAggregate; +using System; +using System.Data; using System.Reflection; +using System.Threading; +using System.Threading.Tasks; namespace Nethereum.eShop.Infrastructure.Data { - public class CatalogContext : DbContext + public class CatalogContext : DbContext, IUnitOfWork { - public CatalogContext(DbContextOptions options) : base(options) + private readonly IMediator _mediator; + private IDbContextTransaction _currentTransaction; + + public CatalogContext(DbContextOptions options, IMediator mediator) : base(options) { + _mediator = mediator; } public DbSet Buyers { get; set; } @@ -37,5 +47,73 @@ protected override void OnModelCreating(ModelBuilder builder) base.OnModelCreating(builder); builder.ApplyConfigurationsFromAssembly(Assembly.GetExecutingAssembly()); } + + + public async Task SaveEntitiesAsync(CancellationToken cancellationToken = default(CancellationToken)) + { + // Dispatch Domain Events collection. + // Choices: + // A) Right BEFORE committing data (EF SaveChanges) into the DB will make a single transaction including + // side effects from the domain event handlers which are using the same DbContext with "InstancePerLifetimeScope" or "scoped" lifetime + // B) Right AFTER committing data (EF SaveChanges) into the DB will make multiple transactions. + // You will need to handle eventual consistency and compensatory actions in case of failures in any of the Handlers. + await _mediator.DispatchDomainEventsAsync(this); + + // After executing this line all the changes (from the Command Handler and Domain Event Handlers) + // performed through the DbContext will be committed + var result = await base.SaveChangesAsync(cancellationToken); + + return true; + } + + public async Task BeginTransactionAsync() + { + if (_currentTransaction != null) return null; + + _currentTransaction = await Database.BeginTransactionAsync(IsolationLevel.ReadCommitted); + + return _currentTransaction; + } + + public async Task CommitTransactionAsync(IDbContextTransaction transaction) + { + if (transaction == null) throw new ArgumentNullException(nameof(transaction)); + if (transaction != _currentTransaction) throw new InvalidOperationException($"Transaction {transaction.TransactionId} is not current"); + + try + { + await SaveChangesAsync(); + transaction.Commit(); + } + catch + { + RollbackTransaction(); + throw; + } + finally + { + if (_currentTransaction != null) + { + _currentTransaction.Dispose(); + _currentTransaction = null; + } + } + } + + public void RollbackTransaction() + { + try + { + _currentTransaction?.Rollback(); + } + finally + { + if (_currentTransaction != null) + { + _currentTransaction.Dispose(); + _currentTransaction = null; + } + } + } } } diff --git a/src/Nethereum.eShop/Infrastructure/Data/IRepository.cs b/src/Nethereum.eShop/Infrastructure/Data/IRepository.cs new file mode 100644 index 0000000..357f4dc --- /dev/null +++ b/src/Nethereum.eShop/Infrastructure/Data/IRepository.cs @@ -0,0 +1,7 @@ +namespace Nethereum.eShop.Infrastructure.Data +{ + public interface IRepository + { + IUnitOfWork UnitOfWork { get; } + } +} diff --git a/src/Nethereum.eShop/Infrastructure/Data/MediatorExtension.cs b/src/Nethereum.eShop/Infrastructure/Data/MediatorExtension.cs new file mode 100644 index 0000000..4319358 --- /dev/null +++ b/src/Nethereum.eShop/Infrastructure/Data/MediatorExtension.cs @@ -0,0 +1,28 @@ +using MediatR; +using Nethereum.eShop.ApplicationCore.Entities; +using System.Data; +using System.Linq; +using System.Threading.Tasks; + +namespace Nethereum.eShop.Infrastructure.Data +{ + public static class MediatorExtension + { + public static async Task DispatchDomainEventsAsync(this IMediator mediator, CatalogContext ctx) + { + var domainEntities = ctx.ChangeTracker + .Entries() + .Where(x => x.Entity.DomainEvents != null && x.Entity.DomainEvents.Any()); + + var domainEvents = domainEntities + .SelectMany(x => x.Entity.DomainEvents) + .ToList(); + + domainEntities.ToList() + .ForEach(entity => entity.Entity.ClearDomainEvents()); + + foreach (var domainEvent in domainEvents) + await mediator.Publish(domainEvent); + } + } +} diff --git a/src/Nethereum.eShop/Infrastructure/Data/OrderRepository.cs b/src/Nethereum.eShop/Infrastructure/Data/OrderRepository.cs index 396d427..cded68f 100644 --- a/src/Nethereum.eShop/Infrastructure/Data/OrderRepository.cs +++ b/src/Nethereum.eShop/Infrastructure/Data/OrderRepository.cs @@ -5,8 +5,18 @@ namespace Nethereum.eShop.Infrastructure.Data { + public class OrderRepository : EfRepository, IOrderRepository { + + public IUnitOfWork UnitOfWork + { + get + { + return _dbContext; + } + } + public OrderRepository(CatalogContext dbContext) : base(dbContext) { } @@ -18,5 +28,58 @@ public Task GetByIdWithItemsAsync(int id) .Include($"{nameof(Order.OrderItems)}.{nameof(OrderItem.ItemOrdered)}") .FirstOrDefaultAsync(x => x.Id == id); } + + public Order Add(Order order) + { + return _dbContext.Orders.Add(order).Entity; + } + + public Order Update(Order order) + { + return _dbContext.Orders.Update(order).Entity; + } + + /* + public Buyer Add(Buyer buyer) + { + if (buyer.IsTransient()) + { + return _context.Buyers + .Add(buyer) + .Entity; + } + else + { + return buyer; + } + } + + public Buyer Update(Buyer buyer) + { + return _context.Buyers + .Update(buyer) + .Entity; + } + + public async Task FindAsync(string identity) + { + var buyer = await _context.Buyers + .Include(b => b.PaymentMethods) + .Where(b => b.IdentityGuid == identity) + .SingleOrDefaultAsync(); + + return buyer; + } + + public async Task FindByIdAsync(string id) + { + var buyer = await _context.Buyers + .Include(b => b.PaymentMethods) + .Where(b => b.Id == int.Parse(id)) + .SingleOrDefaultAsync(); + + return buyer; + } + */ } } diff --git a/src/Nethereum.eShop/Infrastructure/Data/QuoteRepository.cs b/src/Nethereum.eShop/Infrastructure/Data/QuoteRepository.cs index 6fa3c37..70eea4b 100644 --- a/src/Nethereum.eShop/Infrastructure/Data/QuoteRepository.cs +++ b/src/Nethereum.eShop/Infrastructure/Data/QuoteRepository.cs @@ -7,16 +7,11 @@ namespace Nethereum.eShop.Infrastructure.Data { public class QuoteRepository : EfRepository, IQuoteRepository { - public QuoteRepository(CatalogContext dbContext) : base(dbContext) - { - } + public QuoteRepository(CatalogContext dbContext) : base(dbContext){} - public Task GetByIdWithItemsAsync(int id) - { - return _dbContext.Quotes - .Include(o => o.QuoteItems) - .Include($"{nameof(Quote.QuoteItems)}.{nameof(QuoteItem.ItemOrdered)}") - .FirstOrDefaultAsync(x => x.Id == id); - } + public IUnitOfWork UnitOfWork => _dbContext; + public Quote Add(Quote quote) => _dbContext.Quotes.Add(quote).Entity; + public Quote Update(Quote quote) => _dbContext.Quotes.Update(quote).Entity; + public Task GetByIdWithItemsAsync(int id) => _dbContext.GetQuoteWithItemsOrDefault(id); } } diff --git a/src/Nethereum.eShop/Infrastructure/IUnitOfWork.cs b/src/Nethereum.eShop/Infrastructure/IUnitOfWork.cs new file mode 100644 index 0000000..9fe72d0 --- /dev/null +++ b/src/Nethereum.eShop/Infrastructure/IUnitOfWork.cs @@ -0,0 +1,12 @@ +using System; +using System.Threading; +using System.Threading.Tasks; + +namespace Nethereum.eShop.Infrastructure +{ + public interface IUnitOfWork : IDisposable + { + Task SaveChangesAsync(CancellationToken cancellationToken = default(CancellationToken)); + Task SaveEntitiesAsync(CancellationToken cancellationToken = default(CancellationToken)); + } +} diff --git a/src/Nethereum.eShop/Nethereum.eShop.csproj b/src/Nethereum.eShop/Nethereum.eShop.csproj index e69c8d5..40f66ce 100644 --- a/src/Nethereum.eShop/Nethereum.eShop.csproj +++ b/src/Nethereum.eShop/Nethereum.eShop.csproj @@ -7,6 +7,8 @@ + + diff --git a/src/Web/Controllers/QuoteController.cs b/src/Web/Controllers/QuoteController.cs index 695b09e..9d6176e 100644 --- a/src/Web/Controllers/QuoteController.cs +++ b/src/Web/Controllers/QuoteController.cs @@ -2,7 +2,6 @@ using Microsoft.AspNetCore.Authorization; using Microsoft.AspNetCore.Mvc; using Nethereum.eShop.Web.Features.MyQuotes; -using Nethereum.eShop.Web.Features.OrderDetails; using Nethereum.eShop.Web.Features.QuoteDetails; using System.Threading.Tasks; diff --git a/src/Web/Features/MyQuotes/GetMyQuotes.cs b/src/Web/Features/MyQuotes/GetMyQuotes.cs index 431c7a8..c18ec19 100644 --- a/src/Web/Features/MyQuotes/GetMyQuotes.cs +++ b/src/Web/Features/MyQuotes/GetMyQuotes.cs @@ -4,7 +4,7 @@ namespace Nethereum.eShop.Web.Features.MyQuotes { - public class GetMyQuotes : IRequest> + public class GetMyQuotes : IRequest> { public string UserName { get; set; } diff --git a/src/Web/Features/MyQuotes/GetMyQuotesHandler.cs b/src/Web/Features/MyQuotes/GetMyQuotesHandler.cs index dff2578..f11ed6c 100644 --- a/src/Web/Features/MyQuotes/GetMyQuotesHandler.cs +++ b/src/Web/Features/MyQuotes/GetMyQuotesHandler.cs @@ -1,6 +1,7 @@ -using MediatR; -using Nethereum.eShop.ApplicationCore.Interfaces; -using Nethereum.eShop.ApplicationCore.Specifications; +using AutoMapper; +using MediatR; +using Nethereum.eShop.ApplicationCore.Queries; +using Nethereum.eShop.ApplicationCore.Queries.Quotes; using Nethereum.eShop.Web.ViewModels; using System.Collections.Generic; using System.Linq; @@ -9,38 +10,35 @@ namespace Nethereum.eShop.Web.Features.MyQuotes { - public class GetMyQuotesHandler : IRequestHandler> + + public class GetMyQuotesHandler : IRequestHandler> { - private readonly IQuoteRepository _quoteRepository; + private readonly static Mapper _mapper; + static GetMyQuotesHandler() + { + var config = new MapperConfiguration(cfg => cfg.AddProfile()); + _mapper = new Mapper(config); + } + + private readonly IQuoteQueries _quoteQueries; - public GetMyQuotesHandler(IQuoteRepository quoteRepository) + public GetMyQuotesHandler(IQuoteQueries quoteRepository) { - _quoteRepository = quoteRepository; + _quoteQueries = quoteRepository; } - public async Task> Handle(GetMyQuotes request, CancellationToken cancellationToken) + public async Task> Handle(GetMyQuotes request, CancellationToken cancellationToken) { - var specification = new CustomerQuotesWithItemsSpecification(request.UserName); - var orders = await _quoteRepository.ListAsync(specification); + var quotes = await _quoteQueries.GetByBuyerIdAsync(request.UserName, fetch: 100); + return quotes.Data.Select(excerpt => _mapper.Map(excerpt)); + } + } - return orders.Select(o => new QuoteViewModel - { - QuoteDate = o.Date, - QuoteItems = o.QuoteItems?.Select(oi => new QuoteItemViewModel() - { - PictureUrl = oi.ItemOrdered.PictureUri, - ProductId = oi.ItemOrdered.CatalogItemId, - ProductName = oi.ItemOrdered.ProductName, - UnitPrice = oi.UnitPrice, - Units = oi.Quantity - }).ToList(), - QuoteId = o.Id, - Status = o.Status.ToString(), - TransactionHash = o.TransactionHash, - ShipTo = o.ShipTo, - BillTo = o.BillTo, - Total = o.Total() - }); + public class QuoteExcerptProfile : Profile + { + public QuoteExcerptProfile() + { + this.CreateMap(); } } } diff --git a/src/Web/GenerateDbCreationScripts.bat b/src/Web/GenerateDbCreationScripts.bat index 59432d1..d629c90 100644 --- a/src/Web/GenerateDbCreationScripts.bat +++ b/src/Web/GenerateDbCreationScripts.bat @@ -1,4 +1,4 @@ rem Create First Migration aka InitialCreate dotnet build -dotnet-ef migrations script -o c:\temp\CreateCatalogDb.sql --project ..\Nethereum.eShop --context Nethereum.eShop.Infrastructure.Data.CatalogContext --no-build +dotnet ef migrations script -o c:\temp\CreateCatalogDb.sql --project ..\Nethereum.eShop --context Nethereum.eShop.Infrastructure.Data.CatalogContext --no-build dotnet ef migrations script -o c:\temp\CreateAppIdentityContextDb.sql --project ..\Nethereum.eShop --context Nethereum.eShop.Infrastructure.Identity.AppIdentityDbContext --no-build \ No newline at end of file diff --git a/src/Web/Startup.cs b/src/Web/Startup.cs index e533763..0b8e4c7 100644 --- a/src/Web/Startup.cs +++ b/src/Web/Startup.cs @@ -24,6 +24,8 @@ using System.Collections.Generic; using System.Linq; using System.Net.Mime; +using Nethereum.eShop.ApplicationCore.Queries; +using Nethereum.eShop.ApplicationCore.Queries.Quotes; namespace Nethereum.eShop.Web { @@ -110,15 +112,18 @@ public void ConfigureServices(IServiceCollection services) services.AddMediatR(typeof(BasketViewModelService).Assembly); + IQuoteQueries quoteQueries = new QuoteQueries(Configuration.GetConnectionString("CatalogConnection")); + services.AddSingleton(quoteQueries); + services.AddScoped(typeof(IAsyncCache<>), typeof(GeneralCache<>)); services.AddScoped(typeof(IAsyncRepository<>), typeof(EfRepository<>)); + services.AddScoped(); services.AddScoped(); services.AddScoped(); services.AddScoped(); services.AddScoped(); services.AddScoped(); services.AddScoped(); - services.AddScoped(); services.AddScoped(); services.AddScoped(); services.AddScoped(); diff --git a/src/Web/ViewModels/QuoteViewModel.cs b/src/Web/ViewModels/QuoteViewModel.cs index faa47cb..779707d 100644 --- a/src/Web/ViewModels/QuoteViewModel.cs +++ b/src/Web/ViewModels/QuoteViewModel.cs @@ -18,4 +18,29 @@ public class QuoteViewModel public PostalAddress BillTo { get; set; } public List QuoteItems { get; set; } = new List(); } + + public class QuoteExcerptViewModel + { + public int QuoteId { get; set; } + public string TransactionHash { get; set; } + + public string PoNumber { get; set; } + + public string PoType { get; set; } + public string CurrencySymbol { get; set; } + + public string BuyerId { get; set; } + public string BuyerAddress { get; set; } + public DateTimeOffset QuoteDate { get; set; } + + public DateTimeOffset? Expiry { get; set; } + public decimal Total { get; set; } + public int ItemCount { get; set; } + public string Status { get; set; } + + public String ShipTo_RecipientName { get; set; } + public String ShipTo_ZipCode { get; set; } + public String BillTo_RecipientName { get; set; } + public String BillTo_ZipCode { get; set; } + } } diff --git a/src/Web/Views/Quote/MyQuotes.cshtml b/src/Web/Views/Quote/MyQuotes.cshtml index a44a2bf..dab1a5d 100644 --- a/src/Web/Views/Quote/MyQuotes.cshtml +++ b/src/Web/Views/Quote/MyQuotes.cshtml @@ -1,4 +1,4 @@ -@model IEnumerable +@model IEnumerable @{ ViewData["Title"] = "My Quotes"; } diff --git a/src/Web/Web.csproj b/src/Web/Web.csproj index 3802e6c..0ecbd4d 100644 --- a/src/Web/Web.csproj +++ b/src/Web/Web.csproj @@ -13,6 +13,7 @@ + From 6b7c0d0ffbf74b4adeec157af382a9d4249cbe8e Mon Sep 17 00:00:00 2001 From: Dave Whiffin Date: Fri, 6 Mar 2020 12:07:09 +0000 Subject: [PATCH 03/27] OrderQueries --- .../Queries/Orders/IOrderQueries.cs | 9 +++ .../Queries/Orders/OrderQueries.cs | 71 +++++++++++++++++++ .../Queries/Orders/OrderQueryDtos.cs | 34 +++++++++ .../ApplicationCore/Queries/Paginated.cs | 5 +- .../Queries/Quotes/QuoteQueries.cs | 2 +- src/Web/Features/MyOrders/GetMyOrders.cs | 2 +- .../Features/MyOrders/GetMyOrdersHandler.cs | 48 +++++++------ src/Web/Startup.cs | 17 ++--- src/Web/ViewModels/OrderExcerptViewModel.cs | 31 ++++++++ src/Web/ViewModels/QuoteExcerptViewModel.cs | 29 ++++++++ src/Web/ViewModels/QuoteViewModel.cs | 25 ------- src/Web/Views/Order/MyOrders.cshtml | 36 +++++----- 12 files changed, 233 insertions(+), 76 deletions(-) create mode 100644 src/Nethereum.eShop/ApplicationCore/Queries/Orders/IOrderQueries.cs create mode 100644 src/Nethereum.eShop/ApplicationCore/Queries/Orders/OrderQueries.cs create mode 100644 src/Nethereum.eShop/ApplicationCore/Queries/Orders/OrderQueryDtos.cs create mode 100644 src/Web/ViewModels/OrderExcerptViewModel.cs create mode 100644 src/Web/ViewModels/QuoteExcerptViewModel.cs diff --git a/src/Nethereum.eShop/ApplicationCore/Queries/Orders/IOrderQueries.cs b/src/Nethereum.eShop/ApplicationCore/Queries/Orders/IOrderQueries.cs new file mode 100644 index 0000000..3c87da8 --- /dev/null +++ b/src/Nethereum.eShop/ApplicationCore/Queries/Orders/IOrderQueries.cs @@ -0,0 +1,9 @@ +using System.Threading.Tasks; + +namespace Nethereum.eShop.ApplicationCore.Queries.Orders +{ + public interface IOrderQueries + { + Task> GetByBuyerIdAsync(string buyerId, string sortBy = null, int offset = 0, int fetch = 50); + } +} diff --git a/src/Nethereum.eShop/ApplicationCore/Queries/Orders/OrderQueries.cs b/src/Nethereum.eShop/ApplicationCore/Queries/Orders/OrderQueries.cs new file mode 100644 index 0000000..000598b --- /dev/null +++ b/src/Nethereum.eShop/ApplicationCore/Queries/Orders/OrderQueries.cs @@ -0,0 +1,71 @@ +using Dapper; +using Microsoft.Data.SqlClient; +using System; +using System.Data; +using System.Linq; +using System.Threading.Tasks; + +namespace Nethereum.eShop.ApplicationCore.Queries.Orders +{ + public class OrderQueries: IOrderQueries + { + private readonly string _connectionString; + + public OrderQueries(string connectionString) + { + _connectionString = connectionString ?? throw new ArgumentNullException(nameof(connectionString)); + } + + private static string[] SortByColumns = new[] { "Id", "Status" }; + + public async Task> GetByBuyerIdAsync(string buyerId, string sortBy = null, int offset = 0, int fetch = 50) + { + sortBy = sortBy ?? "Id"; + + if (!SortByColumns.Contains(sortBy)) throw new ArgumentException(nameof(sortBy)); + + using (var connection = new SqlConnection(_connectionString)) + { + connection.Open(); + + var parameters = new DynamicParameters(); + parameters.Add("@buyerId", buyerId); + parameters.Add("@offset", offset); + parameters.Add("@fetch", fetch); + parameters.Add("@totalCount", dbType: DbType.Int32, direction: ParameterDirection.Output); + + var rows = await connection.QueryAsync( +@$" +SELECT @totalCount = COUNT(1) FROM [Orders] as o WHERE o.BuyerId = @buyerId; +SELECT + o.Id as OrderId, + o.QuoteId as QuoteId, + o.BuyerAddress, + o.BuyerId, + o.TransactionHash, + o.OrderDate, + o.Status, + o.PoNumber, + o.PoType, + o.CurrencySymbol, + o.[BillTo_RecipientName], + o.[BillTo_ZipCode], + o.[ShipTo_RecipientName], + o.[ShipTo_ZipCode], + (select sum(oi.Quantity * oi.UnitPrice) from OrderItems oi where oi.OrderId = o.Id) as Total, + (select count(1) from OrderItems oi where oi.OrderId = o.Id) as ItemCount +FROM [Orders] as o +WHERE o.BuyerId = @buyerId +ORDER BY [{sortBy}] +OFFSET @offset ROWS +FETCH NEXT @fetch ROWS ONLY; +" + , parameters + ); + + return new Paginated(offset, fetch, parameters.Get("@totalCount"), rows, sortBy); + } + } + + } +} diff --git a/src/Nethereum.eShop/ApplicationCore/Queries/Orders/OrderQueryDtos.cs b/src/Nethereum.eShop/ApplicationCore/Queries/Orders/OrderQueryDtos.cs new file mode 100644 index 0000000..a91382b --- /dev/null +++ b/src/Nethereum.eShop/ApplicationCore/Queries/Orders/OrderQueryDtos.cs @@ -0,0 +1,34 @@ +using System; + +namespace Nethereum.eShop.ApplicationCore.Queries.Orders +{ + public class OrderExcerpt + { + public int OrderId { get; set; } + public int QuoteId { get; set; } + public string TransactionHash { get; set; } + + public string PoNumber { get; set; } + + public string PoType { get; set; } + public string CurrencySymbol { get; set; } + + public string BuyerId { get; set; } + public string BuyerAddress { get; set; } + public DateTimeOffset QuoteDate { get; set; } + + public DateTimeOffset? Expiry { get; set; } + public decimal Total { get; set; } + public int ItemCount { get; set; } + public string Status { get; set; } + + public String ShipTo_RecipientName { get; set; } + public String ShipTo_ZipCode { get; set; } + public String BillTo_RecipientName { get; set; } + public String BillTo_ZipCode { get; set; } + } + + + + +} diff --git a/src/Nethereum.eShop/ApplicationCore/Queries/Paginated.cs b/src/Nethereum.eShop/ApplicationCore/Queries/Paginated.cs index 20131b8..f5e66dc 100644 --- a/src/Nethereum.eShop/ApplicationCore/Queries/Paginated.cs +++ b/src/Nethereum.eShop/ApplicationCore/Queries/Paginated.cs @@ -12,12 +12,15 @@ public class Paginated where TModel : class public IEnumerable Data { get; private set; } - public Paginated(int offset, int fetch, long totalCount, IEnumerable data) + public string SortedBy { get; private set; } + + public Paginated(int offset, int fetch, long totalCount, IEnumerable data, string sortedBy) { Offset = offset; Fetch = fetch; TotalCount = totalCount; Data = data; + SortedBy = sortedBy; } } } diff --git a/src/Nethereum.eShop/ApplicationCore/Queries/Quotes/QuoteQueries.cs b/src/Nethereum.eShop/ApplicationCore/Queries/Quotes/QuoteQueries.cs index 2e6668c..0e3f92e 100644 --- a/src/Nethereum.eShop/ApplicationCore/Queries/Quotes/QuoteQueries.cs +++ b/src/Nethereum.eShop/ApplicationCore/Queries/Quotes/QuoteQueries.cs @@ -63,7 +63,7 @@ OFFSET @offset ROWS , parameters ); - return new Paginated(offset, fetch, parameters.Get("@totalCount"), rows); + return new Paginated(offset, fetch, parameters.Get("@totalCount"), rows, sortBy); } } diff --git a/src/Web/Features/MyOrders/GetMyOrders.cs b/src/Web/Features/MyOrders/GetMyOrders.cs index 24d65a4..e56c1c6 100644 --- a/src/Web/Features/MyOrders/GetMyOrders.cs +++ b/src/Web/Features/MyOrders/GetMyOrders.cs @@ -4,7 +4,7 @@ namespace Nethereum.eShop.Web.Features.MyOrders { - public class GetMyOrders : IRequest> + public class GetMyOrders : IRequest> { public string UserName { get; set; } diff --git a/src/Web/Features/MyOrders/GetMyOrdersHandler.cs b/src/Web/Features/MyOrders/GetMyOrdersHandler.cs index 10c1286..3fef60a 100644 --- a/src/Web/Features/MyOrders/GetMyOrdersHandler.cs +++ b/src/Web/Features/MyOrders/GetMyOrdersHandler.cs @@ -1,5 +1,6 @@ -using MediatR; -using Nethereum.eShop.ApplicationCore.Interfaces; +using AutoMapper; +using MediatR; +using Nethereum.eShop.ApplicationCore.Queries.Orders; using Nethereum.eShop.ApplicationCore.Specifications; using Nethereum.eShop.Web.ViewModels; using System.Collections.Generic; @@ -9,35 +10,36 @@ namespace Nethereum.eShop.Web.Features.MyOrders { - public class GetMyOrdersHandler : IRequestHandler> + public class GetMyOrdersHandler : IRequestHandler> { - private readonly IOrderRepository _orderRepository; + private readonly static Mapper _mapper; + static GetMyOrdersHandler() + { + var config = new MapperConfiguration(cfg => cfg.AddProfile()); + _mapper = new Mapper(config); + } - public GetMyOrdersHandler(IOrderRepository orderRepository) + private readonly IOrderQueries _orderQueries; + + public GetMyOrdersHandler(IOrderQueries orderQueries) { - _orderRepository = orderRepository; + _orderQueries = orderQueries; } - public async Task> Handle(GetMyOrders request, CancellationToken cancellationToken) + public async Task> Handle(GetMyOrders request, CancellationToken cancellationToken) { var specification = new CustomerOrdersWithItemsSpecification(request.UserName); - var orders = await _orderRepository.ListAsync(specification); + var orders = await _orderQueries.GetByBuyerIdAsync(request.UserName, fetch: 100); + + return orders.Data.Select(o => _mapper.Map(o)); + } + } - return orders.Select(o => new OrderViewModel - { - OrderDate = o.OrderDate, - OrderItems = o.OrderItems?.Select(oi => new OrderItemViewModel() - { - PictureUrl = oi.ItemOrdered.PictureUri, - ProductId = oi.ItemOrdered.CatalogItemId, - ProductName = oi.ItemOrdered.ProductName, - UnitPrice = oi.UnitPrice, - Units = oi.Quantity - }).ToList(), - OrderNumber = o.Id, - ShippingAddress = o.ShipTo, - Total = o.Total() - }); + public class OrderExcerptProfile : Profile + { + public OrderExcerptProfile() + { + this.CreateMap(); } } } diff --git a/src/Web/Startup.cs b/src/Web/Startup.cs index 0b8e4c7..3e80649 100644 --- a/src/Web/Startup.cs +++ b/src/Web/Startup.cs @@ -7,7 +7,13 @@ using Microsoft.AspNetCore.Identity; using Microsoft.AspNetCore.Mvc.ApplicationModels; using Microsoft.EntityFrameworkCore; +using Microsoft.Extensions.Configuration; +using Microsoft.Extensions.DependencyInjection; +using Microsoft.Extensions.Diagnostics.HealthChecks; +using Microsoft.Extensions.Hosting; using Nethereum.eShop.ApplicationCore.Interfaces; +using Nethereum.eShop.ApplicationCore.Queries.Orders; +using Nethereum.eShop.ApplicationCore.Queries.Quotes; using Nethereum.eShop.ApplicationCore.Services; using Nethereum.eShop.Infrastructure.Data; using Nethereum.eShop.Infrastructure.Identity; @@ -15,17 +21,11 @@ using Nethereum.eShop.Infrastructure.Services; using Nethereum.eShop.Web.Interfaces; using Nethereum.eShop.Web.Services; -using Microsoft.Extensions.Configuration; -using Microsoft.Extensions.DependencyInjection; -using Microsoft.Extensions.Diagnostics.HealthChecks; -using Microsoft.Extensions.Hosting; using Newtonsoft.Json; using System; using System.Collections.Generic; using System.Linq; using System.Net.Mime; -using Nethereum.eShop.ApplicationCore.Queries; -using Nethereum.eShop.ApplicationCore.Queries.Quotes; namespace Nethereum.eShop.Web { @@ -112,8 +112,9 @@ public void ConfigureServices(IServiceCollection services) services.AddMediatR(typeof(BasketViewModelService).Assembly); - IQuoteQueries quoteQueries = new QuoteQueries(Configuration.GetConnectionString("CatalogConnection")); - services.AddSingleton(quoteQueries); + string queryConnectionString = Configuration.GetConnectionString("CatalogConnection"); + services.AddSingleton(new QuoteQueries(queryConnectionString)); + services.AddSingleton(new OrderQueries(queryConnectionString)); services.AddScoped(typeof(IAsyncCache<>), typeof(GeneralCache<>)); services.AddScoped(typeof(IAsyncRepository<>), typeof(EfRepository<>)); diff --git a/src/Web/ViewModels/OrderExcerptViewModel.cs b/src/Web/ViewModels/OrderExcerptViewModel.cs new file mode 100644 index 0000000..4c7d5f9 --- /dev/null +++ b/src/Web/ViewModels/OrderExcerptViewModel.cs @@ -0,0 +1,31 @@ +using System; + +namespace Nethereum.eShop.Web.ViewModels +{ + public class OrderExcerptViewModel + { + public int OrderId { get; set; } + + public int? QuoteId { get; set; } + public string TransactionHash { get; set; } + + public string PoNumber { get; set; } + + public string PoType { get; set; } + public string CurrencySymbol { get; set; } + + public string BuyerId { get; set; } + public string BuyerAddress { get; set; } + public DateTimeOffset OrderDate { get; set; } + + public DateTimeOffset? Expiry { get; set; } + public decimal Total { get; set; } + public int ItemCount { get; set; } + public string Status { get; set; } + + public String ShipTo_RecipientName { get; set; } + public String ShipTo_ZipCode { get; set; } + public String BillTo_RecipientName { get; set; } + public String BillTo_ZipCode { get; set; } + } +} diff --git a/src/Web/ViewModels/QuoteExcerptViewModel.cs b/src/Web/ViewModels/QuoteExcerptViewModel.cs new file mode 100644 index 0000000..20fdada --- /dev/null +++ b/src/Web/ViewModels/QuoteExcerptViewModel.cs @@ -0,0 +1,29 @@ +using System; + +namespace Nethereum.eShop.Web.ViewModels +{ + public class QuoteExcerptViewModel + { + public int QuoteId { get; set; } + public string TransactionHash { get; set; } + + public string PoNumber { get; set; } + + public string PoType { get; set; } + public string CurrencySymbol { get; set; } + + public string BuyerId { get; set; } + public string BuyerAddress { get; set; } + public DateTimeOffset QuoteDate { get; set; } + + public DateTimeOffset? Expiry { get; set; } + public decimal Total { get; set; } + public int ItemCount { get; set; } + public string Status { get; set; } + + public String ShipTo_RecipientName { get; set; } + public String ShipTo_ZipCode { get; set; } + public String BillTo_RecipientName { get; set; } + public String BillTo_ZipCode { get; set; } + } +} diff --git a/src/Web/ViewModels/QuoteViewModel.cs b/src/Web/ViewModels/QuoteViewModel.cs index 779707d..faa47cb 100644 --- a/src/Web/ViewModels/QuoteViewModel.cs +++ b/src/Web/ViewModels/QuoteViewModel.cs @@ -18,29 +18,4 @@ public class QuoteViewModel public PostalAddress BillTo { get; set; } public List QuoteItems { get; set; } = new List(); } - - public class QuoteExcerptViewModel - { - public int QuoteId { get; set; } - public string TransactionHash { get; set; } - - public string PoNumber { get; set; } - - public string PoType { get; set; } - public string CurrencySymbol { get; set; } - - public string BuyerId { get; set; } - public string BuyerAddress { get; set; } - public DateTimeOffset QuoteDate { get; set; } - - public DateTimeOffset? Expiry { get; set; } - public decimal Total { get; set; } - public int ItemCount { get; set; } - public string Status { get; set; } - - public String ShipTo_RecipientName { get; set; } - public String ShipTo_ZipCode { get; set; } - public String BillTo_RecipientName { get; set; } - public String BillTo_ZipCode { get; set; } - } } diff --git a/src/Web/Views/Order/MyOrders.cshtml b/src/Web/Views/Order/MyOrders.cshtml index 7478ba6..9b94b71 100644 --- a/src/Web/Views/Order/MyOrders.cshtml +++ b/src/Web/Views/Order/MyOrders.cshtml @@ -1,4 +1,4 @@ -@model IEnumerable +@model IEnumerable @{ ViewData["Title"] = "My Order History"; } @@ -7,7 +7,8 @@

@ViewData["Title"]

-
Order number
+
Id
+
PO
Date
Total
Status
@@ -17,21 +18,22 @@ { @foreach (var item in Model) { -
-
@Html.DisplayFor(modelItem => item.OrderNumber)
-
@Html.DisplayFor(modelItem => item.OrderDate)
-
$ @Html.DisplayFor(modelItem => item.Total)
-
@Html.DisplayFor(modelItem => item.Status)
-
- Detail -
-
- @if (item.Status.ToLower() == "submitted") - { - Cancel - } -
-
+
+
@Html.DisplayFor(modelItem => item.OrderId)
+
@Html.DisplayFor(modelItem => item.PoNumber)
+
@Html.DisplayFor(modelItem => item.OrderDate)
+
$ @Html.DisplayFor(modelItem => item.Total)
+
@Html.DisplayFor(modelItem => item.Status)
+
+ Detail +
+
+ @if (item.Status.ToLower() == "submitted") + { + Cancel + } +
+
} }
From 7014ed022ee8099709bc1f534b222606245678ff Mon Sep 17 00:00:00 2001 From: Dave Whiffin Date: Fri, 6 Mar 2020 12:20:52 +0000 Subject: [PATCH 04/27] Added PO number to MyQuotes view --- src/Web/Views/Quote/MyQuotes.cshtml | 34 +++++++++++++++-------------- 1 file changed, 18 insertions(+), 16 deletions(-) diff --git a/src/Web/Views/Quote/MyQuotes.cshtml b/src/Web/Views/Quote/MyQuotes.cshtml index dab1a5d..784cc65 100644 --- a/src/Web/Views/Quote/MyQuotes.cshtml +++ b/src/Web/Views/Quote/MyQuotes.cshtml @@ -9,7 +9,8 @@
Id
Date
-
Total
+
PO
+
Total
Status
@@ -17,21 +18,22 @@ { @foreach (var item in Model) { -
-
@Html.DisplayFor(modelItem => item.QuoteId)
-
@Html.DisplayFor(modelItem => item.QuoteDate)
-
$ @Html.DisplayFor(modelItem => item.Total)
-
@Html.DisplayFor(modelItem => item.Status)
-
- Detail -
-
- @if (item.Status.ToLower() == "submitted") - { - Cancel - } -
-
+
+
@Html.DisplayFor(modelItem => item.QuoteId)
+
@Html.DisplayFor(modelItem => item.QuoteDate)
+
@Html.DisplayFor(modelItem => item.PoNumber)
+
$ @Html.DisplayFor(modelItem => item.Total)
+
@Html.DisplayFor(modelItem => item.Status)
+
+ Detail +
+
+ @if (item.Status.ToLower() == "submitted") + { + Cancel + } +
+
@if (item.TransactionHash?.Length > 0) { From 3b22fb5a5828df192e317d2b57d758a81113bb4e Mon Sep 17 00:00:00 2001 From: Dave Whiffin Date: Fri, 6 Mar 2020 14:38:50 +0000 Subject: [PATCH 05/27] CatalogQueries --- .../Queries/Catalog/CatalogQueries.cs | 68 +++++++++++++++++++ .../Queries/Catalog/CatalogQueryDtos.cs | 15 ++++ .../Catalog/GetCatalogItemsSpecification.cs | 11 +++ .../Queries/Catalog/ICatalogQueries.cs | 10 +++ .../ApplicationCore/Queries/Paginated.cs | 22 +++++- src/Web/Services/CatalogViewModelService.cs | 33 +++++---- src/Web/Startup.cs | 2 + 7 files changed, 144 insertions(+), 17 deletions(-) create mode 100644 src/Nethereum.eShop/ApplicationCore/Queries/Catalog/CatalogQueries.cs create mode 100644 src/Nethereum.eShop/ApplicationCore/Queries/Catalog/CatalogQueryDtos.cs create mode 100644 src/Nethereum.eShop/ApplicationCore/Queries/Catalog/GetCatalogItemsSpecification.cs create mode 100644 src/Nethereum.eShop/ApplicationCore/Queries/Catalog/ICatalogQueries.cs diff --git a/src/Nethereum.eShop/ApplicationCore/Queries/Catalog/CatalogQueries.cs b/src/Nethereum.eShop/ApplicationCore/Queries/Catalog/CatalogQueries.cs new file mode 100644 index 0000000..ee9ae21 --- /dev/null +++ b/src/Nethereum.eShop/ApplicationCore/Queries/Catalog/CatalogQueries.cs @@ -0,0 +1,68 @@ +using Dapper; +using Microsoft.Data.SqlClient; +using System; +using System.Data; +using System.Linq; +using System.Threading.Tasks; + +namespace Nethereum.eShop.ApplicationCore.Queries.Catalog +{ + public class CatalogQueries : ICatalogQueries + { + private readonly string _connectionString; + + public CatalogQueries(string connectionString) + { + _connectionString = connectionString ?? throw new ArgumentNullException(nameof(connectionString)); + } + + private static string[] SortByColumns = new[] { "Rank" }; + public async Task> GetCatalogItemsAsync(GetCatalogItemsSpecification catalogQuerySpecification) + { + catalogQuerySpecification.SortBy = catalogQuerySpecification.SortBy ?? "Rank"; + + if (!SortByColumns.Contains(catalogQuerySpecification.SortBy)) throw new ArgumentException(nameof(catalogQuerySpecification.SortBy)); + + using (var connection = new SqlConnection(_connectionString)) + { + connection.Open(); + + var parameters = new DynamicParameters(); + parameters.Add("@searchText", catalogQuerySpecification.SearchText); + parameters.Add("@brandId", catalogQuerySpecification.BrandId); + parameters.Add("@typeId", catalogQuerySpecification.TypeId); + parameters.Add("@offset", catalogQuerySpecification.Offset); + parameters.Add("@fetch", catalogQuerySpecification.Fetch); + parameters.Add("@totalCount", dbType: DbType.Int32, direction: ParameterDirection.Output); + + + var rows = await connection.QueryAsync( +@$" + SELECT @totalCount = Count(1) FROM Catalog c + INNER JOIN CatalogBrands b ON c.CatalogBrandId = b.Id + INNER JOIN CatalogTypes t ON c.CatalogTypeId = t.Id + WHERE + (@brandId IS NULL OR (b.Id = @brandId)) AND + (@typeId IS NULL OR (t.Id = @typeId)) AND + (@searchText IS NULL OR ((c.[Name] LIKE '%' + @searchText + '%')) OR (b.Brand LIKE '%' + @searchText + '%')); + + SELECT c.Id, c.[Name], c.CatalogBrandId, b.[Brand], c.CatalogTypeId, t.[Type], c.PictureUri, c.Price, c.[Rank] + FROM Catalog c + INNER JOIN CatalogBrands b ON c.CatalogBrandId = b.Id + INNER JOIN CatalogTypes t ON c.CatalogTypeId = t.Id + WHERE + (@brandId IS NULL OR (b.Id = @brandId)) AND + (@typeId IS NULL OR (t.Id = @typeId)) AND + (@searchText IS NULL OR ((c.[Name] LIKE '%' + @searchText + '%')) OR (b.Brand LIKE '%' + @searchText + '%')) + ORDER BY [{catalogQuerySpecification.SortBy}] + OFFSET @offset ROWS + FETCH NEXT @fetch ROWS ONLY; +" + , parameters + ); + + return new Paginated(parameters.Get("@totalCount"), rows, catalogQuerySpecification); + } + } + } +} diff --git a/src/Nethereum.eShop/ApplicationCore/Queries/Catalog/CatalogQueryDtos.cs b/src/Nethereum.eShop/ApplicationCore/Queries/Catalog/CatalogQueryDtos.cs new file mode 100644 index 0000000..b25ac79 --- /dev/null +++ b/src/Nethereum.eShop/ApplicationCore/Queries/Catalog/CatalogQueryDtos.cs @@ -0,0 +1,15 @@ +using System; +using System.Collections.Generic; +using System.Text; + +namespace Nethereum.eShop.ApplicationCore.Queries.Catalog +{ + public class CatalogExcerpt + { + public int Id { get; set; } + public string Name { get; set; } + public string Brand { get; set; } + public string PictureUri { get; set; } + public decimal Price { get; set; } + } +} diff --git a/src/Nethereum.eShop/ApplicationCore/Queries/Catalog/GetCatalogItemsSpecification.cs b/src/Nethereum.eShop/ApplicationCore/Queries/Catalog/GetCatalogItemsSpecification.cs new file mode 100644 index 0000000..86ec656 --- /dev/null +++ b/src/Nethereum.eShop/ApplicationCore/Queries/Catalog/GetCatalogItemsSpecification.cs @@ -0,0 +1,11 @@ +namespace Nethereum.eShop.ApplicationCore.Queries.Catalog +{ + public class GetCatalogItemsSpecification: PaginatedQuerySpecification + { + public int? BrandId { get; set; } + + public int? TypeId { get; set; } + + public string SearchText { get; set; } + } +} diff --git a/src/Nethereum.eShop/ApplicationCore/Queries/Catalog/ICatalogQueries.cs b/src/Nethereum.eShop/ApplicationCore/Queries/Catalog/ICatalogQueries.cs new file mode 100644 index 0000000..f123b8b --- /dev/null +++ b/src/Nethereum.eShop/ApplicationCore/Queries/Catalog/ICatalogQueries.cs @@ -0,0 +1,10 @@ +using System.Threading.Tasks; + +namespace Nethereum.eShop.ApplicationCore.Queries.Catalog +{ + + public interface ICatalogQueries + { + Task> GetCatalogItemsAsync(GetCatalogItemsSpecification catalogQuerySpecification); + } +} diff --git a/src/Nethereum.eShop/ApplicationCore/Queries/Paginated.cs b/src/Nethereum.eShop/ApplicationCore/Queries/Paginated.cs index f5e66dc..a9da1e0 100644 --- a/src/Nethereum.eShop/ApplicationCore/Queries/Paginated.cs +++ b/src/Nethereum.eShop/ApplicationCore/Queries/Paginated.cs @@ -8,13 +8,13 @@ public class Paginated where TModel : class public int Fetch { get; private set; } - public long TotalCount { get; private set; } + public int TotalCount { get; private set; } public IEnumerable Data { get; private set; } public string SortedBy { get; private set; } - public Paginated(int offset, int fetch, long totalCount, IEnumerable data, string sortedBy) + public Paginated(int offset, int fetch, int totalCount, IEnumerable data, string sortedBy) { Offset = offset; Fetch = fetch; @@ -22,5 +22,23 @@ public Paginated(int offset, int fetch, long totalCount, IEnumerable dat Data = data; SortedBy = sortedBy; } + + public Paginated(int totalCount, IEnumerable data, PaginatedQuerySpecification paginatedQuery) + { + TotalCount = totalCount; + Data = data; + Offset = paginatedQuery.Offset; + Fetch = paginatedQuery.Fetch; + SortedBy = paginatedQuery.SortBy; + } + } + + public class PaginatedQuerySpecification + { + public int Offset { get; set; } + + public int Fetch { get; set; } + + public string SortBy { get; set; } } } diff --git a/src/Web/Services/CatalogViewModelService.cs b/src/Web/Services/CatalogViewModelService.cs index 9bbe85e..a1aa28e 100644 --- a/src/Web/Services/CatalogViewModelService.cs +++ b/src/Web/Services/CatalogViewModelService.cs @@ -2,6 +2,7 @@ using Microsoft.Extensions.Logging; using Nethereum.eShop.ApplicationCore.Entities; using Nethereum.eShop.ApplicationCore.Interfaces; +using Nethereum.eShop.ApplicationCore.Queries.Catalog; using Nethereum.eShop.ApplicationCore.Specifications; using Nethereum.eShop.Web.ViewModels; using System; @@ -18,20 +19,20 @@ namespace Nethereum.eShop.Web.Services public class CatalogViewModelService : ICatalogViewModelService { private readonly ILogger _logger; - private readonly ICatalogItemRepository _itemRepository; + private readonly ICatalogQueries _catalogQueries; private readonly IAsyncRepository _brandRepository; private readonly IAsyncRepository _typeRepository; private readonly IUriComposer _uriComposer; public CatalogViewModelService( ILoggerFactory loggerFactory, - ICatalogItemRepository itemRepository, + ICatalogQueries catalogQueries, IAsyncRepository brandRepository, IAsyncRepository typeRepository, IUriComposer uriComposer) { _logger = loggerFactory.CreateLogger(); - _itemRepository = itemRepository; + _catalogQueries = catalogQueries; _brandRepository = brandRepository; _typeRepository = typeRepository; _uriComposer = uriComposer; @@ -41,15 +42,17 @@ public async Task GetCatalogItems(int pageIndex, int item { _logger.LogInformation("GetCatalogItems called."); - var filterSpecification = new CatalogFilterSpecification(brandId, typeId, searchText); - var filterPaginatedSpecification = - new CatalogFilterPaginatedSpecification(itemsPage * pageIndex, itemsPage, brandId, typeId, searchText); - // the implementation below using ForEach and Count. We need a List. - var itemsOnPage = await _itemRepository.ListAsync(filterPaginatedSpecification); - var totalItems = await _itemRepository.CountAsync(filterSpecification); + var itemsOnPage = await _catalogQueries.GetCatalogItemsAsync(new GetCatalogItemsSpecification + { + BrandId = brandId, + TypeId = typeId, + Fetch = itemsPage, + SearchText = searchText, + Offset = (pageIndex * itemsPage) + }); - foreach (var itemOnPage in itemsOnPage) + foreach (var itemOnPage in itemsOnPage.Data) { itemOnPage.PictureUri = _uriComposer.ComposePicUri(itemOnPage.PictureUri); } @@ -58,13 +61,13 @@ public async Task GetCatalogItems(int pageIndex, int item var vm = new CatalogIndexViewModel() { - CatalogItems = itemsOnPage.Select(i => new CatalogItemViewModel() + CatalogItems = itemsOnPage.Data.Select(i => new CatalogItemViewModel() { Id = i.Id, Name = i.Name, PictureUri = i.PictureUri, Price = i.Price, - Brand = brands.FirstOrDefault(b => b.Id == i.CatalogBrandId)?.Brand + Brand = i.Brand }), Brands = await GetBrands(), Types = await GetTypes(), @@ -73,9 +76,9 @@ public async Task GetCatalogItems(int pageIndex, int item PaginationInfo = new PaginationInfoViewModel() { ActualPage = pageIndex, - ItemsPerPage = itemsOnPage.Count, - TotalItems = totalItems, - TotalPages = int.Parse(Math.Ceiling(((decimal)totalItems / itemsPage)).ToString()) + ItemsPerPage = itemsOnPage.Data.Count(), + TotalItems = itemsOnPage.TotalCount, + TotalPages = int.Parse(Math.Ceiling(((decimal)itemsOnPage.TotalCount / itemsPage)).ToString()) } }; diff --git a/src/Web/Startup.cs b/src/Web/Startup.cs index 3e80649..87d7af2 100644 --- a/src/Web/Startup.cs +++ b/src/Web/Startup.cs @@ -12,6 +12,7 @@ using Microsoft.Extensions.Diagnostics.HealthChecks; using Microsoft.Extensions.Hosting; using Nethereum.eShop.ApplicationCore.Interfaces; +using Nethereum.eShop.ApplicationCore.Queries.Catalog; using Nethereum.eShop.ApplicationCore.Queries.Orders; using Nethereum.eShop.ApplicationCore.Queries.Quotes; using Nethereum.eShop.ApplicationCore.Services; @@ -115,6 +116,7 @@ public void ConfigureServices(IServiceCollection services) string queryConnectionString = Configuration.GetConnectionString("CatalogConnection"); services.AddSingleton(new QuoteQueries(queryConnectionString)); services.AddSingleton(new OrderQueries(queryConnectionString)); + services.AddSingleton(new CatalogQueries(queryConnectionString)); services.AddScoped(typeof(IAsyncCache<>), typeof(GeneralCache<>)); services.AddScoped(typeof(IAsyncRepository<>), typeof(EfRepository<>)); From f0cbd5f0934dd6be71aaf16dd6e2d598e6fb1ba8 Mon Sep 17 00:00:00 2001 From: Dave Whiffin Date: Fri, 6 Mar 2020 15:09:26 +0000 Subject: [PATCH 06/27] Applying Sorts To Query and Pagination --- .../Queries/Catalog/CatalogQueries.cs | 8 ++++---- .../Catalog/GetCatalogItemsSpecification.cs | 2 +- .../Queries/Catalog/ICatalogQueries.cs | 2 +- .../Queries/Orders/IOrderQueries.cs | 2 +- .../Queries/Orders/OrderQueries.cs | 16 +++++++++------- .../Queries/{Paginated.cs => PaginatedResult.cs} | 15 +++------------ .../ApplicationCore/Queries/PaginationArgs.cs | 13 +++++++++++++ .../Queries/Quotes/IQuoteQueries.cs | 2 +- .../Queries/Quotes/QuoteQueries.cs | 16 +++++++++------- .../Specifications/CatalogFilterSpecification.cs | 15 --------------- src/Web/Features/MyOrders/GetMyOrdersHandler.cs | 6 ++---- src/Web/Features/MyQuotes/GetMyQuotesHandler.cs | 2 +- 12 files changed, 45 insertions(+), 54 deletions(-) rename src/Nethereum.eShop/ApplicationCore/Queries/{Paginated.cs => PaginatedResult.cs} (62%) create mode 100644 src/Nethereum.eShop/ApplicationCore/Queries/PaginationArgs.cs delete mode 100644 src/Nethereum.eShop/ApplicationCore/Specifications/CatalogFilterSpecification.cs diff --git a/src/Nethereum.eShop/ApplicationCore/Queries/Catalog/CatalogQueries.cs b/src/Nethereum.eShop/ApplicationCore/Queries/Catalog/CatalogQueries.cs index ee9ae21..d5570b9 100644 --- a/src/Nethereum.eShop/ApplicationCore/Queries/Catalog/CatalogQueries.cs +++ b/src/Nethereum.eShop/ApplicationCore/Queries/Catalog/CatalogQueries.cs @@ -17,8 +17,9 @@ public CatalogQueries(string connectionString) } private static string[] SortByColumns = new[] { "Rank" }; - public async Task> GetCatalogItemsAsync(GetCatalogItemsSpecification catalogQuerySpecification) + public async Task> GetCatalogItemsAsync(GetCatalogItemsSpecification catalogQuerySpecification) { + string sortOrder = catalogQuerySpecification.SortDescending ? "desc" : "asc"; catalogQuerySpecification.SortBy = catalogQuerySpecification.SortBy ?? "Rank"; if (!SortByColumns.Contains(catalogQuerySpecification.SortBy)) throw new ArgumentException(nameof(catalogQuerySpecification.SortBy)); @@ -35,7 +36,6 @@ public async Task> GetCatalogItemsAsync(GetCatalogItem parameters.Add("@fetch", catalogQuerySpecification.Fetch); parameters.Add("@totalCount", dbType: DbType.Int32, direction: ParameterDirection.Output); - var rows = await connection.QueryAsync( @$" SELECT @totalCount = Count(1) FROM Catalog c @@ -54,14 +54,14 @@ FROM Catalog c (@brandId IS NULL OR (b.Id = @brandId)) AND (@typeId IS NULL OR (t.Id = @typeId)) AND (@searchText IS NULL OR ((c.[Name] LIKE '%' + @searchText + '%')) OR (b.Brand LIKE '%' + @searchText + '%')) - ORDER BY [{catalogQuerySpecification.SortBy}] + ORDER BY [{catalogQuerySpecification.SortBy}] {sortOrder} OFFSET @offset ROWS FETCH NEXT @fetch ROWS ONLY; " , parameters ); - return new Paginated(parameters.Get("@totalCount"), rows, catalogQuerySpecification); + return new PaginatedResult(parameters.Get("@totalCount"), rows, catalogQuerySpecification); } } } diff --git a/src/Nethereum.eShop/ApplicationCore/Queries/Catalog/GetCatalogItemsSpecification.cs b/src/Nethereum.eShop/ApplicationCore/Queries/Catalog/GetCatalogItemsSpecification.cs index 86ec656..e55d525 100644 --- a/src/Nethereum.eShop/ApplicationCore/Queries/Catalog/GetCatalogItemsSpecification.cs +++ b/src/Nethereum.eShop/ApplicationCore/Queries/Catalog/GetCatalogItemsSpecification.cs @@ -1,6 +1,6 @@ namespace Nethereum.eShop.ApplicationCore.Queries.Catalog { - public class GetCatalogItemsSpecification: PaginatedQuerySpecification + public class GetCatalogItemsSpecification: PaginationArgs { public int? BrandId { get; set; } diff --git a/src/Nethereum.eShop/ApplicationCore/Queries/Catalog/ICatalogQueries.cs b/src/Nethereum.eShop/ApplicationCore/Queries/Catalog/ICatalogQueries.cs index f123b8b..64144c9 100644 --- a/src/Nethereum.eShop/ApplicationCore/Queries/Catalog/ICatalogQueries.cs +++ b/src/Nethereum.eShop/ApplicationCore/Queries/Catalog/ICatalogQueries.cs @@ -5,6 +5,6 @@ namespace Nethereum.eShop.ApplicationCore.Queries.Catalog public interface ICatalogQueries { - Task> GetCatalogItemsAsync(GetCatalogItemsSpecification catalogQuerySpecification); + Task> GetCatalogItemsAsync(GetCatalogItemsSpecification catalogQuerySpecification); } } diff --git a/src/Nethereum.eShop/ApplicationCore/Queries/Orders/IOrderQueries.cs b/src/Nethereum.eShop/ApplicationCore/Queries/Orders/IOrderQueries.cs index 3c87da8..a3bb415 100644 --- a/src/Nethereum.eShop/ApplicationCore/Queries/Orders/IOrderQueries.cs +++ b/src/Nethereum.eShop/ApplicationCore/Queries/Orders/IOrderQueries.cs @@ -4,6 +4,6 @@ namespace Nethereum.eShop.ApplicationCore.Queries.Orders { public interface IOrderQueries { - Task> GetByBuyerIdAsync(string buyerId, string sortBy = null, int offset = 0, int fetch = 50); + Task> GetByBuyerIdAsync(string buyerId, PaginationArgs paginationArgs); } } diff --git a/src/Nethereum.eShop/ApplicationCore/Queries/Orders/OrderQueries.cs b/src/Nethereum.eShop/ApplicationCore/Queries/Orders/OrderQueries.cs index 000598b..c01d338 100644 --- a/src/Nethereum.eShop/ApplicationCore/Queries/Orders/OrderQueries.cs +++ b/src/Nethereum.eShop/ApplicationCore/Queries/Orders/OrderQueries.cs @@ -18,11 +18,11 @@ public OrderQueries(string connectionString) private static string[] SortByColumns = new[] { "Id", "Status" }; - public async Task> GetByBuyerIdAsync(string buyerId, string sortBy = null, int offset = 0, int fetch = 50) + public async Task> GetByBuyerIdAsync(string buyerId, PaginationArgs paginationArgs) { - sortBy = sortBy ?? "Id"; + paginationArgs.SortBy = paginationArgs.SortBy ?? "Id"; - if (!SortByColumns.Contains(sortBy)) throw new ArgumentException(nameof(sortBy)); + if (!SortByColumns.Contains(paginationArgs.SortBy)) throw new ArgumentException(nameof(paginationArgs.SortBy)); using (var connection = new SqlConnection(_connectionString)) { @@ -30,10 +30,12 @@ public async Task> GetByBuyerIdAsync(string buyerId, str var parameters = new DynamicParameters(); parameters.Add("@buyerId", buyerId); - parameters.Add("@offset", offset); - parameters.Add("@fetch", fetch); + parameters.Add("@offset", paginationArgs.Offset); + parameters.Add("@fetch", paginationArgs.Fetch); parameters.Add("@totalCount", dbType: DbType.Int32, direction: ParameterDirection.Output); + string sortOrder = paginationArgs.SortDescending ? "desc" : "asc"; + var rows = await connection.QueryAsync( @$" SELECT @totalCount = COUNT(1) FROM [Orders] as o WHERE o.BuyerId = @buyerId; @@ -56,14 +58,14 @@ public async Task> GetByBuyerIdAsync(string buyerId, str (select count(1) from OrderItems oi where oi.OrderId = o.Id) as ItemCount FROM [Orders] as o WHERE o.BuyerId = @buyerId -ORDER BY [{sortBy}] +ORDER BY [{paginationArgs.SortBy}] {sortOrder} OFFSET @offset ROWS FETCH NEXT @fetch ROWS ONLY; " , parameters ); - return new Paginated(offset, fetch, parameters.Get("@totalCount"), rows, sortBy); + return new PaginatedResult(parameters.Get("@totalCount"), rows, paginationArgs); } } diff --git a/src/Nethereum.eShop/ApplicationCore/Queries/Paginated.cs b/src/Nethereum.eShop/ApplicationCore/Queries/PaginatedResult.cs similarity index 62% rename from src/Nethereum.eShop/ApplicationCore/Queries/Paginated.cs rename to src/Nethereum.eShop/ApplicationCore/Queries/PaginatedResult.cs index a9da1e0..cf08532 100644 --- a/src/Nethereum.eShop/ApplicationCore/Queries/Paginated.cs +++ b/src/Nethereum.eShop/ApplicationCore/Queries/PaginatedResult.cs @@ -2,7 +2,7 @@ namespace Nethereum.eShop.ApplicationCore.Queries { - public class Paginated where TModel : class + public class PaginatedResult where TModel : class { public int Offset { get; private set; } @@ -14,7 +14,7 @@ public class Paginated where TModel : class public string SortedBy { get; private set; } - public Paginated(int offset, int fetch, int totalCount, IEnumerable data, string sortedBy) + public PaginatedResult(int offset, int fetch, int totalCount, IEnumerable data, string sortedBy) { Offset = offset; Fetch = fetch; @@ -23,7 +23,7 @@ public Paginated(int offset, int fetch, int totalCount, IEnumerable data SortedBy = sortedBy; } - public Paginated(int totalCount, IEnumerable data, PaginatedQuerySpecification paginatedQuery) + public PaginatedResult(int totalCount, IEnumerable data, PaginationArgs paginatedQuery) { TotalCount = totalCount; Data = data; @@ -32,13 +32,4 @@ public Paginated(int totalCount, IEnumerable data, PaginatedQuerySpecifi SortedBy = paginatedQuery.SortBy; } } - - public class PaginatedQuerySpecification - { - public int Offset { get; set; } - - public int Fetch { get; set; } - - public string SortBy { get; set; } - } } diff --git a/src/Nethereum.eShop/ApplicationCore/Queries/PaginationArgs.cs b/src/Nethereum.eShop/ApplicationCore/Queries/PaginationArgs.cs new file mode 100644 index 0000000..153ceb7 --- /dev/null +++ b/src/Nethereum.eShop/ApplicationCore/Queries/PaginationArgs.cs @@ -0,0 +1,13 @@ +namespace Nethereum.eShop.ApplicationCore.Queries +{ + public class PaginationArgs + { + public int Offset { get; set; } = 0; + + public int Fetch { get; set; } = 50; + + public string SortBy { get; set; } + + public bool SortDescending { get; set; } + } +} diff --git a/src/Nethereum.eShop/ApplicationCore/Queries/Quotes/IQuoteQueries.cs b/src/Nethereum.eShop/ApplicationCore/Queries/Quotes/IQuoteQueries.cs index fbe01e4..4341b36 100644 --- a/src/Nethereum.eShop/ApplicationCore/Queries/Quotes/IQuoteQueries.cs +++ b/src/Nethereum.eShop/ApplicationCore/Queries/Quotes/IQuoteQueries.cs @@ -4,6 +4,6 @@ namespace Nethereum.eShop.ApplicationCore.Queries.Quotes { public interface IQuoteQueries { - Task> GetByBuyerIdAsync(string buyerId, string sortBy = null, int offset = 0, int fetch = 50); + Task> GetByBuyerIdAsync(string buyerId, PaginationArgs paginationArgs); } } diff --git a/src/Nethereum.eShop/ApplicationCore/Queries/Quotes/QuoteQueries.cs b/src/Nethereum.eShop/ApplicationCore/Queries/Quotes/QuoteQueries.cs index 0e3f92e..753cb45 100644 --- a/src/Nethereum.eShop/ApplicationCore/Queries/Quotes/QuoteQueries.cs +++ b/src/Nethereum.eShop/ApplicationCore/Queries/Quotes/QuoteQueries.cs @@ -18,11 +18,11 @@ public QuoteQueries(string connectionString) private static string[] SortByColumns = new[] { "Id", "Status" }; - public async Task> GetByBuyerIdAsync(string buyerId, string sortBy = null, int offset = 0, int fetch = 50) + public async Task> GetByBuyerIdAsync(string buyerId, PaginationArgs paginationArgs) { - sortBy = sortBy ?? "Id"; + paginationArgs.SortBy = paginationArgs.SortBy ?? "Id"; - if (!SortByColumns.Contains(sortBy)) throw new ArgumentException(nameof(sortBy)); + if (!SortByColumns.Contains(paginationArgs.SortBy)) throw new ArgumentException(nameof(paginationArgs.SortBy)); using (var connection = new SqlConnection(_connectionString)) { @@ -30,10 +30,12 @@ public async Task> GetByBuyerIdAsync(string buyerId, str var parameters = new DynamicParameters(); parameters.Add("@buyerId", buyerId); - parameters.Add("@offset", offset); - parameters.Add("@fetch", fetch); + parameters.Add("@offset", paginationArgs.Offset); + parameters.Add("@fetch", paginationArgs.Fetch); parameters.Add("@totalCount", dbType: DbType.Int32, direction: ParameterDirection.Output); + string sortOrder = paginationArgs.SortDescending ? "desc" : "asc"; + var rows = await connection.QueryAsync( @$" SELECT @totalCount = COUNT(1) FROM Quotes as q WHERE q.BuyerId = @buyerId; @@ -56,14 +58,14 @@ public async Task> GetByBuyerIdAsync(string buyerId, str (select count(1) from QuoteItems qi where qi.QuoteId = q.Id) as ItemCount FROM Quotes as q WHERE q.BuyerId = @buyerId -ORDER BY [{sortBy}] +ORDER BY [{paginationArgs.SortBy}] {sortOrder} OFFSET @offset ROWS FETCH NEXT @fetch ROWS ONLY; " , parameters ); - return new Paginated(offset, fetch, parameters.Get("@totalCount"), rows, sortBy); + return new PaginatedResult(parameters.Get("@totalCount"), rows, paginationArgs); } } diff --git a/src/Nethereum.eShop/ApplicationCore/Specifications/CatalogFilterSpecification.cs b/src/Nethereum.eShop/ApplicationCore/Specifications/CatalogFilterSpecification.cs deleted file mode 100644 index 03cf530..0000000 --- a/src/Nethereum.eShop/ApplicationCore/Specifications/CatalogFilterSpecification.cs +++ /dev/null @@ -1,15 +0,0 @@ -using Nethereum.eShop.ApplicationCore.Entities; - -namespace Nethereum.eShop.ApplicationCore.Specifications -{ - - public class CatalogFilterSpecification : BaseSpecification - { - public CatalogFilterSpecification(int? brandId, int? typeId, string searchText = null) - : base(i => (!brandId.HasValue || i.CatalogBrandId == brandId) && - (!typeId.HasValue || i.CatalogTypeId == typeId) && - (searchText == null || (i.Name.Contains(searchText) || i.CatalogBrand.Brand.Contains(searchText)))) - { - } - } -} diff --git a/src/Web/Features/MyOrders/GetMyOrdersHandler.cs b/src/Web/Features/MyOrders/GetMyOrdersHandler.cs index 3fef60a..4c85c71 100644 --- a/src/Web/Features/MyOrders/GetMyOrdersHandler.cs +++ b/src/Web/Features/MyOrders/GetMyOrdersHandler.cs @@ -1,7 +1,7 @@ using AutoMapper; using MediatR; +using Nethereum.eShop.ApplicationCore.Queries; using Nethereum.eShop.ApplicationCore.Queries.Orders; -using Nethereum.eShop.ApplicationCore.Specifications; using Nethereum.eShop.Web.ViewModels; using System.Collections.Generic; using System.Linq; @@ -28,9 +28,7 @@ public GetMyOrdersHandler(IOrderQueries orderQueries) public async Task> Handle(GetMyOrders request, CancellationToken cancellationToken) { - var specification = new CustomerOrdersWithItemsSpecification(request.UserName); - var orders = await _orderQueries.GetByBuyerIdAsync(request.UserName, fetch: 100); - + var orders = await _orderQueries.GetByBuyerIdAsync(request.UserName, new PaginationArgs { Fetch = 100, SortDescending = true }); return orders.Data.Select(o => _mapper.Map(o)); } } diff --git a/src/Web/Features/MyQuotes/GetMyQuotesHandler.cs b/src/Web/Features/MyQuotes/GetMyQuotesHandler.cs index f11ed6c..a9aa950 100644 --- a/src/Web/Features/MyQuotes/GetMyQuotesHandler.cs +++ b/src/Web/Features/MyQuotes/GetMyQuotesHandler.cs @@ -29,7 +29,7 @@ public GetMyQuotesHandler(IQuoteQueries quoteRepository) public async Task> Handle(GetMyQuotes request, CancellationToken cancellationToken) { - var quotes = await _quoteQueries.GetByBuyerIdAsync(request.UserName, fetch: 100); + var quotes = await _quoteQueries.GetByBuyerIdAsync(request.UserName, new PaginationArgs { Fetch = 100, SortDescending = true }); return quotes.Data.Select(excerpt => _mapper.Map(excerpt)); } } From aebba48f79a263f088b65863fe9c5e784449571a Mon Sep 17 00:00:00 2001 From: Dave Whiffin Date: Fri, 6 Mar 2020 18:09:22 +0000 Subject: [PATCH 07/27] Separating SQL Server Implementation --- .../Queries/Catalog/CatalogQueries.cs | 0 .../Queries/Orders/OrderQueries.cs | 0 .../Queries/Quotes/QuoteQueries.cs | 0 .../Data/Config/BasketConfiguration.cs | 0 .../Data/Config/BasketItemConfiguration.cs | 0 .../Data/Config/BuyerConfiguration.cs | 0 .../Config/BuyerPostalAddressConfiguration.cs | 0 .../Data/Config/CatalogBrandConfiguration.cs | 0 .../Data/Config/CatalogItemConfiguration.cs | 0 .../Data/Config/CatalogItemExcerptBuilder.cs | 2 +- .../Data/Config/CatalogTypeConfiguration.cs | 0 .../Data/Config/OrderConfiguration.cs | 0 .../Data/Config/OrderItemConfiguration.cs | 0 .../Data/Config/PostalAddressBuilder.cs | 0 .../Data/Config/QuoteConfiguration.cs | 0 .../Data/Config/QuoteItemConfiguration.cs | 0 .../Data/Config/StockItemConfiguration.cs | 0 .../20200221124040_InitialCreate.Designer.cs | 0 .../20200221124040_InitialCreate.cs | 0 .../20200304170042_ResizeColumns.Designer.cs | 0 .../20200304170042_ResizeColumns.cs | 0 ...200304171630_SetGtinColumnSize.Designer.cs | 0 .../20200304171630_SetGtinColumnSize.cs | 0 .../Migrations/CatalogContextModelSnapshot.cs | 0 .../20200221124042_InitialCreate.Designer.cs | 0 .../20200221124042_InitialCreate.cs | 0 .../AppIdentityDbContextModelSnapshot.cs | 0 .../Nethereum.eShop.SqlServer.csproj | 32 +++++++++++++++++++ src/Nethereum.eShop.sln | 6 ++++ .../Entities/RulesEngine/RulesDomainSeed.cs | 3 +- .../Interfaces/IAsyncRepository.cs | 4 --- .../Interfaces/ICatalogItemRepository.cs | 4 ++- .../Interfaces/IQuoteRepository.cs | 3 ++ .../Infrastructure/Data/CatalogContext.cs | 24 ++++++++++++-- .../Data/CatalogItemRepository.cs | 12 +++---- .../Infrastructure/Data/EfRepository.cs | 30 ----------------- .../Infrastructure/Data/QuoteRepository.cs | 7 ++++ src/Nethereum.eShop/Nethereum.eShop.csproj | 3 +- .../OrderDetails/GetOrderDetailsHandler.cs | 3 +- .../QuoteDetails/GetQuoteDetailsHandler.cs | 3 +- src/Web/Services/BasketViewModelService.cs | 10 +++--- .../Services/CatalogItemViewModelService.cs | 6 ++-- src/Web/Startup.cs | 5 +++ src/Web/Web.csproj | 1 + src/WebJobs/Jobs/CreateFakePurchaseOrders.cs | 17 +++------- 45 files changed, 100 insertions(+), 75 deletions(-) rename src/{Nethereum.eShop => Nethereum.eShop.SqlServer}/ApplicationCore/Queries/Catalog/CatalogQueries.cs (100%) rename src/{Nethereum.eShop => Nethereum.eShop.SqlServer}/ApplicationCore/Queries/Orders/OrderQueries.cs (100%) rename src/{Nethereum.eShop => Nethereum.eShop.SqlServer}/ApplicationCore/Queries/Quotes/QuoteQueries.cs (100%) rename src/{Nethereum.eShop => Nethereum.eShop.SqlServer}/Infrastructure/Data/Config/BasketConfiguration.cs (100%) rename src/{Nethereum.eShop => Nethereum.eShop.SqlServer}/Infrastructure/Data/Config/BasketItemConfiguration.cs (100%) rename src/{Nethereum.eShop => Nethereum.eShop.SqlServer}/Infrastructure/Data/Config/BuyerConfiguration.cs (100%) rename src/{Nethereum.eShop => Nethereum.eShop.SqlServer}/Infrastructure/Data/Config/BuyerPostalAddressConfiguration.cs (100%) rename src/{Nethereum.eShop => Nethereum.eShop.SqlServer}/Infrastructure/Data/Config/CatalogBrandConfiguration.cs (100%) rename src/{Nethereum.eShop => Nethereum.eShop.SqlServer}/Infrastructure/Data/Config/CatalogItemConfiguration.cs (100%) rename src/{Nethereum.eShop => Nethereum.eShop.SqlServer}/Infrastructure/Data/Config/CatalogItemExcerptBuilder.cs (96%) rename src/{Nethereum.eShop => Nethereum.eShop.SqlServer}/Infrastructure/Data/Config/CatalogTypeConfiguration.cs (100%) rename src/{Nethereum.eShop => Nethereum.eShop.SqlServer}/Infrastructure/Data/Config/OrderConfiguration.cs (100%) rename src/{Nethereum.eShop => Nethereum.eShop.SqlServer}/Infrastructure/Data/Config/OrderItemConfiguration.cs (100%) rename src/{Nethereum.eShop => Nethereum.eShop.SqlServer}/Infrastructure/Data/Config/PostalAddressBuilder.cs (100%) rename src/{Nethereum.eShop => Nethereum.eShop.SqlServer}/Infrastructure/Data/Config/QuoteConfiguration.cs (100%) rename src/{Nethereum.eShop => Nethereum.eShop.SqlServer}/Infrastructure/Data/Config/QuoteItemConfiguration.cs (100%) rename src/{Nethereum.eShop => Nethereum.eShop.SqlServer}/Infrastructure/Data/Config/StockItemConfiguration.cs (100%) rename src/{Nethereum.eShop => Nethereum.eShop.SqlServer}/Infrastructure/Data/Migrations/20200221124040_InitialCreate.Designer.cs (100%) rename src/{Nethereum.eShop => Nethereum.eShop.SqlServer}/Infrastructure/Data/Migrations/20200221124040_InitialCreate.cs (100%) rename src/{Nethereum.eShop => Nethereum.eShop.SqlServer}/Infrastructure/Data/Migrations/20200304170042_ResizeColumns.Designer.cs (100%) rename src/{Nethereum.eShop => Nethereum.eShop.SqlServer}/Infrastructure/Data/Migrations/20200304170042_ResizeColumns.cs (100%) rename src/{Nethereum.eShop => Nethereum.eShop.SqlServer}/Infrastructure/Data/Migrations/20200304171630_SetGtinColumnSize.Designer.cs (100%) rename src/{Nethereum.eShop => Nethereum.eShop.SqlServer}/Infrastructure/Data/Migrations/20200304171630_SetGtinColumnSize.cs (100%) rename src/{Nethereum.eShop => Nethereum.eShop.SqlServer}/Infrastructure/Data/Migrations/CatalogContextModelSnapshot.cs (100%) rename src/{Nethereum.eShop => Nethereum.eShop.SqlServer}/Infrastructure/Identity/Migrations/20200221124042_InitialCreate.Designer.cs (100%) rename src/{Nethereum.eShop => Nethereum.eShop.SqlServer}/Infrastructure/Identity/Migrations/20200221124042_InitialCreate.cs (100%) rename src/{Nethereum.eShop => Nethereum.eShop.SqlServer}/Infrastructure/Identity/Migrations/AppIdentityDbContextModelSnapshot.cs (100%) create mode 100644 src/Nethereum.eShop.SqlServer/Nethereum.eShop.SqlServer.csproj diff --git a/src/Nethereum.eShop/ApplicationCore/Queries/Catalog/CatalogQueries.cs b/src/Nethereum.eShop.SqlServer/ApplicationCore/Queries/Catalog/CatalogQueries.cs similarity index 100% rename from src/Nethereum.eShop/ApplicationCore/Queries/Catalog/CatalogQueries.cs rename to src/Nethereum.eShop.SqlServer/ApplicationCore/Queries/Catalog/CatalogQueries.cs diff --git a/src/Nethereum.eShop/ApplicationCore/Queries/Orders/OrderQueries.cs b/src/Nethereum.eShop.SqlServer/ApplicationCore/Queries/Orders/OrderQueries.cs similarity index 100% rename from src/Nethereum.eShop/ApplicationCore/Queries/Orders/OrderQueries.cs rename to src/Nethereum.eShop.SqlServer/ApplicationCore/Queries/Orders/OrderQueries.cs diff --git a/src/Nethereum.eShop/ApplicationCore/Queries/Quotes/QuoteQueries.cs b/src/Nethereum.eShop.SqlServer/ApplicationCore/Queries/Quotes/QuoteQueries.cs similarity index 100% rename from src/Nethereum.eShop/ApplicationCore/Queries/Quotes/QuoteQueries.cs rename to src/Nethereum.eShop.SqlServer/ApplicationCore/Queries/Quotes/QuoteQueries.cs diff --git a/src/Nethereum.eShop/Infrastructure/Data/Config/BasketConfiguration.cs b/src/Nethereum.eShop.SqlServer/Infrastructure/Data/Config/BasketConfiguration.cs similarity index 100% rename from src/Nethereum.eShop/Infrastructure/Data/Config/BasketConfiguration.cs rename to src/Nethereum.eShop.SqlServer/Infrastructure/Data/Config/BasketConfiguration.cs diff --git a/src/Nethereum.eShop/Infrastructure/Data/Config/BasketItemConfiguration.cs b/src/Nethereum.eShop.SqlServer/Infrastructure/Data/Config/BasketItemConfiguration.cs similarity index 100% rename from src/Nethereum.eShop/Infrastructure/Data/Config/BasketItemConfiguration.cs rename to src/Nethereum.eShop.SqlServer/Infrastructure/Data/Config/BasketItemConfiguration.cs diff --git a/src/Nethereum.eShop/Infrastructure/Data/Config/BuyerConfiguration.cs b/src/Nethereum.eShop.SqlServer/Infrastructure/Data/Config/BuyerConfiguration.cs similarity index 100% rename from src/Nethereum.eShop/Infrastructure/Data/Config/BuyerConfiguration.cs rename to src/Nethereum.eShop.SqlServer/Infrastructure/Data/Config/BuyerConfiguration.cs diff --git a/src/Nethereum.eShop/Infrastructure/Data/Config/BuyerPostalAddressConfiguration.cs b/src/Nethereum.eShop.SqlServer/Infrastructure/Data/Config/BuyerPostalAddressConfiguration.cs similarity index 100% rename from src/Nethereum.eShop/Infrastructure/Data/Config/BuyerPostalAddressConfiguration.cs rename to src/Nethereum.eShop.SqlServer/Infrastructure/Data/Config/BuyerPostalAddressConfiguration.cs diff --git a/src/Nethereum.eShop/Infrastructure/Data/Config/CatalogBrandConfiguration.cs b/src/Nethereum.eShop.SqlServer/Infrastructure/Data/Config/CatalogBrandConfiguration.cs similarity index 100% rename from src/Nethereum.eShop/Infrastructure/Data/Config/CatalogBrandConfiguration.cs rename to src/Nethereum.eShop.SqlServer/Infrastructure/Data/Config/CatalogBrandConfiguration.cs diff --git a/src/Nethereum.eShop/Infrastructure/Data/Config/CatalogItemConfiguration.cs b/src/Nethereum.eShop.SqlServer/Infrastructure/Data/Config/CatalogItemConfiguration.cs similarity index 100% rename from src/Nethereum.eShop/Infrastructure/Data/Config/CatalogItemConfiguration.cs rename to src/Nethereum.eShop.SqlServer/Infrastructure/Data/Config/CatalogItemConfiguration.cs diff --git a/src/Nethereum.eShop/Infrastructure/Data/Config/CatalogItemExcerptBuilder.cs b/src/Nethereum.eShop.SqlServer/Infrastructure/Data/Config/CatalogItemExcerptBuilder.cs similarity index 96% rename from src/Nethereum.eShop/Infrastructure/Data/Config/CatalogItemExcerptBuilder.cs rename to src/Nethereum.eShop.SqlServer/Infrastructure/Data/Config/CatalogItemExcerptBuilder.cs index bc32ae1..3bf9659 100644 --- a/src/Nethereum.eShop/Infrastructure/Data/Config/CatalogItemExcerptBuilder.cs +++ b/src/Nethereum.eShop.SqlServer/Infrastructure/Data/Config/CatalogItemExcerptBuilder.cs @@ -6,7 +6,7 @@ namespace Nethereum.eShop.Infrastructure.Data.Config public static class CatalogItemExcerptBuilder { public static void ConfigureCatalogItemExcerpt(this OwnedNavigationBuilder a) where TParentEntity : class{ - a.WithOwner(); + a.WithOwner(); a.Property(cio => cio.ProductName) diff --git a/src/Nethereum.eShop/Infrastructure/Data/Config/CatalogTypeConfiguration.cs b/src/Nethereum.eShop.SqlServer/Infrastructure/Data/Config/CatalogTypeConfiguration.cs similarity index 100% rename from src/Nethereum.eShop/Infrastructure/Data/Config/CatalogTypeConfiguration.cs rename to src/Nethereum.eShop.SqlServer/Infrastructure/Data/Config/CatalogTypeConfiguration.cs diff --git a/src/Nethereum.eShop/Infrastructure/Data/Config/OrderConfiguration.cs b/src/Nethereum.eShop.SqlServer/Infrastructure/Data/Config/OrderConfiguration.cs similarity index 100% rename from src/Nethereum.eShop/Infrastructure/Data/Config/OrderConfiguration.cs rename to src/Nethereum.eShop.SqlServer/Infrastructure/Data/Config/OrderConfiguration.cs diff --git a/src/Nethereum.eShop/Infrastructure/Data/Config/OrderItemConfiguration.cs b/src/Nethereum.eShop.SqlServer/Infrastructure/Data/Config/OrderItemConfiguration.cs similarity index 100% rename from src/Nethereum.eShop/Infrastructure/Data/Config/OrderItemConfiguration.cs rename to src/Nethereum.eShop.SqlServer/Infrastructure/Data/Config/OrderItemConfiguration.cs diff --git a/src/Nethereum.eShop/Infrastructure/Data/Config/PostalAddressBuilder.cs b/src/Nethereum.eShop.SqlServer/Infrastructure/Data/Config/PostalAddressBuilder.cs similarity index 100% rename from src/Nethereum.eShop/Infrastructure/Data/Config/PostalAddressBuilder.cs rename to src/Nethereum.eShop.SqlServer/Infrastructure/Data/Config/PostalAddressBuilder.cs diff --git a/src/Nethereum.eShop/Infrastructure/Data/Config/QuoteConfiguration.cs b/src/Nethereum.eShop.SqlServer/Infrastructure/Data/Config/QuoteConfiguration.cs similarity index 100% rename from src/Nethereum.eShop/Infrastructure/Data/Config/QuoteConfiguration.cs rename to src/Nethereum.eShop.SqlServer/Infrastructure/Data/Config/QuoteConfiguration.cs diff --git a/src/Nethereum.eShop/Infrastructure/Data/Config/QuoteItemConfiguration.cs b/src/Nethereum.eShop.SqlServer/Infrastructure/Data/Config/QuoteItemConfiguration.cs similarity index 100% rename from src/Nethereum.eShop/Infrastructure/Data/Config/QuoteItemConfiguration.cs rename to src/Nethereum.eShop.SqlServer/Infrastructure/Data/Config/QuoteItemConfiguration.cs diff --git a/src/Nethereum.eShop/Infrastructure/Data/Config/StockItemConfiguration.cs b/src/Nethereum.eShop.SqlServer/Infrastructure/Data/Config/StockItemConfiguration.cs similarity index 100% rename from src/Nethereum.eShop/Infrastructure/Data/Config/StockItemConfiguration.cs rename to src/Nethereum.eShop.SqlServer/Infrastructure/Data/Config/StockItemConfiguration.cs diff --git a/src/Nethereum.eShop/Infrastructure/Data/Migrations/20200221124040_InitialCreate.Designer.cs b/src/Nethereum.eShop.SqlServer/Infrastructure/Data/Migrations/20200221124040_InitialCreate.Designer.cs similarity index 100% rename from src/Nethereum.eShop/Infrastructure/Data/Migrations/20200221124040_InitialCreate.Designer.cs rename to src/Nethereum.eShop.SqlServer/Infrastructure/Data/Migrations/20200221124040_InitialCreate.Designer.cs diff --git a/src/Nethereum.eShop/Infrastructure/Data/Migrations/20200221124040_InitialCreate.cs b/src/Nethereum.eShop.SqlServer/Infrastructure/Data/Migrations/20200221124040_InitialCreate.cs similarity index 100% rename from src/Nethereum.eShop/Infrastructure/Data/Migrations/20200221124040_InitialCreate.cs rename to src/Nethereum.eShop.SqlServer/Infrastructure/Data/Migrations/20200221124040_InitialCreate.cs diff --git a/src/Nethereum.eShop/Infrastructure/Data/Migrations/20200304170042_ResizeColumns.Designer.cs b/src/Nethereum.eShop.SqlServer/Infrastructure/Data/Migrations/20200304170042_ResizeColumns.Designer.cs similarity index 100% rename from src/Nethereum.eShop/Infrastructure/Data/Migrations/20200304170042_ResizeColumns.Designer.cs rename to src/Nethereum.eShop.SqlServer/Infrastructure/Data/Migrations/20200304170042_ResizeColumns.Designer.cs diff --git a/src/Nethereum.eShop/Infrastructure/Data/Migrations/20200304170042_ResizeColumns.cs b/src/Nethereum.eShop.SqlServer/Infrastructure/Data/Migrations/20200304170042_ResizeColumns.cs similarity index 100% rename from src/Nethereum.eShop/Infrastructure/Data/Migrations/20200304170042_ResizeColumns.cs rename to src/Nethereum.eShop.SqlServer/Infrastructure/Data/Migrations/20200304170042_ResizeColumns.cs diff --git a/src/Nethereum.eShop/Infrastructure/Data/Migrations/20200304171630_SetGtinColumnSize.Designer.cs b/src/Nethereum.eShop.SqlServer/Infrastructure/Data/Migrations/20200304171630_SetGtinColumnSize.Designer.cs similarity index 100% rename from src/Nethereum.eShop/Infrastructure/Data/Migrations/20200304171630_SetGtinColumnSize.Designer.cs rename to src/Nethereum.eShop.SqlServer/Infrastructure/Data/Migrations/20200304171630_SetGtinColumnSize.Designer.cs diff --git a/src/Nethereum.eShop/Infrastructure/Data/Migrations/20200304171630_SetGtinColumnSize.cs b/src/Nethereum.eShop.SqlServer/Infrastructure/Data/Migrations/20200304171630_SetGtinColumnSize.cs similarity index 100% rename from src/Nethereum.eShop/Infrastructure/Data/Migrations/20200304171630_SetGtinColumnSize.cs rename to src/Nethereum.eShop.SqlServer/Infrastructure/Data/Migrations/20200304171630_SetGtinColumnSize.cs diff --git a/src/Nethereum.eShop/Infrastructure/Data/Migrations/CatalogContextModelSnapshot.cs b/src/Nethereum.eShop.SqlServer/Infrastructure/Data/Migrations/CatalogContextModelSnapshot.cs similarity index 100% rename from src/Nethereum.eShop/Infrastructure/Data/Migrations/CatalogContextModelSnapshot.cs rename to src/Nethereum.eShop.SqlServer/Infrastructure/Data/Migrations/CatalogContextModelSnapshot.cs diff --git a/src/Nethereum.eShop/Infrastructure/Identity/Migrations/20200221124042_InitialCreate.Designer.cs b/src/Nethereum.eShop.SqlServer/Infrastructure/Identity/Migrations/20200221124042_InitialCreate.Designer.cs similarity index 100% rename from src/Nethereum.eShop/Infrastructure/Identity/Migrations/20200221124042_InitialCreate.Designer.cs rename to src/Nethereum.eShop.SqlServer/Infrastructure/Identity/Migrations/20200221124042_InitialCreate.Designer.cs diff --git a/src/Nethereum.eShop/Infrastructure/Identity/Migrations/20200221124042_InitialCreate.cs b/src/Nethereum.eShop.SqlServer/Infrastructure/Identity/Migrations/20200221124042_InitialCreate.cs similarity index 100% rename from src/Nethereum.eShop/Infrastructure/Identity/Migrations/20200221124042_InitialCreate.cs rename to src/Nethereum.eShop.SqlServer/Infrastructure/Identity/Migrations/20200221124042_InitialCreate.cs diff --git a/src/Nethereum.eShop/Infrastructure/Identity/Migrations/AppIdentityDbContextModelSnapshot.cs b/src/Nethereum.eShop.SqlServer/Infrastructure/Identity/Migrations/AppIdentityDbContextModelSnapshot.cs similarity index 100% rename from src/Nethereum.eShop/Infrastructure/Identity/Migrations/AppIdentityDbContextModelSnapshot.cs rename to src/Nethereum.eShop.SqlServer/Infrastructure/Identity/Migrations/AppIdentityDbContextModelSnapshot.cs diff --git a/src/Nethereum.eShop.SqlServer/Nethereum.eShop.SqlServer.csproj b/src/Nethereum.eShop.SqlServer/Nethereum.eShop.SqlServer.csproj new file mode 100644 index 0000000..a3b5bab --- /dev/null +++ b/src/Nethereum.eShop.SqlServer/Nethereum.eShop.SqlServer.csproj @@ -0,0 +1,32 @@ + + + + netstandard2.1 + 80b8bc7f-cc13-45f4-967c-6c2b164a22e3 + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/src/Nethereum.eShop.sln b/src/Nethereum.eShop.sln index d3fd56e..fb390c4 100644 --- a/src/Nethereum.eShop.sln +++ b/src/Nethereum.eShop.sln @@ -21,6 +21,8 @@ Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Nethereum.Commerce.Contract EndProject Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "WebJobs", "WebJobs\WebJobs.csproj", "{C817D513-88E9-4721-A1EA-57EFE0FABCD5}" EndProject +Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Nethereum.eShop.SqlServer", "Nethereum.eShop.SqlServer\Nethereum.eShop.SqlServer.csproj", "{658EAD99-D587-4105-9743-8DF2722858EA}" +EndProject Global GlobalSection(SolutionConfigurationPlatforms) = preSolution Debug|Any CPU = Debug|Any CPU @@ -51,6 +53,10 @@ Global {C817D513-88E9-4721-A1EA-57EFE0FABCD5}.Debug|Any CPU.Build.0 = Debug|Any CPU {C817D513-88E9-4721-A1EA-57EFE0FABCD5}.Release|Any CPU.ActiveCfg = Release|Any CPU {C817D513-88E9-4721-A1EA-57EFE0FABCD5}.Release|Any CPU.Build.0 = Release|Any CPU + {658EAD99-D587-4105-9743-8DF2722858EA}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {658EAD99-D587-4105-9743-8DF2722858EA}.Debug|Any CPU.Build.0 = Debug|Any CPU + {658EAD99-D587-4105-9743-8DF2722858EA}.Release|Any CPU.ActiveCfg = Release|Any CPU + {658EAD99-D587-4105-9743-8DF2722858EA}.Release|Any CPU.Build.0 = Release|Any CPU EndGlobalSection GlobalSection(SolutionProperties) = preSolution HideSolutionNode = FALSE diff --git a/src/Nethereum.eShop/ApplicationCore/Entities/RulesEngine/RulesDomainSeed.cs b/src/Nethereum.eShop/ApplicationCore/Entities/RulesEngine/RulesDomainSeed.cs index 9f2b23d..1c88add 100644 --- a/src/Nethereum.eShop/ApplicationCore/Entities/RulesEngine/RulesDomainSeed.cs +++ b/src/Nethereum.eShop/ApplicationCore/Entities/RulesEngine/RulesDomainSeed.cs @@ -1,7 +1,6 @@ using System; using System.Collections.Generic; - -using Microsoft.Data.SqlClient; +using System.Data.SqlClient; namespace Nethereum.eShop.ApplicationCore.Entities.RulesEngine { diff --git a/src/Nethereum.eShop/ApplicationCore/Interfaces/IAsyncRepository.cs b/src/Nethereum.eShop/ApplicationCore/Interfaces/IAsyncRepository.cs index e5395fb..f332285 100644 --- a/src/Nethereum.eShop/ApplicationCore/Interfaces/IAsyncRepository.cs +++ b/src/Nethereum.eShop/ApplicationCore/Interfaces/IAsyncRepository.cs @@ -10,9 +10,5 @@ public interface IAsyncRepository where T : BaseEntity, IAggregateRoot Task GetByIdAsync(int id); Task> ListAllAsync(); Task> ListAsync(ISpecification spec); - Task AddAsync(T entity); - Task UpdateAsync(T entity); - Task DeleteAsync(T entity); - Task CountAsync(ISpecification spec); } } diff --git a/src/Nethereum.eShop/ApplicationCore/Interfaces/ICatalogItemRepository.cs b/src/Nethereum.eShop/ApplicationCore/Interfaces/ICatalogItemRepository.cs index 09f7bd6..2208923 100644 --- a/src/Nethereum.eShop/ApplicationCore/Interfaces/ICatalogItemRepository.cs +++ b/src/Nethereum.eShop/ApplicationCore/Interfaces/ICatalogItemRepository.cs @@ -1,8 +1,10 @@ using Nethereum.eShop.ApplicationCore.Entities; +using Nethereum.eShop.Infrastructure.Data; namespace Nethereum.eShop.ApplicationCore.Interfaces { - public interface ICatalogItemRepository : IAsyncRepository + public interface ICatalogItemRepository : IAsyncRepository, IRepository { + } } diff --git a/src/Nethereum.eShop/ApplicationCore/Interfaces/IQuoteRepository.cs b/src/Nethereum.eShop/ApplicationCore/Interfaces/IQuoteRepository.cs index f502fd4..da61b2b 100644 --- a/src/Nethereum.eShop/ApplicationCore/Interfaces/IQuoteRepository.cs +++ b/src/Nethereum.eShop/ApplicationCore/Interfaces/IQuoteRepository.cs @@ -1,5 +1,6 @@ using Nethereum.eShop.ApplicationCore.Entities.QuoteAggregate; using Nethereum.eShop.Infrastructure.Data; +using System.Collections.Generic; using System.Threading.Tasks; namespace Nethereum.eShop.ApplicationCore.Interfaces @@ -10,5 +11,7 @@ public interface IQuoteRepository : IAsyncRepository, IRepository Quote Update(Quote quote); Task GetByIdWithItemsAsync(int id); + + Task> GetQuotesRequiringPurchaseOrderAsync(); } } diff --git a/src/Nethereum.eShop/Infrastructure/Data/CatalogContext.cs b/src/Nethereum.eShop/Infrastructure/Data/CatalogContext.cs index f97fa33..25bc04f 100644 --- a/src/Nethereum.eShop/Infrastructure/Data/CatalogContext.cs +++ b/src/Nethereum.eShop/Infrastructure/Data/CatalogContext.cs @@ -14,15 +14,33 @@ namespace Nethereum.eShop.Infrastructure.Data { + public interface IModelBuilderAssemblyHandler + { + Assembly GetModelBuilderAssembly(); + } + + public class ModelBuilderAssemblyHandler : IModelBuilderAssemblyHandler + { + private readonly Assembly _assembly; + + public ModelBuilderAssemblyHandler(Assembly assembly) + { + _assembly = assembly; + } + public Assembly GetModelBuilderAssembly() => _assembly; + } public class CatalogContext : DbContext, IUnitOfWork { private readonly IMediator _mediator; + private readonly IModelBuilderAssemblyHandler _modelBuilderAssemblyHandler; private IDbContextTransaction _currentTransaction; - public CatalogContext(DbContextOptions options, IMediator mediator) : base(options) + public CatalogContext( + DbContextOptions options, IMediator mediator, IModelBuilderAssemblyHandler modelBuilderAssemblyHandler) : base(options) { _mediator = mediator; + _modelBuilderAssemblyHandler = modelBuilderAssemblyHandler; } public DbSet Buyers { get; set; } @@ -45,10 +63,10 @@ public CatalogContext(DbContextOptions options, IMediator mediat protected override void OnModelCreating(ModelBuilder builder) { base.OnModelCreating(builder); - builder.ApplyConfigurationsFromAssembly(Assembly.GetExecutingAssembly()); + var modelBuilderAssembly = _modelBuilderAssemblyHandler?.GetModelBuilderAssembly() ?? Assembly.GetExecutingAssembly(); + builder.ApplyConfigurationsFromAssembly(modelBuilderAssembly); } - public async Task SaveEntitiesAsync(CancellationToken cancellationToken = default(CancellationToken)) { // Dispatch Domain Events collection. diff --git a/src/Nethereum.eShop/Infrastructure/Data/CatalogItemRepository.cs b/src/Nethereum.eShop/Infrastructure/Data/CatalogItemRepository.cs index ab584ac..0b84b4a 100644 --- a/src/Nethereum.eShop/Infrastructure/Data/CatalogItemRepository.cs +++ b/src/Nethereum.eShop/Infrastructure/Data/CatalogItemRepository.cs @@ -1,16 +1,12 @@ -using Microsoft.EntityFrameworkCore; -using Nethereum.eShop.ApplicationCore.Entities; +using Nethereum.eShop.ApplicationCore.Entities; using Nethereum.eShop.ApplicationCore.Interfaces; -using System.Collections.Generic; -using System.Linq; -using System.Threading.Tasks; namespace Nethereum.eShop.Infrastructure.Data { public class CatalogItemRepository : EfRepository, ICatalogItemRepository { - public CatalogItemRepository(CatalogContext dbContext) : base(dbContext) - { - } + public CatalogItemRepository(CatalogContext dbContext) : base(dbContext){} + + public IUnitOfWork UnitOfWork => _dbContext; } } diff --git a/src/Nethereum.eShop/Infrastructure/Data/EfRepository.cs b/src/Nethereum.eShop/Infrastructure/Data/EfRepository.cs index 64c68ba..d32d5e2 100644 --- a/src/Nethereum.eShop/Infrastructure/Data/EfRepository.cs +++ b/src/Nethereum.eShop/Infrastructure/Data/EfRepository.cs @@ -7,11 +7,6 @@ namespace Nethereum.eShop.Infrastructure.Data { - /// - /// "There's some repetition here - couldn't we have some the sync methods call the async?" - /// https://blogs.msdn.microsoft.com/pfxteam/2012/04/13/should-i-expose-synchronous-wrappers-for-asynchronous-methods/ - /// - /// public class EfRepository : IAsyncRepository where T : BaseEntity, IAggregateRoot { protected readonly CatalogContext _dbContext; @@ -36,31 +31,6 @@ public async Task> ListAsync(ISpecification spec) return await ApplySpecification(spec).ToListAsync(); } - public async Task CountAsync(ISpecification spec) - { - return await ApplySpecification(spec).CountAsync(); - } - - public async Task AddAsync(T entity) - { - await _dbContext.Set().AddAsync(entity); - await _dbContext.SaveChangesAsync(); - - return entity; - } - - public async Task UpdateAsync(T entity) - { - _dbContext.Entry(entity).State = EntityState.Modified; - await _dbContext.SaveChangesAsync(); - } - - public async Task DeleteAsync(T entity) - { - _dbContext.Set().Remove(entity); - await _dbContext.SaveChangesAsync(); - } - private IQueryable ApplySpecification(ISpecification spec) { return SpecificationEvaluator.GetQuery(_dbContext.Set().AsQueryable(), spec); diff --git a/src/Nethereum.eShop/Infrastructure/Data/QuoteRepository.cs b/src/Nethereum.eShop/Infrastructure/Data/QuoteRepository.cs index 70eea4b..bc5f732 100644 --- a/src/Nethereum.eShop/Infrastructure/Data/QuoteRepository.cs +++ b/src/Nethereum.eShop/Infrastructure/Data/QuoteRepository.cs @@ -1,6 +1,8 @@ using Microsoft.EntityFrameworkCore; using Nethereum.eShop.ApplicationCore.Entities.QuoteAggregate; using Nethereum.eShop.ApplicationCore.Interfaces; +using System.Collections.Generic; +using System.Linq; using System.Threading.Tasks; namespace Nethereum.eShop.Infrastructure.Data @@ -13,5 +15,10 @@ public QuoteRepository(CatalogContext dbContext) : base(dbContext){} public Quote Add(Quote quote) => _dbContext.Quotes.Add(quote).Entity; public Quote Update(Quote quote) => _dbContext.Quotes.Update(quote).Entity; public Task GetByIdWithItemsAsync(int id) => _dbContext.GetQuoteWithItemsOrDefault(id); + + public Task> GetQuotesRequiringPurchaseOrderAsync() => + _dbContext.Quotes.Where(quote => quote.Status == QuoteStatus.Pending && quote.PoNumber == null) + .Include(q => q.QuoteItems) + .ToListAsync(); } } diff --git a/src/Nethereum.eShop/Nethereum.eShop.csproj b/src/Nethereum.eShop/Nethereum.eShop.csproj index 40f66ce..4f36434 100644 --- a/src/Nethereum.eShop/Nethereum.eShop.csproj +++ b/src/Nethereum.eShop/Nethereum.eShop.csproj @@ -11,17 +11,16 @@ + -
- diff --git a/src/Web/Features/OrderDetails/GetOrderDetailsHandler.cs b/src/Web/Features/OrderDetails/GetOrderDetailsHandler.cs index 3aaab70..97a83c9 100644 --- a/src/Web/Features/OrderDetails/GetOrderDetailsHandler.cs +++ b/src/Web/Features/OrderDetails/GetOrderDetailsHandler.cs @@ -19,8 +19,7 @@ public GetOrderDetailsHandler(IOrderRepository orderRepository) public async Task Handle(GetOrderDetails request, CancellationToken cancellationToken) { - var customerOrders = await _orderRepository.ListAsync(new CustomerOrdersWithItemsSpecification(request.UserName)); - var order = customerOrders.FirstOrDefault(o => o.Id == request.OrderId); + var order = await _orderRepository.GetByIdWithItemsAsync(request.OrderId); if (order == null) { diff --git a/src/Web/Features/QuoteDetails/GetQuoteDetailsHandler.cs b/src/Web/Features/QuoteDetails/GetQuoteDetailsHandler.cs index c4e30c5..c0f2d5a 100644 --- a/src/Web/Features/QuoteDetails/GetQuoteDetailsHandler.cs +++ b/src/Web/Features/QuoteDetails/GetQuoteDetailsHandler.cs @@ -19,8 +19,7 @@ public GetQuoteDetailsHandler(IQuoteRepository quoteRepository) public async Task Handle(GetQuoteDetails request, CancellationToken cancellationToken) { - var customerQuotes = await _quoteRepository.ListAsync(new CustomerQuotesWithItemsSpecification(request.UserName)); - var quote = customerQuotes.FirstOrDefault(o => o.Id == request.QuoteId); + var quote = await _quoteRepository.GetByIdWithItemsAsync(request.QuoteId); if (quote == null) { diff --git a/src/Web/Services/BasketViewModelService.cs b/src/Web/Services/BasketViewModelService.cs index 9d7f64f..ee9f7e2 100644 --- a/src/Web/Services/BasketViewModelService.cs +++ b/src/Web/Services/BasketViewModelService.cs @@ -12,11 +12,11 @@ namespace Nethereum.eShop.Web.Services { public class BasketViewModelService : IBasketViewModelService { - private readonly IAsyncRepository _basketRepository; + private readonly IBasketRepository _basketRepository; private readonly IUriComposer _uriComposer; private readonly IAsyncRepository _itemRepository; - public BasketViewModelService(IAsyncRepository basketRepository, + public BasketViewModelService(IBasketRepository basketRepository, IAsyncRepository itemRepository, IUriComposer uriComposer) { @@ -27,8 +27,7 @@ public BasketViewModelService(IAsyncRepository basketRepository, public async Task GetOrCreateBasketForUser(string userName) { - var basketSpec = new BasketWithItemsSpecification(userName); - var basket = (await _basketRepository.ListAsync(basketSpec)).FirstOrDefault(); + var basket = await _basketRepository.GetByBuyerIdWithItemsAsync(userName); if (basket == null) { @@ -50,7 +49,8 @@ private async Task CreateBasketForUser(string userId) { // TODO: populate from buyer entity var basket = new Basket() { BuyerId = userId, BuyerAddress = string.Empty }; - await _basketRepository.AddAsync(basket); + _basketRepository.Add(basket); + await _basketRepository.UnitOfWork.SaveEntitiesAsync(); return new BasketViewModel() { diff --git a/src/Web/Services/CatalogItemViewModelService.cs b/src/Web/Services/CatalogItemViewModelService.cs index fceaca3..9afde99 100644 --- a/src/Web/Services/CatalogItemViewModelService.cs +++ b/src/Web/Services/CatalogItemViewModelService.cs @@ -8,9 +8,9 @@ namespace Nethereum.eShop.Web.Services { public class CatalogItemViewModelService : ICatalogItemViewModelService { - private readonly IAsyncRepository _catalogItemRepository; + private readonly ICatalogItemRepository _catalogItemRepository; - public CatalogItemViewModelService(IAsyncRepository catalogItemRepository) + public CatalogItemViewModelService(ICatalogItemRepository catalogItemRepository) { _catalogItemRepository = catalogItemRepository; } @@ -25,7 +25,7 @@ public async Task UpdateCatalogItem(CatalogItemViewModel viewModel) updatedCatalogItem.Name = viewModel.Name; updatedCatalogItem.Price = viewModel.Price; - await _catalogItemRepository.UpdateAsync(updatedCatalogItem); + await _catalogItemRepository.UnitOfWork.SaveEntitiesAsync(); } } } diff --git a/src/Web/Startup.cs b/src/Web/Startup.cs index 87d7af2..bd86b81 100644 --- a/src/Web/Startup.cs +++ b/src/Web/Startup.cs @@ -17,6 +17,7 @@ using Nethereum.eShop.ApplicationCore.Queries.Quotes; using Nethereum.eShop.ApplicationCore.Services; using Nethereum.eShop.Infrastructure.Data; +using Nethereum.eShop.Infrastructure.Data.Config; using Nethereum.eShop.Infrastructure.Identity; using Nethereum.eShop.Infrastructure.Logging; using Nethereum.eShop.Infrastructure.Services; @@ -111,6 +112,10 @@ public void ConfigureServices(IServiceCollection services) CreateIdentityIfNotCreated(services); + // a place to repoint DataContext model builder configuration to another assembly + services.AddSingleton>( + new ModelBuilderAssemblyHandler(typeof(BasketConfiguration).Assembly)); + services.AddMediatR(typeof(BasketViewModelService).Assembly); string queryConnectionString = Configuration.GetConnectionString("CatalogConnection"); diff --git a/src/Web/Web.csproj b/src/Web/Web.csproj index 0ecbd4d..822a1f6 100644 --- a/src/Web/Web.csproj +++ b/src/Web/Web.csproj @@ -39,6 +39,7 @@ + diff --git a/src/WebJobs/Jobs/CreateFakePurchaseOrders.cs b/src/WebJobs/Jobs/CreateFakePurchaseOrders.cs index a34fc11..bc71a92 100644 --- a/src/WebJobs/Jobs/CreateFakePurchaseOrders.cs +++ b/src/WebJobs/Jobs/CreateFakePurchaseOrders.cs @@ -29,20 +29,11 @@ public CreateFakePurchaseOrders(EshopConfiguration config, IQuoteRepository quot this._quoteRepository = quoteRepository; } - public class GetQuotesRequiringPurchaseOrderSpec : BaseSpecification - { - public GetQuotesRequiringPurchaseOrderSpec() - : base(quote => quote.Status == QuoteStatus.Pending && quote.PoNumber == null) - { - AddInclude(b => b.QuoteItems); - } - } - public async Task ExecuteAsync(ILogger logger) { if (!_config.CreateFakePurchaseOrders) return; - var pendingQuotes = await _quoteRepository.ListAsync(new GetQuotesRequiringPurchaseOrderSpec()); + var pendingQuotes = await _quoteRepository.GetQuotesRequiringPurchaseOrderAsync(); logger.LogInformation($"{pendingQuotes.Count} were found requiring a purchase order"); @@ -65,7 +56,8 @@ private async Task CreatePoForQuote(ILogger logger, WalletBuyerService walletBuy { quote.PoNumber = (long)existing.Po.PoNumber; quote.Status = QuoteStatus.AwaitingOrder; - await _quoteRepository.UpdateAsync(quote); + _quoteRepository.Update(quote); + await _quoteRepository.UnitOfWork.SaveEntitiesAsync(); return; } @@ -80,7 +72,8 @@ private async Task CreatePoForQuote(ILogger logger, WalletBuyerService walletBuy quote.PoNumber = (long)createdEvent.Event.PoNumber; quote.Status = QuoteStatus.AwaitingOrder; quote.TransactionHash = receipt.TransactionHash; - await _quoteRepository.UpdateAsync(quote); + _quoteRepository.Update(quote); + await _quoteRepository.UnitOfWork.SaveEntitiesAsync(); } else { From 295375092e5efa64cf94356c36fa9466c0aa8a97 Mon Sep 17 00:00:00 2001 From: Dave Whiffin Date: Mon, 9 Mar 2020 17:22:19 +0000 Subject: [PATCH 08/27] Implementing in-memory DB in another assembly --- .../Queries/Catalog/CatalogQueries.cs | 60 +++++++++++++++++ .../Queries/Orders/OrderQueries.cs | 65 +++++++++++++++++++ .../ApplicationCore/Queries/QueriesBase.cs | 14 ++++ .../Queries/Quotes/QuoteQueries.cs | 63 ++++++++++++++++++ src/Nethereum.eShop.InMemory/Bootstrapper.cs | 45 +++++++++++++ .../Nethereum.eShop.InMemory.csproj | 15 +++++ .../Queries/Quotes/QuoteQueries.cs | 2 +- .../SqlServer/BasketConfiguration.cs | 15 +++++ .../SqlServer/BasketItemConfiguration.cs | 15 +++++ .../SqlServer/BuyerConfiguration.cs | 15 +++++ .../BuyerPostalAddressConfiguration.cs | 15 +++++ .../SqlServer/CatalogBrandConfiguration.cs | 17 +++++ .../SqlServer/CatalogItemConfiguration.cs | 17 +++++ .../SqlServer}/CatalogTypeConfiguration.cs | 3 +- .../SqlServer/OrderConfiguration.cs | 15 +++++ .../SqlServer/OrderItemConfiguration.cs | 15 +++++ .../SqlServer/QuoteConfiguration.cs | 15 +++++ .../SqlServer/QuoteItemConfiguration.cs | 15 +++++ .../SqlServer/StockItemConfiguration.cs | 18 +++++ .../Config/SqlServerEShopDbBootstrapper.cs | 46 +++++++++++++ src/Nethereum.eShop.sln | 6 ++ .../Entities/BasketAggregate/BasketQueries.cs | 20 ------ .../Entities/OrderAggregate/Order.cs | 5 ++ .../Entities/QuoteAggregate/Quote.cs | 10 +++ .../Entities/QuoteAggregate/QuoteQueries.cs | 15 ----- .../Queries/Orders/OrderQueryDtos.cs | 5 +- .../ApplicationCore/Services/OrderService.cs | 31 +++++---- .../Infrastructure/Data/BasketRepository.cs | 26 ++++---- .../Infrastructure/Data/CatalogContext.cs | 29 ++------- .../Data/CatalogItemRepository.cs | 2 - .../Data/Config/EShopDbBootstrapperBase.cs | 22 +++++++ .../EntityBuilders}/BasketConfiguration.cs | 15 ++--- .../BasketItemConfiguration.cs | 4 +- .../EntityBuilders}/BuyerConfiguration.cs | 4 +- .../BuyerPostalAddressConfiguration.cs | 9 +-- .../CatalogBrandConfiguration.cs | 6 +- .../CatalogItemConfiguration.cs | 6 +- .../CatalogItemExcerptBuilder.cs | 2 +- .../CatalogTypeConfiguration.cs | 22 +++++++ .../EntityBuilders}/OrderConfiguration.cs | 23 ++----- .../EntityBuilders}/OrderItemConfiguration.cs | 9 +-- .../EntityBuilders}/PostalAddressBuilder.cs | 2 +- .../EntityBuilders}/QuoteConfiguration.cs | 16 ++--- .../EntityBuilders}/QuoteItemConfiguration.cs | 9 +-- .../EntityBuilders}/StockItemConfiguration.cs | 6 +- .../Data/Config/IEShopDbBootstrapper.cs | 18 +++++ .../Infrastructure/Data/EfRepository.cs | 16 +++-- .../Data/IModelBuilderAssemblyHandler.cs | 9 +++ .../Data/ModelBuilderAssemblyHandler.cs | 15 +++++ .../Infrastructure/Data/OrderRepository.cs | 19 ------ .../Infrastructure/Data/QuoteRepository.cs | 9 +-- src/Web/Services/BasketViewModelService.cs | 9 +-- src/Web/Services/CatalogViewModelService.cs | 1 - src/Web/Startup.cs | 55 +++++++--------- src/Web/Web.csproj | 1 + .../JsonFileBlockProgressRepository.cs | 14 ++-- 56 files changed, 723 insertions(+), 232 deletions(-) create mode 100644 src/Nethereum.eShop.InMemory/ApplicationCore/Queries/Catalog/CatalogQueries.cs create mode 100644 src/Nethereum.eShop.InMemory/ApplicationCore/Queries/Orders/OrderQueries.cs create mode 100644 src/Nethereum.eShop.InMemory/ApplicationCore/Queries/QueriesBase.cs create mode 100644 src/Nethereum.eShop.InMemory/ApplicationCore/Queries/Quotes/QuoteQueries.cs create mode 100644 src/Nethereum.eShop.InMemory/Bootstrapper.cs create mode 100644 src/Nethereum.eShop.InMemory/Nethereum.eShop.InMemory.csproj create mode 100644 src/Nethereum.eShop.SqlServer/Infrastructure/Data/Config/EntityBuilders/SqlServer/BasketConfiguration.cs create mode 100644 src/Nethereum.eShop.SqlServer/Infrastructure/Data/Config/EntityBuilders/SqlServer/BasketItemConfiguration.cs create mode 100644 src/Nethereum.eShop.SqlServer/Infrastructure/Data/Config/EntityBuilders/SqlServer/BuyerConfiguration.cs create mode 100644 src/Nethereum.eShop.SqlServer/Infrastructure/Data/Config/EntityBuilders/SqlServer/BuyerPostalAddressConfiguration.cs create mode 100644 src/Nethereum.eShop.SqlServer/Infrastructure/Data/Config/EntityBuilders/SqlServer/CatalogBrandConfiguration.cs create mode 100644 src/Nethereum.eShop.SqlServer/Infrastructure/Data/Config/EntityBuilders/SqlServer/CatalogItemConfiguration.cs rename src/Nethereum.eShop.SqlServer/Infrastructure/Data/Config/{ => EntityBuilders/SqlServer}/CatalogTypeConfiguration.cs (80%) create mode 100644 src/Nethereum.eShop.SqlServer/Infrastructure/Data/Config/EntityBuilders/SqlServer/OrderConfiguration.cs create mode 100644 src/Nethereum.eShop.SqlServer/Infrastructure/Data/Config/EntityBuilders/SqlServer/OrderItemConfiguration.cs create mode 100644 src/Nethereum.eShop.SqlServer/Infrastructure/Data/Config/EntityBuilders/SqlServer/QuoteConfiguration.cs create mode 100644 src/Nethereum.eShop.SqlServer/Infrastructure/Data/Config/EntityBuilders/SqlServer/QuoteItemConfiguration.cs create mode 100644 src/Nethereum.eShop.SqlServer/Infrastructure/Data/Config/EntityBuilders/SqlServer/StockItemConfiguration.cs create mode 100644 src/Nethereum.eShop.SqlServer/Infrastructure/Data/Config/SqlServerEShopDbBootstrapper.cs delete mode 100644 src/Nethereum.eShop/ApplicationCore/Entities/BasketAggregate/BasketQueries.cs delete mode 100644 src/Nethereum.eShop/ApplicationCore/Entities/QuoteAggregate/QuoteQueries.cs create mode 100644 src/Nethereum.eShop/Infrastructure/Data/Config/EShopDbBootstrapperBase.cs rename src/{Nethereum.eShop.SqlServer/Infrastructure/Data/Config => Nethereum.eShop/Infrastructure/Data/Config/EntityBuilders}/BasketConfiguration.cs (69%) rename src/{Nethereum.eShop.SqlServer/Infrastructure/Data/Config => Nethereum.eShop/Infrastructure/Data/Config/EntityBuilders}/BasketItemConfiguration.cs (72%) rename src/{Nethereum.eShop.SqlServer/Infrastructure/Data/Config => Nethereum.eShop/Infrastructure/Data/Config/EntityBuilders}/BuyerConfiguration.cs (83%) rename src/{Nethereum.eShop.SqlServer/Infrastructure/Data/Config => Nethereum.eShop/Infrastructure/Data/Config/EntityBuilders}/BuyerPostalAddressConfiguration.cs (53%) rename src/{Nethereum.eShop.SqlServer/Infrastructure/Data/Config => Nethereum.eShop/Infrastructure/Data/Config/EntityBuilders}/CatalogBrandConfiguration.cs (71%) rename src/{Nethereum.eShop.SqlServer/Infrastructure/Data/Config => Nethereum.eShop/Infrastructure/Data/Config/EntityBuilders}/CatalogItemConfiguration.cs (88%) rename src/{Nethereum.eShop.SqlServer/Infrastructure/Data/Config => Nethereum.eShop/Infrastructure/Data/Config/EntityBuilders}/CatalogItemExcerptBuilder.cs (89%) create mode 100644 src/Nethereum.eShop/Infrastructure/Data/Config/EntityBuilders/CatalogTypeConfiguration.cs rename src/{Nethereum.eShop.SqlServer/Infrastructure/Data/Config => Nethereum.eShop/Infrastructure/Data/Config/EntityBuilders}/OrderConfiguration.cs (72%) rename src/{Nethereum.eShop.SqlServer/Infrastructure/Data/Config => Nethereum.eShop/Infrastructure/Data/Config/EntityBuilders}/OrderItemConfiguration.cs (71%) rename src/{Nethereum.eShop.SqlServer/Infrastructure/Data/Config => Nethereum.eShop/Infrastructure/Data/Config/EntityBuilders}/PostalAddressBuilder.cs (93%) rename src/{Nethereum.eShop.SqlServer/Infrastructure/Data/Config => Nethereum.eShop/Infrastructure/Data/Config/EntityBuilders}/QuoteConfiguration.cs (74%) rename src/{Nethereum.eShop.SqlServer/Infrastructure/Data/Config => Nethereum.eShop/Infrastructure/Data/Config/EntityBuilders}/QuoteItemConfiguration.cs (59%) rename src/{Nethereum.eShop.SqlServer/Infrastructure/Data/Config => Nethereum.eShop/Infrastructure/Data/Config/EntityBuilders}/StockItemConfiguration.cs (76%) create mode 100644 src/Nethereum.eShop/Infrastructure/Data/Config/IEShopDbBootstrapper.cs create mode 100644 src/Nethereum.eShop/Infrastructure/Data/IModelBuilderAssemblyHandler.cs create mode 100644 src/Nethereum.eShop/Infrastructure/Data/ModelBuilderAssemblyHandler.cs diff --git a/src/Nethereum.eShop.InMemory/ApplicationCore/Queries/Catalog/CatalogQueries.cs b/src/Nethereum.eShop.InMemory/ApplicationCore/Queries/Catalog/CatalogQueries.cs new file mode 100644 index 0000000..0869953 --- /dev/null +++ b/src/Nethereum.eShop.InMemory/ApplicationCore/Queries/Catalog/CatalogQueries.cs @@ -0,0 +1,60 @@ +using Microsoft.EntityFrameworkCore; +using Nethereum.eShop.ApplicationCore.Entities; +using Nethereum.eShop.ApplicationCore.Queries; +using Nethereum.eShop.ApplicationCore.Queries.Catalog; +using Nethereum.eShop.Infrastructure.Data; +using System; +using System.Linq; +using System.Linq.Expressions; +using System.Threading.Tasks; + +namespace Nethereum.eShop.InMemory.ApplicationCore.Queries.Catalog +{ + public class CatalogQueries : QueriesBase, ICatalogQueries + { + public CatalogQueries(CatalogContext dbContext) : base(dbContext) + { + } + + public async Task> GetCatalogItemsAsync(GetCatalogItemsSpecification catalogQuerySpecification) + { + var query = Where(catalogQuerySpecification).AsNoTracking(); + + var totalCount = await query.CountAsync(); + + var items = await query + .Skip(catalogQuerySpecification.Offset) + .Take(catalogQuerySpecification.Fetch) + .Select(i => + new CatalogExcerpt + { + Id = i.Id, + Brand = i.CatalogBrand.Brand, + Name = i.Name, + PictureUri = i.PictureUri, + Price = i.Price + }) + .ToListAsync(); + + return new PaginatedResult(totalCount, items, catalogQuerySpecification); + } + + private IQueryable Where(GetCatalogItemsSpecification spec) + { + var query = _dbContext.CatalogItems + .Include(c => c.CatalogBrand) + .Where(c => + (string.IsNullOrEmpty(spec.SearchText) || (c.Name.Contains(spec.SearchText, StringComparison.OrdinalIgnoreCase) || c.CatalogBrand.Brand.Contains(spec.SearchText, StringComparison.OrdinalIgnoreCase))) && + (spec.BrandId == null || (c.CatalogBrandId == spec.BrandId)) && + (spec.TypeId == null || (c.CatalogTypeId == spec.TypeId)) + ); + + //TODO: implement other sort columns + switch (spec.SortBy) + { + default: + return spec.SortDescending ? query.OrderByDescending(c => c.Rank) : query.OrderBy(c => c.Rank); + } + } + } +} diff --git a/src/Nethereum.eShop.InMemory/ApplicationCore/Queries/Orders/OrderQueries.cs b/src/Nethereum.eShop.InMemory/ApplicationCore/Queries/Orders/OrderQueries.cs new file mode 100644 index 0000000..817b065 --- /dev/null +++ b/src/Nethereum.eShop.InMemory/ApplicationCore/Queries/Orders/OrderQueries.cs @@ -0,0 +1,65 @@ +using Microsoft.EntityFrameworkCore; +using Nethereum.eShop.ApplicationCore.Entities.OrderAggregate; +using Nethereum.eShop.ApplicationCore.Queries; +using Nethereum.eShop.ApplicationCore.Queries.Orders; +using Nethereum.eShop.Infrastructure.Data; +using System; +using System.Linq; +using System.Threading.Tasks; + +namespace Nethereum.eShop.InMemory.ApplicationCore.Queries.Orders +{ + public class OrderQueries : QueriesBase, IOrderQueries + { + public OrderQueries(CatalogContext dbContext) : base(dbContext) + { + } + + public async Task> GetByBuyerIdAsync(string buyerId, PaginationArgs paginationArgs) + { + var query = Where(buyerId, paginationArgs).AsNoTracking(); + + var totalCount = await query.CountAsync(); + + var items = await query. + // Include(o => o.OrderItems). + Include($"{nameof(Order.OrderItems)}.{nameof(OrderItem.ItemOrdered)}") + .Skip(paginationArgs.Offset) + .Take(paginationArgs.Fetch) + .Select(o => new OrderExcerpt + { + BillTo_RecipientName = o.BillTo.RecipientName, + BillTo_ZipCode = o.BillTo.ZipCode, + BuyerAddress = o.BuyerAddress, + BuyerId = o.BuyerId, + CurrencySymbol = o.CurrencySymbol, + ItemCount = o.ItemCount(), + OrderDate = o.OrderDate, + OrderId = o.Id, + PoNumber = o.PoNumber.ToString(), + PoType = o.PoType.ToString(), + QuoteId = o.QuoteId ?? 0, + ShipTo_RecipientName = o.ShipTo.RecipientName, + ShipTo_ZipCode = o.ShipTo.ZipCode, + Status = o.Status.ToString(), + Total = o.Total(), + TransactionHash = o.TransactionHash + }) + .ToListAsync(); + + return new PaginatedResult(totalCount, items, paginationArgs); + } + + private IQueryable Where(string buyerId, PaginationArgs paginationArgs) + { + var query = _dbContext.Orders.Where(o => o.BuyerId == buyerId); + + //TODO: implement other sort columns + switch (paginationArgs.SortBy) + { + default: + return paginationArgs.SortDescending ? query.OrderByDescending(c => c.Id) : query.OrderBy(c => c.Id); + } + } + } +} diff --git a/src/Nethereum.eShop.InMemory/ApplicationCore/Queries/QueriesBase.cs b/src/Nethereum.eShop.InMemory/ApplicationCore/Queries/QueriesBase.cs new file mode 100644 index 0000000..4fe21c1 --- /dev/null +++ b/src/Nethereum.eShop.InMemory/ApplicationCore/Queries/QueriesBase.cs @@ -0,0 +1,14 @@ +using Nethereum.eShop.Infrastructure.Data; + +namespace Nethereum.eShop.InMemory.ApplicationCore.Queries +{ + public abstract class QueriesBase + { + protected readonly CatalogContext _dbContext; + + public QueriesBase(CatalogContext dbContext) + { + _dbContext = dbContext; + } + } +} diff --git a/src/Nethereum.eShop.InMemory/ApplicationCore/Queries/Quotes/QuoteQueries.cs b/src/Nethereum.eShop.InMemory/ApplicationCore/Queries/Quotes/QuoteQueries.cs new file mode 100644 index 0000000..c017099 --- /dev/null +++ b/src/Nethereum.eShop.InMemory/ApplicationCore/Queries/Quotes/QuoteQueries.cs @@ -0,0 +1,63 @@ +using Microsoft.EntityFrameworkCore; +using Nethereum.eShop.ApplicationCore.Entities.QuoteAggregate; +using Nethereum.eShop.ApplicationCore.Queries; +using Nethereum.eShop.ApplicationCore.Queries.Quotes; +using Nethereum.eShop.Infrastructure.Data; +using System.Linq; +using System.Threading.Tasks; + +namespace Nethereum.eShop.InMemory.ApplicationCore.Queries.Quotes +{ + public class QuoteQueries : QueriesBase, IQuoteQueries + { + public QuoteQueries(CatalogContext dbContext) : base(dbContext) + { + } + + public async Task> GetByBuyerIdAsync(string buyerId, PaginationArgs paginationArgs) + { + var query = Where(buyerId, paginationArgs).AsNoTracking(); + + var totalCount = await query.CountAsync(); + + var items = await query. + Include(o => o.QuoteItems) + .Skip(paginationArgs.Offset) + .Take(paginationArgs.Fetch) + .Select(o => new QuoteExcerpt + { + BillTo_RecipientName = o.BillTo.RecipientName, + BillTo_ZipCode = o.BillTo.ZipCode, + BuyerAddress = o.BuyerAddress, + BuyerId = o.BuyerId, + CurrencySymbol = o.CurrencySymbol, + ItemCount = o.ItemCount(), + QuoteDate = o.Date, + QuoteId = o.Id, + PoNumber = o.PoNumber.ToString(), + PoType = o.PoType.ToString(), + Expiry = o.Expiry, + ShipTo_RecipientName = o.ShipTo.RecipientName, + ShipTo_ZipCode = o.ShipTo.ZipCode, + Status = o.Status.ToString(), + Total = o.Total(), + TransactionHash = o.TransactionHash + }) + .ToListAsync(); + + return new PaginatedResult(totalCount, items, paginationArgs); + } + + private IQueryable Where(string buyerId, PaginationArgs paginationArgs) + { + var query = _dbContext.Quotes.Where(o => o.BuyerId == buyerId); + + //TODO: implement other sort columns + switch (paginationArgs.SortBy) + { + default: + return paginationArgs.SortDescending ? query.OrderByDescending(c => c.Id) : query.OrderBy(c => c.Id); + } + } + } +} diff --git a/src/Nethereum.eShop.InMemory/Bootstrapper.cs b/src/Nethereum.eShop.InMemory/Bootstrapper.cs new file mode 100644 index 0000000..6c608f3 --- /dev/null +++ b/src/Nethereum.eShop.InMemory/Bootstrapper.cs @@ -0,0 +1,45 @@ +using Microsoft.EntityFrameworkCore; +using Microsoft.Extensions.Configuration; +using Microsoft.Extensions.DependencyInjection; +using Nethereum.eShop.ApplicationCore.Queries.Catalog; +using Nethereum.eShop.ApplicationCore.Queries.Orders; +using Nethereum.eShop.ApplicationCore.Queries.Quotes; +using Nethereum.eShop.Infrastructure.Data; +using Nethereum.eShop.Infrastructure.Data.Config; +using Nethereum.eShop.Infrastructure.Data.Config.EntityBuilders; +using Nethereum.eShop.Infrastructure.Identity; +using Nethereum.eShop.InMemory.ApplicationCore.Queries.Catalog; +using Nethereum.eShop.InMemory.ApplicationCore.Queries.Orders; +using Nethereum.eShop.InMemory.ApplicationCore.Queries.Quotes; + +namespace Nethereum.eShop.InMemory +{ + public class InMemoryEShopDbBootrapper : EShopDbBootstrapperBase, IEShopDbBootstrapper + { + public void AddDbContext(IServiceCollection services, IConfiguration configuration) + { + services.AddDbContext(c => + c.UseInMemoryDatabase("Catalog")); + + // for in-memory, we'll use the basic model builders + services.AddSingleton>( + new ModelBuilderAssemblyHandler(typeof(BasketConfiguration).Assembly)); + } + + public void AddQueries(IServiceCollection services, IConfiguration configuration) + { + services.AddScoped(); + services.AddScoped(); + services.AddScoped(); + } + } + + public class InMemoryEShopIdentityDbBootrapper : IEShopIdentityDbBootstrapper + { + public void AddDbContext(IServiceCollection services, IConfiguration configuration) + { + services.AddDbContext(options => + options.UseInMemoryDatabase("Identity")); + } + } +} diff --git a/src/Nethereum.eShop.InMemory/Nethereum.eShop.InMemory.csproj b/src/Nethereum.eShop.InMemory/Nethereum.eShop.InMemory.csproj new file mode 100644 index 0000000..e64ae45 --- /dev/null +++ b/src/Nethereum.eShop.InMemory/Nethereum.eShop.InMemory.csproj @@ -0,0 +1,15 @@ + + + + netstandard2.1 + + + + + + + + + + + diff --git a/src/Nethereum.eShop.SqlServer/ApplicationCore/Queries/Quotes/QuoteQueries.cs b/src/Nethereum.eShop.SqlServer/ApplicationCore/Queries/Quotes/QuoteQueries.cs index 753cb45..23a396f 100644 --- a/src/Nethereum.eShop.SqlServer/ApplicationCore/Queries/Quotes/QuoteQueries.cs +++ b/src/Nethereum.eShop.SqlServer/ApplicationCore/Queries/Quotes/QuoteQueries.cs @@ -44,7 +44,7 @@ public async Task> GetByBuyerIdAsync(string buyerI q.BuyerAddress, q.BuyerId, q.TransactionHash, - q.Date, + q.Date as QuoteDate, q.Status, q.PoNumber, q.PoType, diff --git a/src/Nethereum.eShop.SqlServer/Infrastructure/Data/Config/EntityBuilders/SqlServer/BasketConfiguration.cs b/src/Nethereum.eShop.SqlServer/Infrastructure/Data/Config/EntityBuilders/SqlServer/BasketConfiguration.cs new file mode 100644 index 0000000..b0661bb --- /dev/null +++ b/src/Nethereum.eShop.SqlServer/Infrastructure/Data/Config/EntityBuilders/SqlServer/BasketConfiguration.cs @@ -0,0 +1,15 @@ +using Microsoft.EntityFrameworkCore; +using Microsoft.EntityFrameworkCore.Metadata.Builders; +using Nethereum.eShop.ApplicationCore.Entities.BasketAggregate; +using b = Nethereum.eShop.Infrastructure.Data.Config.EntityBuilders; + +namespace Nethereum.eShop.Infrastructure.Data.Config.EntityBuilders.SqlServer +{ + public class BasketConfiguration : b.BasketConfiguration + { + public override void Configure(EntityTypeBuilder builder) + { + base.Configure(builder); + } + } +} diff --git a/src/Nethereum.eShop.SqlServer/Infrastructure/Data/Config/EntityBuilders/SqlServer/BasketItemConfiguration.cs b/src/Nethereum.eShop.SqlServer/Infrastructure/Data/Config/EntityBuilders/SqlServer/BasketItemConfiguration.cs new file mode 100644 index 0000000..93b7a9a --- /dev/null +++ b/src/Nethereum.eShop.SqlServer/Infrastructure/Data/Config/EntityBuilders/SqlServer/BasketItemConfiguration.cs @@ -0,0 +1,15 @@ +using Microsoft.EntityFrameworkCore; +using Microsoft.EntityFrameworkCore.Metadata.Builders; +using Nethereum.eShop.ApplicationCore.Entities.BasketAggregate; +using b = Nethereum.eShop.Infrastructure.Data.Config.EntityBuilders; + +namespace Nethereum.eShop.Infrastructure.Data.Config.EntityBuilders.SqlServer +{ + public class BasketItemConfiguration : b.BasketItemConfiguration + { + public override void Configure(EntityTypeBuilder builder) + { + base.Configure(builder); + } + } +} diff --git a/src/Nethereum.eShop.SqlServer/Infrastructure/Data/Config/EntityBuilders/SqlServer/BuyerConfiguration.cs b/src/Nethereum.eShop.SqlServer/Infrastructure/Data/Config/EntityBuilders/SqlServer/BuyerConfiguration.cs new file mode 100644 index 0000000..44e7192 --- /dev/null +++ b/src/Nethereum.eShop.SqlServer/Infrastructure/Data/Config/EntityBuilders/SqlServer/BuyerConfiguration.cs @@ -0,0 +1,15 @@ +using Microsoft.EntityFrameworkCore; +using Microsoft.EntityFrameworkCore.Metadata.Builders; +using Nethereum.eShop.ApplicationCore.Entities.BuyerAggregate; +using b = Nethereum.eShop.Infrastructure.Data.Config.EntityBuilders; + +namespace Nethereum.eShop.Infrastructure.Data.Config.EntityBuilders.SqlServer +{ + public class BuyerConfiguration : b.BuyerConfiguration + { + public override void Configure(EntityTypeBuilder builder) + { + base.Configure(builder); + } + } +} diff --git a/src/Nethereum.eShop.SqlServer/Infrastructure/Data/Config/EntityBuilders/SqlServer/BuyerPostalAddressConfiguration.cs b/src/Nethereum.eShop.SqlServer/Infrastructure/Data/Config/EntityBuilders/SqlServer/BuyerPostalAddressConfiguration.cs new file mode 100644 index 0000000..6f765f5 --- /dev/null +++ b/src/Nethereum.eShop.SqlServer/Infrastructure/Data/Config/EntityBuilders/SqlServer/BuyerPostalAddressConfiguration.cs @@ -0,0 +1,15 @@ +using Microsoft.EntityFrameworkCore; +using Microsoft.EntityFrameworkCore.Metadata.Builders; +using Nethereum.eShop.ApplicationCore.Entities.BuyerAggregate; +using b = Nethereum.eShop.Infrastructure.Data.Config.EntityBuilders; + +namespace Nethereum.eShop.Infrastructure.Data.Config.EntityBuilders.SqlServer +{ + public class BuyerPostalAddressConfiguration : b.BuyerPostalAddressConfiguration + { + public override void Configure(EntityTypeBuilder builder) + { + base.Configure(builder); + } + } +} diff --git a/src/Nethereum.eShop.SqlServer/Infrastructure/Data/Config/EntityBuilders/SqlServer/CatalogBrandConfiguration.cs b/src/Nethereum.eShop.SqlServer/Infrastructure/Data/Config/EntityBuilders/SqlServer/CatalogBrandConfiguration.cs new file mode 100644 index 0000000..fef1bb0 --- /dev/null +++ b/src/Nethereum.eShop.SqlServer/Infrastructure/Data/Config/EntityBuilders/SqlServer/CatalogBrandConfiguration.cs @@ -0,0 +1,17 @@ +using Microsoft.EntityFrameworkCore; +using Microsoft.EntityFrameworkCore.Metadata.Builders; +using Nethereum.eShop.ApplicationCore.Entities; +using b = Nethereum.eShop.Infrastructure.Data.Config.EntityBuilders; + +namespace Nethereum.eShop.Infrastructure.Data.Config.EntityBuilders.SqlServer +{ + public class CatalogBrandConfiguration : b.CatalogBrandConfiguration + { + public override void Configure(EntityTypeBuilder builder) + { + base.Configure(builder); + builder.Property(ci => ci.Id) + .UseHiLo("catalog_brand_hilo"); + } + } +} diff --git a/src/Nethereum.eShop.SqlServer/Infrastructure/Data/Config/EntityBuilders/SqlServer/CatalogItemConfiguration.cs b/src/Nethereum.eShop.SqlServer/Infrastructure/Data/Config/EntityBuilders/SqlServer/CatalogItemConfiguration.cs new file mode 100644 index 0000000..9d75725 --- /dev/null +++ b/src/Nethereum.eShop.SqlServer/Infrastructure/Data/Config/EntityBuilders/SqlServer/CatalogItemConfiguration.cs @@ -0,0 +1,17 @@ +using Microsoft.EntityFrameworkCore; +using Microsoft.EntityFrameworkCore.Metadata.Builders; +using Nethereum.eShop.ApplicationCore.Entities; +using b = Nethereum.eShop.Infrastructure.Data.Config.EntityBuilders; + +namespace Nethereum.eShop.Infrastructure.Data.Config.EntityBuilders.SqlServer +{ + public class CatalogItemConfiguration : b.CatalogItemConfiguration + { + public override void Configure(EntityTypeBuilder builder) + { + base.Configure(builder); + builder.Property(ci => ci.Id) + .UseHiLo("catalog_hilo"); + } + } +} diff --git a/src/Nethereum.eShop.SqlServer/Infrastructure/Data/Config/CatalogTypeConfiguration.cs b/src/Nethereum.eShop.SqlServer/Infrastructure/Data/Config/EntityBuilders/SqlServer/CatalogTypeConfiguration.cs similarity index 80% rename from src/Nethereum.eShop.SqlServer/Infrastructure/Data/Config/CatalogTypeConfiguration.cs rename to src/Nethereum.eShop.SqlServer/Infrastructure/Data/Config/EntityBuilders/SqlServer/CatalogTypeConfiguration.cs index 02e9ef8..1eb0be4 100644 --- a/src/Nethereum.eShop.SqlServer/Infrastructure/Data/Config/CatalogTypeConfiguration.cs +++ b/src/Nethereum.eShop.SqlServer/Infrastructure/Data/Config/EntityBuilders/SqlServer/CatalogTypeConfiguration.cs @@ -1,8 +1,9 @@ using Microsoft.EntityFrameworkCore; using Microsoft.EntityFrameworkCore.Metadata.Builders; using Nethereum.eShop.ApplicationCore.Entities; +using b = Nethereum.eShop.Infrastructure.Data.Config.EntityBuilders; -namespace Nethereum.eShop.Infrastructure.Data.Config +namespace Nethereum.eShop.Infrastructure.Data.Config.EntityBuilders.SqlServer { public class CatalogTypeConfiguration : IEntityTypeConfiguration { diff --git a/src/Nethereum.eShop.SqlServer/Infrastructure/Data/Config/EntityBuilders/SqlServer/OrderConfiguration.cs b/src/Nethereum.eShop.SqlServer/Infrastructure/Data/Config/EntityBuilders/SqlServer/OrderConfiguration.cs new file mode 100644 index 0000000..3dfbe70 --- /dev/null +++ b/src/Nethereum.eShop.SqlServer/Infrastructure/Data/Config/EntityBuilders/SqlServer/OrderConfiguration.cs @@ -0,0 +1,15 @@ +using Microsoft.EntityFrameworkCore; +using Microsoft.EntityFrameworkCore.Metadata.Builders; +using Nethereum.eShop.ApplicationCore.Entities.OrderAggregate; +using b = Nethereum.eShop.Infrastructure.Data.Config.EntityBuilders; + +namespace Nethereum.eShop.Infrastructure.Data.Config.EntityBuilders.SqlServer +{ + public class OrderConfiguration : b.OrderConfiguration + { + public override void Configure(EntityTypeBuilder builder) + { + base.Configure(builder); + } + } +} diff --git a/src/Nethereum.eShop.SqlServer/Infrastructure/Data/Config/EntityBuilders/SqlServer/OrderItemConfiguration.cs b/src/Nethereum.eShop.SqlServer/Infrastructure/Data/Config/EntityBuilders/SqlServer/OrderItemConfiguration.cs new file mode 100644 index 0000000..43e06c1 --- /dev/null +++ b/src/Nethereum.eShop.SqlServer/Infrastructure/Data/Config/EntityBuilders/SqlServer/OrderItemConfiguration.cs @@ -0,0 +1,15 @@ +using Microsoft.EntityFrameworkCore; +using Microsoft.EntityFrameworkCore.Metadata.Builders; +using Nethereum.eShop.ApplicationCore.Entities.OrderAggregate; +using b = Nethereum.eShop.Infrastructure.Data.Config.EntityBuilders; + +namespace Nethereum.eShop.Infrastructure.Data.Config.EntityBuilders.SqlServer +{ + public class OrderItemConfiguration : b.OrderItemConfiguration + { + public override void Configure(EntityTypeBuilder builder) + { + base.Configure(builder); + } + } +} diff --git a/src/Nethereum.eShop.SqlServer/Infrastructure/Data/Config/EntityBuilders/SqlServer/QuoteConfiguration.cs b/src/Nethereum.eShop.SqlServer/Infrastructure/Data/Config/EntityBuilders/SqlServer/QuoteConfiguration.cs new file mode 100644 index 0000000..9320b10 --- /dev/null +++ b/src/Nethereum.eShop.SqlServer/Infrastructure/Data/Config/EntityBuilders/SqlServer/QuoteConfiguration.cs @@ -0,0 +1,15 @@ +using Microsoft.EntityFrameworkCore; +using Microsoft.EntityFrameworkCore.Metadata.Builders; +using Nethereum.eShop.ApplicationCore.Entities.QuoteAggregate; +using b = Nethereum.eShop.Infrastructure.Data.Config.EntityBuilders; + +namespace Nethereum.eShop.Infrastructure.Data.Config.EntityBuilders.SqlServer +{ + public class QuoteConfiguration : b.QuoteConfiguration + { + public override void Configure(EntityTypeBuilder builder) + { + base.Configure(builder); + } + } +} diff --git a/src/Nethereum.eShop.SqlServer/Infrastructure/Data/Config/EntityBuilders/SqlServer/QuoteItemConfiguration.cs b/src/Nethereum.eShop.SqlServer/Infrastructure/Data/Config/EntityBuilders/SqlServer/QuoteItemConfiguration.cs new file mode 100644 index 0000000..a0630d0 --- /dev/null +++ b/src/Nethereum.eShop.SqlServer/Infrastructure/Data/Config/EntityBuilders/SqlServer/QuoteItemConfiguration.cs @@ -0,0 +1,15 @@ +using Microsoft.EntityFrameworkCore; +using Microsoft.EntityFrameworkCore.Metadata.Builders; +using Nethereum.eShop.ApplicationCore.Entities.QuoteAggregate; +using b = Nethereum.eShop.Infrastructure.Data.Config.EntityBuilders; + +namespace Nethereum.eShop.Infrastructure.Data.Config.EntityBuilders.SqlServer +{ + public class QuoteItemConfiguration : b.QuoteItemConfiguration + { + public override void Configure(EntityTypeBuilder builder) + { + base.Configure(builder); + } + } +} diff --git a/src/Nethereum.eShop.SqlServer/Infrastructure/Data/Config/EntityBuilders/SqlServer/StockItemConfiguration.cs b/src/Nethereum.eShop.SqlServer/Infrastructure/Data/Config/EntityBuilders/SqlServer/StockItemConfiguration.cs new file mode 100644 index 0000000..f0ccdff --- /dev/null +++ b/src/Nethereum.eShop.SqlServer/Infrastructure/Data/Config/EntityBuilders/SqlServer/StockItemConfiguration.cs @@ -0,0 +1,18 @@ +using Microsoft.EntityFrameworkCore; +using Microsoft.EntityFrameworkCore.Metadata.Builders; +using Nethereum.eShop.ApplicationCore.Entities; +using b = Nethereum.eShop.Infrastructure.Data.Config.EntityBuilders; + +namespace Nethereum.eShop.Infrastructure.Data.Config.EntityBuilders.SqlServer +{ + public class StockItemConfiguration : b.StockItemConfiguration + { + public override void Configure(EntityTypeBuilder builder) + { + base.Configure(builder); + + builder.Property(ci => ci.Id) + .UseHiLo("stock_hilo"); + } + } +} diff --git a/src/Nethereum.eShop.SqlServer/Infrastructure/Data/Config/SqlServerEShopDbBootstrapper.cs b/src/Nethereum.eShop.SqlServer/Infrastructure/Data/Config/SqlServerEShopDbBootstrapper.cs new file mode 100644 index 0000000..e6ebff6 --- /dev/null +++ b/src/Nethereum.eShop.SqlServer/Infrastructure/Data/Config/SqlServerEShopDbBootstrapper.cs @@ -0,0 +1,46 @@ +using Microsoft.EntityFrameworkCore; +using Microsoft.Extensions.Configuration; +using Microsoft.Extensions.DependencyInjection; +using Nethereum.eShop.ApplicationCore.Interfaces; +using Nethereum.eShop.ApplicationCore.Queries.Catalog; +using Nethereum.eShop.ApplicationCore.Queries.Orders; +using Nethereum.eShop.ApplicationCore.Queries.Quotes; +using Nethereum.eShop.Infrastructure.Data; +using Nethereum.eShop.Infrastructure.Data.Config; +using Nethereum.eShop.Infrastructure.Identity; + +namespace Nethereum.eShop.SqlServer.Infrastructure.Data.Config +{ + public class SqlServerEShopDbBootstrapper : EShopDbBootstrapperBase, IEShopDbBootstrapper + { + private const string ConnectionName = "CatalogConnection"; + + public void AddDbContext(IServiceCollection services, IConfiguration configuration) + { + services.AddDbContext((serviceProvider, options) => + options.UseSqlServer(configuration.GetConnectionString(ConnectionName))); + + // Point the CatalogContext at this assembly for the Model Builder Configurations + // these have some SQL specific tweaks + services.AddSingleton>( + new ModelBuilderAssemblyHandler(this.GetType().Assembly)); + } + + public void AddQueries(IServiceCollection services, IConfiguration configuration) + { + string queryConnectionString = configuration.GetConnectionString(ConnectionName); + services.AddSingleton(new QuoteQueries(queryConnectionString)); + services.AddSingleton(new OrderQueries(queryConnectionString)); + services.AddSingleton(new CatalogQueries(queryConnectionString)); + } + } + + public class SqlServerEShopAppIdentityDbBootstrapper : IEShopIdentityDbBootstrapper + { + public void AddDbContext(IServiceCollection services, IConfiguration configuration) + { + services.AddDbContext(options => + options.UseSqlServer(configuration.GetConnectionString("IdentityConnection"))); + } + } +} diff --git a/src/Nethereum.eShop.sln b/src/Nethereum.eShop.sln index fb390c4..164416f 100644 --- a/src/Nethereum.eShop.sln +++ b/src/Nethereum.eShop.sln @@ -23,6 +23,8 @@ Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "WebJobs", "WebJobs\WebJobs. EndProject Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Nethereum.eShop.SqlServer", "Nethereum.eShop.SqlServer\Nethereum.eShop.SqlServer.csproj", "{658EAD99-D587-4105-9743-8DF2722858EA}" EndProject +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Nethereum.eShop.InMemory", "Nethereum.eShop.InMemory\Nethereum.eShop.InMemory.csproj", "{D7C0A1E5-3867-46AE-86F3-1436E514001B}" +EndProject Global GlobalSection(SolutionConfigurationPlatforms) = preSolution Debug|Any CPU = Debug|Any CPU @@ -57,6 +59,10 @@ Global {658EAD99-D587-4105-9743-8DF2722858EA}.Debug|Any CPU.Build.0 = Debug|Any CPU {658EAD99-D587-4105-9743-8DF2722858EA}.Release|Any CPU.ActiveCfg = Release|Any CPU {658EAD99-D587-4105-9743-8DF2722858EA}.Release|Any CPU.Build.0 = Release|Any CPU + {D7C0A1E5-3867-46AE-86F3-1436E514001B}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {D7C0A1E5-3867-46AE-86F3-1436E514001B}.Debug|Any CPU.Build.0 = Debug|Any CPU + {D7C0A1E5-3867-46AE-86F3-1436E514001B}.Release|Any CPU.ActiveCfg = Release|Any CPU + {D7C0A1E5-3867-46AE-86F3-1436E514001B}.Release|Any CPU.Build.0 = Release|Any CPU EndGlobalSection GlobalSection(SolutionProperties) = preSolution HideSolutionNode = FALSE diff --git a/src/Nethereum.eShop/ApplicationCore/Entities/BasketAggregate/BasketQueries.cs b/src/Nethereum.eShop/ApplicationCore/Entities/BasketAggregate/BasketQueries.cs deleted file mode 100644 index 93c2a76..0000000 --- a/src/Nethereum.eShop/ApplicationCore/Entities/BasketAggregate/BasketQueries.cs +++ /dev/null @@ -1,20 +0,0 @@ -using Microsoft.EntityFrameworkCore; -using Nethereum.eShop.Infrastructure.Data; -using System.Linq; -using System.Threading.Tasks; - -namespace Nethereum.eShop.ApplicationCore.Entities.BasketAggregate -{ - public static class BasketQueries - { - public static Task GetBasketWithItemsOrDefault(this CatalogContext context, int basketId) - { - return context.Baskets.Include(b => b.Items).Where(b => b.Id == basketId).FirstOrDefaultAsync(); - } - - public static Task GetBasketWithItemsOrDefault(this CatalogContext context, string buyerId) - { - return context.Baskets.Include(b => b.Items).Where(b => b.BuyerId == buyerId).FirstOrDefaultAsync(); - } - } -} diff --git a/src/Nethereum.eShop/ApplicationCore/Entities/OrderAggregate/Order.cs b/src/Nethereum.eShop/ApplicationCore/Entities/OrderAggregate/Order.cs index 0cf2157..f9a06eb 100644 --- a/src/Nethereum.eShop/ApplicationCore/Entities/OrderAggregate/Order.cs +++ b/src/Nethereum.eShop/ApplicationCore/Entities/OrderAggregate/Order.cs @@ -103,5 +103,10 @@ public decimal Total() } return total; } + + public int ItemCount() + { + return _orderItems == null ? 0 : _orderItems.Count; + } } } diff --git a/src/Nethereum.eShop/ApplicationCore/Entities/QuoteAggregate/Quote.cs b/src/Nethereum.eShop/ApplicationCore/Entities/QuoteAggregate/Quote.cs index b34ca02..3da8240 100644 --- a/src/Nethereum.eShop/ApplicationCore/Entities/QuoteAggregate/Quote.cs +++ b/src/Nethereum.eShop/ApplicationCore/Entities/QuoteAggregate/Quote.cs @@ -81,5 +81,15 @@ public decimal Total() return total; } + public int ItemCount() => _quoteItems == null ? 0 : _quoteItems.Count; + + public void SetConvertedToOrder(int orderNumber, long purchaseOrderNumber, string transactionHash) + { + //TODO: Add order number/id field + TransactionHash = transactionHash; + PoNumber = purchaseOrderNumber; + Status = QuoteStatus.Complete; + } + } } diff --git a/src/Nethereum.eShop/ApplicationCore/Entities/QuoteAggregate/QuoteQueries.cs b/src/Nethereum.eShop/ApplicationCore/Entities/QuoteAggregate/QuoteQueries.cs deleted file mode 100644 index 91f12e4..0000000 --- a/src/Nethereum.eShop/ApplicationCore/Entities/QuoteAggregate/QuoteQueries.cs +++ /dev/null @@ -1,15 +0,0 @@ -using Microsoft.EntityFrameworkCore; -using Nethereum.eShop.Infrastructure.Data; -using System.Linq; -using System.Threading.Tasks; - -namespace Nethereum.eShop.ApplicationCore.Entities.QuoteAggregate -{ - public static class QuoteQueries - { - public static Task GetQuoteWithItemsOrDefault(this CatalogContext context, int quoteId) - { - return context.Quotes.Include(b => b.QuoteItems).Where(b => b.Id == quoteId).FirstOrDefaultAsync(); - } - } -} diff --git a/src/Nethereum.eShop/ApplicationCore/Queries/Orders/OrderQueryDtos.cs b/src/Nethereum.eShop/ApplicationCore/Queries/Orders/OrderQueryDtos.cs index a91382b..0ad3061 100644 --- a/src/Nethereum.eShop/ApplicationCore/Queries/Orders/OrderQueryDtos.cs +++ b/src/Nethereum.eShop/ApplicationCore/Queries/Orders/OrderQueryDtos.cs @@ -5,7 +5,7 @@ namespace Nethereum.eShop.ApplicationCore.Queries.Orders public class OrderExcerpt { public int OrderId { get; set; } - public int QuoteId { get; set; } + public int? QuoteId { get; set; } public string TransactionHash { get; set; } public string PoNumber { get; set; } @@ -15,9 +15,8 @@ public class OrderExcerpt public string BuyerId { get; set; } public string BuyerAddress { get; set; } - public DateTimeOffset QuoteDate { get; set; } + public DateTimeOffset OrderDate { get; set; } - public DateTimeOffset? Expiry { get; set; } public decimal Total { get; set; } public int ItemCount { get; set; } public string Status { get; set; } diff --git a/src/Nethereum.eShop/ApplicationCore/Services/OrderService.cs b/src/Nethereum.eShop/ApplicationCore/Services/OrderService.cs index dd2333a..c097aff 100644 --- a/src/Nethereum.eShop/ApplicationCore/Services/OrderService.cs +++ b/src/Nethereum.eShop/ApplicationCore/Services/OrderService.cs @@ -25,18 +25,33 @@ public async Task CreateOrderAsync(string transactionHash, Po purchaseOrder) { // TODO: write purchase order values to order // TODO: Ensure po values are consistent with quote - int quoteId = (int)purchaseOrder.QuoteId; - var quote = await _quoteRepository.GetByIdWithItemsAsync(quoteId).ConfigureAwait(false); - Guard.Against.NullQuote(quoteId, quote); + + List orderItems = MapQuoteItemsToOrderItems(quote); + Order order = MapQuoteToOrder(transactionHash, purchaseOrder, quote, orderItems); + + quote.SetConvertedToOrder(order.Id, (long)purchaseOrder.PoNumber, transactionHash); + + _orderRepository.Add(order); + await _orderRepository.UnitOfWork.SaveChangesAsync().ConfigureAwait(false); + } + + private static List MapQuoteItemsToOrderItems(Quote quote) + { var items = new List(); foreach (var item in quote.QuoteItems) { var orderItem = new OrderItem(item.ItemOrdered, item.UnitPrice, item.Quantity); items.Add(orderItem); } + + return items; + } + + private static Order MapQuoteToOrder(string transactionHash, Po purchaseOrder, Quote quote, List items) + { var order = new Order(quote.BuyerId, purchaseOrder.BuyerAddress, quote.BillTo, quote.ShipTo, items); order.QuoteId = quote.Id; order.PoDate = DateTimeOffset.FromUnixTimeSeconds((long)purchaseOrder.PoCreateDate); @@ -55,7 +70,7 @@ public async Task CreateOrderAsync(string transactionHash, Po purchaseOrder) order.Status = OrderStatus.Pending; order.TransactionHash = transactionHash; - foreach(var poItem in purchaseOrder.PoItems) + foreach (var poItem in purchaseOrder.PoItems) { var orderItem = quote.QuoteItems.ElementAtOrDefault((int)poItem.PoItemNumber - 1); if (orderItem == null) continue; @@ -69,13 +84,7 @@ public async Task CreateOrderAsync(string transactionHash, Po purchaseOrder) orderItem.EscrowReleaseDate = DateTimeOffset.FromUnixTimeSeconds((long)poItem.PlannedEscrowReleaseDate); } - quote.TransactionHash = transactionHash; - quote.PoNumber = (long)purchaseOrder.PoNumber; - quote.Status = QuoteStatus.Complete; - - _orderRepository.Add(order); - - await _orderRepository.UnitOfWork.SaveChangesAsync().ConfigureAwait(false); + return order; } } } diff --git a/src/Nethereum.eShop/Infrastructure/Data/BasketRepository.cs b/src/Nethereum.eShop/Infrastructure/Data/BasketRepository.cs index 0d4dcfa..23b7fdf 100644 --- a/src/Nethereum.eShop/Infrastructure/Data/BasketRepository.cs +++ b/src/Nethereum.eShop/Infrastructure/Data/BasketRepository.cs @@ -1,5 +1,7 @@ -using Nethereum.eShop.ApplicationCore.Entities.BasketAggregate; +using Microsoft.EntityFrameworkCore; +using Nethereum.eShop.ApplicationCore.Entities.BasketAggregate; using Nethereum.eShop.ApplicationCore.Interfaces; +using System.Linq; using System.Threading.Tasks; namespace Nethereum.eShop.Infrastructure.Data @@ -8,21 +10,21 @@ public class BasketRepository : EfRepository, IBasketRepository { public BasketRepository(CatalogContext dbContext) : base(dbContext) { } - public IUnitOfWork UnitOfWork => _dbContext; - public Basket Add(Basket basket) => _dbContext.Baskets.Add(basket).Entity; - public Basket Update(Basket basket) => _dbContext.Baskets.Update(basket).Entity; - public Task GetByIdWithItemsAsync(int id) => _dbContext.GetBasketWithItemsOrDefault(id); + public Task GetByIdWithItemsAsync(int id) => + _dbContext.Baskets + .Include(b => b.Items) + .Where(b => b.Id == id) + .FirstOrDefaultAsync(); - public Task GetByBuyerIdWithItemsAsync(string buyerId) => _dbContext.GetBasketWithItemsOrDefault(buyerId); - - public void Delete(Basket basket) - { - _dbContext.Baskets.Remove(basket); - } + public Task GetByBuyerIdWithItemsAsync(string buyerId) => + _dbContext.Baskets + .Include(b => b.Items) + .Where(b => b.BuyerId == buyerId) + .FirstOrDefaultAsync(); public void Delete(int basketId) { - _dbContext.Entry(Basket.CreateForDeletion(basketId)).State = Microsoft.EntityFrameworkCore.EntityState.Deleted; + _dbContext.Entry(Basket.CreateForDeletion(basketId)).State = EntityState.Deleted; } } } diff --git a/src/Nethereum.eShop/Infrastructure/Data/CatalogContext.cs b/src/Nethereum.eShop/Infrastructure/Data/CatalogContext.cs index 25bc04f..92f4ca0 100644 --- a/src/Nethereum.eShop/Infrastructure/Data/CatalogContext.cs +++ b/src/Nethereum.eShop/Infrastructure/Data/CatalogContext.cs @@ -14,22 +14,6 @@ namespace Nethereum.eShop.Infrastructure.Data { - public interface IModelBuilderAssemblyHandler - { - Assembly GetModelBuilderAssembly(); - } - - public class ModelBuilderAssemblyHandler : IModelBuilderAssemblyHandler - { - private readonly Assembly _assembly; - - public ModelBuilderAssemblyHandler(Assembly assembly) - { - _assembly = assembly; - } - public Assembly GetModelBuilderAssembly() => _assembly; - } - public class CatalogContext : DbContext, IUnitOfWork { private readonly IMediator _mediator; @@ -44,19 +28,14 @@ public CatalogContext( } public DbSet Buyers { get; set; } - public DbSet Baskets { get; set; } - public DbSet BasketItems { get; set; } public DbSet CatalogItems { get; set; } public DbSet CatalogBrands { get; set; } public DbSet CatalogTypes { get; set; } public DbSet StockItems { get; set; } - public DbSet Quotes { get; set; } - public DbSet QuoteItems { get; set; } - public DbSet Orders { get; set; } public DbSet OrderItems { get; set; } @@ -75,11 +54,11 @@ protected override void OnModelCreating(ModelBuilder builder) // side effects from the domain event handlers which are using the same DbContext with "InstancePerLifetimeScope" or "scoped" lifetime // B) Right AFTER committing data (EF SaveChanges) into the DB will make multiple transactions. // You will need to handle eventual consistency and compensatory actions in case of failures in any of the Handlers. - await _mediator.DispatchDomainEventsAsync(this); + await _mediator.DispatchDomainEventsAsync(this).ConfigureAwait(false); // After executing this line all the changes (from the Command Handler and Domain Event Handlers) // performed through the DbContext will be committed - var result = await base.SaveChangesAsync(cancellationToken); + var result = await base.SaveChangesAsync(cancellationToken).ConfigureAwait(false); return true; } @@ -88,7 +67,7 @@ public async Task BeginTransactionAsync() { if (_currentTransaction != null) return null; - _currentTransaction = await Database.BeginTransactionAsync(IsolationLevel.ReadCommitted); + _currentTransaction = await Database.BeginTransactionAsync(IsolationLevel.ReadCommitted).ConfigureAwait(false); return _currentTransaction; } @@ -100,7 +79,7 @@ public async Task CommitTransactionAsync(IDbContextTransaction transaction) try { - await SaveChangesAsync(); + await SaveChangesAsync().ConfigureAwait(false); transaction.Commit(); } catch diff --git a/src/Nethereum.eShop/Infrastructure/Data/CatalogItemRepository.cs b/src/Nethereum.eShop/Infrastructure/Data/CatalogItemRepository.cs index 0b84b4a..bd0dc4e 100644 --- a/src/Nethereum.eShop/Infrastructure/Data/CatalogItemRepository.cs +++ b/src/Nethereum.eShop/Infrastructure/Data/CatalogItemRepository.cs @@ -6,7 +6,5 @@ namespace Nethereum.eShop.Infrastructure.Data public class CatalogItemRepository : EfRepository, ICatalogItemRepository { public CatalogItemRepository(CatalogContext dbContext) : base(dbContext){} - - public IUnitOfWork UnitOfWork => _dbContext; } } diff --git a/src/Nethereum.eShop/Infrastructure/Data/Config/EShopDbBootstrapperBase.cs b/src/Nethereum.eShop/Infrastructure/Data/Config/EShopDbBootstrapperBase.cs new file mode 100644 index 0000000..c98e3c0 --- /dev/null +++ b/src/Nethereum.eShop/Infrastructure/Data/Config/EShopDbBootstrapperBase.cs @@ -0,0 +1,22 @@ +using Microsoft.Extensions.Configuration; +using Microsoft.Extensions.DependencyInjection; +using Nethereum.eShop.ApplicationCore.Interfaces; +using System; +using System.Collections.Generic; +using System.Text; + +namespace Nethereum.eShop.Infrastructure.Data.Config +{ + public abstract class EShopDbBootstrapperBase + { + public virtual void AddRepositories(IServiceCollection services, IConfiguration configuration) + { + services.AddScoped(typeof(IAsyncRepository<>), typeof(EfRepository<>)); + services.AddScoped(); + services.AddScoped(); + services.AddScoped(); + services.AddScoped(); + services.AddScoped(); + } + } +} diff --git a/src/Nethereum.eShop.SqlServer/Infrastructure/Data/Config/BasketConfiguration.cs b/src/Nethereum.eShop/Infrastructure/Data/Config/EntityBuilders/BasketConfiguration.cs similarity index 69% rename from src/Nethereum.eShop.SqlServer/Infrastructure/Data/Config/BasketConfiguration.cs rename to src/Nethereum.eShop/Infrastructure/Data/Config/EntityBuilders/BasketConfiguration.cs index 324a36f..b0eeb8f 100644 --- a/src/Nethereum.eShop.SqlServer/Infrastructure/Data/Config/BasketConfiguration.cs +++ b/src/Nethereum.eShop/Infrastructure/Data/Config/EntityBuilders/BasketConfiguration.cs @@ -2,11 +2,11 @@ using Microsoft.EntityFrameworkCore.Metadata.Builders; using Nethereum.eShop.ApplicationCore.Entities.BasketAggregate; -namespace Nethereum.eShop.Infrastructure.Data.Config +namespace Nethereum.eShop.Infrastructure.Data.Config.EntityBuilders { public class BasketConfiguration : IEntityTypeConfiguration { - public void Configure(EntityTypeBuilder builder) + public virtual void Configure(EntityTypeBuilder builder) { var navigation = builder.Metadata.FindNavigation(nameof(Basket.Items)); navigation.SetPropertyAccessMode(PropertyAccessMode.Field); @@ -20,16 +20,9 @@ public void Configure(EntityTypeBuilder builder) .IsRequired(); builder.Property(b => b.TransactionHash).IsHash(); + builder.OwnsOne(o => o.ShipTo, a => a.ConfigureAddress()); + builder.OwnsOne(o => o.BillTo, a => a.ConfigureAddress()); - builder.OwnsOne(o => o.ShipTo, a => - { - a.ConfigureAddress(); - }); - - builder.OwnsOne(o => o.BillTo, a => - { - a.ConfigureAddress(); - }); builder.HasIndex(b => b.BuyerId); builder.HasIndex(b => b.BuyerAddress); diff --git a/src/Nethereum.eShop.SqlServer/Infrastructure/Data/Config/BasketItemConfiguration.cs b/src/Nethereum.eShop/Infrastructure/Data/Config/EntityBuilders/BasketItemConfiguration.cs similarity index 72% rename from src/Nethereum.eShop.SqlServer/Infrastructure/Data/Config/BasketItemConfiguration.cs rename to src/Nethereum.eShop/Infrastructure/Data/Config/EntityBuilders/BasketItemConfiguration.cs index ddbddbc..3b56f76 100644 --- a/src/Nethereum.eShop.SqlServer/Infrastructure/Data/Config/BasketItemConfiguration.cs +++ b/src/Nethereum.eShop/Infrastructure/Data/Config/EntityBuilders/BasketItemConfiguration.cs @@ -2,11 +2,11 @@ using Microsoft.EntityFrameworkCore.Metadata.Builders; using Nethereum.eShop.ApplicationCore.Entities.BasketAggregate; -namespace Nethereum.eShop.Infrastructure.Data.Config +namespace Nethereum.eShop.Infrastructure.Data.Config.EntityBuilders { public class BasketItemConfiguration : IEntityTypeConfiguration { - public void Configure(EntityTypeBuilder builder) + public virtual void Configure(EntityTypeBuilder builder) { builder.Property(bi => bi.UnitPrice) .IsRequired(true) diff --git a/src/Nethereum.eShop.SqlServer/Infrastructure/Data/Config/BuyerConfiguration.cs b/src/Nethereum.eShop/Infrastructure/Data/Config/EntityBuilders/BuyerConfiguration.cs similarity index 83% rename from src/Nethereum.eShop.SqlServer/Infrastructure/Data/Config/BuyerConfiguration.cs rename to src/Nethereum.eShop/Infrastructure/Data/Config/EntityBuilders/BuyerConfiguration.cs index 556e964..a32f511 100644 --- a/src/Nethereum.eShop.SqlServer/Infrastructure/Data/Config/BuyerConfiguration.cs +++ b/src/Nethereum.eShop/Infrastructure/Data/Config/EntityBuilders/BuyerConfiguration.cs @@ -2,11 +2,11 @@ using Microsoft.EntityFrameworkCore.Metadata.Builders; using Nethereum.eShop.ApplicationCore.Entities.BuyerAggregate; -namespace Nethereum.eShop.Infrastructure.Data.Config +namespace Nethereum.eShop.Infrastructure.Data.Config.EntityBuilders { public class BuyerConfiguration : IEntityTypeConfiguration { - public void Configure(EntityTypeBuilder builder) + public virtual void Configure(EntityTypeBuilder builder) { var navigation = builder.Metadata.FindNavigation(nameof(Buyer.PostalAddresses)); navigation.SetPropertyAccessMode(PropertyAccessMode.Field); diff --git a/src/Nethereum.eShop.SqlServer/Infrastructure/Data/Config/BuyerPostalAddressConfiguration.cs b/src/Nethereum.eShop/Infrastructure/Data/Config/EntityBuilders/BuyerPostalAddressConfiguration.cs similarity index 53% rename from src/Nethereum.eShop.SqlServer/Infrastructure/Data/Config/BuyerPostalAddressConfiguration.cs rename to src/Nethereum.eShop/Infrastructure/Data/Config/EntityBuilders/BuyerPostalAddressConfiguration.cs index 13e5ec9..b403ed7 100644 --- a/src/Nethereum.eShop.SqlServer/Infrastructure/Data/Config/BuyerPostalAddressConfiguration.cs +++ b/src/Nethereum.eShop/Infrastructure/Data/Config/EntityBuilders/BuyerPostalAddressConfiguration.cs @@ -2,16 +2,13 @@ using Microsoft.EntityFrameworkCore.Metadata.Builders; using Nethereum.eShop.ApplicationCore.Entities.BuyerAggregate; -namespace Nethereum.eShop.Infrastructure.Data.Config +namespace Nethereum.eShop.Infrastructure.Data.Config.EntityBuilders { public class BuyerPostalAddressConfiguration : IEntityTypeConfiguration { - public void Configure(EntityTypeBuilder builder) + public virtual void Configure(EntityTypeBuilder builder) { - builder.OwnsOne(o => o.PostalAddress, a => - { - a.ConfigureAddress(); - }); + builder.OwnsOne(o => o.PostalAddress, a => a.ConfigureAddress()); } } } diff --git a/src/Nethereum.eShop.SqlServer/Infrastructure/Data/Config/CatalogBrandConfiguration.cs b/src/Nethereum.eShop/Infrastructure/Data/Config/EntityBuilders/CatalogBrandConfiguration.cs similarity index 71% rename from src/Nethereum.eShop.SqlServer/Infrastructure/Data/Config/CatalogBrandConfiguration.cs rename to src/Nethereum.eShop/Infrastructure/Data/Config/EntityBuilders/CatalogBrandConfiguration.cs index a167a52..2690a53 100644 --- a/src/Nethereum.eShop.SqlServer/Infrastructure/Data/Config/CatalogBrandConfiguration.cs +++ b/src/Nethereum.eShop/Infrastructure/Data/Config/EntityBuilders/CatalogBrandConfiguration.cs @@ -2,16 +2,16 @@ using Microsoft.EntityFrameworkCore.Metadata.Builders; using Nethereum.eShop.ApplicationCore.Entities; -namespace Nethereum.eShop.Infrastructure.Data.Config +namespace Nethereum.eShop.Infrastructure.Data.Config.EntityBuilders { public class CatalogBrandConfiguration : IEntityTypeConfiguration { - public void Configure(EntityTypeBuilder builder) + public virtual void Configure(EntityTypeBuilder builder) { builder.HasKey(ci => ci.Id); builder.Property(ci => ci.Id) - .UseHiLo("catalog_brand_hilo") + // .UseHiLo("catalog_brand_hilo") .IsRequired(); builder.Property(cb => cb.Brand) diff --git a/src/Nethereum.eShop.SqlServer/Infrastructure/Data/Config/CatalogItemConfiguration.cs b/src/Nethereum.eShop/Infrastructure/Data/Config/EntityBuilders/CatalogItemConfiguration.cs similarity index 88% rename from src/Nethereum.eShop.SqlServer/Infrastructure/Data/Config/CatalogItemConfiguration.cs rename to src/Nethereum.eShop/Infrastructure/Data/Config/EntityBuilders/CatalogItemConfiguration.cs index 80f303c..5b62f1c 100644 --- a/src/Nethereum.eShop.SqlServer/Infrastructure/Data/Config/CatalogItemConfiguration.cs +++ b/src/Nethereum.eShop/Infrastructure/Data/Config/EntityBuilders/CatalogItemConfiguration.cs @@ -2,16 +2,16 @@ using Microsoft.EntityFrameworkCore.Metadata.Builders; using Nethereum.eShop.ApplicationCore.Entities; -namespace Nethereum.eShop.Infrastructure.Data.Config +namespace Nethereum.eShop.Infrastructure.Data.Config.EntityBuilders { public class CatalogItemConfiguration : IEntityTypeConfiguration { - public void Configure(EntityTypeBuilder builder) + public virtual void Configure(EntityTypeBuilder builder) { builder.ToTable("Catalog"); builder.Property(ci => ci.Id) - .UseHiLo("catalog_hilo") + //.UseHiLo("catalog_hilo") .IsRequired(); builder.Property(ci => ci.Name) diff --git a/src/Nethereum.eShop.SqlServer/Infrastructure/Data/Config/CatalogItemExcerptBuilder.cs b/src/Nethereum.eShop/Infrastructure/Data/Config/EntityBuilders/CatalogItemExcerptBuilder.cs similarity index 89% rename from src/Nethereum.eShop.SqlServer/Infrastructure/Data/Config/CatalogItemExcerptBuilder.cs rename to src/Nethereum.eShop/Infrastructure/Data/Config/EntityBuilders/CatalogItemExcerptBuilder.cs index 3bf9659..dffbc1b 100644 --- a/src/Nethereum.eShop.SqlServer/Infrastructure/Data/Config/CatalogItemExcerptBuilder.cs +++ b/src/Nethereum.eShop/Infrastructure/Data/Config/EntityBuilders/CatalogItemExcerptBuilder.cs @@ -1,7 +1,7 @@ using Microsoft.EntityFrameworkCore.Metadata.Builders; using Nethereum.eShop.ApplicationCore.Entities; -namespace Nethereum.eShop.Infrastructure.Data.Config +namespace Nethereum.eShop.Infrastructure.Data.Config.EntityBuilders { public static class CatalogItemExcerptBuilder { diff --git a/src/Nethereum.eShop/Infrastructure/Data/Config/EntityBuilders/CatalogTypeConfiguration.cs b/src/Nethereum.eShop/Infrastructure/Data/Config/EntityBuilders/CatalogTypeConfiguration.cs new file mode 100644 index 0000000..8e84960 --- /dev/null +++ b/src/Nethereum.eShop/Infrastructure/Data/Config/EntityBuilders/CatalogTypeConfiguration.cs @@ -0,0 +1,22 @@ +using Microsoft.EntityFrameworkCore; +using Microsoft.EntityFrameworkCore.Metadata.Builders; +using Nethereum.eShop.ApplicationCore.Entities; + +namespace Nethereum.eShop.Infrastructure.Data.Config.EntityBuilders +{ + public class CatalogTypeConfiguration : IEntityTypeConfiguration + { + public virtual void Configure(EntityTypeBuilder builder) + { + builder.HasKey(ci => ci.Id); + + builder.Property(ci => ci.Id) + //.UseHiLo("catalog_type_hilo") + .IsRequired(); + + builder.Property(cb => cb.Type) + .IsRequired() + .HasMaxLength(100); + } + } +} diff --git a/src/Nethereum.eShop.SqlServer/Infrastructure/Data/Config/OrderConfiguration.cs b/src/Nethereum.eShop/Infrastructure/Data/Config/EntityBuilders/OrderConfiguration.cs similarity index 72% rename from src/Nethereum.eShop.SqlServer/Infrastructure/Data/Config/OrderConfiguration.cs rename to src/Nethereum.eShop/Infrastructure/Data/Config/EntityBuilders/OrderConfiguration.cs index d3ce6f8..58cf2cf 100644 --- a/src/Nethereum.eShop.SqlServer/Infrastructure/Data/Config/OrderConfiguration.cs +++ b/src/Nethereum.eShop/Infrastructure/Data/Config/EntityBuilders/OrderConfiguration.cs @@ -1,31 +1,19 @@ using Microsoft.EntityFrameworkCore; using Microsoft.EntityFrameworkCore.Metadata.Builders; -using Nethereum.eShop.ApplicationCore.Entities; using Nethereum.eShop.ApplicationCore.Entities.OrderAggregate; -namespace Nethereum.eShop.Infrastructure.Data.Config +namespace Nethereum.eShop.Infrastructure.Data.Config.EntityBuilders { public class OrderConfiguration : IEntityTypeConfiguration { - public void Configure(EntityTypeBuilder builder) + public virtual void Configure(EntityTypeBuilder builder) { var navigation = builder.Metadata.FindNavigation(nameof(Order.OrderItems)); navigation.SetPropertyAccessMode(PropertyAccessMode.Field); - builder.HasIndex(b => b.BuyerId); - builder.HasIndex(b => b.BuyerAddress); - - builder.OwnsOne(o => o.ShipTo, a => - { - a.ConfigureAddress(); - }); - - builder.OwnsOne(o => o.BillTo, a => - { - a.ConfigureAddress(); - }); - + builder.OwnsOne(o => o.ShipTo, a => a.ConfigureAddress()); + builder.OwnsOne(o => o.BillTo, a => a.ConfigureAddress()); builder.Property(o => o.BuyerId).HasMaxLength(256).IsRequired(); builder.Property(o => o.BuyerAddress).IsAddress(); builder.Property(o => o.ApproverAddress).IsAddress(); @@ -34,6 +22,9 @@ public void Configure(EntityTypeBuilder builder) builder.Property(o => o.CurrencyAddress).IsAddress(); builder.Property(o => o.CurrencySymbol).IsBytes32(); builder.Property(o => o.SellerId).IsBytes32(); + + builder.HasIndex(b => b.BuyerId); + builder.HasIndex(b => b.BuyerAddress); } } } diff --git a/src/Nethereum.eShop.SqlServer/Infrastructure/Data/Config/OrderItemConfiguration.cs b/src/Nethereum.eShop/Infrastructure/Data/Config/EntityBuilders/OrderItemConfiguration.cs similarity index 71% rename from src/Nethereum.eShop.SqlServer/Infrastructure/Data/Config/OrderItemConfiguration.cs rename to src/Nethereum.eShop/Infrastructure/Data/Config/EntityBuilders/OrderItemConfiguration.cs index f02d8c1..5d16d64 100644 --- a/src/Nethereum.eShop.SqlServer/Infrastructure/Data/Config/OrderItemConfiguration.cs +++ b/src/Nethereum.eShop/Infrastructure/Data/Config/EntityBuilders/OrderItemConfiguration.cs @@ -2,16 +2,13 @@ using Microsoft.EntityFrameworkCore.Metadata.Builders; using Nethereum.eShop.ApplicationCore.Entities.OrderAggregate; -namespace Nethereum.eShop.Infrastructure.Data.Config +namespace Nethereum.eShop.Infrastructure.Data.Config.EntityBuilders { public class OrderItemConfiguration : IEntityTypeConfiguration { - public void Configure(EntityTypeBuilder builder) + public virtual void Configure(EntityTypeBuilder builder) { - builder.OwnsOne(i => i.ItemOrdered, io => - { - io.ConfigureCatalogItemExcerpt(); - }); + builder.OwnsOne(i => i.ItemOrdered, io => io.ConfigureCatalogItemExcerpt()); builder.Property(oi => oi.UnitPrice) .IsRequired(true) diff --git a/src/Nethereum.eShop.SqlServer/Infrastructure/Data/Config/PostalAddressBuilder.cs b/src/Nethereum.eShop/Infrastructure/Data/Config/EntityBuilders/PostalAddressBuilder.cs similarity index 93% rename from src/Nethereum.eShop.SqlServer/Infrastructure/Data/Config/PostalAddressBuilder.cs rename to src/Nethereum.eShop/Infrastructure/Data/Config/EntityBuilders/PostalAddressBuilder.cs index 11f28e3..8731571 100644 --- a/src/Nethereum.eShop.SqlServer/Infrastructure/Data/Config/PostalAddressBuilder.cs +++ b/src/Nethereum.eShop/Infrastructure/Data/Config/EntityBuilders/PostalAddressBuilder.cs @@ -4,7 +4,7 @@ using System.Collections.Generic; using System.Text; -namespace Nethereum.eShop.Infrastructure.Data.Config +namespace Nethereum.eShop.Infrastructure.Data.Config.EntityBuilders { public static class PostalAddressBuilder { diff --git a/src/Nethereum.eShop.SqlServer/Infrastructure/Data/Config/QuoteConfiguration.cs b/src/Nethereum.eShop/Infrastructure/Data/Config/EntityBuilders/QuoteConfiguration.cs similarity index 74% rename from src/Nethereum.eShop.SqlServer/Infrastructure/Data/Config/QuoteConfiguration.cs rename to src/Nethereum.eShop/Infrastructure/Data/Config/EntityBuilders/QuoteConfiguration.cs index 645e7d8..9d042f5 100644 --- a/src/Nethereum.eShop.SqlServer/Infrastructure/Data/Config/QuoteConfiguration.cs +++ b/src/Nethereum.eShop/Infrastructure/Data/Config/EntityBuilders/QuoteConfiguration.cs @@ -2,26 +2,18 @@ using Microsoft.EntityFrameworkCore.Metadata.Builders; using Nethereum.eShop.ApplicationCore.Entities.QuoteAggregate; -namespace Nethereum.eShop.Infrastructure.Data.Config +namespace Nethereum.eShop.Infrastructure.Data.Config.EntityBuilders { public class QuoteConfiguration : IEntityTypeConfiguration { - public void Configure(EntityTypeBuilder builder) + public virtual void Configure(EntityTypeBuilder builder) { var navigation = builder.Metadata.FindNavigation(nameof(Quote.QuoteItems)); navigation.SetPropertyAccessMode(PropertyAccessMode.Field); - builder.OwnsOne(o => o.ShipTo, a => - { - a.ConfigureAddress(); - }); - - builder.OwnsOne(o => o.BillTo, a => - { - a.ConfigureAddress(); - }); - + builder.OwnsOne(o => o.ShipTo, a => a.ConfigureAddress()); + builder.OwnsOne(o => o.BillTo, a => a.ConfigureAddress()); builder.Property(o => o.BuyerId).HasMaxLength(256).IsRequired(); builder.Property(o => o.BuyerAddress).IsAddress(); builder.Property(o => o.ApproverAddress).IsAddress(); diff --git a/src/Nethereum.eShop.SqlServer/Infrastructure/Data/Config/QuoteItemConfiguration.cs b/src/Nethereum.eShop/Infrastructure/Data/Config/EntityBuilders/QuoteItemConfiguration.cs similarity index 59% rename from src/Nethereum.eShop.SqlServer/Infrastructure/Data/Config/QuoteItemConfiguration.cs rename to src/Nethereum.eShop/Infrastructure/Data/Config/EntityBuilders/QuoteItemConfiguration.cs index 97b37a0..f5c5260 100644 --- a/src/Nethereum.eShop.SqlServer/Infrastructure/Data/Config/QuoteItemConfiguration.cs +++ b/src/Nethereum.eShop/Infrastructure/Data/Config/EntityBuilders/QuoteItemConfiguration.cs @@ -2,16 +2,13 @@ using Microsoft.EntityFrameworkCore.Metadata.Builders; using Nethereum.eShop.ApplicationCore.Entities.QuoteAggregate; -namespace Nethereum.eShop.Infrastructure.Data.Config +namespace Nethereum.eShop.Infrastructure.Data.Config.EntityBuilders { public class QuoteItemConfiguration : IEntityTypeConfiguration { - public void Configure(EntityTypeBuilder builder) + public virtual void Configure(EntityTypeBuilder builder) { - builder.OwnsOne(i => i.ItemOrdered, io => - { - io.ConfigureCatalogItemExcerpt(); - }); + builder.OwnsOne(i => i.ItemOrdered, io => io.ConfigureCatalogItemExcerpt()); builder.Property(oi => oi.UnitPrice) .IsPrice() diff --git a/src/Nethereum.eShop.SqlServer/Infrastructure/Data/Config/StockItemConfiguration.cs b/src/Nethereum.eShop/Infrastructure/Data/Config/EntityBuilders/StockItemConfiguration.cs similarity index 76% rename from src/Nethereum.eShop.SqlServer/Infrastructure/Data/Config/StockItemConfiguration.cs rename to src/Nethereum.eShop/Infrastructure/Data/Config/EntityBuilders/StockItemConfiguration.cs index 413189f..02f0e69 100644 --- a/src/Nethereum.eShop.SqlServer/Infrastructure/Data/Config/StockItemConfiguration.cs +++ b/src/Nethereum.eShop/Infrastructure/Data/Config/EntityBuilders/StockItemConfiguration.cs @@ -2,16 +2,16 @@ using Microsoft.EntityFrameworkCore.Metadata.Builders; using Nethereum.eShop.ApplicationCore.Entities; -namespace Nethereum.eShop.Infrastructure.Data.Config +namespace Nethereum.eShop.Infrastructure.Data.Config.EntityBuilders { public class StockItemConfiguration : IEntityTypeConfiguration { - public void Configure(EntityTypeBuilder builder) + public virtual void Configure(EntityTypeBuilder builder) { builder.ToTable("Stock"); builder.Property(ci => ci.Id) - .UseHiLo("stock_hilo") + // .UseHiLo("stock_hilo") .IsRequired(); builder.Property(ci => ci.Location) diff --git a/src/Nethereum.eShop/Infrastructure/Data/Config/IEShopDbBootstrapper.cs b/src/Nethereum.eShop/Infrastructure/Data/Config/IEShopDbBootstrapper.cs new file mode 100644 index 0000000..2dd5aa3 --- /dev/null +++ b/src/Nethereum.eShop/Infrastructure/Data/Config/IEShopDbBootstrapper.cs @@ -0,0 +1,18 @@ +using Microsoft.Extensions.Configuration; +using Microsoft.Extensions.DependencyInjection; + +namespace Nethereum.eShop.Infrastructure.Data.Config +{ + public interface IEShopDbBootstrapper + { + void AddDbContext(IServiceCollection services, IConfiguration configuration); + void AddRepositories(IServiceCollection services, IConfiguration configuration); + + void AddQueries(IServiceCollection services, IConfiguration configuration); + } + + public interface IEShopIdentityDbBootstrapper + { + void AddDbContext(IServiceCollection services, IConfiguration configuration); + } +} diff --git a/src/Nethereum.eShop/Infrastructure/Data/EfRepository.cs b/src/Nethereum.eShop/Infrastructure/Data/EfRepository.cs index d32d5e2..a792719 100644 --- a/src/Nethereum.eShop/Infrastructure/Data/EfRepository.cs +++ b/src/Nethereum.eShop/Infrastructure/Data/EfRepository.cs @@ -11,6 +11,8 @@ public class EfRepository : IAsyncRepository where T : BaseEntity, IAggreg { protected readonly CatalogContext _dbContext; + public virtual IUnitOfWork UnitOfWork => _dbContext; + public EfRepository(CatalogContext dbContext) { _dbContext = dbContext; @@ -18,22 +20,26 @@ public EfRepository(CatalogContext dbContext) public virtual async Task GetByIdAsync(int id) { - return await _dbContext.Set().FindAsync(id); + return await _dbContext.Set().FindAsync(id).ConfigureAwait(false); } - public async Task> ListAllAsync() + public virtual async Task> ListAllAsync() { - return await _dbContext.Set().ToListAsync(); + return await _dbContext.Set().ToListAsync().ConfigureAwait(false); } - public async Task> ListAsync(ISpecification spec) + public virtual async Task> ListAsync(ISpecification spec) { - return await ApplySpecification(spec).ToListAsync(); + return await ApplySpecification(spec).ToListAsync().ConfigureAwait(false); } private IQueryable ApplySpecification(ISpecification spec) { return SpecificationEvaluator.GetQuery(_dbContext.Set().AsQueryable(), spec); } + + public virtual T Add(T entity) => _dbContext.Set().Add(entity).Entity; + public virtual T Update(T entity) => _dbContext.Set().Update(entity).Entity; + public virtual void Delete(T entity) => _dbContext.Set().Remove(entity); } } \ No newline at end of file diff --git a/src/Nethereum.eShop/Infrastructure/Data/IModelBuilderAssemblyHandler.cs b/src/Nethereum.eShop/Infrastructure/Data/IModelBuilderAssemblyHandler.cs new file mode 100644 index 0000000..042ab87 --- /dev/null +++ b/src/Nethereum.eShop/Infrastructure/Data/IModelBuilderAssemblyHandler.cs @@ -0,0 +1,9 @@ +using System.Reflection; + +namespace Nethereum.eShop.Infrastructure.Data +{ + public interface IModelBuilderAssemblyHandler + { + Assembly GetModelBuilderAssembly(); + } +} diff --git a/src/Nethereum.eShop/Infrastructure/Data/ModelBuilderAssemblyHandler.cs b/src/Nethereum.eShop/Infrastructure/Data/ModelBuilderAssemblyHandler.cs new file mode 100644 index 0000000..ce7e97b --- /dev/null +++ b/src/Nethereum.eShop/Infrastructure/Data/ModelBuilderAssemblyHandler.cs @@ -0,0 +1,15 @@ +using System.Reflection; + +namespace Nethereum.eShop.Infrastructure.Data +{ + public class ModelBuilderAssemblyHandler : IModelBuilderAssemblyHandler + { + private readonly Assembly _assembly; + + public ModelBuilderAssemblyHandler(Assembly assembly) + { + _assembly = assembly; + } + public Assembly GetModelBuilderAssembly() => _assembly; + } +} diff --git a/src/Nethereum.eShop/Infrastructure/Data/OrderRepository.cs b/src/Nethereum.eShop/Infrastructure/Data/OrderRepository.cs index cded68f..f3b717b 100644 --- a/src/Nethereum.eShop/Infrastructure/Data/OrderRepository.cs +++ b/src/Nethereum.eShop/Infrastructure/Data/OrderRepository.cs @@ -8,15 +8,6 @@ namespace Nethereum.eShop.Infrastructure.Data public class OrderRepository : EfRepository, IOrderRepository { - - public IUnitOfWork UnitOfWork - { - get - { - return _dbContext; - } - } - public OrderRepository(CatalogContext dbContext) : base(dbContext) { } @@ -29,16 +20,6 @@ public Task GetByIdWithItemsAsync(int id) .FirstOrDefaultAsync(x => x.Id == id); } - public Order Add(Order order) - { - return _dbContext.Orders.Add(order).Entity; - } - - public Order Update(Order order) - { - return _dbContext.Orders.Update(order).Entity; - } - /* public Buyer Add(Buyer buyer) { diff --git a/src/Nethereum.eShop/Infrastructure/Data/QuoteRepository.cs b/src/Nethereum.eShop/Infrastructure/Data/QuoteRepository.cs index bc5f732..7dcc340 100644 --- a/src/Nethereum.eShop/Infrastructure/Data/QuoteRepository.cs +++ b/src/Nethereum.eShop/Infrastructure/Data/QuoteRepository.cs @@ -11,10 +11,11 @@ public class QuoteRepository : EfRepository, IQuoteRepository { public QuoteRepository(CatalogContext dbContext) : base(dbContext){} - public IUnitOfWork UnitOfWork => _dbContext; - public Quote Add(Quote quote) => _dbContext.Quotes.Add(quote).Entity; - public Quote Update(Quote quote) => _dbContext.Quotes.Update(quote).Entity; - public Task GetByIdWithItemsAsync(int id) => _dbContext.GetQuoteWithItemsOrDefault(id); + public Task GetByIdWithItemsAsync(int id) => + _dbContext.Quotes + .Include(b => b.QuoteItems) + .Where(b => b.Id == id) + .FirstOrDefaultAsync(); public Task> GetQuotesRequiringPurchaseOrderAsync() => _dbContext.Quotes.Where(quote => quote.Status == QuoteStatus.Pending && quote.PoNumber == null) diff --git a/src/Web/Services/BasketViewModelService.cs b/src/Web/Services/BasketViewModelService.cs index ee9f7e2..4607fbb 100644 --- a/src/Web/Services/BasketViewModelService.cs +++ b/src/Web/Services/BasketViewModelService.cs @@ -1,11 +1,8 @@ -using Nethereum.eShop.ApplicationCore.Entities; -using Nethereum.eShop.ApplicationCore.Entities.BasketAggregate; +using Nethereum.eShop.ApplicationCore.Entities.BasketAggregate; using Nethereum.eShop.ApplicationCore.Interfaces; -using Nethereum.eShop.ApplicationCore.Specifications; using Nethereum.eShop.Web.Interfaces; using Nethereum.eShop.Web.Pages.Basket; using System.Collections.Generic; -using System.Linq; using System.Threading.Tasks; namespace Nethereum.eShop.Web.Services @@ -14,10 +11,10 @@ public class BasketViewModelService : IBasketViewModelService { private readonly IBasketRepository _basketRepository; private readonly IUriComposer _uriComposer; - private readonly IAsyncRepository _itemRepository; + private readonly ICatalogItemRepository _itemRepository; public BasketViewModelService(IBasketRepository basketRepository, - IAsyncRepository itemRepository, + ICatalogItemRepository itemRepository, IUriComposer uriComposer) { _basketRepository = basketRepository; diff --git a/src/Web/Services/CatalogViewModelService.cs b/src/Web/Services/CatalogViewModelService.cs index a1aa28e..2420234 100644 --- a/src/Web/Services/CatalogViewModelService.cs +++ b/src/Web/Services/CatalogViewModelService.cs @@ -3,7 +3,6 @@ using Nethereum.eShop.ApplicationCore.Entities; using Nethereum.eShop.ApplicationCore.Interfaces; using Nethereum.eShop.ApplicationCore.Queries.Catalog; -using Nethereum.eShop.ApplicationCore.Specifications; using Nethereum.eShop.Web.ViewModels; using System; using System.Collections.Generic; diff --git a/src/Web/Startup.cs b/src/Web/Startup.cs index bd86b81..8feb5df 100644 --- a/src/Web/Startup.cs +++ b/src/Web/Startup.cs @@ -12,15 +12,15 @@ using Microsoft.Extensions.Diagnostics.HealthChecks; using Microsoft.Extensions.Hosting; using Nethereum.eShop.ApplicationCore.Interfaces; -using Nethereum.eShop.ApplicationCore.Queries.Catalog; -using Nethereum.eShop.ApplicationCore.Queries.Orders; -using Nethereum.eShop.ApplicationCore.Queries.Quotes; using Nethereum.eShop.ApplicationCore.Services; using Nethereum.eShop.Infrastructure.Data; using Nethereum.eShop.Infrastructure.Data.Config; +using Nethereum.eShop.Infrastructure.Data.Config.EntityBuilders; using Nethereum.eShop.Infrastructure.Identity; using Nethereum.eShop.Infrastructure.Logging; using Nethereum.eShop.Infrastructure.Services; +using Nethereum.eShop.InMemory; +using Nethereum.eShop.SqlServer.Infrastructure.Data.Config; using Nethereum.eShop.Web.Interfaces; using Nethereum.eShop.Web.Services; using Newtonsoft.Json; @@ -63,15 +63,13 @@ public void ConfigureDevelopmentServices(IServiceCollection services) private void ConfigureInMemoryDatabases(IServiceCollection services) { - // use in-memory database - services.AddDbContext(c => - c.UseInMemoryDatabase("Catalog")); + IEShopDbBootstrapper dbBootstrapper = new InMemoryEShopDbBootrapper(); + dbBootstrapper.AddDbContext(services, Configuration); - // Add Identity DbContext - services.AddDbContext(options => - options.UseInMemoryDatabase("Identity")); + IEShopIdentityDbBootstrapper identityBootstrapper = new InMemoryEShopIdentityDbBootrapper(); + identityBootstrapper.AddDbContext(services, Configuration); - ConfigureServices(services); + ConfigureServices(services, dbBootstrapper); } public void ConfigureProductionServices(IServiceCollection services) @@ -89,14 +87,13 @@ public void ConfigureProductionServices(IServiceCollection services) See CreateAndApplyDbMigrations.bat in the root of the Web project */ - services.AddDbContext((serviceProvider, options) => - options.UseSqlServer(Configuration.GetConnectionString("CatalogConnection"))); + IEShopDbBootstrapper dbBootstrapper = CreateDbBootstrapper(Configuration); + dbBootstrapper.AddDbContext(services, Configuration); - // Add Identity DbContext - services.AddDbContext(options => - options.UseSqlServer(Configuration.GetConnectionString("IdentityConnection"))); + IEShopIdentityDbBootstrapper identityDbBootstrapper = CreateAppIdentityDbBootstrapper(Configuration); + identityDbBootstrapper.AddDbContext(services, Configuration); - ConfigureServices(services); + ConfigureServices(services, dbBootstrapper); } public void ConfigureTestingServices(IServiceCollection services) @@ -106,36 +103,25 @@ public void ConfigureTestingServices(IServiceCollection services) // This method gets called by the runtime. Use this method to add services to the container. - public void ConfigureServices(IServiceCollection services) + public void ConfigureServices( + IServiceCollection services, IEShopDbBootstrapper dbBootstrapper) { ConfigureCookieSettings(services); CreateIdentityIfNotCreated(services); - // a place to repoint DataContext model builder configuration to another assembly - services.AddSingleton>( - new ModelBuilderAssemblyHandler(typeof(BasketConfiguration).Assembly)); - services.AddMediatR(typeof(BasketViewModelService).Assembly); - string queryConnectionString = Configuration.GetConnectionString("CatalogConnection"); - services.AddSingleton(new QuoteQueries(queryConnectionString)); - services.AddSingleton(new OrderQueries(queryConnectionString)); - services.AddSingleton(new CatalogQueries(queryConnectionString)); + dbBootstrapper.AddQueries(services, Configuration); + dbBootstrapper.AddRepositories(services, Configuration); services.AddScoped(typeof(IAsyncCache<>), typeof(GeneralCache<>)); - services.AddScoped(typeof(IAsyncRepository<>), typeof(EfRepository<>)); - services.AddScoped(); - services.AddScoped(); services.AddScoped(); services.AddScoped(); services.AddScoped(); services.AddScoped(); services.AddScoped(); services.AddScoped(); - services.AddScoped(); - services.AddScoped(); - services.AddScoped(); services.AddScoped(); services.AddScoped(); services.AddScoped(); @@ -197,6 +183,12 @@ public void ConfigureServices(IServiceCollection services) _services = services; // used to debug registered services } + private static IEShopDbBootstrapper CreateDbBootstrapper(IConfiguration configuration) + => new SqlServerEShopDbBootstrapper(); + + private static IEShopIdentityDbBootstrapper CreateAppIdentityDbBootstrapper(IConfiguration configuration) + => new SqlServerEShopAppIdentityDbBootstrapper(); + private static void CreateIdentityIfNotCreated(IServiceCollection services) { var sp = services.BuildServiceProvider(); @@ -296,4 +288,5 @@ public void Configure(IApplicationBuilder app, IWebHostEnvironment env) }); } } + } diff --git a/src/Web/Web.csproj b/src/Web/Web.csproj index 822a1f6..535f53b 100644 --- a/src/Web/Web.csproj +++ b/src/Web/Web.csproj @@ -39,6 +39,7 @@ + diff --git a/src/WebJobs/JsonFileBlockProgressRepository.cs b/src/WebJobs/JsonFileBlockProgressRepository.cs index 08451d8..a3404f9 100644 --- a/src/WebJobs/JsonFileBlockProgressRepository.cs +++ b/src/WebJobs/JsonFileBlockProgressRepository.cs @@ -7,10 +7,16 @@ namespace Nethereum.eShop.WebJobs { public class JsonFileBlockProgressRepository: JsonBlockProgressRepository { - public JsonFileBlockProgressRepository(EshopConfiguration eshopConfiguration):base( - () => Task.FromResult(File.Exists(eshopConfiguration.PurchaseOrderEventLogConfiguration.BlockProgressJsonFile)), - async (json) => await File.WriteAllTextAsync(eshopConfiguration.PurchaseOrderEventLogConfiguration.BlockProgressJsonFile, json), - async () => await File.ReadAllTextAsync(eshopConfiguration.PurchaseOrderEventLogConfiguration.BlockProgressJsonFile)) + public JsonFileBlockProgressRepository(EshopConfiguration eshopConfiguration): + this(eshopConfiguration.PurchaseOrderEventLogConfiguration.BlockProgressJsonFile) + { + + } + + private JsonFileBlockProgressRepository(string jsonFile):base( + () => Task.FromResult(File.Exists(jsonFile)), + async (json) => await File.WriteAllTextAsync(jsonFile, json), + async () => await File.ReadAllTextAsync(jsonFile)) { } From 1595fc426e4518bb42fa3b17740c73244ae982e6 Mon Sep 17 00:00:00 2001 From: Dave Whiffin Date: Tue, 10 Mar 2020 11:07:37 +0000 Subject: [PATCH 09/27] Project and Solution Restructure --- .../Infrastructure/Data/BasketRepository.cs | 0 .../Infrastructure/Data/CatalogContext.cs | 1 + .../Infrastructure/Data/CatalogContextSeed.cs | 12 ++++++--- .../Infrastructure/Data/CatalogImportDto.cs | 0 .../Data/CatalogItemRepository.cs | 0 .../Data/Config/EShopDbBootstrapperBase.cs | 3 --- .../Data/Config/EntityBuilderExtensions.cs | 0 .../EntityBuilders/BasketConfiguration.cs | 0 .../EntityBuilders/BasketItemConfiguration.cs | 0 .../EntityBuilders/BuyerConfiguration.cs | 0 .../BuyerPostalAddressConfiguration.cs | 0 .../CatalogBrandConfiguration.cs | 0 .../CatalogItemConfiguration.cs | 0 .../CatalogItemExcerptBuilder.cs | 0 .../CatalogTypeConfiguration.cs | 0 .../EntityBuilders/OrderConfiguration.cs | 0 .../EntityBuilders/OrderItemConfiguration.cs | 0 .../EntityBuilders/PostalAddressBuilder.cs | 0 .../EntityBuilders/QuoteConfiguration.cs | 0 .../EntityBuilders/QuoteItemConfiguration.cs | 0 .../EntityBuilders/StockItemConfiguration.cs | 0 .../Infrastructure/Data/EfRepository.cs | 0 .../Infrastructure/Data/GeneralCache.cs | 0 .../Data/IModelBuilderAssemblyHandler.cs | 0 .../Data/JsonCatalogContextSeeder.cs | 14 ++++++---- .../Infrastructure/Data/MediatorExtension.cs | 0 .../Data/ModelBuilderAssemblyHandler.cs | 0 .../Infrastructure/Data/OrderRepository.cs | 0 .../Infrastructure/Data/QuoteRepository.cs | 0 .../Infrastructure/Data/RuleTreeCache.cs | 0 .../Data/SpecificationEvaluator.cs | 0 .../Data/StockItemRepository.cs | 0 .../Identity/AppIdentityDbContext.cs | 0 .../Nethereum.eShop.EntityFramework.csproj | 27 +++++++++++++++++++ .../Data/Config/InMemoryEShopDbBootrapper.cs} | 13 ++------- .../InMemoryEShopIdentityDbBootrapper.cs | 17 ++++++++++++ .../Nethereum.eShop.InMemory.csproj | 1 + .../Nethereum.eShop.SqlServer.csproj | 1 + src/Nethereum.eShop.sln | 20 +++++++++++++- .../Interfaces/IBasketRepository.cs | 1 - .../Interfaces/ICatalogContextSeeder.cs | 10 +++++++ .../Interfaces/ICatalogItemRepository.cs | 1 - .../Interfaces}/IEShopDbBootstrapper.cs | 7 +---- .../IEShopIdentityDbBootstrapper.cs | 10 +++++++ .../Interfaces/IOrderRepository.cs | 1 - .../Interfaces/IQuoteRepository.cs | 1 - .../Interfaces}/IRepository.cs | 2 +- .../Interfaces}/IUnitOfWork.cs | 2 +- .../Data/ICatalogContextSeeder.cs | 10 ------- src/Nethereum.eShop/Nethereum.eShop.csproj | 4 --- src/Web/Program.cs | 4 +-- src/Web/Startup.cs | 18 +++++++------ src/Web/Web.csproj | 1 + src/WebJobs/Program.cs | 5 ---- src/WebJobs/WebJobs.csproj | 1 + 55 files changed, 123 insertions(+), 64 deletions(-) rename src/{Nethereum.eShop => Nethereum.eShop.EntityFramework}/Infrastructure/Data/BasketRepository.cs (100%) rename src/{Nethereum.eShop => Nethereum.eShop.EntityFramework}/Infrastructure/Data/CatalogContext.cs (98%) rename src/{Nethereum.eShop => Nethereum.eShop.EntityFramework}/Infrastructure/Data/CatalogContextSeed.cs (92%) rename src/{Nethereum.eShop => Nethereum.eShop.EntityFramework}/Infrastructure/Data/CatalogImportDto.cs (100%) rename src/{Nethereum.eShop => Nethereum.eShop.EntityFramework}/Infrastructure/Data/CatalogItemRepository.cs (100%) rename src/{Nethereum.eShop => Nethereum.eShop.EntityFramework}/Infrastructure/Data/Config/EShopDbBootstrapperBase.cs (92%) rename src/{Nethereum.eShop => Nethereum.eShop.EntityFramework}/Infrastructure/Data/Config/EntityBuilderExtensions.cs (100%) rename src/{Nethereum.eShop => Nethereum.eShop.EntityFramework}/Infrastructure/Data/Config/EntityBuilders/BasketConfiguration.cs (100%) rename src/{Nethereum.eShop => Nethereum.eShop.EntityFramework}/Infrastructure/Data/Config/EntityBuilders/BasketItemConfiguration.cs (100%) rename src/{Nethereum.eShop => Nethereum.eShop.EntityFramework}/Infrastructure/Data/Config/EntityBuilders/BuyerConfiguration.cs (100%) rename src/{Nethereum.eShop => Nethereum.eShop.EntityFramework}/Infrastructure/Data/Config/EntityBuilders/BuyerPostalAddressConfiguration.cs (100%) rename src/{Nethereum.eShop => Nethereum.eShop.EntityFramework}/Infrastructure/Data/Config/EntityBuilders/CatalogBrandConfiguration.cs (100%) rename src/{Nethereum.eShop => Nethereum.eShop.EntityFramework}/Infrastructure/Data/Config/EntityBuilders/CatalogItemConfiguration.cs (100%) rename src/{Nethereum.eShop => Nethereum.eShop.EntityFramework}/Infrastructure/Data/Config/EntityBuilders/CatalogItemExcerptBuilder.cs (100%) rename src/{Nethereum.eShop => Nethereum.eShop.EntityFramework}/Infrastructure/Data/Config/EntityBuilders/CatalogTypeConfiguration.cs (100%) rename src/{Nethereum.eShop => Nethereum.eShop.EntityFramework}/Infrastructure/Data/Config/EntityBuilders/OrderConfiguration.cs (100%) rename src/{Nethereum.eShop => Nethereum.eShop.EntityFramework}/Infrastructure/Data/Config/EntityBuilders/OrderItemConfiguration.cs (100%) rename src/{Nethereum.eShop => Nethereum.eShop.EntityFramework}/Infrastructure/Data/Config/EntityBuilders/PostalAddressBuilder.cs (100%) rename src/{Nethereum.eShop => Nethereum.eShop.EntityFramework}/Infrastructure/Data/Config/EntityBuilders/QuoteConfiguration.cs (100%) rename src/{Nethereum.eShop => Nethereum.eShop.EntityFramework}/Infrastructure/Data/Config/EntityBuilders/QuoteItemConfiguration.cs (100%) rename src/{Nethereum.eShop => Nethereum.eShop.EntityFramework}/Infrastructure/Data/Config/EntityBuilders/StockItemConfiguration.cs (100%) rename src/{Nethereum.eShop => Nethereum.eShop.EntityFramework}/Infrastructure/Data/EfRepository.cs (100%) rename src/{Nethereum.eShop => Nethereum.eShop.EntityFramework}/Infrastructure/Data/GeneralCache.cs (100%) rename src/{Nethereum.eShop => Nethereum.eShop.EntityFramework}/Infrastructure/Data/IModelBuilderAssemblyHandler.cs (100%) rename src/{Nethereum.eShop => Nethereum.eShop.EntityFramework}/Infrastructure/Data/JsonCatalogContextSeeder.cs (83%) rename src/{Nethereum.eShop => Nethereum.eShop.EntityFramework}/Infrastructure/Data/MediatorExtension.cs (100%) rename src/{Nethereum.eShop => Nethereum.eShop.EntityFramework}/Infrastructure/Data/ModelBuilderAssemblyHandler.cs (100%) rename src/{Nethereum.eShop => Nethereum.eShop.EntityFramework}/Infrastructure/Data/OrderRepository.cs (100%) rename src/{Nethereum.eShop => Nethereum.eShop.EntityFramework}/Infrastructure/Data/QuoteRepository.cs (100%) rename src/{Nethereum.eShop => Nethereum.eShop.EntityFramework}/Infrastructure/Data/RuleTreeCache.cs (100%) rename src/{Nethereum.eShop => Nethereum.eShop.EntityFramework}/Infrastructure/Data/SpecificationEvaluator.cs (100%) rename src/{Nethereum.eShop => Nethereum.eShop.EntityFramework}/Infrastructure/Data/StockItemRepository.cs (100%) rename src/{Nethereum.eShop => Nethereum.eShop.EntityFramework}/Infrastructure/Identity/AppIdentityDbContext.cs (100%) create mode 100644 src/Nethereum.eShop.EntityFramework/Nethereum.eShop.EntityFramework.csproj rename src/Nethereum.eShop.InMemory/{Bootstrapper.cs => Infrastructure/Data/Config/InMemoryEShopDbBootrapper.cs} (78%) create mode 100644 src/Nethereum.eShop.InMemory/Infrastructure/Data/Config/InMemoryEShopIdentityDbBootrapper.cs create mode 100644 src/Nethereum.eShop/ApplicationCore/Interfaces/ICatalogContextSeeder.cs rename src/Nethereum.eShop/{Infrastructure/Data/Config => ApplicationCore/Interfaces}/IEShopDbBootstrapper.cs (67%) create mode 100644 src/Nethereum.eShop/ApplicationCore/Interfaces/IEShopIdentityDbBootstrapper.cs rename src/Nethereum.eShop/{Infrastructure/Data => ApplicationCore/Interfaces}/IRepository.cs (61%) rename src/Nethereum.eShop/{Infrastructure => ApplicationCore/Interfaces}/IUnitOfWork.cs (86%) delete mode 100644 src/Nethereum.eShop/Infrastructure/Data/ICatalogContextSeeder.cs diff --git a/src/Nethereum.eShop/Infrastructure/Data/BasketRepository.cs b/src/Nethereum.eShop.EntityFramework/Infrastructure/Data/BasketRepository.cs similarity index 100% rename from src/Nethereum.eShop/Infrastructure/Data/BasketRepository.cs rename to src/Nethereum.eShop.EntityFramework/Infrastructure/Data/BasketRepository.cs diff --git a/src/Nethereum.eShop/Infrastructure/Data/CatalogContext.cs b/src/Nethereum.eShop.EntityFramework/Infrastructure/Data/CatalogContext.cs similarity index 98% rename from src/Nethereum.eShop/Infrastructure/Data/CatalogContext.cs rename to src/Nethereum.eShop.EntityFramework/Infrastructure/Data/CatalogContext.cs index 92f4ca0..67b6e20 100644 --- a/src/Nethereum.eShop/Infrastructure/Data/CatalogContext.cs +++ b/src/Nethereum.eShop.EntityFramework/Infrastructure/Data/CatalogContext.cs @@ -6,6 +6,7 @@ using Nethereum.eShop.ApplicationCore.Entities.BuyerAggregate; using Nethereum.eShop.ApplicationCore.Entities.OrderAggregate; using Nethereum.eShop.ApplicationCore.Entities.QuoteAggregate; +using Nethereum.eShop.ApplicationCore.Interfaces; using System; using System.Data; using System.Reflection; diff --git a/src/Nethereum.eShop/Infrastructure/Data/CatalogContextSeed.cs b/src/Nethereum.eShop.EntityFramework/Infrastructure/Data/CatalogContextSeed.cs similarity index 92% rename from src/Nethereum.eShop/Infrastructure/Data/CatalogContextSeed.cs rename to src/Nethereum.eShop.EntityFramework/Infrastructure/Data/CatalogContextSeed.cs index 6b005aa..8072e9f 100644 --- a/src/Nethereum.eShop/Infrastructure/Data/CatalogContextSeed.cs +++ b/src/Nethereum.eShop.EntityFramework/Infrastructure/Data/CatalogContextSeed.cs @@ -1,5 +1,6 @@ using Microsoft.Extensions.Logging; using Nethereum.eShop.ApplicationCore.Entities; +using Nethereum.eShop.ApplicationCore.Interfaces; using System; using System.Collections.Generic; using System.Linq; @@ -10,8 +11,13 @@ namespace Nethereum.eShop.Infrastructure.Data public class HardCodedCatalogContextSeeder: ICatalogContextSeeder { - public async Task SeedAsync(CatalogContext catalogContext, - ILoggerFactory loggerFactory, int? retry = 0) + private readonly CatalogContext catalogContext; + public HardCodedCatalogContextSeeder(CatalogContext catalogContext) + { + this.catalogContext = catalogContext; + } + + public async Task SeedAsync(ILoggerFactory loggerFactory, int? retry = 0) { int retryForAvailability = retry.Value; try @@ -50,7 +56,7 @@ public async Task SeedAsync(CatalogContext catalogContext, retryForAvailability++; var log = loggerFactory.CreateLogger(); log.LogError(ex.Message); - await SeedAsync(catalogContext, loggerFactory, retryForAvailability); + await SeedAsync(loggerFactory, retryForAvailability); } } } diff --git a/src/Nethereum.eShop/Infrastructure/Data/CatalogImportDto.cs b/src/Nethereum.eShop.EntityFramework/Infrastructure/Data/CatalogImportDto.cs similarity index 100% rename from src/Nethereum.eShop/Infrastructure/Data/CatalogImportDto.cs rename to src/Nethereum.eShop.EntityFramework/Infrastructure/Data/CatalogImportDto.cs diff --git a/src/Nethereum.eShop/Infrastructure/Data/CatalogItemRepository.cs b/src/Nethereum.eShop.EntityFramework/Infrastructure/Data/CatalogItemRepository.cs similarity index 100% rename from src/Nethereum.eShop/Infrastructure/Data/CatalogItemRepository.cs rename to src/Nethereum.eShop.EntityFramework/Infrastructure/Data/CatalogItemRepository.cs diff --git a/src/Nethereum.eShop/Infrastructure/Data/Config/EShopDbBootstrapperBase.cs b/src/Nethereum.eShop.EntityFramework/Infrastructure/Data/Config/EShopDbBootstrapperBase.cs similarity index 92% rename from src/Nethereum.eShop/Infrastructure/Data/Config/EShopDbBootstrapperBase.cs rename to src/Nethereum.eShop.EntityFramework/Infrastructure/Data/Config/EShopDbBootstrapperBase.cs index c98e3c0..7baae4c 100644 --- a/src/Nethereum.eShop/Infrastructure/Data/Config/EShopDbBootstrapperBase.cs +++ b/src/Nethereum.eShop.EntityFramework/Infrastructure/Data/Config/EShopDbBootstrapperBase.cs @@ -1,9 +1,6 @@ using Microsoft.Extensions.Configuration; using Microsoft.Extensions.DependencyInjection; using Nethereum.eShop.ApplicationCore.Interfaces; -using System; -using System.Collections.Generic; -using System.Text; namespace Nethereum.eShop.Infrastructure.Data.Config { diff --git a/src/Nethereum.eShop/Infrastructure/Data/Config/EntityBuilderExtensions.cs b/src/Nethereum.eShop.EntityFramework/Infrastructure/Data/Config/EntityBuilderExtensions.cs similarity index 100% rename from src/Nethereum.eShop/Infrastructure/Data/Config/EntityBuilderExtensions.cs rename to src/Nethereum.eShop.EntityFramework/Infrastructure/Data/Config/EntityBuilderExtensions.cs diff --git a/src/Nethereum.eShop/Infrastructure/Data/Config/EntityBuilders/BasketConfiguration.cs b/src/Nethereum.eShop.EntityFramework/Infrastructure/Data/Config/EntityBuilders/BasketConfiguration.cs similarity index 100% rename from src/Nethereum.eShop/Infrastructure/Data/Config/EntityBuilders/BasketConfiguration.cs rename to src/Nethereum.eShop.EntityFramework/Infrastructure/Data/Config/EntityBuilders/BasketConfiguration.cs diff --git a/src/Nethereum.eShop/Infrastructure/Data/Config/EntityBuilders/BasketItemConfiguration.cs b/src/Nethereum.eShop.EntityFramework/Infrastructure/Data/Config/EntityBuilders/BasketItemConfiguration.cs similarity index 100% rename from src/Nethereum.eShop/Infrastructure/Data/Config/EntityBuilders/BasketItemConfiguration.cs rename to src/Nethereum.eShop.EntityFramework/Infrastructure/Data/Config/EntityBuilders/BasketItemConfiguration.cs diff --git a/src/Nethereum.eShop/Infrastructure/Data/Config/EntityBuilders/BuyerConfiguration.cs b/src/Nethereum.eShop.EntityFramework/Infrastructure/Data/Config/EntityBuilders/BuyerConfiguration.cs similarity index 100% rename from src/Nethereum.eShop/Infrastructure/Data/Config/EntityBuilders/BuyerConfiguration.cs rename to src/Nethereum.eShop.EntityFramework/Infrastructure/Data/Config/EntityBuilders/BuyerConfiguration.cs diff --git a/src/Nethereum.eShop/Infrastructure/Data/Config/EntityBuilders/BuyerPostalAddressConfiguration.cs b/src/Nethereum.eShop.EntityFramework/Infrastructure/Data/Config/EntityBuilders/BuyerPostalAddressConfiguration.cs similarity index 100% rename from src/Nethereum.eShop/Infrastructure/Data/Config/EntityBuilders/BuyerPostalAddressConfiguration.cs rename to src/Nethereum.eShop.EntityFramework/Infrastructure/Data/Config/EntityBuilders/BuyerPostalAddressConfiguration.cs diff --git a/src/Nethereum.eShop/Infrastructure/Data/Config/EntityBuilders/CatalogBrandConfiguration.cs b/src/Nethereum.eShop.EntityFramework/Infrastructure/Data/Config/EntityBuilders/CatalogBrandConfiguration.cs similarity index 100% rename from src/Nethereum.eShop/Infrastructure/Data/Config/EntityBuilders/CatalogBrandConfiguration.cs rename to src/Nethereum.eShop.EntityFramework/Infrastructure/Data/Config/EntityBuilders/CatalogBrandConfiguration.cs diff --git a/src/Nethereum.eShop/Infrastructure/Data/Config/EntityBuilders/CatalogItemConfiguration.cs b/src/Nethereum.eShop.EntityFramework/Infrastructure/Data/Config/EntityBuilders/CatalogItemConfiguration.cs similarity index 100% rename from src/Nethereum.eShop/Infrastructure/Data/Config/EntityBuilders/CatalogItemConfiguration.cs rename to src/Nethereum.eShop.EntityFramework/Infrastructure/Data/Config/EntityBuilders/CatalogItemConfiguration.cs diff --git a/src/Nethereum.eShop/Infrastructure/Data/Config/EntityBuilders/CatalogItemExcerptBuilder.cs b/src/Nethereum.eShop.EntityFramework/Infrastructure/Data/Config/EntityBuilders/CatalogItemExcerptBuilder.cs similarity index 100% rename from src/Nethereum.eShop/Infrastructure/Data/Config/EntityBuilders/CatalogItemExcerptBuilder.cs rename to src/Nethereum.eShop.EntityFramework/Infrastructure/Data/Config/EntityBuilders/CatalogItemExcerptBuilder.cs diff --git a/src/Nethereum.eShop/Infrastructure/Data/Config/EntityBuilders/CatalogTypeConfiguration.cs b/src/Nethereum.eShop.EntityFramework/Infrastructure/Data/Config/EntityBuilders/CatalogTypeConfiguration.cs similarity index 100% rename from src/Nethereum.eShop/Infrastructure/Data/Config/EntityBuilders/CatalogTypeConfiguration.cs rename to src/Nethereum.eShop.EntityFramework/Infrastructure/Data/Config/EntityBuilders/CatalogTypeConfiguration.cs diff --git a/src/Nethereum.eShop/Infrastructure/Data/Config/EntityBuilders/OrderConfiguration.cs b/src/Nethereum.eShop.EntityFramework/Infrastructure/Data/Config/EntityBuilders/OrderConfiguration.cs similarity index 100% rename from src/Nethereum.eShop/Infrastructure/Data/Config/EntityBuilders/OrderConfiguration.cs rename to src/Nethereum.eShop.EntityFramework/Infrastructure/Data/Config/EntityBuilders/OrderConfiguration.cs diff --git a/src/Nethereum.eShop/Infrastructure/Data/Config/EntityBuilders/OrderItemConfiguration.cs b/src/Nethereum.eShop.EntityFramework/Infrastructure/Data/Config/EntityBuilders/OrderItemConfiguration.cs similarity index 100% rename from src/Nethereum.eShop/Infrastructure/Data/Config/EntityBuilders/OrderItemConfiguration.cs rename to src/Nethereum.eShop.EntityFramework/Infrastructure/Data/Config/EntityBuilders/OrderItemConfiguration.cs diff --git a/src/Nethereum.eShop/Infrastructure/Data/Config/EntityBuilders/PostalAddressBuilder.cs b/src/Nethereum.eShop.EntityFramework/Infrastructure/Data/Config/EntityBuilders/PostalAddressBuilder.cs similarity index 100% rename from src/Nethereum.eShop/Infrastructure/Data/Config/EntityBuilders/PostalAddressBuilder.cs rename to src/Nethereum.eShop.EntityFramework/Infrastructure/Data/Config/EntityBuilders/PostalAddressBuilder.cs diff --git a/src/Nethereum.eShop/Infrastructure/Data/Config/EntityBuilders/QuoteConfiguration.cs b/src/Nethereum.eShop.EntityFramework/Infrastructure/Data/Config/EntityBuilders/QuoteConfiguration.cs similarity index 100% rename from src/Nethereum.eShop/Infrastructure/Data/Config/EntityBuilders/QuoteConfiguration.cs rename to src/Nethereum.eShop.EntityFramework/Infrastructure/Data/Config/EntityBuilders/QuoteConfiguration.cs diff --git a/src/Nethereum.eShop/Infrastructure/Data/Config/EntityBuilders/QuoteItemConfiguration.cs b/src/Nethereum.eShop.EntityFramework/Infrastructure/Data/Config/EntityBuilders/QuoteItemConfiguration.cs similarity index 100% rename from src/Nethereum.eShop/Infrastructure/Data/Config/EntityBuilders/QuoteItemConfiguration.cs rename to src/Nethereum.eShop.EntityFramework/Infrastructure/Data/Config/EntityBuilders/QuoteItemConfiguration.cs diff --git a/src/Nethereum.eShop/Infrastructure/Data/Config/EntityBuilders/StockItemConfiguration.cs b/src/Nethereum.eShop.EntityFramework/Infrastructure/Data/Config/EntityBuilders/StockItemConfiguration.cs similarity index 100% rename from src/Nethereum.eShop/Infrastructure/Data/Config/EntityBuilders/StockItemConfiguration.cs rename to src/Nethereum.eShop.EntityFramework/Infrastructure/Data/Config/EntityBuilders/StockItemConfiguration.cs diff --git a/src/Nethereum.eShop/Infrastructure/Data/EfRepository.cs b/src/Nethereum.eShop.EntityFramework/Infrastructure/Data/EfRepository.cs similarity index 100% rename from src/Nethereum.eShop/Infrastructure/Data/EfRepository.cs rename to src/Nethereum.eShop.EntityFramework/Infrastructure/Data/EfRepository.cs diff --git a/src/Nethereum.eShop/Infrastructure/Data/GeneralCache.cs b/src/Nethereum.eShop.EntityFramework/Infrastructure/Data/GeneralCache.cs similarity index 100% rename from src/Nethereum.eShop/Infrastructure/Data/GeneralCache.cs rename to src/Nethereum.eShop.EntityFramework/Infrastructure/Data/GeneralCache.cs diff --git a/src/Nethereum.eShop/Infrastructure/Data/IModelBuilderAssemblyHandler.cs b/src/Nethereum.eShop.EntityFramework/Infrastructure/Data/IModelBuilderAssemblyHandler.cs similarity index 100% rename from src/Nethereum.eShop/Infrastructure/Data/IModelBuilderAssemblyHandler.cs rename to src/Nethereum.eShop.EntityFramework/Infrastructure/Data/IModelBuilderAssemblyHandler.cs diff --git a/src/Nethereum.eShop/Infrastructure/Data/JsonCatalogContextSeeder.cs b/src/Nethereum.eShop.EntityFramework/Infrastructure/Data/JsonCatalogContextSeeder.cs similarity index 83% rename from src/Nethereum.eShop/Infrastructure/Data/JsonCatalogContextSeeder.cs rename to src/Nethereum.eShop.EntityFramework/Infrastructure/Data/JsonCatalogContextSeeder.cs index fb1f079..05bb040 100644 --- a/src/Nethereum.eShop/Infrastructure/Data/JsonCatalogContextSeeder.cs +++ b/src/Nethereum.eShop.EntityFramework/Infrastructure/Data/JsonCatalogContextSeeder.cs @@ -1,4 +1,6 @@ -using Microsoft.Extensions.Logging; +using Microsoft.Extensions.Configuration; +using Microsoft.Extensions.Logging; +using Nethereum.eShop.ApplicationCore.Interfaces; using Newtonsoft.Json; using System; using System.IO; @@ -11,10 +13,12 @@ namespace Nethereum.eShop.Infrastructure.Data public class JsonCatalogContextSeeder : ICatalogContextSeeder { private readonly string _productImportJsonFile; + private readonly CatalogContext catalogContext; - public JsonCatalogContextSeeder(string productImportJsonFile) + public JsonCatalogContextSeeder(CatalogSettings catalogSettings, CatalogContext catalogContext) { - this._productImportJsonFile = productImportJsonFile; + this.catalogContext = catalogContext; + _productImportJsonFile = catalogSettings.CatalogSeedJsonFile; } private CatalogImportDto GetImportDataFromJsonFile() @@ -30,7 +34,7 @@ private CatalogImportDto GetImportDataFromJsonFile() } } - public async Task SeedAsync(CatalogContext catalogContext, ILoggerFactory loggerFactory, int? retry = 0) + public async Task SeedAsync(ILoggerFactory loggerFactory, int? retry = 0) { int retryForAvailability = retry.Value; @@ -77,7 +81,7 @@ public async Task SeedAsync(CatalogContext catalogContext, ILoggerFactory logger retryForAvailability++; var log = loggerFactory.CreateLogger(); log.LogError(ex.Message); - await SeedAsync(catalogContext, loggerFactory, retryForAvailability); + await SeedAsync(loggerFactory, retryForAvailability); } } } diff --git a/src/Nethereum.eShop/Infrastructure/Data/MediatorExtension.cs b/src/Nethereum.eShop.EntityFramework/Infrastructure/Data/MediatorExtension.cs similarity index 100% rename from src/Nethereum.eShop/Infrastructure/Data/MediatorExtension.cs rename to src/Nethereum.eShop.EntityFramework/Infrastructure/Data/MediatorExtension.cs diff --git a/src/Nethereum.eShop/Infrastructure/Data/ModelBuilderAssemblyHandler.cs b/src/Nethereum.eShop.EntityFramework/Infrastructure/Data/ModelBuilderAssemblyHandler.cs similarity index 100% rename from src/Nethereum.eShop/Infrastructure/Data/ModelBuilderAssemblyHandler.cs rename to src/Nethereum.eShop.EntityFramework/Infrastructure/Data/ModelBuilderAssemblyHandler.cs diff --git a/src/Nethereum.eShop/Infrastructure/Data/OrderRepository.cs b/src/Nethereum.eShop.EntityFramework/Infrastructure/Data/OrderRepository.cs similarity index 100% rename from src/Nethereum.eShop/Infrastructure/Data/OrderRepository.cs rename to src/Nethereum.eShop.EntityFramework/Infrastructure/Data/OrderRepository.cs diff --git a/src/Nethereum.eShop/Infrastructure/Data/QuoteRepository.cs b/src/Nethereum.eShop.EntityFramework/Infrastructure/Data/QuoteRepository.cs similarity index 100% rename from src/Nethereum.eShop/Infrastructure/Data/QuoteRepository.cs rename to src/Nethereum.eShop.EntityFramework/Infrastructure/Data/QuoteRepository.cs diff --git a/src/Nethereum.eShop/Infrastructure/Data/RuleTreeCache.cs b/src/Nethereum.eShop.EntityFramework/Infrastructure/Data/RuleTreeCache.cs similarity index 100% rename from src/Nethereum.eShop/Infrastructure/Data/RuleTreeCache.cs rename to src/Nethereum.eShop.EntityFramework/Infrastructure/Data/RuleTreeCache.cs diff --git a/src/Nethereum.eShop/Infrastructure/Data/SpecificationEvaluator.cs b/src/Nethereum.eShop.EntityFramework/Infrastructure/Data/SpecificationEvaluator.cs similarity index 100% rename from src/Nethereum.eShop/Infrastructure/Data/SpecificationEvaluator.cs rename to src/Nethereum.eShop.EntityFramework/Infrastructure/Data/SpecificationEvaluator.cs diff --git a/src/Nethereum.eShop/Infrastructure/Data/StockItemRepository.cs b/src/Nethereum.eShop.EntityFramework/Infrastructure/Data/StockItemRepository.cs similarity index 100% rename from src/Nethereum.eShop/Infrastructure/Data/StockItemRepository.cs rename to src/Nethereum.eShop.EntityFramework/Infrastructure/Data/StockItemRepository.cs diff --git a/src/Nethereum.eShop/Infrastructure/Identity/AppIdentityDbContext.cs b/src/Nethereum.eShop.EntityFramework/Infrastructure/Identity/AppIdentityDbContext.cs similarity index 100% rename from src/Nethereum.eShop/Infrastructure/Identity/AppIdentityDbContext.cs rename to src/Nethereum.eShop.EntityFramework/Infrastructure/Identity/AppIdentityDbContext.cs diff --git a/src/Nethereum.eShop.EntityFramework/Nethereum.eShop.EntityFramework.csproj b/src/Nethereum.eShop.EntityFramework/Nethereum.eShop.EntityFramework.csproj new file mode 100644 index 0000000..b0d940b --- /dev/null +++ b/src/Nethereum.eShop.EntityFramework/Nethereum.eShop.EntityFramework.csproj @@ -0,0 +1,27 @@ + + + + netstandard2.1 + 80b8bc7f-cc13-45f4-967c-6c2b164a22e3 + + + + + + + + + + + + + + + + + + + + + + diff --git a/src/Nethereum.eShop.InMemory/Bootstrapper.cs b/src/Nethereum.eShop.InMemory/Infrastructure/Data/Config/InMemoryEShopDbBootrapper.cs similarity index 78% rename from src/Nethereum.eShop.InMemory/Bootstrapper.cs rename to src/Nethereum.eShop.InMemory/Infrastructure/Data/Config/InMemoryEShopDbBootrapper.cs index 6c608f3..1d732c3 100644 --- a/src/Nethereum.eShop.InMemory/Bootstrapper.cs +++ b/src/Nethereum.eShop.InMemory/Infrastructure/Data/Config/InMemoryEShopDbBootrapper.cs @@ -1,18 +1,18 @@ using Microsoft.EntityFrameworkCore; using Microsoft.Extensions.Configuration; using Microsoft.Extensions.DependencyInjection; +using Nethereum.eShop.ApplicationCore.Interfaces; using Nethereum.eShop.ApplicationCore.Queries.Catalog; using Nethereum.eShop.ApplicationCore.Queries.Orders; using Nethereum.eShop.ApplicationCore.Queries.Quotes; using Nethereum.eShop.Infrastructure.Data; using Nethereum.eShop.Infrastructure.Data.Config; using Nethereum.eShop.Infrastructure.Data.Config.EntityBuilders; -using Nethereum.eShop.Infrastructure.Identity; using Nethereum.eShop.InMemory.ApplicationCore.Queries.Catalog; using Nethereum.eShop.InMemory.ApplicationCore.Queries.Orders; using Nethereum.eShop.InMemory.ApplicationCore.Queries.Quotes; -namespace Nethereum.eShop.InMemory +namespace Nethereum.eShop.InMemory.Infrastructure.Data.Config { public class InMemoryEShopDbBootrapper : EShopDbBootstrapperBase, IEShopDbBootstrapper { @@ -33,13 +33,4 @@ public void AddQueries(IServiceCollection services, IConfiguration configuration services.AddScoped(); } } - - public class InMemoryEShopIdentityDbBootrapper : IEShopIdentityDbBootstrapper - { - public void AddDbContext(IServiceCollection services, IConfiguration configuration) - { - services.AddDbContext(options => - options.UseInMemoryDatabase("Identity")); - } - } } diff --git a/src/Nethereum.eShop.InMemory/Infrastructure/Data/Config/InMemoryEShopIdentityDbBootrapper.cs b/src/Nethereum.eShop.InMemory/Infrastructure/Data/Config/InMemoryEShopIdentityDbBootrapper.cs new file mode 100644 index 0000000..bf03548 --- /dev/null +++ b/src/Nethereum.eShop.InMemory/Infrastructure/Data/Config/InMemoryEShopIdentityDbBootrapper.cs @@ -0,0 +1,17 @@ +using Microsoft.EntityFrameworkCore; +using Microsoft.Extensions.Configuration; +using Microsoft.Extensions.DependencyInjection; +using Nethereum.eShop.ApplicationCore.Interfaces; +using Nethereum.eShop.Infrastructure.Identity; + +namespace Nethereum.eShop.InMemory.Infrastructure.Data.Config +{ + public class InMemoryEShopIdentityDbBootrapper : IEShopIdentityDbBootstrapper + { + public void AddDbContext(IServiceCollection services, IConfiguration configuration) + { + services.AddDbContext(options => + options.UseInMemoryDatabase("Identity")); + } + } +} diff --git a/src/Nethereum.eShop.InMemory/Nethereum.eShop.InMemory.csproj b/src/Nethereum.eShop.InMemory/Nethereum.eShop.InMemory.csproj index e64ae45..87d2b4b 100644 --- a/src/Nethereum.eShop.InMemory/Nethereum.eShop.InMemory.csproj +++ b/src/Nethereum.eShop.InMemory/Nethereum.eShop.InMemory.csproj @@ -5,6 +5,7 @@ + diff --git a/src/Nethereum.eShop.SqlServer/Nethereum.eShop.SqlServer.csproj b/src/Nethereum.eShop.SqlServer/Nethereum.eShop.SqlServer.csproj index a3b5bab..8844c00 100644 --- a/src/Nethereum.eShop.SqlServer/Nethereum.eShop.SqlServer.csproj +++ b/src/Nethereum.eShop.SqlServer/Nethereum.eShop.SqlServer.csproj @@ -26,6 +26,7 @@ + diff --git a/src/Nethereum.eShop.sln b/src/Nethereum.eShop.sln index 164416f..5f3a237 100644 --- a/src/Nethereum.eShop.sln +++ b/src/Nethereum.eShop.sln @@ -23,7 +23,15 @@ Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "WebJobs", "WebJobs\WebJobs. EndProject Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Nethereum.eShop.SqlServer", "Nethereum.eShop.SqlServer\Nethereum.eShop.SqlServer.csproj", "{658EAD99-D587-4105-9743-8DF2722858EA}" EndProject -Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Nethereum.eShop.InMemory", "Nethereum.eShop.InMemory\Nethereum.eShop.InMemory.csproj", "{D7C0A1E5-3867-46AE-86F3-1436E514001B}" +Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Nethereum.eShop.InMemory", "Nethereum.eShop.InMemory\Nethereum.eShop.InMemory.csproj", "{D7C0A1E5-3867-46AE-86F3-1436E514001B}" +EndProject +Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Nethereum.eShop.EntityFramework", "Nethereum.eShop.EntityFramework\Nethereum.eShop.EntityFramework.csproj", "{EEE22A14-93DE-4F3D-BE2F-748F40CD2706}" +EndProject +Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "data", "data", "{8ABF2EF8-3DBE-4F90-A681-9CBAF211EA6D}" +EndProject +Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "core", "core", "{757AB3ED-223F-45A7-8B6F-8BDA2CEB1EA2}" +EndProject +Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "apps", "apps", "{826D820C-C91E-4FBC-804E-1773C372CCA3}" EndProject Global GlobalSection(SolutionConfigurationPlatforms) = preSolution @@ -63,14 +71,24 @@ Global {D7C0A1E5-3867-46AE-86F3-1436E514001B}.Debug|Any CPU.Build.0 = Debug|Any CPU {D7C0A1E5-3867-46AE-86F3-1436E514001B}.Release|Any CPU.ActiveCfg = Release|Any CPU {D7C0A1E5-3867-46AE-86F3-1436E514001B}.Release|Any CPU.Build.0 = Release|Any CPU + {EEE22A14-93DE-4F3D-BE2F-748F40CD2706}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {EEE22A14-93DE-4F3D-BE2F-748F40CD2706}.Debug|Any CPU.Build.0 = Debug|Any CPU + {EEE22A14-93DE-4F3D-BE2F-748F40CD2706}.Release|Any CPU.ActiveCfg = Release|Any CPU + {EEE22A14-93DE-4F3D-BE2F-748F40CD2706}.Release|Any CPU.Build.0 = Release|Any CPU EndGlobalSection GlobalSection(SolutionProperties) = preSolution HideSolutionNode = FALSE EndGlobalSection GlobalSection(NestedProjects) = preSolution + {BA120028-FA8C-4EBD-8F2B-161F0C16A38C} = {757AB3ED-223F-45A7-8B6F-8BDA2CEB1EA2} + {F01D9C50-41B3-4975-AF7C-E6E5D4F24337} = {826D820C-C91E-4FBC-804E-1773C372CCA3} {3A6E7DC1-79B8-41DE-B9AD-A5E60F7C9CA7} = {11EFE1E8-51CF-4528-BC17-545478FE3BD0} {C22EF243-52C6-4976-8ADE-5504B40A37C3} = {5CC42B8D-582C-47C1-814A-E12B75FAC69E} {0281AF81-6DB5-48C4-9137-671D5E95E958} = {5CC42B8D-582C-47C1-814A-E12B75FAC69E} + {C817D513-88E9-4721-A1EA-57EFE0FABCD5} = {826D820C-C91E-4FBC-804E-1773C372CCA3} + {658EAD99-D587-4105-9743-8DF2722858EA} = {8ABF2EF8-3DBE-4F90-A681-9CBAF211EA6D} + {D7C0A1E5-3867-46AE-86F3-1436E514001B} = {8ABF2EF8-3DBE-4F90-A681-9CBAF211EA6D} + {EEE22A14-93DE-4F3D-BE2F-748F40CD2706} = {8ABF2EF8-3DBE-4F90-A681-9CBAF211EA6D} EndGlobalSection GlobalSection(ExtensibilityGlobals) = postSolution SolutionGuid = {8BEA2189-D111-472E-BA29-993E206C6CE3} diff --git a/src/Nethereum.eShop/ApplicationCore/Interfaces/IBasketRepository.cs b/src/Nethereum.eShop/ApplicationCore/Interfaces/IBasketRepository.cs index 6e30df8..ffadfbe 100644 --- a/src/Nethereum.eShop/ApplicationCore/Interfaces/IBasketRepository.cs +++ b/src/Nethereum.eShop/ApplicationCore/Interfaces/IBasketRepository.cs @@ -1,5 +1,4 @@ using Nethereum.eShop.ApplicationCore.Entities.BasketAggregate; -using Nethereum.eShop.Infrastructure.Data; using System.Threading.Tasks; namespace Nethereum.eShop.ApplicationCore.Interfaces diff --git a/src/Nethereum.eShop/ApplicationCore/Interfaces/ICatalogContextSeeder.cs b/src/Nethereum.eShop/ApplicationCore/Interfaces/ICatalogContextSeeder.cs new file mode 100644 index 0000000..4f73df9 --- /dev/null +++ b/src/Nethereum.eShop/ApplicationCore/Interfaces/ICatalogContextSeeder.cs @@ -0,0 +1,10 @@ +using Microsoft.Extensions.Logging; +using System.Threading.Tasks; + +namespace Nethereum.eShop.ApplicationCore.Interfaces +{ + public interface ICatalogContextSeeder + { + Task SeedAsync(ILoggerFactory loggerFactory, int? retry = 0); + } +} diff --git a/src/Nethereum.eShop/ApplicationCore/Interfaces/ICatalogItemRepository.cs b/src/Nethereum.eShop/ApplicationCore/Interfaces/ICatalogItemRepository.cs index 2208923..a550314 100644 --- a/src/Nethereum.eShop/ApplicationCore/Interfaces/ICatalogItemRepository.cs +++ b/src/Nethereum.eShop/ApplicationCore/Interfaces/ICatalogItemRepository.cs @@ -1,5 +1,4 @@ using Nethereum.eShop.ApplicationCore.Entities; -using Nethereum.eShop.Infrastructure.Data; namespace Nethereum.eShop.ApplicationCore.Interfaces { diff --git a/src/Nethereum.eShop/Infrastructure/Data/Config/IEShopDbBootstrapper.cs b/src/Nethereum.eShop/ApplicationCore/Interfaces/IEShopDbBootstrapper.cs similarity index 67% rename from src/Nethereum.eShop/Infrastructure/Data/Config/IEShopDbBootstrapper.cs rename to src/Nethereum.eShop/ApplicationCore/Interfaces/IEShopDbBootstrapper.cs index 2dd5aa3..839d44d 100644 --- a/src/Nethereum.eShop/Infrastructure/Data/Config/IEShopDbBootstrapper.cs +++ b/src/Nethereum.eShop/ApplicationCore/Interfaces/IEShopDbBootstrapper.cs @@ -1,7 +1,7 @@ using Microsoft.Extensions.Configuration; using Microsoft.Extensions.DependencyInjection; -namespace Nethereum.eShop.Infrastructure.Data.Config +namespace Nethereum.eShop.ApplicationCore.Interfaces { public interface IEShopDbBootstrapper { @@ -10,9 +10,4 @@ public interface IEShopDbBootstrapper void AddQueries(IServiceCollection services, IConfiguration configuration); } - - public interface IEShopIdentityDbBootstrapper - { - void AddDbContext(IServiceCollection services, IConfiguration configuration); - } } diff --git a/src/Nethereum.eShop/ApplicationCore/Interfaces/IEShopIdentityDbBootstrapper.cs b/src/Nethereum.eShop/ApplicationCore/Interfaces/IEShopIdentityDbBootstrapper.cs new file mode 100644 index 0000000..e505232 --- /dev/null +++ b/src/Nethereum.eShop/ApplicationCore/Interfaces/IEShopIdentityDbBootstrapper.cs @@ -0,0 +1,10 @@ +using Microsoft.Extensions.Configuration; +using Microsoft.Extensions.DependencyInjection; + +namespace Nethereum.eShop.ApplicationCore.Interfaces +{ + public interface IEShopIdentityDbBootstrapper + { + void AddDbContext(IServiceCollection services, IConfiguration configuration); + } +} diff --git a/src/Nethereum.eShop/ApplicationCore/Interfaces/IOrderRepository.cs b/src/Nethereum.eShop/ApplicationCore/Interfaces/IOrderRepository.cs index 6523427..06e6b60 100644 --- a/src/Nethereum.eShop/ApplicationCore/Interfaces/IOrderRepository.cs +++ b/src/Nethereum.eShop/ApplicationCore/Interfaces/IOrderRepository.cs @@ -1,5 +1,4 @@ using Nethereum.eShop.ApplicationCore.Entities.OrderAggregate; -using Nethereum.eShop.Infrastructure.Data; using System.Threading.Tasks; namespace Nethereum.eShop.ApplicationCore.Interfaces diff --git a/src/Nethereum.eShop/ApplicationCore/Interfaces/IQuoteRepository.cs b/src/Nethereum.eShop/ApplicationCore/Interfaces/IQuoteRepository.cs index da61b2b..9bef1ce 100644 --- a/src/Nethereum.eShop/ApplicationCore/Interfaces/IQuoteRepository.cs +++ b/src/Nethereum.eShop/ApplicationCore/Interfaces/IQuoteRepository.cs @@ -1,5 +1,4 @@ using Nethereum.eShop.ApplicationCore.Entities.QuoteAggregate; -using Nethereum.eShop.Infrastructure.Data; using System.Collections.Generic; using System.Threading.Tasks; diff --git a/src/Nethereum.eShop/Infrastructure/Data/IRepository.cs b/src/Nethereum.eShop/ApplicationCore/Interfaces/IRepository.cs similarity index 61% rename from src/Nethereum.eShop/Infrastructure/Data/IRepository.cs rename to src/Nethereum.eShop/ApplicationCore/Interfaces/IRepository.cs index 357f4dc..1c81032 100644 --- a/src/Nethereum.eShop/Infrastructure/Data/IRepository.cs +++ b/src/Nethereum.eShop/ApplicationCore/Interfaces/IRepository.cs @@ -1,4 +1,4 @@ -namespace Nethereum.eShop.Infrastructure.Data +namespace Nethereum.eShop.ApplicationCore.Interfaces { public interface IRepository { diff --git a/src/Nethereum.eShop/Infrastructure/IUnitOfWork.cs b/src/Nethereum.eShop/ApplicationCore/Interfaces/IUnitOfWork.cs similarity index 86% rename from src/Nethereum.eShop/Infrastructure/IUnitOfWork.cs rename to src/Nethereum.eShop/ApplicationCore/Interfaces/IUnitOfWork.cs index 9fe72d0..5daa1fa 100644 --- a/src/Nethereum.eShop/Infrastructure/IUnitOfWork.cs +++ b/src/Nethereum.eShop/ApplicationCore/Interfaces/IUnitOfWork.cs @@ -2,7 +2,7 @@ using System.Threading; using System.Threading.Tasks; -namespace Nethereum.eShop.Infrastructure +namespace Nethereum.eShop.ApplicationCore.Interfaces { public interface IUnitOfWork : IDisposable { diff --git a/src/Nethereum.eShop/Infrastructure/Data/ICatalogContextSeeder.cs b/src/Nethereum.eShop/Infrastructure/Data/ICatalogContextSeeder.cs deleted file mode 100644 index cbe5aa9..0000000 --- a/src/Nethereum.eShop/Infrastructure/Data/ICatalogContextSeeder.cs +++ /dev/null @@ -1,10 +0,0 @@ -using Microsoft.Extensions.Logging; -using System.Threading.Tasks; - -namespace Nethereum.eShop.Infrastructure.Data -{ - public interface ICatalogContextSeeder - { - Task SeedAsync(CatalogContext catalogContext, ILoggerFactory loggerFactory, int? retry = 0); - } -} diff --git a/src/Nethereum.eShop/Nethereum.eShop.csproj b/src/Nethereum.eShop/Nethereum.eShop.csproj index 4f36434..f0370e0 100644 --- a/src/Nethereum.eShop/Nethereum.eShop.csproj +++ b/src/Nethereum.eShop/Nethereum.eShop.csproj @@ -19,10 +19,6 @@
- - - - diff --git a/src/Web/Program.cs b/src/Web/Program.cs index 5dcb5e8..05c3fa2 100644 --- a/src/Web/Program.cs +++ b/src/Web/Program.cs @@ -7,6 +7,7 @@ using Microsoft.Extensions.Logging; using System; using System.Threading.Tasks; +using Nethereum.eShop.ApplicationCore.Interfaces; namespace Nethereum.eShop.Web { @@ -24,9 +25,8 @@ public async static Task Main(string[] args) var loggerFactory = services.GetRequiredService(); try { - var catalogContext = services.GetRequiredService(); var catalogContextSeeder = services.GetRequiredService(); - await catalogContextSeeder.SeedAsync(catalogContext, loggerFactory); + await catalogContextSeeder.SeedAsync(loggerFactory); var userManager = services.GetRequiredService>(); var roleManager = services.GetRequiredService>(); diff --git a/src/Web/Startup.cs b/src/Web/Startup.cs index 8feb5df..947fa41 100644 --- a/src/Web/Startup.cs +++ b/src/Web/Startup.cs @@ -6,7 +6,6 @@ using Microsoft.AspNetCore.Http; using Microsoft.AspNetCore.Identity; using Microsoft.AspNetCore.Mvc.ApplicationModels; -using Microsoft.EntityFrameworkCore; using Microsoft.Extensions.Configuration; using Microsoft.Extensions.DependencyInjection; using Microsoft.Extensions.Diagnostics.HealthChecks; @@ -15,11 +14,10 @@ using Nethereum.eShop.ApplicationCore.Services; using Nethereum.eShop.Infrastructure.Data; using Nethereum.eShop.Infrastructure.Data.Config; -using Nethereum.eShop.Infrastructure.Data.Config.EntityBuilders; using Nethereum.eShop.Infrastructure.Identity; using Nethereum.eShop.Infrastructure.Logging; using Nethereum.eShop.Infrastructure.Services; -using Nethereum.eShop.InMemory; +using Nethereum.eShop.InMemory.Infrastructure.Data.Config; using Nethereum.eShop.SqlServer.Infrastructure.Data.Config; using Nethereum.eShop.Web.Interfaces; using Nethereum.eShop.Web.Services; @@ -128,14 +126,18 @@ public void ConfigureServices( services.Configure(Configuration); var catalogSettings = Configuration.Get(); + services.AddSingleton(catalogSettings); services.AddSingleton(new UriComposer(catalogSettings)); - var catalogContextSeeder = string.IsNullOrEmpty(catalogSettings.CatalogSeedJsonFile) ? - (ICatalogContextSeeder)new HardCodedCatalogContextSeeder() : - (ICatalogContextSeeder)new JsonCatalogContextSeeder(catalogSettings.CatalogSeedJsonFile); - - services.AddSingleton(catalogContextSeeder); + if(string.IsNullOrEmpty(catalogSettings.CatalogSeedJsonFile)) + { + services.AddScoped(); + } + else + { + services.AddScoped(); + } var rulesEngineSettings = Configuration.Get(); diff --git a/src/Web/Web.csproj b/src/Web/Web.csproj index 535f53b..1dfeca3 100644 --- a/src/Web/Web.csproj +++ b/src/Web/Web.csproj @@ -39,6 +39,7 @@ + diff --git a/src/WebJobs/Program.cs b/src/WebJobs/Program.cs index 10cc038..d52b92b 100644 --- a/src/WebJobs/Program.cs +++ b/src/WebJobs/Program.cs @@ -3,17 +3,12 @@ using Microsoft.Extensions.DependencyInjection; using Microsoft.Extensions.Hosting; using Microsoft.Extensions.Logging; -using Nethereum.BlockchainProcessing.BlockStorage.Entities; using Nethereum.BlockchainProcessing.ProgressRepositories; -using Nethereum.BlockchainStore.EFCore; -using Nethereum.BlockchainStore.EFCore.Repositories; -using Nethereum.BlockchainStore.EFCore.SqlServer; using Nethereum.eShop.ApplicationCore.Interfaces; using Nethereum.eShop.ApplicationCore.Services; using Nethereum.eShop.Infrastructure.Data; using Nethereum.eShop.WebJobs.Configuration; using Nethereum.eShop.WebJobs.Jobs; -using System; namespace Nethereum.eShop.WebJobs { diff --git a/src/WebJobs/WebJobs.csproj b/src/WebJobs/WebJobs.csproj index 372866b..6957acd 100644 --- a/src/WebJobs/WebJobs.csproj +++ b/src/WebJobs/WebJobs.csproj @@ -23,6 +23,7 @@ + From 9f6b06a6c9fb33060d67980e16d6ac4535d6e359 Mon Sep 17 00:00:00 2001 From: Dave Whiffin Date: Tue, 10 Mar 2020 12:38:32 +0000 Subject: [PATCH 10/27] Sqlite Implementation Working --- ...> InMemoryEShopAppIdentityDbBootrapper.cs} | 6 +- .../Data/Config/InMemoryEShopDbBootrapper.cs | 4 + ...SqlServerEShopAppIdentityDbBootstrapper.cs | 25 ++++++ .../Config/SqlServerEShopDbBootstrapper.cs | 12 ++- .../Queries/Catalog/CatalogQueries.cs | 73 ++++++++++++++++++ .../Queries/Orders/OrderQueries.cs | 76 +++++++++++++++++++ .../Queries/Quotes/QuoteQueries.cs | 76 +++++++++++++++++++ .../DateTimeOffsetHandler.cs | 25 ++++++ .../SqliteEShopAppIdentityDbBootstrapper.cs | 29 +++++++ .../Data/Config/SqliteEShopDbBootstrapper.cs | 46 +++++++++++ .../Nethereum.eShop.Sqlite.csproj | 19 +++++ src/Nethereum.eShop.sln | 7 ++ .../Interfaces/IEShopDbBootstrapper.cs | 4 + .../IEShopIdentityDbBootstrapper.cs | 4 + src/Web/Program.cs | 3 + src/Web/Startup.cs | 31 ++++++-- src/Web/Web.csproj | 1 + src/Web/appsettings.json | 3 + 18 files changed, 431 insertions(+), 13 deletions(-) rename src/Nethereum.eShop.InMemory/Infrastructure/Data/Config/{InMemoryEShopIdentityDbBootrapper.cs => InMemoryEShopAppIdentityDbBootrapper.cs} (70%) create mode 100644 src/Nethereum.eShop.SqlServer/Infrastructure/Data/Config/SqlServerEShopAppIdentityDbBootstrapper.cs create mode 100644 src/Nethereum.eShop.Sqlite/ApplicationCore/Queries/Catalog/CatalogQueries.cs create mode 100644 src/Nethereum.eShop.Sqlite/ApplicationCore/Queries/Orders/OrderQueries.cs create mode 100644 src/Nethereum.eShop.Sqlite/ApplicationCore/Queries/Quotes/QuoteQueries.cs create mode 100644 src/Nethereum.eShop.Sqlite/DateTimeOffsetHandler.cs create mode 100644 src/Nethereum.eShop.Sqlite/Infrastructure/Data/Config/SqliteEShopAppIdentityDbBootstrapper.cs create mode 100644 src/Nethereum.eShop.Sqlite/Infrastructure/Data/Config/SqliteEShopDbBootstrapper.cs create mode 100644 src/Nethereum.eShop.Sqlite/Nethereum.eShop.Sqlite.csproj diff --git a/src/Nethereum.eShop.InMemory/Infrastructure/Data/Config/InMemoryEShopIdentityDbBootrapper.cs b/src/Nethereum.eShop.InMemory/Infrastructure/Data/Config/InMemoryEShopAppIdentityDbBootrapper.cs similarity index 70% rename from src/Nethereum.eShop.InMemory/Infrastructure/Data/Config/InMemoryEShopIdentityDbBootrapper.cs rename to src/Nethereum.eShop.InMemory/Infrastructure/Data/Config/InMemoryEShopAppIdentityDbBootrapper.cs index bf03548..4b64c9a 100644 --- a/src/Nethereum.eShop.InMemory/Infrastructure/Data/Config/InMemoryEShopIdentityDbBootrapper.cs +++ b/src/Nethereum.eShop.InMemory/Infrastructure/Data/Config/InMemoryEShopAppIdentityDbBootrapper.cs @@ -3,15 +3,19 @@ using Microsoft.Extensions.DependencyInjection; using Nethereum.eShop.ApplicationCore.Interfaces; using Nethereum.eShop.Infrastructure.Identity; +using System; +using System.Threading.Tasks; namespace Nethereum.eShop.InMemory.Infrastructure.Data.Config { - public class InMemoryEShopIdentityDbBootrapper : IEShopIdentityDbBootstrapper + public class InMemoryEShopAppIdentityDbBootrapper : IEShopIdentityDbBootstrapper { public void AddDbContext(IServiceCollection services, IConfiguration configuration) { services.AddDbContext(options => options.UseInMemoryDatabase("Identity")); } + + public Task EnsureCreatedAsync(IServiceProvider serviceProvider) => Task.CompletedTask; } } diff --git a/src/Nethereum.eShop.InMemory/Infrastructure/Data/Config/InMemoryEShopDbBootrapper.cs b/src/Nethereum.eShop.InMemory/Infrastructure/Data/Config/InMemoryEShopDbBootrapper.cs index 1d732c3..abaee18 100644 --- a/src/Nethereum.eShop.InMemory/Infrastructure/Data/Config/InMemoryEShopDbBootrapper.cs +++ b/src/Nethereum.eShop.InMemory/Infrastructure/Data/Config/InMemoryEShopDbBootrapper.cs @@ -11,6 +11,8 @@ using Nethereum.eShop.InMemory.ApplicationCore.Queries.Catalog; using Nethereum.eShop.InMemory.ApplicationCore.Queries.Orders; using Nethereum.eShop.InMemory.ApplicationCore.Queries.Quotes; +using System; +using System.Threading.Tasks; namespace Nethereum.eShop.InMemory.Infrastructure.Data.Config { @@ -32,5 +34,7 @@ public void AddQueries(IServiceCollection services, IConfiguration configuration services.AddScoped(); services.AddScoped(); } + + public Task EnsureCreatedAsync(IServiceProvider serviceProvider) => Task.CompletedTask; } } diff --git a/src/Nethereum.eShop.SqlServer/Infrastructure/Data/Config/SqlServerEShopAppIdentityDbBootstrapper.cs b/src/Nethereum.eShop.SqlServer/Infrastructure/Data/Config/SqlServerEShopAppIdentityDbBootstrapper.cs new file mode 100644 index 0000000..47a9126 --- /dev/null +++ b/src/Nethereum.eShop.SqlServer/Infrastructure/Data/Config/SqlServerEShopAppIdentityDbBootstrapper.cs @@ -0,0 +1,25 @@ +using Microsoft.EntityFrameworkCore; +using Microsoft.Extensions.Configuration; +using Microsoft.Extensions.DependencyInjection; +using Nethereum.eShop.ApplicationCore.Interfaces; +using Nethereum.eShop.Infrastructure.Identity; +using System; +using System.Threading.Tasks; + +namespace Nethereum.eShop.SqlServer.Infrastructure.Data.Config +{ + public class SqlServerEShopAppIdentityDbBootstrapper : IEShopIdentityDbBootstrapper + { + public void AddDbContext(IServiceCollection services, IConfiguration configuration) + { + services.AddDbContext(options => + options.UseSqlServer(configuration.GetConnectionString("IdentityConnection"))); + } + + public Task EnsureCreatedAsync(IServiceProvider serviceProvider) + { + //TODO: implement migrations + return Task.CompletedTask; + } + } +} diff --git a/src/Nethereum.eShop.SqlServer/Infrastructure/Data/Config/SqlServerEShopDbBootstrapper.cs b/src/Nethereum.eShop.SqlServer/Infrastructure/Data/Config/SqlServerEShopDbBootstrapper.cs index e6ebff6..8524549 100644 --- a/src/Nethereum.eShop.SqlServer/Infrastructure/Data/Config/SqlServerEShopDbBootstrapper.cs +++ b/src/Nethereum.eShop.SqlServer/Infrastructure/Data/Config/SqlServerEShopDbBootstrapper.cs @@ -7,7 +7,8 @@ using Nethereum.eShop.ApplicationCore.Queries.Quotes; using Nethereum.eShop.Infrastructure.Data; using Nethereum.eShop.Infrastructure.Data.Config; -using Nethereum.eShop.Infrastructure.Identity; +using System; +using System.Threading.Tasks; namespace Nethereum.eShop.SqlServer.Infrastructure.Data.Config { @@ -33,14 +34,11 @@ public void AddQueries(IServiceCollection services, IConfiguration configuration services.AddSingleton(new OrderQueries(queryConnectionString)); services.AddSingleton(new CatalogQueries(queryConnectionString)); } - } - public class SqlServerEShopAppIdentityDbBootstrapper : IEShopIdentityDbBootstrapper - { - public void AddDbContext(IServiceCollection services, IConfiguration configuration) + public Task EnsureCreatedAsync(IServiceProvider serviceProvider) { - services.AddDbContext(options => - options.UseSqlServer(configuration.GetConnectionString("IdentityConnection"))); + //TODO: Configure migrations etc + return Task.CompletedTask; } } } diff --git a/src/Nethereum.eShop.Sqlite/ApplicationCore/Queries/Catalog/CatalogQueries.cs b/src/Nethereum.eShop.Sqlite/ApplicationCore/Queries/Catalog/CatalogQueries.cs new file mode 100644 index 0000000..620529e --- /dev/null +++ b/src/Nethereum.eShop.Sqlite/ApplicationCore/Queries/Catalog/CatalogQueries.cs @@ -0,0 +1,73 @@ +using Dapper; +using Microsoft.Data.Sqlite; +using Nethereum.eShop.ApplicationCore.Queries; +using Nethereum.eShop.ApplicationCore.Queries.Catalog; +using System; +using System.Data; +using System.Linq; +using System.Threading.Tasks; + +namespace Nethereum.eShop.Sqlite.ApplicationCore.Queries.Catalog +{ + public class CatalogQueries : ICatalogQueries + { + private readonly string _connectionString; + + public CatalogQueries(string connectionString) + { + _connectionString = connectionString ?? throw new ArgumentNullException(nameof(connectionString)); + } + + private static string[] SortByColumns = new[] { "Rank" }; + public async Task> GetCatalogItemsAsync(GetCatalogItemsSpecification catalogQuerySpecification) + { + string sortOrder = catalogQuerySpecification.SortDescending ? "desc" : "asc"; + catalogQuerySpecification.SortBy = catalogQuerySpecification.SortBy ?? "Rank"; + + if (!SortByColumns.Contains(catalogQuerySpecification.SortBy)) throw new ArgumentException(nameof(catalogQuerySpecification.SortBy)); + + using (var connection = new SqliteConnection(_connectionString)) + { + connection.Open(); + + var parameters = new DynamicParameters(); + parameters.Add("@searchText", catalogQuerySpecification.SearchText); + parameters.Add("@brandId", catalogQuerySpecification.BrandId); + parameters.Add("@typeId", catalogQuerySpecification.TypeId); + parameters.Add("@offset", catalogQuerySpecification.Offset); + parameters.Add("@fetch", catalogQuerySpecification.Fetch); + + + + var dbResults = await connection.QueryMultipleAsync( +@$" + SELECT Count(1) FROM Catalog c + INNER JOIN CatalogBrands b ON c.CatalogBrandId = b.Id + INNER JOIN CatalogTypes t ON c.CatalogTypeId = t.Id + WHERE + (@brandId IS NULL OR (b.Id = @brandId)) AND + (@typeId IS NULL OR (t.Id = @typeId)) AND + (@searchText IS NULL OR ((c.[Name] LIKE '%' + @searchText + '%')) OR (b.Brand LIKE '%' + @searchText + '%')); + + SELECT c.Id, c.[Name], c.CatalogBrandId, b.[Brand], c.CatalogTypeId, t.[Type], c.PictureUri, CAST(c.Price AS REAL) AS Price, c.[Rank] + FROM Catalog c + INNER JOIN CatalogBrands b ON c.CatalogBrandId = b.Id + INNER JOIN CatalogTypes t ON c.CatalogTypeId = t.Id + WHERE + (@brandId IS NULL OR (b.Id = @brandId)) AND + (@typeId IS NULL OR (t.Id = @typeId)) AND + (@searchText IS NULL OR ((c.[Name] LIKE '%' + @searchText + '%')) OR (b.Brand LIKE '%' + @searchText + '%')) + ORDER BY [{catalogQuerySpecification.SortBy}] {sortOrder} + LIMIT @fetch OFFSET @offset; +" + , parameters + ); + + var totalCount = dbResults.Read().Single(); + var rows = dbResults.Read(); + + return new PaginatedResult(totalCount, rows, catalogQuerySpecification); + } + } + } +} diff --git a/src/Nethereum.eShop.Sqlite/ApplicationCore/Queries/Orders/OrderQueries.cs b/src/Nethereum.eShop.Sqlite/ApplicationCore/Queries/Orders/OrderQueries.cs new file mode 100644 index 0000000..49c5947 --- /dev/null +++ b/src/Nethereum.eShop.Sqlite/ApplicationCore/Queries/Orders/OrderQueries.cs @@ -0,0 +1,76 @@ +using Dapper; +using Microsoft.Data.Sqlite; +using Nethereum.eShop.ApplicationCore.Queries; +using Nethereum.eShop.ApplicationCore.Queries.Orders; +using System; +using System.Data; +using System.Linq; +using System.Threading.Tasks; + +namespace Nethereum.eShop.Sqlite.ApplicationCore.Queries.Orders +{ + public class OrderQueries: IOrderQueries + { + private readonly string _connectionString; + + public OrderQueries(string connectionString) + { + _connectionString = connectionString ?? throw new ArgumentNullException(nameof(connectionString)); + } + + private static string[] SortByColumns = new[] { "Id", "Status" }; + + public async Task> GetByBuyerIdAsync(string buyerId, PaginationArgs paginationArgs) + { + paginationArgs.SortBy = paginationArgs.SortBy ?? "Id"; + + if (!SortByColumns.Contains(paginationArgs.SortBy)) throw new ArgumentException(nameof(paginationArgs.SortBy)); + + using (var connection = new SqliteConnection(_connectionString)) + { + connection.Open(); + + var parameters = new DynamicParameters(); + parameters.Add("@buyerId", buyerId); + parameters.Add("@offset", paginationArgs.Offset); + parameters.Add("@fetch", paginationArgs.Fetch); + + string sortOrder = paginationArgs.SortDescending ? "desc" : "asc"; + + var dbResults = await connection.QueryMultipleAsync( +@$" +SELECT COUNT(1) FROM [Orders] as o WHERE o.BuyerId = @buyerId; +SELECT + o.Id as OrderId, + o.QuoteId as QuoteId, + o.BuyerAddress, + o.BuyerId, + o.TransactionHash, + o.OrderDate, + o.Status, + o.PoNumber, + o.PoType, + o.CurrencySymbol, + o.[BillTo_RecipientName], + o.[BillTo_ZipCode], + o.[ShipTo_RecipientName], + o.[ShipTo_ZipCode], + CAST((select sum(oi.Quantity * oi.UnitPrice) from OrderItems oi where oi.OrderId = o.Id) AS REAL) as Total, + CAST((select count(1) from OrderItems oi where oi.OrderId = o.Id) AS REAL) as ItemCount +FROM [Orders] as o +WHERE o.BuyerId = @buyerId +ORDER BY [{paginationArgs.SortBy}] {sortOrder} +LIMIT @fetch OFFSET @offset; +" + , parameters + ); + + var totalCount = dbResults.Read().First(); + var rows = dbResults.Read(); + + return new PaginatedResult(totalCount, rows, paginationArgs); + } + } + + } +} diff --git a/src/Nethereum.eShop.Sqlite/ApplicationCore/Queries/Quotes/QuoteQueries.cs b/src/Nethereum.eShop.Sqlite/ApplicationCore/Queries/Quotes/QuoteQueries.cs new file mode 100644 index 0000000..0056b1e --- /dev/null +++ b/src/Nethereum.eShop.Sqlite/ApplicationCore/Queries/Quotes/QuoteQueries.cs @@ -0,0 +1,76 @@ +using Dapper; +using Microsoft.Data.Sqlite; +using Nethereum.eShop.ApplicationCore.Queries; +using Nethereum.eShop.ApplicationCore.Queries.Quotes; +using System; +using System.Data; +using System.Linq; +using System.Threading.Tasks; + +namespace Nethereum.eShop.Sqlite.ApplicationCore.Queries.Quotes +{ + public class QuoteQueries: IQuoteQueries + { + private readonly string _connectionString; + + public QuoteQueries(string connectionString) + { + _connectionString = connectionString ?? throw new ArgumentNullException(nameof(connectionString)); + } + + private static string[] SortByColumns = new[] { "Id", "Status" }; + + public async Task> GetByBuyerIdAsync(string buyerId, PaginationArgs paginationArgs) + { + paginationArgs.SortBy = paginationArgs.SortBy ?? "Id"; + + if (!SortByColumns.Contains(paginationArgs.SortBy)) throw new ArgumentException(nameof(paginationArgs.SortBy)); + + using (var connection = new SqliteConnection(_connectionString)) + { + connection.Open(); + + var parameters = new DynamicParameters(); + parameters.Add("@buyerId", buyerId); + parameters.Add("@offset", paginationArgs.Offset); + parameters.Add("@fetch", paginationArgs.Fetch); + + string sortOrder = paginationArgs.SortDescending ? "desc" : "asc"; + + var dbResults = await connection.QueryMultipleAsync( +@$" +SELECT COUNT(1) FROM Quotes as q WHERE q.BuyerId = @buyerId; +SELECT + q.Id as QuoteId, + q.BuyerAddress, + q.BuyerId, + q.TransactionHash, + q.Date as QuoteDate, + q.Status, + q.PoNumber, + q.PoType, + q.CurrencySymbol, + q.Expiry, + q.[BillTo_RecipientName], + q.[BillTo_ZipCode], + q.[ShipTo_RecipientName], + q.[ShipTo_ZipCode], + CAST((select sum(qi.Quantity * qi.UnitPrice) from QuoteItems qi where qi.QuoteId = q.Id) AS REAL) as Total, + CAST((select count(1) from QuoteItems qi where qi.QuoteId = q.Id) AS REAL) as ItemCount +FROM Quotes as q +WHERE q.BuyerId = @buyerId +ORDER BY [{paginationArgs.SortBy}] {sortOrder} +LIMIT @fetch OFFSET @offset; +" + , parameters + ); + + var totalCount = dbResults.Read().First(); + var rows = dbResults.Read(); + + return new PaginatedResult(totalCount, rows, paginationArgs); + } + } + + } +} diff --git a/src/Nethereum.eShop.Sqlite/DateTimeOffsetHandler.cs b/src/Nethereum.eShop.Sqlite/DateTimeOffsetHandler.cs new file mode 100644 index 0000000..ef38f0a --- /dev/null +++ b/src/Nethereum.eShop.Sqlite/DateTimeOffsetHandler.cs @@ -0,0 +1,25 @@ +using Dapper; +using System; +using System.Data; + +namespace Nethereum.eShop.Sqlite +{ + public class DateTimeOffsetHandler : SqlMapper.TypeHandler + { + public static readonly DateTimeOffsetHandler Instance = new DateTimeOffsetHandler(); + + public override DateTimeOffset Parse(object value) + { + //2020-03-10 12:16:08.4610707+00:00 + return DateTimeOffset.TryParse((string)value, out DateTimeOffset date) ? date : DateTimeOffset.MinValue; + } + + public override void SetValue(IDbDataParameter parameter, DateTimeOffset value) + { + //2020-03-10 12:16:08.4610707+00:00 + //somewhat naive and optimistic approach! + //we're not yet implementing datetimeoffset parameters in queries + parameter.Value = value.ToString(); + } + } +} diff --git a/src/Nethereum.eShop.Sqlite/Infrastructure/Data/Config/SqliteEShopAppIdentityDbBootstrapper.cs b/src/Nethereum.eShop.Sqlite/Infrastructure/Data/Config/SqliteEShopAppIdentityDbBootstrapper.cs new file mode 100644 index 0000000..474fab8 --- /dev/null +++ b/src/Nethereum.eShop.Sqlite/Infrastructure/Data/Config/SqliteEShopAppIdentityDbBootstrapper.cs @@ -0,0 +1,29 @@ +using Dapper; +using Microsoft.EntityFrameworkCore; +using Microsoft.Extensions.Configuration; +using Microsoft.Extensions.DependencyInjection; +using Nethereum.eShop.ApplicationCore.Interfaces; +using Nethereum.eShop.Infrastructure.Identity; +using System; +using System.Threading.Tasks; + +namespace Nethereum.eShop.Sqlite.Infrastructure.Data.Config +{ + public class SqliteEShopAppIdentityDbBootstrapper : IEShopIdentityDbBootstrapper + { + public void AddDbContext(IServiceCollection services, IConfiguration configuration) + { + SqlMapper.RemoveTypeMap(typeof(DateTimeOffset)); + SqlMapper.AddTypeHandler(DateTimeOffsetHandler.Instance); + + services.AddDbContext(options => + options.UseSqlite(configuration.GetConnectionString("IdentityConnection"))); + } + + public Task EnsureCreatedAsync(IServiceProvider serviceProvider) + { + var context = serviceProvider.GetRequiredService(); + return context.Database.EnsureCreatedAsync(); + } + } +} diff --git a/src/Nethereum.eShop.Sqlite/Infrastructure/Data/Config/SqliteEShopDbBootstrapper.cs b/src/Nethereum.eShop.Sqlite/Infrastructure/Data/Config/SqliteEShopDbBootstrapper.cs new file mode 100644 index 0000000..36e43bc --- /dev/null +++ b/src/Nethereum.eShop.Sqlite/Infrastructure/Data/Config/SqliteEShopDbBootstrapper.cs @@ -0,0 +1,46 @@ +using Microsoft.EntityFrameworkCore; +using Microsoft.Extensions.Configuration; +using Microsoft.Extensions.DependencyInjection; +using Nethereum.eShop.ApplicationCore.Interfaces; +using Nethereum.eShop.ApplicationCore.Queries.Catalog; +using Nethereum.eShop.ApplicationCore.Queries.Orders; +using Nethereum.eShop.ApplicationCore.Queries.Quotes; +using Nethereum.eShop.Infrastructure.Data; +using Nethereum.eShop.Infrastructure.Data.Config; +using Nethereum.eShop.Sqlite.ApplicationCore.Queries.Catalog; +using Nethereum.eShop.Sqlite.ApplicationCore.Queries.Orders; +using Nethereum.eShop.Sqlite.ApplicationCore.Queries.Quotes; +using System; +using System.Threading.Tasks; + +namespace Nethereum.eShop.Sqlite.Infrastructure.Data.Config +{ + public class SqliteEShopDbBootstrapper : EShopDbBootstrapperBase, IEShopDbBootstrapper + { + private const string ConnectionName = "CatalogConnection"; + + public void AddDbContext(IServiceCollection services, IConfiguration configuration) + { + services.AddDbContext((serviceProvider, options) => + options.UseSqlite(configuration.GetConnectionString(ConnectionName))); + + // Point the CatalogContext at this assembly for the Model Builder Configurations + services.AddSingleton>( + new ModelBuilderAssemblyHandler(typeof(CatalogContext).Assembly)); + } + + public void AddQueries(IServiceCollection services, IConfiguration configuration) + { + string queryConnectionString = configuration.GetConnectionString(ConnectionName); + services.AddSingleton(new QuoteQueries(queryConnectionString)); + services.AddSingleton(new OrderQueries(queryConnectionString)); + services.AddSingleton(new CatalogQueries(queryConnectionString)); + } + + public Task EnsureCreatedAsync(IServiceProvider serviceProvider) + { + var context = serviceProvider.GetRequiredService(); + return context.Database.EnsureCreatedAsync(); + } + } +} diff --git a/src/Nethereum.eShop.Sqlite/Nethereum.eShop.Sqlite.csproj b/src/Nethereum.eShop.Sqlite/Nethereum.eShop.Sqlite.csproj new file mode 100644 index 0000000..1ee9ae0 --- /dev/null +++ b/src/Nethereum.eShop.Sqlite/Nethereum.eShop.Sqlite.csproj @@ -0,0 +1,19 @@ + + + + netstandard2.1 + + + + + + + + + + + + + + + diff --git a/src/Nethereum.eShop.sln b/src/Nethereum.eShop.sln index 5f3a237..6da9230 100644 --- a/src/Nethereum.eShop.sln +++ b/src/Nethereum.eShop.sln @@ -33,6 +33,8 @@ Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "core", "core", "{757AB3ED-2 EndProject Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "apps", "apps", "{826D820C-C91E-4FBC-804E-1773C372CCA3}" EndProject +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Nethereum.eShop.Sqlite", "Nethereum.eShop.Sqlite\Nethereum.eShop.Sqlite.csproj", "{2914543B-FDB7-46A0-BB4D-A192765D4072}" +EndProject Global GlobalSection(SolutionConfigurationPlatforms) = preSolution Debug|Any CPU = Debug|Any CPU @@ -75,6 +77,10 @@ Global {EEE22A14-93DE-4F3D-BE2F-748F40CD2706}.Debug|Any CPU.Build.0 = Debug|Any CPU {EEE22A14-93DE-4F3D-BE2F-748F40CD2706}.Release|Any CPU.ActiveCfg = Release|Any CPU {EEE22A14-93DE-4F3D-BE2F-748F40CD2706}.Release|Any CPU.Build.0 = Release|Any CPU + {2914543B-FDB7-46A0-BB4D-A192765D4072}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {2914543B-FDB7-46A0-BB4D-A192765D4072}.Debug|Any CPU.Build.0 = Debug|Any CPU + {2914543B-FDB7-46A0-BB4D-A192765D4072}.Release|Any CPU.ActiveCfg = Release|Any CPU + {2914543B-FDB7-46A0-BB4D-A192765D4072}.Release|Any CPU.Build.0 = Release|Any CPU EndGlobalSection GlobalSection(SolutionProperties) = preSolution HideSolutionNode = FALSE @@ -89,6 +95,7 @@ Global {658EAD99-D587-4105-9743-8DF2722858EA} = {8ABF2EF8-3DBE-4F90-A681-9CBAF211EA6D} {D7C0A1E5-3867-46AE-86F3-1436E514001B} = {8ABF2EF8-3DBE-4F90-A681-9CBAF211EA6D} {EEE22A14-93DE-4F3D-BE2F-748F40CD2706} = {8ABF2EF8-3DBE-4F90-A681-9CBAF211EA6D} + {2914543B-FDB7-46A0-BB4D-A192765D4072} = {8ABF2EF8-3DBE-4F90-A681-9CBAF211EA6D} EndGlobalSection GlobalSection(ExtensibilityGlobals) = postSolution SolutionGuid = {8BEA2189-D111-472E-BA29-993E206C6CE3} diff --git a/src/Nethereum.eShop/ApplicationCore/Interfaces/IEShopDbBootstrapper.cs b/src/Nethereum.eShop/ApplicationCore/Interfaces/IEShopDbBootstrapper.cs index 839d44d..4813861 100644 --- a/src/Nethereum.eShop/ApplicationCore/Interfaces/IEShopDbBootstrapper.cs +++ b/src/Nethereum.eShop/ApplicationCore/Interfaces/IEShopDbBootstrapper.cs @@ -1,5 +1,7 @@ using Microsoft.Extensions.Configuration; using Microsoft.Extensions.DependencyInjection; +using System; +using System.Threading.Tasks; namespace Nethereum.eShop.ApplicationCore.Interfaces { @@ -9,5 +11,7 @@ public interface IEShopDbBootstrapper void AddRepositories(IServiceCollection services, IConfiguration configuration); void AddQueries(IServiceCollection services, IConfiguration configuration); + + Task EnsureCreatedAsync(IServiceProvider serviceProvider); } } diff --git a/src/Nethereum.eShop/ApplicationCore/Interfaces/IEShopIdentityDbBootstrapper.cs b/src/Nethereum.eShop/ApplicationCore/Interfaces/IEShopIdentityDbBootstrapper.cs index e505232..0d2065a 100644 --- a/src/Nethereum.eShop/ApplicationCore/Interfaces/IEShopIdentityDbBootstrapper.cs +++ b/src/Nethereum.eShop/ApplicationCore/Interfaces/IEShopIdentityDbBootstrapper.cs @@ -1,10 +1,14 @@ using Microsoft.Extensions.Configuration; using Microsoft.Extensions.DependencyInjection; +using System; +using System.Threading.Tasks; namespace Nethereum.eShop.ApplicationCore.Interfaces { public interface IEShopIdentityDbBootstrapper { void AddDbContext(IServiceCollection services, IConfiguration configuration); + + Task EnsureCreatedAsync(IServiceProvider serviceProvider); } } diff --git a/src/Web/Program.cs b/src/Web/Program.cs index 05c3fa2..4f8fd13 100644 --- a/src/Web/Program.cs +++ b/src/Web/Program.cs @@ -25,6 +25,9 @@ public async static Task Main(string[] args) var loggerFactory = services.GetRequiredService(); try { + await services.GetRequiredService().EnsureCreatedAsync(services); + await services.GetRequiredService().EnsureCreatedAsync(services); + var catalogContextSeeder = services.GetRequiredService(); await catalogContextSeeder.SeedAsync(loggerFactory); diff --git a/src/Web/Startup.cs b/src/Web/Startup.cs index 947fa41..106892a 100644 --- a/src/Web/Startup.cs +++ b/src/Web/Startup.cs @@ -18,6 +18,7 @@ using Nethereum.eShop.Infrastructure.Logging; using Nethereum.eShop.Infrastructure.Services; using Nethereum.eShop.InMemory.Infrastructure.Data.Config; +using Nethereum.eShop.Sqlite.Infrastructure.Data.Config; using Nethereum.eShop.SqlServer.Infrastructure.Data.Config; using Nethereum.eShop.Web.Interfaces; using Nethereum.eShop.Web.Services; @@ -62,9 +63,11 @@ public void ConfigureDevelopmentServices(IServiceCollection services) private void ConfigureInMemoryDatabases(IServiceCollection services) { IEShopDbBootstrapper dbBootstrapper = new InMemoryEShopDbBootrapper(); + services.AddSingleton(dbBootstrapper); dbBootstrapper.AddDbContext(services, Configuration); - IEShopIdentityDbBootstrapper identityBootstrapper = new InMemoryEShopIdentityDbBootrapper(); + IEShopIdentityDbBootstrapper identityBootstrapper = new InMemoryEShopAppIdentityDbBootrapper(); + services.AddSingleton(identityBootstrapper); identityBootstrapper.AddDbContext(services, Configuration); ConfigureServices(services, dbBootstrapper); @@ -86,9 +89,11 @@ See CreateAndApplyDbMigrations.bat in the root of the Web project */ IEShopDbBootstrapper dbBootstrapper = CreateDbBootstrapper(Configuration); + services.AddSingleton(dbBootstrapper); dbBootstrapper.AddDbContext(services, Configuration); IEShopIdentityDbBootstrapper identityDbBootstrapper = CreateAppIdentityDbBootstrapper(Configuration); + services.AddSingleton(identityDbBootstrapper); identityDbBootstrapper.AddDbContext(services, Configuration); ConfigureServices(services, dbBootstrapper); @@ -185,11 +190,27 @@ public void ConfigureServices( _services = services; // used to debug registered services } - private static IEShopDbBootstrapper CreateDbBootstrapper(IConfiguration configuration) - => new SqlServerEShopDbBootstrapper(); + private static IEShopDbBootstrapper CreateDbBootstrapper(IConfiguration configuration) + { + var name = configuration["CatalogDbProvider"]; + return name switch + { + "SqlServer" => new SqlServerEShopDbBootstrapper(), + "Sqlite" => new SqliteEShopDbBootstrapper(), + _ => new InMemoryEShopDbBootrapper() + }; + } - private static IEShopIdentityDbBootstrapper CreateAppIdentityDbBootstrapper(IConfiguration configuration) - => new SqlServerEShopAppIdentityDbBootstrapper(); + private static IEShopIdentityDbBootstrapper CreateAppIdentityDbBootstrapper(IConfiguration configuration) + { + var name = configuration["CatalogDbProvider"]; + return name switch + { + "SqlServer" => new SqlServerEShopAppIdentityDbBootstrapper(), + "Sqlite" => new SqliteEShopAppIdentityDbBootstrapper(), + _ => new InMemoryEShopAppIdentityDbBootrapper() + }; + } private static void CreateIdentityIfNotCreated(IServiceCollection services) { diff --git a/src/Web/Web.csproj b/src/Web/Web.csproj index 1dfeca3..b8887a9 100644 --- a/src/Web/Web.csproj +++ b/src/Web/Web.csproj @@ -41,6 +41,7 @@ + diff --git a/src/Web/appsettings.json b/src/Web/appsettings.json index e9df41d..37dd66b 100644 --- a/src/Web/appsettings.json +++ b/src/Web/appsettings.json @@ -5,6 +5,9 @@ "CatalogConnection": "Server=localhost;Integrated Security=true;Initial Catalog=eShop;", "IdentityConnection": "Server=localhost;Integrated Security=true;Initial Catalog=eShop;" }, + // SqlServer, Sqlite - if empty defaults to in-memory + "CatalogDbProvider": "SqlServer", + "AppIdentityDbProvider": "SqlServer", "CatalogSeedJsonFile": "../../resources/data/TopRankBooks/ImportData/TopRankBooksForCatalogImport.json", "CatalogBaseUrl": "", "QuoteBizRulesFileUrl": "https://ipfs.infura.io/ipfs/QmXcsGDQthxbGW8C3Sx9r4tV9PGSj4MxJmtXF7dnXN5XUT", From 269b49be440628e64265879506ddff4144c1b64b Mon Sep 17 00:00:00 2001 From: Dave Whiffin Date: Tue, 10 Mar 2020 14:04:37 +0000 Subject: [PATCH 11/27] Common user secrets for web and webjobs --- src/Web/Startup.cs | 1 - src/WebJobs/Program.cs | 43 +++++++++++++++++++++++++----------- src/WebJobs/WebJobs.csproj | 9 ++++++-- src/WebJobs/appsettings.json | 2 +- 4 files changed, 38 insertions(+), 17 deletions(-) diff --git a/src/Web/Startup.cs b/src/Web/Startup.cs index 106892a..889ade9 100644 --- a/src/Web/Startup.cs +++ b/src/Web/Startup.cs @@ -13,7 +13,6 @@ using Nethereum.eShop.ApplicationCore.Interfaces; using Nethereum.eShop.ApplicationCore.Services; using Nethereum.eShop.Infrastructure.Data; -using Nethereum.eShop.Infrastructure.Data.Config; using Nethereum.eShop.Infrastructure.Identity; using Nethereum.eShop.Infrastructure.Logging; using Nethereum.eShop.Infrastructure.Services; diff --git a/src/WebJobs/Program.cs b/src/WebJobs/Program.cs index d52b92b..91fb687 100644 --- a/src/WebJobs/Program.cs +++ b/src/WebJobs/Program.cs @@ -1,4 +1,4 @@ -using Microsoft.EntityFrameworkCore; +using MediatR; using Microsoft.Extensions.Configuration; using Microsoft.Extensions.DependencyInjection; using Microsoft.Extensions.Hosting; @@ -6,7 +6,9 @@ using Nethereum.BlockchainProcessing.ProgressRepositories; using Nethereum.eShop.ApplicationCore.Interfaces; using Nethereum.eShop.ApplicationCore.Services; -using Nethereum.eShop.Infrastructure.Data; +using Nethereum.eShop.InMemory.Infrastructure.Data.Config; +using Nethereum.eShop.Sqlite.Infrastructure.Data.Config; +using Nethereum.eShop.SqlServer.Infrastructure.Data.Config; using Nethereum.eShop.WebJobs.Configuration; using Nethereum.eShop.WebJobs.Jobs; @@ -20,19 +22,23 @@ static void Main(string[] args) EshopConfiguration eShopConfig = null; var hostBuilder = Host.CreateDefaultBuilder(args); - hostBuilder.ConfigureServices(c => + hostBuilder.ConfigureServices(services => { - c.AddDbContext((serviceProvider, options) => - options.UseSqlServer(config.GetConnectionString("CatalogConnection"))); + // TODO: Configure MediatR properly - this is just a place holder + services.AddMediatR(typeof(Program)); // config - c.AddSingleton(eShopConfig); + services.AddSingleton(eShopConfig); + + // db + var dbBootstrapper = CreateDbBootstrapper(config); + dbBootstrapper.AddDbContext(services, config); + + //repositories + dbBootstrapper.AddRepositories(services, config); // supporting services - c.AddScoped(typeof(IAsyncRepository<>), typeof(EfRepository<>)); - c.AddScoped(); - c.AddScoped(); - c.AddScoped(); + services.AddScoped(); // TODO: There's a bug in the BlockProgressRepo // It's using string ordering instead of numeric ordering to get the last block processed @@ -51,11 +57,11 @@ static void Main(string[] args) //} //IBlockProgressRepository progressRepo = new BlockProgressRepository(blockchainDbContextFactory); - c.AddSingleton(); + services.AddSingleton(); // jobs - c.AddScoped(); - c.AddScoped(); + services.AddScoped(); + services.AddScoped(); }); hostBuilder.ConfigureWebJobs(b => @@ -87,5 +93,16 @@ static void Main(string[] args) } } } + + private static IEShopDbBootstrapper CreateDbBootstrapper(IConfiguration configuration) + { + var name = configuration["CatalogDbProvider"]; + return name switch + { + "SqlServer" => new SqlServerEShopDbBootstrapper(), + "Sqlite" => new SqliteEShopDbBootstrapper(), + _ => new InMemoryEShopDbBootrapper() + }; + } } } diff --git a/src/WebJobs/WebJobs.csproj b/src/WebJobs/WebJobs.csproj index 6957acd..3f5f9d5 100644 --- a/src/WebJobs/WebJobs.csproj +++ b/src/WebJobs/WebJobs.csproj @@ -3,12 +3,15 @@ Exe netcoreapp3.1 - Nethereum.Shop.WebJobs Nethereum.eShop.WebJobs - + + + Nethereum.eShop.Web.UserSecrets + + @@ -23,6 +26,8 @@ + + diff --git a/src/WebJobs/appsettings.json b/src/WebJobs/appsettings.json index c6bb43b..936800e 100644 --- a/src/WebJobs/appsettings.json +++ b/src/WebJobs/appsettings.json @@ -3,9 +3,9 @@ // Right click Project and "Manage User Secrets" "ConnectionStrings": { "CatalogConnection": "Server=localhost;Integrated Security=true;Initial Catalog=eShop;", - "IdentityConnection": "Server=localhost;Integrated Security=true;Initial Catalog=eShop;", "BlockchainProcessingProgressDb": "Server=localhost;Integrated Security=true;Initial Catalog=eShopWebJobs;" }, + "CatalogDbProvider": "SqlServer", "AzureWebJobsStorage": "", "EshopConfiguration": { "EthereumRpcUrl": "http://localhost:8545/", From 9e1da7bba7cad6ea2a571f6f7a532a75eee7470a Mon Sep 17 00:00:00 2001 From: Dave Whiffin Date: Tue, 10 Mar 2020 17:30:16 +0000 Subject: [PATCH 12/27] Migration WIP --- .../EShopDbBootstrapper.cs | 36 + .../Nethereum.eShop.DbFactory.csproj | 13 + .../InMemoryEShopAppIdentityDbBootrapper.cs | 3 +- .../Data/Config/InMemoryEShopDbBootrapper.cs | 3 +- .../CreateInitialDbMigration.bat | 3 + ...ethereum.eShop.SqlServer.Migrations.csproj | 19 + .../Program.cs | 12 + ...rverAppIdentityContextDesignTimeFactory.cs | 20 + ...qlServerCatalogContextDesignTimeFactory.cs | 23 + ...SqlServerEShopAppIdentityDbBootstrapper.cs | 7 +- .../Config/SqlServerEShopDbBootstrapper.cs | 7 +- .../20200221124040_InitialCreate.Designer.cs | 931 ----------------- .../20200304170042_ResizeColumns.Designer.cs | 948 ------------------ .../20200304170042_ResizeColumns.cs | 319 ------ .../20200304171630_SetGtinColumnSize.cs | 49 - ...0171921_Catalog_InitialCreate.Designer.cs} | 6 +- ...> 20200310171921_Catalog_InitialCreate.cs} | 42 +- .../Migrations/CatalogContextModelSnapshot.cs | 2 +- ...925_AppIdentity_InitialCreate.Designer.cs} | 8 +- ...200310171925_AppIdentity_InitialCreate.cs} | 4 +- .../AppIdentityDbContextModelSnapshot.cs | 4 +- .../SqliteEShopAppIdentityDbBootstrapper.cs | 5 +- .../Data/Config/SqliteEShopDbBootstrapper.cs | 5 +- src/Nethereum.eShop.sln | 14 + .../Interfaces/IEShopDbBootstrapper.cs | 3 +- .../IEShopIdentityDbBootstrapper.cs | 3 +- src/Web/Startup.cs | 36 +- src/Web/Web.csproj | 5 +- src/WebJobs/WebJobs.csproj | 4 +- 29 files changed, 203 insertions(+), 2331 deletions(-) create mode 100644 src/Nethereum.eShop.DbFactory/EShopDbBootstrapper.cs create mode 100644 src/Nethereum.eShop.DbFactory/Nethereum.eShop.DbFactory.csproj create mode 100644 src/Nethereum.eShop.SqlServer.Migrations/CreateInitialDbMigration.bat create mode 100644 src/Nethereum.eShop.SqlServer.Migrations/Nethereum.eShop.SqlServer.Migrations.csproj create mode 100644 src/Nethereum.eShop.SqlServer.Migrations/Program.cs create mode 100644 src/Nethereum.eShop.SqlServer.Migrations/SqlServerAppIdentityContextDesignTimeFactory.cs create mode 100644 src/Nethereum.eShop.SqlServer.Migrations/SqlServerCatalogContextDesignTimeFactory.cs delete mode 100644 src/Nethereum.eShop.SqlServer/Infrastructure/Data/Migrations/20200221124040_InitialCreate.Designer.cs delete mode 100644 src/Nethereum.eShop.SqlServer/Infrastructure/Data/Migrations/20200304170042_ResizeColumns.Designer.cs delete mode 100644 src/Nethereum.eShop.SqlServer/Infrastructure/Data/Migrations/20200304170042_ResizeColumns.cs delete mode 100644 src/Nethereum.eShop.SqlServer/Infrastructure/Data/Migrations/20200304171630_SetGtinColumnSize.cs rename src/Nethereum.eShop.SqlServer/Infrastructure/Data/Migrations/{20200304171630_SetGtinColumnSize.Designer.cs => 20200310171921_Catalog_InitialCreate.Designer.cs} (99%) rename src/Nethereum.eShop.SqlServer/Infrastructure/Data/Migrations/{20200221124040_InitialCreate.cs => 20200310171921_Catalog_InitialCreate.cs} (92%) rename src/Nethereum.eShop.SqlServer/Infrastructure/Identity/Migrations/{20200221124042_InitialCreate.Designer.cs => 20200310171925_AppIdentity_InitialCreate.Designer.cs} (97%) rename src/Nethereum.eShop.SqlServer/Infrastructure/Identity/Migrations/{20200221124042_InitialCreate.cs => 20200310171925_AppIdentity_InitialCreate.cs} (98%) diff --git a/src/Nethereum.eShop.DbFactory/EShopDbBootstrapper.cs b/src/Nethereum.eShop.DbFactory/EShopDbBootstrapper.cs new file mode 100644 index 0000000..61b78ca --- /dev/null +++ b/src/Nethereum.eShop.DbFactory/EShopDbBootstrapper.cs @@ -0,0 +1,36 @@ +using Microsoft.Extensions.Configuration; +using Nethereum.eShop.ApplicationCore.Interfaces; +using Nethereum.eShop.InMemory.Infrastructure.Data.Config; +using Nethereum.eShop.Sqlite.Infrastructure.Data.Config; +using Nethereum.eShop.SqlServer.Infrastructure.Data.Config; + +namespace Nethereum.eShop.DbFactory +{ + public static class EShopDbBootstrapper + { + public static IEShopDbBootstrapper CreateInMemoryDbBootstrapper() => new InMemoryEShopDbBootrapper(); + public static IEShopIdentityDbBootstrapper CreateInMemoryAppIdentityDbBootstrapper() => new InMemoryEShopAppIdentityDbBootrapper(); + + public static IEShopDbBootstrapper CreateDbBootstrapper(IConfiguration configuration) + { + var name = configuration["CatalogDbProvider"]?.ToLower(); + return name switch + { + "sqlserver" => new SqlServerEShopDbBootstrapper(), + "sqlite" => new SqliteEShopDbBootstrapper(), + _ => new InMemoryEShopDbBootrapper() + }; + } + + public static IEShopIdentityDbBootstrapper CreateAppIdentityDbBootstrapper(IConfiguration configuration) + { + var name = configuration["CatalogDbProvider"]?.ToLower(); + return name switch + { + "sqlserver" => new SqlServerEShopAppIdentityDbBootstrapper(), + "sqlite" => new SqliteEShopAppIdentityDbBootstrapper(), + _ => new InMemoryEShopAppIdentityDbBootrapper() + }; + } + } +} diff --git a/src/Nethereum.eShop.DbFactory/Nethereum.eShop.DbFactory.csproj b/src/Nethereum.eShop.DbFactory/Nethereum.eShop.DbFactory.csproj new file mode 100644 index 0000000..68760ee --- /dev/null +++ b/src/Nethereum.eShop.DbFactory/Nethereum.eShop.DbFactory.csproj @@ -0,0 +1,13 @@ + + + + netstandard2.1 + + + + + + + + + diff --git a/src/Nethereum.eShop.InMemory/Infrastructure/Data/Config/InMemoryEShopAppIdentityDbBootrapper.cs b/src/Nethereum.eShop.InMemory/Infrastructure/Data/Config/InMemoryEShopAppIdentityDbBootrapper.cs index 4b64c9a..a2e2f1d 100644 --- a/src/Nethereum.eShop.InMemory/Infrastructure/Data/Config/InMemoryEShopAppIdentityDbBootrapper.cs +++ b/src/Nethereum.eShop.InMemory/Infrastructure/Data/Config/InMemoryEShopAppIdentityDbBootrapper.cs @@ -4,6 +4,7 @@ using Nethereum.eShop.ApplicationCore.Interfaces; using Nethereum.eShop.Infrastructure.Identity; using System; +using System.Threading; using System.Threading.Tasks; namespace Nethereum.eShop.InMemory.Infrastructure.Data.Config @@ -16,6 +17,6 @@ public void AddDbContext(IServiceCollection services, IConfiguration configurati options.UseInMemoryDatabase("Identity")); } - public Task EnsureCreatedAsync(IServiceProvider serviceProvider) => Task.CompletedTask; + public Task EnsureCreatedAsync(IServiceProvider serviceProvider, CancellationToken cancellationToken = default) => Task.CompletedTask; } } diff --git a/src/Nethereum.eShop.InMemory/Infrastructure/Data/Config/InMemoryEShopDbBootrapper.cs b/src/Nethereum.eShop.InMemory/Infrastructure/Data/Config/InMemoryEShopDbBootrapper.cs index abaee18..64afa93 100644 --- a/src/Nethereum.eShop.InMemory/Infrastructure/Data/Config/InMemoryEShopDbBootrapper.cs +++ b/src/Nethereum.eShop.InMemory/Infrastructure/Data/Config/InMemoryEShopDbBootrapper.cs @@ -12,6 +12,7 @@ using Nethereum.eShop.InMemory.ApplicationCore.Queries.Orders; using Nethereum.eShop.InMemory.ApplicationCore.Queries.Quotes; using System; +using System.Threading; using System.Threading.Tasks; namespace Nethereum.eShop.InMemory.Infrastructure.Data.Config @@ -35,6 +36,6 @@ public void AddQueries(IServiceCollection services, IConfiguration configuration services.AddScoped(); } - public Task EnsureCreatedAsync(IServiceProvider serviceProvider) => Task.CompletedTask; + public Task EnsureCreatedAsync(IServiceProvider serviceProvider, CancellationToken cancellationToken = default) => Task.CompletedTask; } } diff --git a/src/Nethereum.eShop.SqlServer.Migrations/CreateInitialDbMigration.bat b/src/Nethereum.eShop.SqlServer.Migrations/CreateInitialDbMigration.bat new file mode 100644 index 0000000..4e712fd --- /dev/null +++ b/src/Nethereum.eShop.SqlServer.Migrations/CreateInitialDbMigration.bat @@ -0,0 +1,3 @@ +rem Create First Migration aka InitialCreate +dotnet ef migrations add Catalog_InitialCreate --context Nethereum.eShop.Infrastructure.Data.CatalogContext --output-dir ..\Nethereum.eShop.SqlServer\Infrastructure\Data\Migrations +dotnet ef migrations add AppIdentity_InitialCreate --context Nethereum.eShop.Infrastructure.Identity.AppIdentityDbContext --output-dir ..\Nethereum.eShop.SqlServer\Infrastructure\Identity\Migrations \ No newline at end of file diff --git a/src/Nethereum.eShop.SqlServer.Migrations/Nethereum.eShop.SqlServer.Migrations.csproj b/src/Nethereum.eShop.SqlServer.Migrations/Nethereum.eShop.SqlServer.Migrations.csproj new file mode 100644 index 0000000..fd66359 --- /dev/null +++ b/src/Nethereum.eShop.SqlServer.Migrations/Nethereum.eShop.SqlServer.Migrations.csproj @@ -0,0 +1,19 @@ + + + + Exe + netcoreapp3.1 + + + + + all + runtime; build; native; contentfiles; analyzers; buildtransitive + + + + + + + + diff --git a/src/Nethereum.eShop.SqlServer.Migrations/Program.cs b/src/Nethereum.eShop.SqlServer.Migrations/Program.cs new file mode 100644 index 0000000..8608ad9 --- /dev/null +++ b/src/Nethereum.eShop.SqlServer.Migrations/Program.cs @@ -0,0 +1,12 @@ +using System; + +namespace Nethereum.eShop.SqlServer.Migrations +{ + class Program + { + static void Main(string[] args) + { + Console.WriteLine("Hello World!"); + } + } +} diff --git a/src/Nethereum.eShop.SqlServer.Migrations/SqlServerAppIdentityContextDesignTimeFactory.cs b/src/Nethereum.eShop.SqlServer.Migrations/SqlServerAppIdentityContextDesignTimeFactory.cs new file mode 100644 index 0000000..75c2f37 --- /dev/null +++ b/src/Nethereum.eShop.SqlServer.Migrations/SqlServerAppIdentityContextDesignTimeFactory.cs @@ -0,0 +1,20 @@ +using Microsoft.EntityFrameworkCore; +using Microsoft.EntityFrameworkCore.Design; +using Nethereum.eShop.Infrastructure.Identity; + +namespace Nethereum.eShop.SqlServer.Infrastructure.Data.Config +{ + public class SqlServerAppIdentityContextDesignTimeFactory : IDesignTimeDbContextFactory + { + public AppIdentityDbContext CreateDbContext(string[] args) + { + var optionsBuilder = new DbContextOptionsBuilder(); + optionsBuilder.UseSqlServer( + "Server=localhost\\sqldev;Integrated Security=true;Initial Catalog=eShop;", + b => b.MigrationsAssembly("Nethereum.eShop.SqlServer.Migrations")); + + return new AppIdentityDbContext( + optionsBuilder.Options); + } + } +} diff --git a/src/Nethereum.eShop.SqlServer.Migrations/SqlServerCatalogContextDesignTimeFactory.cs b/src/Nethereum.eShop.SqlServer.Migrations/SqlServerCatalogContextDesignTimeFactory.cs new file mode 100644 index 0000000..bbc9ea2 --- /dev/null +++ b/src/Nethereum.eShop.SqlServer.Migrations/SqlServerCatalogContextDesignTimeFactory.cs @@ -0,0 +1,23 @@ +using Microsoft.EntityFrameworkCore; +using Microsoft.EntityFrameworkCore.Design; +using Nethereum.eShop.Infrastructure.Data; +using Nethereum.eShop.Infrastructure.Data.Config.EntityBuilders.SqlServer; + +namespace Nethereum.eShop.SqlServer.Infrastructure.Data.Config +{ + public class SqlServerCatalogContextDesignTimeFactory: IDesignTimeDbContextFactory + { + public CatalogContext CreateDbContext(string[] args) + { + var optionsBuilder = new DbContextOptionsBuilder(); + optionsBuilder.UseSqlServer( + "Server=localhost\\sqldev;Integrated Security=true;Initial Catalog=eShop;", + b => b.MigrationsAssembly("Nethereum.eShop.SqlServer.Migrations")); + + return new CatalogContext( + optionsBuilder.Options, + null, + new ModelBuilderAssemblyHandler(typeof(BasketConfiguration).Assembly)); + } + } +} diff --git a/src/Nethereum.eShop.SqlServer/Infrastructure/Data/Config/SqlServerEShopAppIdentityDbBootstrapper.cs b/src/Nethereum.eShop.SqlServer/Infrastructure/Data/Config/SqlServerEShopAppIdentityDbBootstrapper.cs index 47a9126..d4465b0 100644 --- a/src/Nethereum.eShop.SqlServer/Infrastructure/Data/Config/SqlServerEShopAppIdentityDbBootstrapper.cs +++ b/src/Nethereum.eShop.SqlServer/Infrastructure/Data/Config/SqlServerEShopAppIdentityDbBootstrapper.cs @@ -4,6 +4,7 @@ using Nethereum.eShop.ApplicationCore.Interfaces; using Nethereum.eShop.Infrastructure.Identity; using System; +using System.Threading; using System.Threading.Tasks; namespace Nethereum.eShop.SqlServer.Infrastructure.Data.Config @@ -16,10 +17,10 @@ public void AddDbContext(IServiceCollection services, IConfiguration configurati options.UseSqlServer(configuration.GetConnectionString("IdentityConnection"))); } - public Task EnsureCreatedAsync(IServiceProvider serviceProvider) + public Task EnsureCreatedAsync(IServiceProvider serviceProvider, CancellationToken cancellationToken = default) { - //TODO: implement migrations - return Task.CompletedTask; + var context = serviceProvider.GetRequiredService(); + return context.Database.MigrateAsync(cancellationToken); } } } diff --git a/src/Nethereum.eShop.SqlServer/Infrastructure/Data/Config/SqlServerEShopDbBootstrapper.cs b/src/Nethereum.eShop.SqlServer/Infrastructure/Data/Config/SqlServerEShopDbBootstrapper.cs index 8524549..64871d4 100644 --- a/src/Nethereum.eShop.SqlServer/Infrastructure/Data/Config/SqlServerEShopDbBootstrapper.cs +++ b/src/Nethereum.eShop.SqlServer/Infrastructure/Data/Config/SqlServerEShopDbBootstrapper.cs @@ -8,6 +8,7 @@ using Nethereum.eShop.Infrastructure.Data; using Nethereum.eShop.Infrastructure.Data.Config; using System; +using System.Threading; using System.Threading.Tasks; namespace Nethereum.eShop.SqlServer.Infrastructure.Data.Config @@ -35,10 +36,10 @@ public void AddQueries(IServiceCollection services, IConfiguration configuration services.AddSingleton(new CatalogQueries(queryConnectionString)); } - public Task EnsureCreatedAsync(IServiceProvider serviceProvider) + public Task EnsureCreatedAsync(IServiceProvider serviceProvider, CancellationToken cancellationToken = default) { - //TODO: Configure migrations etc - return Task.CompletedTask; + var context = serviceProvider.GetRequiredService(); + return context.Database.MigrateAsync(cancellationToken); } } } diff --git a/src/Nethereum.eShop.SqlServer/Infrastructure/Data/Migrations/20200221124040_InitialCreate.Designer.cs b/src/Nethereum.eShop.SqlServer/Infrastructure/Data/Migrations/20200221124040_InitialCreate.Designer.cs deleted file mode 100644 index f556017..0000000 --- a/src/Nethereum.eShop.SqlServer/Infrastructure/Data/Migrations/20200221124040_InitialCreate.Designer.cs +++ /dev/null @@ -1,931 +0,0 @@ -// -using System; -using Microsoft.EntityFrameworkCore; -using Microsoft.EntityFrameworkCore.Infrastructure; -using Microsoft.EntityFrameworkCore.Metadata; -using Microsoft.EntityFrameworkCore.Migrations; -using Microsoft.EntityFrameworkCore.Storage.ValueConversion; -using Nethereum.eShop.Infrastructure.Data; - -namespace Nethereum.eShop.Infrastructure.Data.Migrations -{ - [DbContext(typeof(CatalogContext))] - [Migration("20200221124040_InitialCreate")] - partial class InitialCreate - { - protected override void BuildTargetModel(ModelBuilder modelBuilder) - { -#pragma warning disable 612, 618 - modelBuilder - .HasAnnotation("ProductVersion", "3.1.1") - .HasAnnotation("Relational:MaxIdentifierLength", 128) - .HasAnnotation("Relational:Sequence:.catalog_brand_hilo", "'catalog_brand_hilo', '', '1', '10', '', '', 'Int64', 'False'") - .HasAnnotation("Relational:Sequence:.catalog_hilo", "'catalog_hilo', '', '1', '10', '', '', 'Int64', 'False'") - .HasAnnotation("Relational:Sequence:.catalog_type_hilo", "'catalog_type_hilo', '', '1', '10', '', '', 'Int64', 'False'") - .HasAnnotation("Relational:Sequence:.stock_hilo", "'stock_hilo', '', '1', '10', '', '', 'Int64', 'False'") - .HasAnnotation("SqlServer:ValueGenerationStrategy", SqlServerValueGenerationStrategy.IdentityColumn); - - modelBuilder.Entity("Nethereum.eShop.ApplicationCore.Entities.BasketAggregate.Basket", b => - { - b.Property("Id") - .ValueGeneratedOnAdd() - .HasColumnType("int") - .HasAnnotation("SqlServer:ValueGenerationStrategy", SqlServerValueGenerationStrategy.IdentityColumn); - - b.Property("BuyerAddress") - .IsRequired() - .HasColumnType("nvarchar(43)") - .HasMaxLength(43); - - b.Property("BuyerId") - .IsRequired() - .HasColumnType("nvarchar(256)") - .HasMaxLength(256); - - b.Property("TransactionHash") - .HasColumnType("nvarchar(max)"); - - b.HasKey("Id"); - - b.HasIndex("BuyerAddress"); - - b.HasIndex("BuyerId"); - - b.ToTable("Baskets"); - }); - - modelBuilder.Entity("Nethereum.eShop.ApplicationCore.Entities.BasketAggregate.BasketItem", b => - { - b.Property("Id") - .ValueGeneratedOnAdd() - .HasColumnType("int") - .HasAnnotation("SqlServer:ValueGenerationStrategy", SqlServerValueGenerationStrategy.IdentityColumn); - - b.Property("BasketId") - .HasColumnType("int"); - - b.Property("CatalogItemId") - .HasColumnType("int"); - - b.Property("Quantity") - .HasColumnType("int"); - - b.Property("UnitPrice") - .HasColumnType("decimal(18,2)"); - - b.HasKey("Id"); - - b.HasIndex("BasketId"); - - b.ToTable("BasketItems"); - }); - - modelBuilder.Entity("Nethereum.eShop.ApplicationCore.Entities.BuyerAggregate.Buyer", b => - { - b.Property("Id") - .ValueGeneratedOnAdd() - .HasColumnType("int") - .HasAnnotation("SqlServer:ValueGenerationStrategy", SqlServerValueGenerationStrategy.IdentityColumn); - - b.Property("BuyerAddress") - .HasColumnType("nvarchar(43)") - .HasMaxLength(43); - - b.Property("BuyerId") - .IsRequired() - .HasColumnType("nvarchar(256)") - .HasMaxLength(256); - - b.HasKey("Id"); - - b.HasIndex("BuyerAddress") - .IsUnique() - .HasFilter("[BuyerAddress] IS NOT NULL"); - - b.HasIndex("BuyerId") - .IsUnique(); - - b.ToTable("Buyers"); - }); - - modelBuilder.Entity("Nethereum.eShop.ApplicationCore.Entities.BuyerAggregate.BuyerPostalAddress", b => - { - b.Property("Id") - .ValueGeneratedOnAdd() - .HasColumnType("int") - .HasAnnotation("SqlServer:ValueGenerationStrategy", SqlServerValueGenerationStrategy.IdentityColumn); - - b.Property("BuyerId") - .HasColumnType("int"); - - b.Property("Name") - .HasColumnType("nvarchar(max)"); - - b.HasKey("Id"); - - b.HasIndex("BuyerId"); - - b.ToTable("BuyerPostalAddress"); - }); - - modelBuilder.Entity("Nethereum.eShop.ApplicationCore.Entities.CatalogBrand", b => - { - b.Property("Id") - .ValueGeneratedOnAdd() - .HasColumnType("int") - .HasAnnotation("SqlServer:HiLoSequenceName", "catalog_brand_hilo") - .HasAnnotation("SqlServer:ValueGenerationStrategy", SqlServerValueGenerationStrategy.SequenceHiLo); - - b.Property("Brand") - .IsRequired() - .HasColumnType("nvarchar(100)") - .HasMaxLength(100); - - b.HasKey("Id"); - - b.ToTable("CatalogBrands"); - }); - - modelBuilder.Entity("Nethereum.eShop.ApplicationCore.Entities.CatalogItem", b => - { - b.Property("Id") - .ValueGeneratedOnAdd() - .HasColumnType("int") - .HasAnnotation("SqlServer:HiLoSequenceName", "catalog_hilo") - .HasAnnotation("SqlServer:ValueGenerationStrategy", SqlServerValueGenerationStrategy.SequenceHiLo); - - b.Property("AttributeJson") - .HasColumnType("nvarchar(max)"); - - b.Property("CatalogBrandId") - .HasColumnType("int"); - - b.Property("CatalogTypeId") - .HasColumnType("int"); - - b.Property("Depth") - .HasColumnType("int"); - - b.Property("Description") - .HasColumnType("nvarchar(max)"); - - b.Property("Gtin") - .IsRequired() - .HasColumnType("nvarchar(14)") - .HasMaxLength(14); - - b.Property("GtinRegistryId") - .HasColumnType("int"); - - b.Property("Height") - .HasColumnType("int"); - - b.Property("Name") - .IsRequired() - .HasColumnType("nvarchar(50)") - .HasMaxLength(50); - - b.Property("PictureLargeUri") - .HasColumnType("nvarchar(max)"); - - b.Property("PictureMediumUri") - .HasColumnType("nvarchar(max)"); - - b.Property("PictureSmallUri") - .HasColumnType("nvarchar(max)"); - - b.Property("PictureUri") - .HasColumnType("nvarchar(max)"); - - b.Property("Price") - .HasColumnType("decimal(18,2)"); - - b.Property("Rank") - .HasColumnType("int"); - - b.Property("Status") - .HasColumnType("int"); - - b.Property("Unit") - .HasColumnType("nvarchar(8)") - .HasMaxLength(8); - - b.Property("Weight") - .HasColumnType("int"); - - b.Property("Width") - .HasColumnType("int"); - - b.HasKey("Id"); - - b.HasIndex("CatalogBrandId"); - - b.HasIndex("CatalogTypeId"); - - b.ToTable("Catalog"); - }); - - modelBuilder.Entity("Nethereum.eShop.ApplicationCore.Entities.CatalogType", b => - { - b.Property("Id") - .ValueGeneratedOnAdd() - .HasColumnType("int") - .HasAnnotation("SqlServer:HiLoSequenceName", "catalog_type_hilo") - .HasAnnotation("SqlServer:ValueGenerationStrategy", SqlServerValueGenerationStrategy.SequenceHiLo); - - b.Property("Type") - .IsRequired() - .HasColumnType("nvarchar(100)") - .HasMaxLength(100); - - b.HasKey("Id"); - - b.ToTable("CatalogTypes"); - }); - - modelBuilder.Entity("Nethereum.eShop.ApplicationCore.Entities.OrderAggregate.Order", b => - { - b.Property("Id") - .ValueGeneratedOnAdd() - .HasColumnType("int") - .HasAnnotation("SqlServer:ValueGenerationStrategy", SqlServerValueGenerationStrategy.IdentityColumn); - - b.Property("ApproverAddress") - .HasColumnType("nvarchar(43)") - .HasMaxLength(43); - - b.Property("BuyerAddress") - .HasColumnType("nvarchar(43)") - .HasMaxLength(43); - - b.Property("BuyerId") - .IsRequired() - .HasColumnType("nvarchar(256)") - .HasMaxLength(256); - - b.Property("BuyerWalletAddress") - .HasColumnType("nvarchar(43)") - .HasMaxLength(43); - - b.Property("CurrencyAddress") - .HasColumnType("nvarchar(max)"); - - b.Property("CurrencySymbol") - .HasColumnType("nvarchar(max)"); - - b.Property("OrderDate") - .HasColumnType("datetimeoffset"); - - b.Property("PoDate") - .HasColumnType("datetimeoffset"); - - b.Property("PoNumber") - .HasColumnType("bigint"); - - b.Property("PoType") - .HasColumnType("int"); - - b.Property("QuoteId") - .HasColumnType("int"); - - b.Property("SellerId") - .HasColumnType("nvarchar(max)"); - - b.Property("Status") - .HasColumnType("int"); - - b.Property("TransactionHash") - .HasColumnType("nvarchar(67)") - .HasMaxLength(67); - - b.HasKey("Id"); - - b.HasIndex("BuyerAddress"); - - b.HasIndex("BuyerId"); - - b.ToTable("Orders"); - }); - - modelBuilder.Entity("Nethereum.eShop.ApplicationCore.Entities.OrderAggregate.OrderItem", b => - { - b.Property("Id") - .ValueGeneratedOnAdd() - .HasColumnType("int") - .HasAnnotation("SqlServer:ValueGenerationStrategy", SqlServerValueGenerationStrategy.IdentityColumn); - - b.Property("ActualEscrowReleaseDate") - .HasColumnType("datetimeoffset"); - - b.Property("CurrencyValue") - .HasColumnType("nvarchar(max)"); - - b.Property("GoodsIssueDate") - .HasColumnType("datetimeoffset"); - - b.Property("IsEscrowReleased") - .HasColumnType("bit"); - - b.Property("OrderId") - .HasColumnType("int"); - - b.Property("PlannedEscrowReleaseDate") - .HasColumnType("datetimeoffset"); - - b.Property("PoItemNumber") - .HasColumnType("int"); - - b.Property("PoItemStatus") - .HasColumnType("int"); - - b.Property("Quantity") - .HasColumnType("int"); - - b.Property("QuantityAddress") - .HasColumnType("nvarchar(max)"); - - b.Property("QuantitySymbol") - .HasColumnType("nvarchar(max)"); - - b.Property("Status") - .HasColumnType("int"); - - b.Property("Unit") - .HasColumnType("nvarchar(max)"); - - b.Property("UnitPrice") - .HasColumnType("decimal(18,2)"); - - b.HasKey("Id"); - - b.HasIndex("OrderId"); - - b.ToTable("OrderItems"); - }); - - modelBuilder.Entity("Nethereum.eShop.ApplicationCore.Entities.QuoteAggregate.Quote", b => - { - b.Property("Id") - .ValueGeneratedOnAdd() - .HasColumnType("int") - .HasAnnotation("SqlServer:ValueGenerationStrategy", SqlServerValueGenerationStrategy.IdentityColumn); - - b.Property("ApproverAddress") - .HasColumnType("nvarchar(43)") - .HasMaxLength(43); - - b.Property("BuyerAddress") - .HasColumnType("nvarchar(43)") - .HasMaxLength(43); - - b.Property("BuyerId") - .IsRequired() - .HasColumnType("nvarchar(256)") - .HasMaxLength(256); - - b.Property("BuyerWalletAddress") - .HasColumnType("nvarchar(43)") - .HasMaxLength(43); - - b.Property("CurrencyAddress") - .HasColumnType("nvarchar(max)"); - - b.Property("CurrencySymbol") - .HasColumnType("nvarchar(max)"); - - b.Property("Date") - .HasColumnType("datetimeoffset"); - - b.Property("Expiry") - .HasColumnType("datetimeoffset"); - - b.Property("PoNumber") - .HasColumnType("bigint"); - - b.Property("PoType") - .HasColumnType("int"); - - b.Property("SellerId") - .HasColumnType("nvarchar(max)"); - - b.Property("Status") - .HasColumnType("int"); - - b.Property("TransactionHash") - .HasColumnType("nvarchar(67)") - .HasMaxLength(67); - - b.HasKey("Id"); - - b.HasIndex("BuyerAddress"); - - b.HasIndex("BuyerId"); - - b.ToTable("Quotes"); - }); - - modelBuilder.Entity("Nethereum.eShop.ApplicationCore.Entities.QuoteAggregate.QuoteItem", b => - { - b.Property("Id") - .ValueGeneratedOnAdd() - .HasColumnType("int") - .HasAnnotation("SqlServer:ValueGenerationStrategy", SqlServerValueGenerationStrategy.IdentityColumn); - - b.Property("CurrencyValue") - .HasColumnType("nvarchar(max)"); - - b.Property("EscrowReleaseDate") - .HasColumnType("datetimeoffset"); - - b.Property("PoItemNumber") - .HasColumnType("int"); - - b.Property("Quantity") - .HasColumnType("int"); - - b.Property("QuantityAddress") - .HasColumnType("nvarchar(max)"); - - b.Property("QuantitySymbol") - .HasColumnType("nvarchar(max)"); - - b.Property("QuoteId") - .HasColumnType("int"); - - b.Property("Unit") - .HasColumnType("nvarchar(max)"); - - b.Property("UnitPrice") - .HasColumnType("decimal(18,2)"); - - b.HasKey("Id"); - - b.HasIndex("QuoteId"); - - b.ToTable("QuoteItems"); - }); - - modelBuilder.Entity("Nethereum.eShop.ApplicationCore.Entities.StockItem", b => - { - b.Property("Id") - .ValueGeneratedOnAdd() - .HasColumnType("int") - .HasAnnotation("SqlServer:HiLoSequenceName", "stock_hilo") - .HasAnnotation("SqlServer:ValueGenerationStrategy", SqlServerValueGenerationStrategy.SequenceHiLo); - - b.Property("CatalogItemId") - .HasColumnType("int"); - - b.Property("Location") - .IsRequired() - .HasColumnType("nvarchar(50)") - .HasMaxLength(50); - - b.Property("Quantity") - .HasColumnType("int"); - - b.HasKey("Id"); - - b.HasIndex("CatalogItemId"); - - b.ToTable("Stock"); - }); - - modelBuilder.Entity("Nethereum.eShop.ApplicationCore.Entities.BasketAggregate.Basket", b => - { - b.OwnsOne("Nethereum.eShop.ApplicationCore.Entities.PostalAddress", "BillTo", b1 => - { - b1.Property("BasketId") - .ValueGeneratedOnAdd() - .HasColumnType("int") - .HasAnnotation("SqlServer:ValueGenerationStrategy", SqlServerValueGenerationStrategy.IdentityColumn); - - b1.Property("City") - .IsRequired() - .HasColumnType("nvarchar(100)") - .HasMaxLength(100); - - b1.Property("Country") - .IsRequired() - .HasColumnType("nvarchar(90)") - .HasMaxLength(90); - - b1.Property("RecipientName") - .IsRequired() - .HasColumnType("nvarchar(255)") - .HasMaxLength(255); - - b1.Property("State") - .HasColumnType("nvarchar(60)") - .HasMaxLength(60); - - b1.Property("Street") - .IsRequired() - .HasColumnType("nvarchar(180)") - .HasMaxLength(180); - - b1.Property("ZipCode") - .IsRequired() - .HasColumnType("nvarchar(18)") - .HasMaxLength(18); - - b1.HasKey("BasketId"); - - b1.ToTable("Baskets"); - - b1.WithOwner() - .HasForeignKey("BasketId"); - }); - - b.OwnsOne("Nethereum.eShop.ApplicationCore.Entities.PostalAddress", "ShipTo", b1 => - { - b1.Property("BasketId") - .ValueGeneratedOnAdd() - .HasColumnType("int") - .HasAnnotation("SqlServer:ValueGenerationStrategy", SqlServerValueGenerationStrategy.IdentityColumn); - - b1.Property("City") - .IsRequired() - .HasColumnType("nvarchar(100)") - .HasMaxLength(100); - - b1.Property("Country") - .IsRequired() - .HasColumnType("nvarchar(90)") - .HasMaxLength(90); - - b1.Property("RecipientName") - .IsRequired() - .HasColumnType("nvarchar(255)") - .HasMaxLength(255); - - b1.Property("State") - .HasColumnType("nvarchar(60)") - .HasMaxLength(60); - - b1.Property("Street") - .IsRequired() - .HasColumnType("nvarchar(180)") - .HasMaxLength(180); - - b1.Property("ZipCode") - .IsRequired() - .HasColumnType("nvarchar(18)") - .HasMaxLength(18); - - b1.HasKey("BasketId"); - - b1.ToTable("Baskets"); - - b1.WithOwner() - .HasForeignKey("BasketId"); - }); - }); - - modelBuilder.Entity("Nethereum.eShop.ApplicationCore.Entities.BasketAggregate.BasketItem", b => - { - b.HasOne("Nethereum.eShop.ApplicationCore.Entities.BasketAggregate.Basket", null) - .WithMany("Items") - .HasForeignKey("BasketId") - .OnDelete(DeleteBehavior.Cascade) - .IsRequired(); - }); - - modelBuilder.Entity("Nethereum.eShop.ApplicationCore.Entities.BuyerAggregate.BuyerPostalAddress", b => - { - b.HasOne("Nethereum.eShop.ApplicationCore.Entities.BuyerAggregate.Buyer", null) - .WithMany("PostalAddresses") - .HasForeignKey("BuyerId"); - - b.OwnsOne("Nethereum.eShop.ApplicationCore.Entities.PostalAddress", "PostalAddress", b1 => - { - b1.Property("BuyerPostalAddressId") - .ValueGeneratedOnAdd() - .HasColumnType("int") - .HasAnnotation("SqlServer:ValueGenerationStrategy", SqlServerValueGenerationStrategy.IdentityColumn); - - b1.Property("City") - .IsRequired() - .HasColumnType("nvarchar(100)") - .HasMaxLength(100); - - b1.Property("Country") - .IsRequired() - .HasColumnType("nvarchar(90)") - .HasMaxLength(90); - - b1.Property("RecipientName") - .IsRequired() - .HasColumnType("nvarchar(255)") - .HasMaxLength(255); - - b1.Property("State") - .HasColumnType("nvarchar(60)") - .HasMaxLength(60); - - b1.Property("Street") - .IsRequired() - .HasColumnType("nvarchar(180)") - .HasMaxLength(180); - - b1.Property("ZipCode") - .IsRequired() - .HasColumnType("nvarchar(18)") - .HasMaxLength(18); - - b1.HasKey("BuyerPostalAddressId"); - - b1.ToTable("BuyerPostalAddress"); - - b1.WithOwner() - .HasForeignKey("BuyerPostalAddressId"); - }); - }); - - modelBuilder.Entity("Nethereum.eShop.ApplicationCore.Entities.CatalogItem", b => - { - b.HasOne("Nethereum.eShop.ApplicationCore.Entities.CatalogBrand", "CatalogBrand") - .WithMany() - .HasForeignKey("CatalogBrandId") - .OnDelete(DeleteBehavior.Cascade) - .IsRequired(); - - b.HasOne("Nethereum.eShop.ApplicationCore.Entities.CatalogType", "CatalogType") - .WithMany() - .HasForeignKey("CatalogTypeId") - .OnDelete(DeleteBehavior.Cascade) - .IsRequired(); - }); - - modelBuilder.Entity("Nethereum.eShop.ApplicationCore.Entities.OrderAggregate.Order", b => - { - b.OwnsOne("Nethereum.eShop.ApplicationCore.Entities.PostalAddress", "BillTo", b1 => - { - b1.Property("OrderId") - .ValueGeneratedOnAdd() - .HasColumnType("int") - .HasAnnotation("SqlServer:ValueGenerationStrategy", SqlServerValueGenerationStrategy.IdentityColumn); - - b1.Property("City") - .IsRequired() - .HasColumnType("nvarchar(100)") - .HasMaxLength(100); - - b1.Property("Country") - .IsRequired() - .HasColumnType("nvarchar(90)") - .HasMaxLength(90); - - b1.Property("RecipientName") - .IsRequired() - .HasColumnType("nvarchar(255)") - .HasMaxLength(255); - - b1.Property("State") - .HasColumnType("nvarchar(60)") - .HasMaxLength(60); - - b1.Property("Street") - .IsRequired() - .HasColumnType("nvarchar(180)") - .HasMaxLength(180); - - b1.Property("ZipCode") - .IsRequired() - .HasColumnType("nvarchar(18)") - .HasMaxLength(18); - - b1.HasKey("OrderId"); - - b1.ToTable("Orders"); - - b1.WithOwner() - .HasForeignKey("OrderId"); - }); - - b.OwnsOne("Nethereum.eShop.ApplicationCore.Entities.PostalAddress", "ShipTo", b1 => - { - b1.Property("OrderId") - .ValueGeneratedOnAdd() - .HasColumnType("int") - .HasAnnotation("SqlServer:ValueGenerationStrategy", SqlServerValueGenerationStrategy.IdentityColumn); - - b1.Property("City") - .IsRequired() - .HasColumnType("nvarchar(100)") - .HasMaxLength(100); - - b1.Property("Country") - .IsRequired() - .HasColumnType("nvarchar(90)") - .HasMaxLength(90); - - b1.Property("RecipientName") - .IsRequired() - .HasColumnType("nvarchar(255)") - .HasMaxLength(255); - - b1.Property("State") - .HasColumnType("nvarchar(60)") - .HasMaxLength(60); - - b1.Property("Street") - .IsRequired() - .HasColumnType("nvarchar(180)") - .HasMaxLength(180); - - b1.Property("ZipCode") - .IsRequired() - .HasColumnType("nvarchar(18)") - .HasMaxLength(18); - - b1.HasKey("OrderId"); - - b1.ToTable("Orders"); - - b1.WithOwner() - .HasForeignKey("OrderId"); - }); - }); - - modelBuilder.Entity("Nethereum.eShop.ApplicationCore.Entities.OrderAggregate.OrderItem", b => - { - b.HasOne("Nethereum.eShop.ApplicationCore.Entities.OrderAggregate.Order", null) - .WithMany("OrderItems") - .HasForeignKey("OrderId"); - - b.OwnsOne("Nethereum.eShop.ApplicationCore.Entities.CatalogItemExcerpt", "ItemOrdered", b1 => - { - b1.Property("OrderItemId") - .ValueGeneratedOnAdd() - .HasColumnType("int") - .HasAnnotation("SqlServer:ValueGenerationStrategy", SqlServerValueGenerationStrategy.IdentityColumn); - - b1.Property("CatalogItemId") - .HasColumnType("int"); - - b1.Property("Gtin") - .HasColumnType("nvarchar(max)"); - - b1.Property("GtinRegistryId") - .HasColumnType("int"); - - b1.Property("PictureUri") - .HasColumnType("nvarchar(max)"); - - b1.Property("ProductName") - .IsRequired() - .HasColumnType("nvarchar(50)") - .HasMaxLength(50); - - b1.HasKey("OrderItemId"); - - b1.ToTable("OrderItems"); - - b1.WithOwner() - .HasForeignKey("OrderItemId"); - }); - }); - - modelBuilder.Entity("Nethereum.eShop.ApplicationCore.Entities.QuoteAggregate.Quote", b => - { - b.OwnsOne("Nethereum.eShop.ApplicationCore.Entities.PostalAddress", "BillTo", b1 => - { - b1.Property("QuoteId") - .ValueGeneratedOnAdd() - .HasColumnType("int") - .HasAnnotation("SqlServer:ValueGenerationStrategy", SqlServerValueGenerationStrategy.IdentityColumn); - - b1.Property("City") - .IsRequired() - .HasColumnType("nvarchar(100)") - .HasMaxLength(100); - - b1.Property("Country") - .IsRequired() - .HasColumnType("nvarchar(90)") - .HasMaxLength(90); - - b1.Property("RecipientName") - .IsRequired() - .HasColumnType("nvarchar(255)") - .HasMaxLength(255); - - b1.Property("State") - .HasColumnType("nvarchar(60)") - .HasMaxLength(60); - - b1.Property("Street") - .IsRequired() - .HasColumnType("nvarchar(180)") - .HasMaxLength(180); - - b1.Property("ZipCode") - .IsRequired() - .HasColumnType("nvarchar(18)") - .HasMaxLength(18); - - b1.HasKey("QuoteId"); - - b1.ToTable("Quotes"); - - b1.WithOwner() - .HasForeignKey("QuoteId"); - }); - - b.OwnsOne("Nethereum.eShop.ApplicationCore.Entities.PostalAddress", "ShipTo", b1 => - { - b1.Property("QuoteId") - .ValueGeneratedOnAdd() - .HasColumnType("int") - .HasAnnotation("SqlServer:ValueGenerationStrategy", SqlServerValueGenerationStrategy.IdentityColumn); - - b1.Property("City") - .IsRequired() - .HasColumnType("nvarchar(100)") - .HasMaxLength(100); - - b1.Property("Country") - .IsRequired() - .HasColumnType("nvarchar(90)") - .HasMaxLength(90); - - b1.Property("RecipientName") - .IsRequired() - .HasColumnType("nvarchar(255)") - .HasMaxLength(255); - - b1.Property("State") - .HasColumnType("nvarchar(60)") - .HasMaxLength(60); - - b1.Property("Street") - .IsRequired() - .HasColumnType("nvarchar(180)") - .HasMaxLength(180); - - b1.Property("ZipCode") - .IsRequired() - .HasColumnType("nvarchar(18)") - .HasMaxLength(18); - - b1.HasKey("QuoteId"); - - b1.ToTable("Quotes"); - - b1.WithOwner() - .HasForeignKey("QuoteId"); - }); - }); - - modelBuilder.Entity("Nethereum.eShop.ApplicationCore.Entities.QuoteAggregate.QuoteItem", b => - { - b.HasOne("Nethereum.eShop.ApplicationCore.Entities.QuoteAggregate.Quote", null) - .WithMany("QuoteItems") - .HasForeignKey("QuoteId"); - - b.OwnsOne("Nethereum.eShop.ApplicationCore.Entities.CatalogItemExcerpt", "ItemOrdered", b1 => - { - b1.Property("QuoteItemId") - .ValueGeneratedOnAdd() - .HasColumnType("int") - .HasAnnotation("SqlServer:ValueGenerationStrategy", SqlServerValueGenerationStrategy.IdentityColumn); - - b1.Property("CatalogItemId") - .HasColumnType("int"); - - b1.Property("Gtin") - .HasColumnType("nvarchar(max)"); - - b1.Property("GtinRegistryId") - .HasColumnType("int"); - - b1.Property("PictureUri") - .HasColumnType("nvarchar(max)"); - - b1.Property("ProductName") - .IsRequired() - .HasColumnType("nvarchar(50)") - .HasMaxLength(50); - - b1.HasKey("QuoteItemId"); - - b1.ToTable("QuoteItems"); - - b1.WithOwner() - .HasForeignKey("QuoteItemId"); - }); - }); - - modelBuilder.Entity("Nethereum.eShop.ApplicationCore.Entities.StockItem", b => - { - b.HasOne("Nethereum.eShop.ApplicationCore.Entities.CatalogItem", "CatalogItem") - .WithMany() - .HasForeignKey("CatalogItemId") - .OnDelete(DeleteBehavior.Cascade) - .IsRequired(); - }); -#pragma warning restore 612, 618 - } - } -} diff --git a/src/Nethereum.eShop.SqlServer/Infrastructure/Data/Migrations/20200304170042_ResizeColumns.Designer.cs b/src/Nethereum.eShop.SqlServer/Infrastructure/Data/Migrations/20200304170042_ResizeColumns.Designer.cs deleted file mode 100644 index e807db1..0000000 --- a/src/Nethereum.eShop.SqlServer/Infrastructure/Data/Migrations/20200304170042_ResizeColumns.Designer.cs +++ /dev/null @@ -1,948 +0,0 @@ -// -using System; -using Microsoft.EntityFrameworkCore; -using Microsoft.EntityFrameworkCore.Infrastructure; -using Microsoft.EntityFrameworkCore.Metadata; -using Microsoft.EntityFrameworkCore.Migrations; -using Microsoft.EntityFrameworkCore.Storage.ValueConversion; -using Nethereum.eShop.Infrastructure.Data; - -namespace Nethereum.eShop.Infrastructure.Data.Migrations -{ - [DbContext(typeof(CatalogContext))] - [Migration("20200304170042_ResizeColumns")] - partial class ResizeColumns - { - protected override void BuildTargetModel(ModelBuilder modelBuilder) - { -#pragma warning disable 612, 618 - modelBuilder - .HasAnnotation("ProductVersion", "3.1.2") - .HasAnnotation("Relational:MaxIdentifierLength", 128) - .HasAnnotation("Relational:Sequence:.catalog_brand_hilo", "'catalog_brand_hilo', '', '1', '10', '', '', 'Int64', 'False'") - .HasAnnotation("Relational:Sequence:.catalog_hilo", "'catalog_hilo', '', '1', '10', '', '', 'Int64', 'False'") - .HasAnnotation("Relational:Sequence:.catalog_type_hilo", "'catalog_type_hilo', '', '1', '10', '', '', 'Int64', 'False'") - .HasAnnotation("Relational:Sequence:.stock_hilo", "'stock_hilo', '', '1', '10', '', '', 'Int64', 'False'") - .HasAnnotation("SqlServer:ValueGenerationStrategy", SqlServerValueGenerationStrategy.IdentityColumn); - - modelBuilder.Entity("Nethereum.eShop.ApplicationCore.Entities.BasketAggregate.Basket", b => - { - b.Property("Id") - .ValueGeneratedOnAdd() - .HasColumnType("int") - .HasAnnotation("SqlServer:ValueGenerationStrategy", SqlServerValueGenerationStrategy.IdentityColumn); - - b.Property("BuyerAddress") - .IsRequired() - .HasColumnType("nvarchar(43)") - .HasMaxLength(43); - - b.Property("BuyerId") - .IsRequired() - .HasColumnType("nvarchar(256)") - .HasMaxLength(256); - - b.Property("TransactionHash") - .HasColumnType("nvarchar(67)") - .HasMaxLength(67); - - b.HasKey("Id"); - - b.HasIndex("BuyerAddress"); - - b.HasIndex("BuyerId"); - - b.ToTable("Baskets"); - }); - - modelBuilder.Entity("Nethereum.eShop.ApplicationCore.Entities.BasketAggregate.BasketItem", b => - { - b.Property("Id") - .ValueGeneratedOnAdd() - .HasColumnType("int") - .HasAnnotation("SqlServer:ValueGenerationStrategy", SqlServerValueGenerationStrategy.IdentityColumn); - - b.Property("BasketId") - .HasColumnType("int"); - - b.Property("CatalogItemId") - .HasColumnType("int"); - - b.Property("Quantity") - .HasColumnType("int"); - - b.Property("UnitPrice") - .HasColumnType("decimal(18,2)"); - - b.HasKey("Id"); - - b.HasIndex("BasketId"); - - b.ToTable("BasketItems"); - }); - - modelBuilder.Entity("Nethereum.eShop.ApplicationCore.Entities.BuyerAggregate.Buyer", b => - { - b.Property("Id") - .ValueGeneratedOnAdd() - .HasColumnType("int") - .HasAnnotation("SqlServer:ValueGenerationStrategy", SqlServerValueGenerationStrategy.IdentityColumn); - - b.Property("BuyerAddress") - .HasColumnType("nvarchar(43)") - .HasMaxLength(43); - - b.Property("BuyerId") - .IsRequired() - .HasColumnType("nvarchar(256)") - .HasMaxLength(256); - - b.HasKey("Id"); - - b.HasIndex("BuyerAddress") - .IsUnique() - .HasFilter("[BuyerAddress] IS NOT NULL"); - - b.HasIndex("BuyerId") - .IsUnique(); - - b.ToTable("Buyers"); - }); - - modelBuilder.Entity("Nethereum.eShop.ApplicationCore.Entities.BuyerAggregate.BuyerPostalAddress", b => - { - b.Property("Id") - .ValueGeneratedOnAdd() - .HasColumnType("int") - .HasAnnotation("SqlServer:ValueGenerationStrategy", SqlServerValueGenerationStrategy.IdentityColumn); - - b.Property("BuyerId") - .HasColumnType("int"); - - b.Property("Name") - .HasColumnType("nvarchar(max)"); - - b.HasKey("Id"); - - b.HasIndex("BuyerId"); - - b.ToTable("BuyerPostalAddress"); - }); - - modelBuilder.Entity("Nethereum.eShop.ApplicationCore.Entities.CatalogBrand", b => - { - b.Property("Id") - .ValueGeneratedOnAdd() - .HasColumnType("int") - .HasAnnotation("SqlServer:HiLoSequenceName", "catalog_brand_hilo") - .HasAnnotation("SqlServer:ValueGenerationStrategy", SqlServerValueGenerationStrategy.SequenceHiLo); - - b.Property("Brand") - .IsRequired() - .HasColumnType("nvarchar(100)") - .HasMaxLength(100); - - b.HasKey("Id"); - - b.ToTable("CatalogBrands"); - }); - - modelBuilder.Entity("Nethereum.eShop.ApplicationCore.Entities.CatalogItem", b => - { - b.Property("Id") - .ValueGeneratedOnAdd() - .HasColumnType("int") - .HasAnnotation("SqlServer:HiLoSequenceName", "catalog_hilo") - .HasAnnotation("SqlServer:ValueGenerationStrategy", SqlServerValueGenerationStrategy.SequenceHiLo); - - b.Property("AttributeJson") - .HasColumnType("nvarchar(max)"); - - b.Property("CatalogBrandId") - .HasColumnType("int"); - - b.Property("CatalogTypeId") - .HasColumnType("int"); - - b.Property("Depth") - .HasColumnType("int"); - - b.Property("Description") - .HasColumnType("nvarchar(max)"); - - b.Property("Gtin") - .IsRequired() - .HasColumnType("nvarchar(14)") - .HasMaxLength(14); - - b.Property("GtinRegistryId") - .HasColumnType("int"); - - b.Property("Height") - .HasColumnType("int"); - - b.Property("Name") - .IsRequired() - .HasColumnType("nvarchar(50)") - .HasMaxLength(50); - - b.Property("PictureLargeUri") - .HasColumnType("nvarchar(512)") - .HasMaxLength(512); - - b.Property("PictureMediumUri") - .HasColumnType("nvarchar(512)") - .HasMaxLength(512); - - b.Property("PictureSmallUri") - .HasColumnType("nvarchar(512)") - .HasMaxLength(512); - - b.Property("PictureUri") - .HasColumnType("nvarchar(512)") - .HasMaxLength(512); - - b.Property("Price") - .HasColumnType("decimal(18,2)"); - - b.Property("Rank") - .HasColumnType("int"); - - b.Property("Status") - .HasColumnType("int"); - - b.Property("Unit") - .HasColumnType("nvarchar(8)") - .HasMaxLength(8); - - b.Property("Weight") - .HasColumnType("int"); - - b.Property("Width") - .HasColumnType("int"); - - b.HasKey("Id"); - - b.HasIndex("CatalogBrandId"); - - b.HasIndex("CatalogTypeId"); - - b.ToTable("Catalog"); - }); - - modelBuilder.Entity("Nethereum.eShop.ApplicationCore.Entities.CatalogType", b => - { - b.Property("Id") - .ValueGeneratedOnAdd() - .HasColumnType("int") - .HasAnnotation("SqlServer:HiLoSequenceName", "catalog_type_hilo") - .HasAnnotation("SqlServer:ValueGenerationStrategy", SqlServerValueGenerationStrategy.SequenceHiLo); - - b.Property("Type") - .IsRequired() - .HasColumnType("nvarchar(100)") - .HasMaxLength(100); - - b.HasKey("Id"); - - b.ToTable("CatalogTypes"); - }); - - modelBuilder.Entity("Nethereum.eShop.ApplicationCore.Entities.OrderAggregate.Order", b => - { - b.Property("Id") - .ValueGeneratedOnAdd() - .HasColumnType("int") - .HasAnnotation("SqlServer:ValueGenerationStrategy", SqlServerValueGenerationStrategy.IdentityColumn); - - b.Property("ApproverAddress") - .HasColumnType("nvarchar(43)") - .HasMaxLength(43); - - b.Property("BuyerAddress") - .HasColumnType("nvarchar(43)") - .HasMaxLength(43); - - b.Property("BuyerId") - .IsRequired() - .HasColumnType("nvarchar(256)") - .HasMaxLength(256); - - b.Property("BuyerWalletAddress") - .HasColumnType("nvarchar(43)") - .HasMaxLength(43); - - b.Property("CurrencyAddress") - .HasColumnType("nvarchar(43)") - .HasMaxLength(43); - - b.Property("CurrencySymbol") - .HasColumnType("nvarchar(32)") - .HasMaxLength(32); - - b.Property("OrderDate") - .HasColumnType("datetimeoffset"); - - b.Property("PoDate") - .HasColumnType("datetimeoffset"); - - b.Property("PoNumber") - .HasColumnType("bigint"); - - b.Property("PoType") - .HasColumnType("int"); - - b.Property("QuoteId") - .HasColumnType("int"); - - b.Property("SellerId") - .HasColumnType("nvarchar(32)") - .HasMaxLength(32); - - b.Property("Status") - .HasColumnType("int"); - - b.Property("TransactionHash") - .HasColumnType("nvarchar(67)") - .HasMaxLength(67); - - b.HasKey("Id"); - - b.HasIndex("BuyerAddress"); - - b.HasIndex("BuyerId"); - - b.ToTable("Orders"); - }); - - modelBuilder.Entity("Nethereum.eShop.ApplicationCore.Entities.OrderAggregate.OrderItem", b => - { - b.Property("Id") - .ValueGeneratedOnAdd() - .HasColumnType("int") - .HasAnnotation("SqlServer:ValueGenerationStrategy", SqlServerValueGenerationStrategy.IdentityColumn); - - b.Property("ActualEscrowReleaseDate") - .HasColumnType("datetimeoffset"); - - b.Property("CurrencyValue") - .HasColumnType("nvarchar(100)") - .HasMaxLength(100); - - b.Property("GoodsIssueDate") - .HasColumnType("datetimeoffset"); - - b.Property("IsEscrowReleased") - .HasColumnType("bit"); - - b.Property("OrderId") - .HasColumnType("int"); - - b.Property("PlannedEscrowReleaseDate") - .HasColumnType("datetimeoffset"); - - b.Property("PoItemNumber") - .HasColumnType("int"); - - b.Property("PoItemStatus") - .HasColumnType("int"); - - b.Property("Quantity") - .HasColumnType("int"); - - b.Property("QuantityAddress") - .HasColumnType("nvarchar(43)") - .HasMaxLength(43); - - b.Property("QuantitySymbol") - .HasColumnType("nvarchar(32)") - .HasMaxLength(32); - - b.Property("Status") - .HasColumnType("int"); - - b.Property("Unit") - .HasColumnType("nvarchar(50)") - .HasMaxLength(50); - - b.Property("UnitPrice") - .HasColumnType("decimal(18,2)"); - - b.HasKey("Id"); - - b.HasIndex("OrderId"); - - b.ToTable("OrderItems"); - }); - - modelBuilder.Entity("Nethereum.eShop.ApplicationCore.Entities.QuoteAggregate.Quote", b => - { - b.Property("Id") - .ValueGeneratedOnAdd() - .HasColumnType("int") - .HasAnnotation("SqlServer:ValueGenerationStrategy", SqlServerValueGenerationStrategy.IdentityColumn); - - b.Property("ApproverAddress") - .HasColumnType("nvarchar(43)") - .HasMaxLength(43); - - b.Property("BuyerAddress") - .HasColumnType("nvarchar(43)") - .HasMaxLength(43); - - b.Property("BuyerId") - .IsRequired() - .HasColumnType("nvarchar(256)") - .HasMaxLength(256); - - b.Property("BuyerWalletAddress") - .HasColumnType("nvarchar(43)") - .HasMaxLength(43); - - b.Property("CurrencyAddress") - .HasColumnType("nvarchar(43)") - .HasMaxLength(43); - - b.Property("CurrencySymbol") - .HasColumnType("nvarchar(32)") - .HasMaxLength(32); - - b.Property("Date") - .HasColumnType("datetimeoffset"); - - b.Property("Expiry") - .HasColumnType("datetimeoffset"); - - b.Property("PoNumber") - .HasColumnType("bigint"); - - b.Property("PoType") - .HasColumnType("int"); - - b.Property("SellerId") - .HasColumnType("nvarchar(32)") - .HasMaxLength(32); - - b.Property("Status") - .HasColumnType("int"); - - b.Property("TransactionHash") - .HasColumnType("nvarchar(67)") - .HasMaxLength(67); - - b.HasKey("Id"); - - b.HasIndex("BuyerAddress"); - - b.HasIndex("BuyerId"); - - b.ToTable("Quotes"); - }); - - modelBuilder.Entity("Nethereum.eShop.ApplicationCore.Entities.QuoteAggregate.QuoteItem", b => - { - b.Property("Id") - .ValueGeneratedOnAdd() - .HasColumnType("int") - .HasAnnotation("SqlServer:ValueGenerationStrategy", SqlServerValueGenerationStrategy.IdentityColumn); - - b.Property("CurrencyValue") - .HasColumnType("nvarchar(max)"); - - b.Property("EscrowReleaseDate") - .HasColumnType("datetimeoffset"); - - b.Property("PoItemNumber") - .HasColumnType("int"); - - b.Property("Quantity") - .HasColumnType("int"); - - b.Property("QuantityAddress") - .HasColumnType("nvarchar(max)"); - - b.Property("QuantitySymbol") - .HasColumnType("nvarchar(max)"); - - b.Property("QuoteId") - .HasColumnType("int"); - - b.Property("Unit") - .HasColumnType("nvarchar(max)"); - - b.Property("UnitPrice") - .HasColumnType("decimal(18,2)"); - - b.HasKey("Id"); - - b.HasIndex("QuoteId"); - - b.ToTable("QuoteItems"); - }); - - modelBuilder.Entity("Nethereum.eShop.ApplicationCore.Entities.StockItem", b => - { - b.Property("Id") - .ValueGeneratedOnAdd() - .HasColumnType("int") - .HasAnnotation("SqlServer:HiLoSequenceName", "stock_hilo") - .HasAnnotation("SqlServer:ValueGenerationStrategy", SqlServerValueGenerationStrategy.SequenceHiLo); - - b.Property("CatalogItemId") - .HasColumnType("int"); - - b.Property("Location") - .IsRequired() - .HasColumnType("nvarchar(50)") - .HasMaxLength(50); - - b.Property("Quantity") - .HasColumnType("int"); - - b.HasKey("Id"); - - b.HasIndex("CatalogItemId"); - - b.ToTable("Stock"); - }); - - modelBuilder.Entity("Nethereum.eShop.ApplicationCore.Entities.BasketAggregate.Basket", b => - { - b.OwnsOne("Nethereum.eShop.ApplicationCore.Entities.PostalAddress", "BillTo", b1 => - { - b1.Property("BasketId") - .ValueGeneratedOnAdd() - .HasColumnType("int") - .HasAnnotation("SqlServer:ValueGenerationStrategy", SqlServerValueGenerationStrategy.IdentityColumn); - - b1.Property("City") - .IsRequired() - .HasColumnType("nvarchar(100)") - .HasMaxLength(100); - - b1.Property("Country") - .IsRequired() - .HasColumnType("nvarchar(90)") - .HasMaxLength(90); - - b1.Property("RecipientName") - .IsRequired() - .HasColumnType("nvarchar(255)") - .HasMaxLength(255); - - b1.Property("State") - .HasColumnType("nvarchar(60)") - .HasMaxLength(60); - - b1.Property("Street") - .IsRequired() - .HasColumnType("nvarchar(180)") - .HasMaxLength(180); - - b1.Property("ZipCode") - .IsRequired() - .HasColumnType("nvarchar(18)") - .HasMaxLength(18); - - b1.HasKey("BasketId"); - - b1.ToTable("Baskets"); - - b1.WithOwner() - .HasForeignKey("BasketId"); - }); - - b.OwnsOne("Nethereum.eShop.ApplicationCore.Entities.PostalAddress", "ShipTo", b1 => - { - b1.Property("BasketId") - .ValueGeneratedOnAdd() - .HasColumnType("int") - .HasAnnotation("SqlServer:ValueGenerationStrategy", SqlServerValueGenerationStrategy.IdentityColumn); - - b1.Property("City") - .IsRequired() - .HasColumnType("nvarchar(100)") - .HasMaxLength(100); - - b1.Property("Country") - .IsRequired() - .HasColumnType("nvarchar(90)") - .HasMaxLength(90); - - b1.Property("RecipientName") - .IsRequired() - .HasColumnType("nvarchar(255)") - .HasMaxLength(255); - - b1.Property("State") - .HasColumnType("nvarchar(60)") - .HasMaxLength(60); - - b1.Property("Street") - .IsRequired() - .HasColumnType("nvarchar(180)") - .HasMaxLength(180); - - b1.Property("ZipCode") - .IsRequired() - .HasColumnType("nvarchar(18)") - .HasMaxLength(18); - - b1.HasKey("BasketId"); - - b1.ToTable("Baskets"); - - b1.WithOwner() - .HasForeignKey("BasketId"); - }); - }); - - modelBuilder.Entity("Nethereum.eShop.ApplicationCore.Entities.BasketAggregate.BasketItem", b => - { - b.HasOne("Nethereum.eShop.ApplicationCore.Entities.BasketAggregate.Basket", null) - .WithMany("Items") - .HasForeignKey("BasketId") - .OnDelete(DeleteBehavior.Cascade) - .IsRequired(); - }); - - modelBuilder.Entity("Nethereum.eShop.ApplicationCore.Entities.BuyerAggregate.BuyerPostalAddress", b => - { - b.HasOne("Nethereum.eShop.ApplicationCore.Entities.BuyerAggregate.Buyer", null) - .WithMany("PostalAddresses") - .HasForeignKey("BuyerId"); - - b.OwnsOne("Nethereum.eShop.ApplicationCore.Entities.PostalAddress", "PostalAddress", b1 => - { - b1.Property("BuyerPostalAddressId") - .ValueGeneratedOnAdd() - .HasColumnType("int") - .HasAnnotation("SqlServer:ValueGenerationStrategy", SqlServerValueGenerationStrategy.IdentityColumn); - - b1.Property("City") - .IsRequired() - .HasColumnType("nvarchar(100)") - .HasMaxLength(100); - - b1.Property("Country") - .IsRequired() - .HasColumnType("nvarchar(90)") - .HasMaxLength(90); - - b1.Property("RecipientName") - .IsRequired() - .HasColumnType("nvarchar(255)") - .HasMaxLength(255); - - b1.Property("State") - .HasColumnType("nvarchar(60)") - .HasMaxLength(60); - - b1.Property("Street") - .IsRequired() - .HasColumnType("nvarchar(180)") - .HasMaxLength(180); - - b1.Property("ZipCode") - .IsRequired() - .HasColumnType("nvarchar(18)") - .HasMaxLength(18); - - b1.HasKey("BuyerPostalAddressId"); - - b1.ToTable("BuyerPostalAddress"); - - b1.WithOwner() - .HasForeignKey("BuyerPostalAddressId"); - }); - }); - - modelBuilder.Entity("Nethereum.eShop.ApplicationCore.Entities.CatalogItem", b => - { - b.HasOne("Nethereum.eShop.ApplicationCore.Entities.CatalogBrand", "CatalogBrand") - .WithMany() - .HasForeignKey("CatalogBrandId") - .OnDelete(DeleteBehavior.Cascade) - .IsRequired(); - - b.HasOne("Nethereum.eShop.ApplicationCore.Entities.CatalogType", "CatalogType") - .WithMany() - .HasForeignKey("CatalogTypeId") - .OnDelete(DeleteBehavior.Cascade) - .IsRequired(); - }); - - modelBuilder.Entity("Nethereum.eShop.ApplicationCore.Entities.OrderAggregate.Order", b => - { - b.OwnsOne("Nethereum.eShop.ApplicationCore.Entities.PostalAddress", "BillTo", b1 => - { - b1.Property("OrderId") - .ValueGeneratedOnAdd() - .HasColumnType("int") - .HasAnnotation("SqlServer:ValueGenerationStrategy", SqlServerValueGenerationStrategy.IdentityColumn); - - b1.Property("City") - .IsRequired() - .HasColumnType("nvarchar(100)") - .HasMaxLength(100); - - b1.Property("Country") - .IsRequired() - .HasColumnType("nvarchar(90)") - .HasMaxLength(90); - - b1.Property("RecipientName") - .IsRequired() - .HasColumnType("nvarchar(255)") - .HasMaxLength(255); - - b1.Property("State") - .HasColumnType("nvarchar(60)") - .HasMaxLength(60); - - b1.Property("Street") - .IsRequired() - .HasColumnType("nvarchar(180)") - .HasMaxLength(180); - - b1.Property("ZipCode") - .IsRequired() - .HasColumnType("nvarchar(18)") - .HasMaxLength(18); - - b1.HasKey("OrderId"); - - b1.ToTable("Orders"); - - b1.WithOwner() - .HasForeignKey("OrderId"); - }); - - b.OwnsOne("Nethereum.eShop.ApplicationCore.Entities.PostalAddress", "ShipTo", b1 => - { - b1.Property("OrderId") - .ValueGeneratedOnAdd() - .HasColumnType("int") - .HasAnnotation("SqlServer:ValueGenerationStrategy", SqlServerValueGenerationStrategy.IdentityColumn); - - b1.Property("City") - .IsRequired() - .HasColumnType("nvarchar(100)") - .HasMaxLength(100); - - b1.Property("Country") - .IsRequired() - .HasColumnType("nvarchar(90)") - .HasMaxLength(90); - - b1.Property("RecipientName") - .IsRequired() - .HasColumnType("nvarchar(255)") - .HasMaxLength(255); - - b1.Property("State") - .HasColumnType("nvarchar(60)") - .HasMaxLength(60); - - b1.Property("Street") - .IsRequired() - .HasColumnType("nvarchar(180)") - .HasMaxLength(180); - - b1.Property("ZipCode") - .IsRequired() - .HasColumnType("nvarchar(18)") - .HasMaxLength(18); - - b1.HasKey("OrderId"); - - b1.ToTable("Orders"); - - b1.WithOwner() - .HasForeignKey("OrderId"); - }); - }); - - modelBuilder.Entity("Nethereum.eShop.ApplicationCore.Entities.OrderAggregate.OrderItem", b => - { - b.HasOne("Nethereum.eShop.ApplicationCore.Entities.OrderAggregate.Order", null) - .WithMany("OrderItems") - .HasForeignKey("OrderId"); - - b.OwnsOne("Nethereum.eShop.ApplicationCore.Entities.CatalogItemExcerpt", "ItemOrdered", b1 => - { - b1.Property("OrderItemId") - .ValueGeneratedOnAdd() - .HasColumnType("int") - .HasAnnotation("SqlServer:ValueGenerationStrategy", SqlServerValueGenerationStrategy.IdentityColumn); - - b1.Property("CatalogItemId") - .HasColumnType("int"); - - b1.Property("Gtin") - .HasColumnType("nvarchar(max)"); - - b1.Property("GtinRegistryId") - .HasColumnType("int"); - - b1.Property("PictureUri") - .HasColumnType("nvarchar(512)") - .HasMaxLength(512); - - b1.Property("ProductName") - .IsRequired() - .HasColumnType("nvarchar(50)") - .HasMaxLength(50); - - b1.HasKey("OrderItemId"); - - b1.ToTable("OrderItems"); - - b1.WithOwner() - .HasForeignKey("OrderItemId"); - }); - }); - - modelBuilder.Entity("Nethereum.eShop.ApplicationCore.Entities.QuoteAggregate.Quote", b => - { - b.OwnsOne("Nethereum.eShop.ApplicationCore.Entities.PostalAddress", "BillTo", b1 => - { - b1.Property("QuoteId") - .ValueGeneratedOnAdd() - .HasColumnType("int") - .HasAnnotation("SqlServer:ValueGenerationStrategy", SqlServerValueGenerationStrategy.IdentityColumn); - - b1.Property("City") - .IsRequired() - .HasColumnType("nvarchar(100)") - .HasMaxLength(100); - - b1.Property("Country") - .IsRequired() - .HasColumnType("nvarchar(90)") - .HasMaxLength(90); - - b1.Property("RecipientName") - .IsRequired() - .HasColumnType("nvarchar(255)") - .HasMaxLength(255); - - b1.Property("State") - .HasColumnType("nvarchar(60)") - .HasMaxLength(60); - - b1.Property("Street") - .IsRequired() - .HasColumnType("nvarchar(180)") - .HasMaxLength(180); - - b1.Property("ZipCode") - .IsRequired() - .HasColumnType("nvarchar(18)") - .HasMaxLength(18); - - b1.HasKey("QuoteId"); - - b1.ToTable("Quotes"); - - b1.WithOwner() - .HasForeignKey("QuoteId"); - }); - - b.OwnsOne("Nethereum.eShop.ApplicationCore.Entities.PostalAddress", "ShipTo", b1 => - { - b1.Property("QuoteId") - .ValueGeneratedOnAdd() - .HasColumnType("int") - .HasAnnotation("SqlServer:ValueGenerationStrategy", SqlServerValueGenerationStrategy.IdentityColumn); - - b1.Property("City") - .IsRequired() - .HasColumnType("nvarchar(100)") - .HasMaxLength(100); - - b1.Property("Country") - .IsRequired() - .HasColumnType("nvarchar(90)") - .HasMaxLength(90); - - b1.Property("RecipientName") - .IsRequired() - .HasColumnType("nvarchar(255)") - .HasMaxLength(255); - - b1.Property("State") - .HasColumnType("nvarchar(60)") - .HasMaxLength(60); - - b1.Property("Street") - .IsRequired() - .HasColumnType("nvarchar(180)") - .HasMaxLength(180); - - b1.Property("ZipCode") - .IsRequired() - .HasColumnType("nvarchar(18)") - .HasMaxLength(18); - - b1.HasKey("QuoteId"); - - b1.ToTable("Quotes"); - - b1.WithOwner() - .HasForeignKey("QuoteId"); - }); - }); - - modelBuilder.Entity("Nethereum.eShop.ApplicationCore.Entities.QuoteAggregate.QuoteItem", b => - { - b.HasOne("Nethereum.eShop.ApplicationCore.Entities.QuoteAggregate.Quote", null) - .WithMany("QuoteItems") - .HasForeignKey("QuoteId"); - - b.OwnsOne("Nethereum.eShop.ApplicationCore.Entities.CatalogItemExcerpt", "ItemOrdered", b1 => - { - b1.Property("QuoteItemId") - .ValueGeneratedOnAdd() - .HasColumnType("int") - .HasAnnotation("SqlServer:ValueGenerationStrategy", SqlServerValueGenerationStrategy.IdentityColumn); - - b1.Property("CatalogItemId") - .HasColumnType("int"); - - b1.Property("Gtin") - .HasColumnType("nvarchar(max)"); - - b1.Property("GtinRegistryId") - .HasColumnType("int"); - - b1.Property("PictureUri") - .HasColumnType("nvarchar(512)") - .HasMaxLength(512); - - b1.Property("ProductName") - .IsRequired() - .HasColumnType("nvarchar(50)") - .HasMaxLength(50); - - b1.HasKey("QuoteItemId"); - - b1.ToTable("QuoteItems"); - - b1.WithOwner() - .HasForeignKey("QuoteItemId"); - }); - }); - - modelBuilder.Entity("Nethereum.eShop.ApplicationCore.Entities.StockItem", b => - { - b.HasOne("Nethereum.eShop.ApplicationCore.Entities.CatalogItem", "CatalogItem") - .WithMany() - .HasForeignKey("CatalogItemId") - .OnDelete(DeleteBehavior.Cascade) - .IsRequired(); - }); -#pragma warning restore 612, 618 - } - } -} diff --git a/src/Nethereum.eShop.SqlServer/Infrastructure/Data/Migrations/20200304170042_ResizeColumns.cs b/src/Nethereum.eShop.SqlServer/Infrastructure/Data/Migrations/20200304170042_ResizeColumns.cs deleted file mode 100644 index 2f4d2a8..0000000 --- a/src/Nethereum.eShop.SqlServer/Infrastructure/Data/Migrations/20200304170042_ResizeColumns.cs +++ /dev/null @@ -1,319 +0,0 @@ -using Microsoft.EntityFrameworkCore.Migrations; - -namespace Nethereum.eShop.Infrastructure.Data.Migrations -{ - public partial class ResizeColumns : Migration - { - protected override void Up(MigrationBuilder migrationBuilder) - { - migrationBuilder.AlterColumn( - name: "SellerId", - table: "Quotes", - maxLength: 32, - nullable: true, - oldClrType: typeof(string), - oldType: "nvarchar(max)", - oldNullable: true); - - migrationBuilder.AlterColumn( - name: "CurrencySymbol", - table: "Quotes", - maxLength: 32, - nullable: true, - oldClrType: typeof(string), - oldType: "nvarchar(max)", - oldNullable: true); - - migrationBuilder.AlterColumn( - name: "CurrencyAddress", - table: "Quotes", - maxLength: 43, - nullable: true, - oldClrType: typeof(string), - oldType: "nvarchar(max)", - oldNullable: true); - - migrationBuilder.AlterColumn( - name: "ItemOrdered_PictureUri", - table: "QuoteItems", - maxLength: 512, - nullable: true, - oldClrType: typeof(string), - oldType: "nvarchar(max)", - oldNullable: true); - - migrationBuilder.AlterColumn( - name: "SellerId", - table: "Orders", - maxLength: 32, - nullable: true, - oldClrType: typeof(string), - oldType: "nvarchar(max)", - oldNullable: true); - - migrationBuilder.AlterColumn( - name: "CurrencySymbol", - table: "Orders", - maxLength: 32, - nullable: true, - oldClrType: typeof(string), - oldType: "nvarchar(max)", - oldNullable: true); - - migrationBuilder.AlterColumn( - name: "CurrencyAddress", - table: "Orders", - maxLength: 43, - nullable: true, - oldClrType: typeof(string), - oldType: "nvarchar(max)", - oldNullable: true); - - migrationBuilder.AlterColumn( - name: "ItemOrdered_PictureUri", - table: "OrderItems", - maxLength: 512, - nullable: true, - oldClrType: typeof(string), - oldType: "nvarchar(max)", - oldNullable: true); - - migrationBuilder.AlterColumn( - name: "Unit", - table: "OrderItems", - maxLength: 50, - nullable: true, - oldClrType: typeof(string), - oldType: "nvarchar(max)", - oldNullable: true); - - migrationBuilder.AlterColumn( - name: "QuantitySymbol", - table: "OrderItems", - maxLength: 32, - nullable: true, - oldClrType: typeof(string), - oldType: "nvarchar(max)", - oldNullable: true); - - migrationBuilder.AlterColumn( - name: "QuantityAddress", - table: "OrderItems", - maxLength: 43, - nullable: true, - oldClrType: typeof(string), - oldType: "nvarchar(max)", - oldNullable: true); - - migrationBuilder.AlterColumn( - name: "CurrencyValue", - table: "OrderItems", - maxLength: 100, - nullable: true, - oldClrType: typeof(string), - oldType: "nvarchar(max)", - oldNullable: true); - - migrationBuilder.AlterColumn( - name: "PictureUri", - table: "Catalog", - maxLength: 512, - nullable: true, - oldClrType: typeof(string), - oldType: "nvarchar(max)", - oldNullable: true); - - migrationBuilder.AlterColumn( - name: "PictureSmallUri", - table: "Catalog", - maxLength: 512, - nullable: true, - oldClrType: typeof(string), - oldType: "nvarchar(max)", - oldNullable: true); - - migrationBuilder.AlterColumn( - name: "PictureMediumUri", - table: "Catalog", - maxLength: 512, - nullable: true, - oldClrType: typeof(string), - oldType: "nvarchar(max)", - oldNullable: true); - - migrationBuilder.AlterColumn( - name: "PictureLargeUri", - table: "Catalog", - maxLength: 512, - nullable: true, - oldClrType: typeof(string), - oldType: "nvarchar(max)", - oldNullable: true); - - migrationBuilder.AlterColumn( - name: "TransactionHash", - table: "Baskets", - maxLength: 67, - nullable: true, - oldClrType: typeof(string), - oldType: "nvarchar(max)", - oldNullable: true); - } - - protected override void Down(MigrationBuilder migrationBuilder) - { - migrationBuilder.AlterColumn( - name: "SellerId", - table: "Quotes", - type: "nvarchar(max)", - nullable: true, - oldClrType: typeof(string), - oldMaxLength: 32, - oldNullable: true); - - migrationBuilder.AlterColumn( - name: "CurrencySymbol", - table: "Quotes", - type: "nvarchar(max)", - nullable: true, - oldClrType: typeof(string), - oldMaxLength: 32, - oldNullable: true); - - migrationBuilder.AlterColumn( - name: "CurrencyAddress", - table: "Quotes", - type: "nvarchar(max)", - nullable: true, - oldClrType: typeof(string), - oldMaxLength: 43, - oldNullable: true); - - migrationBuilder.AlterColumn( - name: "ItemOrdered_PictureUri", - table: "QuoteItems", - type: "nvarchar(max)", - nullable: true, - oldClrType: typeof(string), - oldMaxLength: 512, - oldNullable: true); - - migrationBuilder.AlterColumn( - name: "SellerId", - table: "Orders", - type: "nvarchar(max)", - nullable: true, - oldClrType: typeof(string), - oldMaxLength: 32, - oldNullable: true); - - migrationBuilder.AlterColumn( - name: "CurrencySymbol", - table: "Orders", - type: "nvarchar(max)", - nullable: true, - oldClrType: typeof(string), - oldMaxLength: 32, - oldNullable: true); - - migrationBuilder.AlterColumn( - name: "CurrencyAddress", - table: "Orders", - type: "nvarchar(max)", - nullable: true, - oldClrType: typeof(string), - oldMaxLength: 43, - oldNullable: true); - - migrationBuilder.AlterColumn( - name: "ItemOrdered_PictureUri", - table: "OrderItems", - type: "nvarchar(max)", - nullable: true, - oldClrType: typeof(string), - oldMaxLength: 512, - oldNullable: true); - - migrationBuilder.AlterColumn( - name: "Unit", - table: "OrderItems", - type: "nvarchar(max)", - nullable: true, - oldClrType: typeof(string), - oldMaxLength: 50, - oldNullable: true); - - migrationBuilder.AlterColumn( - name: "QuantitySymbol", - table: "OrderItems", - type: "nvarchar(max)", - nullable: true, - oldClrType: typeof(string), - oldMaxLength: 32, - oldNullable: true); - - migrationBuilder.AlterColumn( - name: "QuantityAddress", - table: "OrderItems", - type: "nvarchar(max)", - nullable: true, - oldClrType: typeof(string), - oldMaxLength: 43, - oldNullable: true); - - migrationBuilder.AlterColumn( - name: "CurrencyValue", - table: "OrderItems", - type: "nvarchar(max)", - nullable: true, - oldClrType: typeof(string), - oldMaxLength: 100, - oldNullable: true); - - migrationBuilder.AlterColumn( - name: "PictureUri", - table: "Catalog", - type: "nvarchar(max)", - nullable: true, - oldClrType: typeof(string), - oldMaxLength: 512, - oldNullable: true); - - migrationBuilder.AlterColumn( - name: "PictureSmallUri", - table: "Catalog", - type: "nvarchar(max)", - nullable: true, - oldClrType: typeof(string), - oldMaxLength: 512, - oldNullable: true); - - migrationBuilder.AlterColumn( - name: "PictureMediumUri", - table: "Catalog", - type: "nvarchar(max)", - nullable: true, - oldClrType: typeof(string), - oldMaxLength: 512, - oldNullable: true); - - migrationBuilder.AlterColumn( - name: "PictureLargeUri", - table: "Catalog", - type: "nvarchar(max)", - nullable: true, - oldClrType: typeof(string), - oldMaxLength: 512, - oldNullable: true); - - migrationBuilder.AlterColumn( - name: "TransactionHash", - table: "Baskets", - type: "nvarchar(max)", - nullable: true, - oldClrType: typeof(string), - oldMaxLength: 67, - oldNullable: true); - } - } -} diff --git a/src/Nethereum.eShop.SqlServer/Infrastructure/Data/Migrations/20200304171630_SetGtinColumnSize.cs b/src/Nethereum.eShop.SqlServer/Infrastructure/Data/Migrations/20200304171630_SetGtinColumnSize.cs deleted file mode 100644 index c4382f2..0000000 --- a/src/Nethereum.eShop.SqlServer/Infrastructure/Data/Migrations/20200304171630_SetGtinColumnSize.cs +++ /dev/null @@ -1,49 +0,0 @@ -using Microsoft.EntityFrameworkCore.Migrations; - -namespace Nethereum.eShop.Infrastructure.Data.Migrations -{ - public partial class SetGtinColumnSize : Migration - { - protected override void Up(MigrationBuilder migrationBuilder) - { - migrationBuilder.AlterColumn( - name: "ItemOrdered_Gtin", - table: "QuoteItems", - maxLength: 14, - nullable: true, - oldClrType: typeof(string), - oldType: "nvarchar(max)", - oldNullable: true); - - migrationBuilder.AlterColumn( - name: "ItemOrdered_Gtin", - table: "OrderItems", - maxLength: 14, - nullable: true, - oldClrType: typeof(string), - oldType: "nvarchar(max)", - oldNullable: true); - } - - protected override void Down(MigrationBuilder migrationBuilder) - { - migrationBuilder.AlterColumn( - name: "ItemOrdered_Gtin", - table: "QuoteItems", - type: "nvarchar(max)", - nullable: true, - oldClrType: typeof(string), - oldMaxLength: 14, - oldNullable: true); - - migrationBuilder.AlterColumn( - name: "ItemOrdered_Gtin", - table: "OrderItems", - type: "nvarchar(max)", - nullable: true, - oldClrType: typeof(string), - oldMaxLength: 14, - oldNullable: true); - } - } -} diff --git a/src/Nethereum.eShop.SqlServer/Infrastructure/Data/Migrations/20200304171630_SetGtinColumnSize.Designer.cs b/src/Nethereum.eShop.SqlServer/Infrastructure/Data/Migrations/20200310171921_Catalog_InitialCreate.Designer.cs similarity index 99% rename from src/Nethereum.eShop.SqlServer/Infrastructure/Data/Migrations/20200304171630_SetGtinColumnSize.Designer.cs rename to src/Nethereum.eShop.SqlServer/Infrastructure/Data/Migrations/20200310171921_Catalog_InitialCreate.Designer.cs index 01bc531..16269df 100644 --- a/src/Nethereum.eShop.SqlServer/Infrastructure/Data/Migrations/20200304171630_SetGtinColumnSize.Designer.cs +++ b/src/Nethereum.eShop.SqlServer/Infrastructure/Data/Migrations/20200310171921_Catalog_InitialCreate.Designer.cs @@ -7,11 +7,11 @@ using Microsoft.EntityFrameworkCore.Storage.ValueConversion; using Nethereum.eShop.Infrastructure.Data; -namespace Nethereum.eShop.Infrastructure.Data.Migrations +namespace Nethereum.eShop.SqlServer.Migrations.Migrations { [DbContext(typeof(CatalogContext))] - [Migration("20200304171630_SetGtinColumnSize")] - partial class SetGtinColumnSize + [Migration("20200310171921_Catalog_InitialCreate")] + partial class Catalog_InitialCreate { protected override void BuildTargetModel(ModelBuilder modelBuilder) { diff --git a/src/Nethereum.eShop.SqlServer/Infrastructure/Data/Migrations/20200221124040_InitialCreate.cs b/src/Nethereum.eShop.SqlServer/Infrastructure/Data/Migrations/20200310171921_Catalog_InitialCreate.cs similarity index 92% rename from src/Nethereum.eShop.SqlServer/Infrastructure/Data/Migrations/20200221124040_InitialCreate.cs rename to src/Nethereum.eShop.SqlServer/Infrastructure/Data/Migrations/20200310171921_Catalog_InitialCreate.cs index 5dba2d3..6fc4c8e 100644 --- a/src/Nethereum.eShop.SqlServer/Infrastructure/Data/Migrations/20200221124040_InitialCreate.cs +++ b/src/Nethereum.eShop.SqlServer/Infrastructure/Data/Migrations/20200310171921_Catalog_InitialCreate.cs @@ -1,9 +1,9 @@ using System; using Microsoft.EntityFrameworkCore.Migrations; -namespace Nethereum.eShop.Infrastructure.Data.Migrations +namespace Nethereum.eShop.SqlServer.Migrations.Migrations { - public partial class InitialCreate : Migration + public partial class Catalog_InitialCreate : Migration { protected override void Up(MigrationBuilder migrationBuilder) { @@ -43,7 +43,7 @@ protected override void Up(MigrationBuilder migrationBuilder) ShipTo_State = table.Column(maxLength: 60, nullable: true), ShipTo_Country = table.Column(maxLength: 90, nullable: true), ShipTo_ZipCode = table.Column(maxLength: 18, nullable: true), - TransactionHash = table.Column(nullable: true) + TransactionHash = table.Column(maxLength: 67, nullable: true) }, constraints: table => { @@ -99,13 +99,13 @@ protected override void Up(MigrationBuilder migrationBuilder) TransactionHash = table.Column(maxLength: 67, nullable: true), BuyerId = table.Column(maxLength: 256, nullable: false), BuyerAddress = table.Column(maxLength: 43, nullable: true), - CurrencyAddress = table.Column(nullable: true), - CurrencySymbol = table.Column(nullable: true), + CurrencyAddress = table.Column(maxLength: 43, nullable: true), + CurrencySymbol = table.Column(maxLength: 32, nullable: true), ApproverAddress = table.Column(maxLength: 43, nullable: true), PoNumber = table.Column(nullable: true), PoType = table.Column(nullable: false), BuyerWalletAddress = table.Column(maxLength: 43, nullable: true), - SellerId = table.Column(nullable: true), + SellerId = table.Column(maxLength: 32, nullable: true), PoDate = table.Column(nullable: true), OrderDate = table.Column(nullable: false), BillTo_RecipientName = table.Column(maxLength: 255, nullable: true), @@ -137,13 +137,13 @@ protected override void Up(MigrationBuilder migrationBuilder) Expiry = table.Column(nullable: false), TransactionHash = table.Column(maxLength: 67, nullable: true), BuyerAddress = table.Column(maxLength: 43, nullable: true), - CurrencySymbol = table.Column(nullable: true), - CurrencyAddress = table.Column(nullable: true), + CurrencySymbol = table.Column(maxLength: 32, nullable: true), + CurrencyAddress = table.Column(maxLength: 43, nullable: true), ApproverAddress = table.Column(maxLength: 43, nullable: true), PoNumber = table.Column(nullable: true), PoType = table.Column(nullable: false), BuyerWalletAddress = table.Column(maxLength: 43, nullable: true), - SellerId = table.Column(nullable: true), + SellerId = table.Column(maxLength: 32, nullable: true), BuyerId = table.Column(maxLength: 256, nullable: false), BillTo_RecipientName = table.Column(maxLength: 255, nullable: true), BillTo_Street = table.Column(maxLength: 180, nullable: true), @@ -225,10 +225,10 @@ protected override void Up(MigrationBuilder migrationBuilder) Unit = table.Column(maxLength: 8, nullable: true), CatalogTypeId = table.Column(nullable: false), CatalogBrandId = table.Column(nullable: false), - PictureUri = table.Column(nullable: true), - PictureSmallUri = table.Column(nullable: true), - PictureMediumUri = table.Column(nullable: true), - PictureLargeUri = table.Column(nullable: true), + PictureUri = table.Column(maxLength: 512, nullable: true), + PictureSmallUri = table.Column(maxLength: 512, nullable: true), + PictureMediumUri = table.Column(maxLength: 512, nullable: true), + PictureLargeUri = table.Column(maxLength: 512, nullable: true), AttributeJson = table.Column(nullable: true), Rank = table.Column(nullable: false), Height = table.Column(nullable: false), @@ -261,22 +261,22 @@ protected override void Up(MigrationBuilder migrationBuilder) .Annotation("SqlServer:Identity", "1, 1"), Status = table.Column(nullable: false), ItemOrdered_CatalogItemId = table.Column(nullable: true), - ItemOrdered_Gtin = table.Column(nullable: true), + ItemOrdered_Gtin = table.Column(maxLength: 14, nullable: true), ItemOrdered_GtinRegistryId = table.Column(nullable: true), ItemOrdered_ProductName = table.Column(maxLength: 50, nullable: true), - ItemOrdered_PictureUri = table.Column(nullable: true), + ItemOrdered_PictureUri = table.Column(maxLength: 512, nullable: true), UnitPrice = table.Column(type: "decimal(18,2)", nullable: false), Quantity = table.Column(nullable: false), - Unit = table.Column(nullable: true), + Unit = table.Column(maxLength: 50, nullable: true), PoItemStatus = table.Column(nullable: true), PoItemNumber = table.Column(nullable: true), GoodsIssueDate = table.Column(nullable: true), ActualEscrowReleaseDate = table.Column(nullable: true), PlannedEscrowReleaseDate = table.Column(nullable: true), IsEscrowReleased = table.Column(nullable: true), - QuantitySymbol = table.Column(nullable: true), - QuantityAddress = table.Column(nullable: true), - CurrencyValue = table.Column(nullable: true), + QuantitySymbol = table.Column(maxLength: 32, nullable: true), + QuantityAddress = table.Column(maxLength: 43, nullable: true), + CurrencyValue = table.Column(maxLength: 100, nullable: true), OrderId = table.Column(nullable: true) }, constraints: table => @@ -297,10 +297,10 @@ protected override void Up(MigrationBuilder migrationBuilder) Id = table.Column(nullable: false) .Annotation("SqlServer:Identity", "1, 1"), ItemOrdered_CatalogItemId = table.Column(nullable: true), - ItemOrdered_Gtin = table.Column(nullable: true), + ItemOrdered_Gtin = table.Column(maxLength: 14, nullable: true), ItemOrdered_GtinRegistryId = table.Column(nullable: true), ItemOrdered_ProductName = table.Column(maxLength: 50, nullable: true), - ItemOrdered_PictureUri = table.Column(nullable: true), + ItemOrdered_PictureUri = table.Column(maxLength: 512, nullable: true), UnitPrice = table.Column(type: "decimal(18,2)", nullable: false), Quantity = table.Column(nullable: false), Unit = table.Column(nullable: true), diff --git a/src/Nethereum.eShop.SqlServer/Infrastructure/Data/Migrations/CatalogContextModelSnapshot.cs b/src/Nethereum.eShop.SqlServer/Infrastructure/Data/Migrations/CatalogContextModelSnapshot.cs index 3275bce..ab128cc 100644 --- a/src/Nethereum.eShop.SqlServer/Infrastructure/Data/Migrations/CatalogContextModelSnapshot.cs +++ b/src/Nethereum.eShop.SqlServer/Infrastructure/Data/Migrations/CatalogContextModelSnapshot.cs @@ -6,7 +6,7 @@ using Microsoft.EntityFrameworkCore.Storage.ValueConversion; using Nethereum.eShop.Infrastructure.Data; -namespace Nethereum.eShop.Infrastructure.Data.Migrations +namespace Nethereum.eShop.SqlServer.Migrations.Migrations { [DbContext(typeof(CatalogContext))] partial class CatalogContextModelSnapshot : ModelSnapshot diff --git a/src/Nethereum.eShop.SqlServer/Infrastructure/Identity/Migrations/20200221124042_InitialCreate.Designer.cs b/src/Nethereum.eShop.SqlServer/Infrastructure/Identity/Migrations/20200310171925_AppIdentity_InitialCreate.Designer.cs similarity index 97% rename from src/Nethereum.eShop.SqlServer/Infrastructure/Identity/Migrations/20200221124042_InitialCreate.Designer.cs rename to src/Nethereum.eShop.SqlServer/Infrastructure/Identity/Migrations/20200310171925_AppIdentity_InitialCreate.Designer.cs index b406a95..702b10f 100644 --- a/src/Nethereum.eShop.SqlServer/Infrastructure/Identity/Migrations/20200221124042_InitialCreate.Designer.cs +++ b/src/Nethereum.eShop.SqlServer/Infrastructure/Identity/Migrations/20200310171925_AppIdentity_InitialCreate.Designer.cs @@ -7,17 +7,17 @@ using Microsoft.EntityFrameworkCore.Storage.ValueConversion; using Nethereum.eShop.Infrastructure.Identity; -namespace Nethereum.eShop.Infrastructure.Identity.Migrations +namespace Nethereum.eShop.SqlServer.Migrations.Migrations { [DbContext(typeof(AppIdentityDbContext))] - [Migration("20200221124042_InitialCreate")] - partial class InitialCreate + [Migration("20200310171925_AppIdentity_InitialCreate")] + partial class AppIdentity_InitialCreate { protected override void BuildTargetModel(ModelBuilder modelBuilder) { #pragma warning disable 612, 618 modelBuilder - .HasAnnotation("ProductVersion", "3.1.1") + .HasAnnotation("ProductVersion", "3.1.2") .HasAnnotation("Relational:MaxIdentifierLength", 128) .HasAnnotation("SqlServer:ValueGenerationStrategy", SqlServerValueGenerationStrategy.IdentityColumn); diff --git a/src/Nethereum.eShop.SqlServer/Infrastructure/Identity/Migrations/20200221124042_InitialCreate.cs b/src/Nethereum.eShop.SqlServer/Infrastructure/Identity/Migrations/20200310171925_AppIdentity_InitialCreate.cs similarity index 98% rename from src/Nethereum.eShop.SqlServer/Infrastructure/Identity/Migrations/20200221124042_InitialCreate.cs rename to src/Nethereum.eShop.SqlServer/Infrastructure/Identity/Migrations/20200310171925_AppIdentity_InitialCreate.cs index 9169e04..6a5c186 100644 --- a/src/Nethereum.eShop.SqlServer/Infrastructure/Identity/Migrations/20200221124042_InitialCreate.cs +++ b/src/Nethereum.eShop.SqlServer/Infrastructure/Identity/Migrations/20200310171925_AppIdentity_InitialCreate.cs @@ -1,9 +1,9 @@ using System; using Microsoft.EntityFrameworkCore.Migrations; -namespace Nethereum.eShop.Infrastructure.Identity.Migrations +namespace Nethereum.eShop.SqlServer.Migrations.Migrations { - public partial class InitialCreate : Migration + public partial class AppIdentity_InitialCreate : Migration { protected override void Up(MigrationBuilder migrationBuilder) { diff --git a/src/Nethereum.eShop.SqlServer/Infrastructure/Identity/Migrations/AppIdentityDbContextModelSnapshot.cs b/src/Nethereum.eShop.SqlServer/Infrastructure/Identity/Migrations/AppIdentityDbContextModelSnapshot.cs index f778f3e..31c334e 100644 --- a/src/Nethereum.eShop.SqlServer/Infrastructure/Identity/Migrations/AppIdentityDbContextModelSnapshot.cs +++ b/src/Nethereum.eShop.SqlServer/Infrastructure/Identity/Migrations/AppIdentityDbContextModelSnapshot.cs @@ -6,7 +6,7 @@ using Microsoft.EntityFrameworkCore.Storage.ValueConversion; using Nethereum.eShop.Infrastructure.Identity; -namespace Nethereum.eShop.Infrastructure.Identity.Migrations +namespace Nethereum.eShop.SqlServer.Migrations.Migrations { [DbContext(typeof(AppIdentityDbContext))] partial class AppIdentityDbContextModelSnapshot : ModelSnapshot @@ -15,7 +15,7 @@ protected override void BuildModel(ModelBuilder modelBuilder) { #pragma warning disable 612, 618 modelBuilder - .HasAnnotation("ProductVersion", "3.1.1") + .HasAnnotation("ProductVersion", "3.1.2") .HasAnnotation("Relational:MaxIdentifierLength", 128) .HasAnnotation("SqlServer:ValueGenerationStrategy", SqlServerValueGenerationStrategy.IdentityColumn); diff --git a/src/Nethereum.eShop.Sqlite/Infrastructure/Data/Config/SqliteEShopAppIdentityDbBootstrapper.cs b/src/Nethereum.eShop.Sqlite/Infrastructure/Data/Config/SqliteEShopAppIdentityDbBootstrapper.cs index 474fab8..8ca3d1a 100644 --- a/src/Nethereum.eShop.Sqlite/Infrastructure/Data/Config/SqliteEShopAppIdentityDbBootstrapper.cs +++ b/src/Nethereum.eShop.Sqlite/Infrastructure/Data/Config/SqliteEShopAppIdentityDbBootstrapper.cs @@ -5,6 +5,7 @@ using Nethereum.eShop.ApplicationCore.Interfaces; using Nethereum.eShop.Infrastructure.Identity; using System; +using System.Threading; using System.Threading.Tasks; namespace Nethereum.eShop.Sqlite.Infrastructure.Data.Config @@ -20,10 +21,10 @@ public void AddDbContext(IServiceCollection services, IConfiguration configurati options.UseSqlite(configuration.GetConnectionString("IdentityConnection"))); } - public Task EnsureCreatedAsync(IServiceProvider serviceProvider) + public Task EnsureCreatedAsync(IServiceProvider serviceProvider, CancellationToken cancellationToken = default) { var context = serviceProvider.GetRequiredService(); - return context.Database.EnsureCreatedAsync(); + return context.Database.MigrateAsync(cancellationToken); } } } diff --git a/src/Nethereum.eShop.Sqlite/Infrastructure/Data/Config/SqliteEShopDbBootstrapper.cs b/src/Nethereum.eShop.Sqlite/Infrastructure/Data/Config/SqliteEShopDbBootstrapper.cs index 36e43bc..1c89357 100644 --- a/src/Nethereum.eShop.Sqlite/Infrastructure/Data/Config/SqliteEShopDbBootstrapper.cs +++ b/src/Nethereum.eShop.Sqlite/Infrastructure/Data/Config/SqliteEShopDbBootstrapper.cs @@ -11,6 +11,7 @@ using Nethereum.eShop.Sqlite.ApplicationCore.Queries.Orders; using Nethereum.eShop.Sqlite.ApplicationCore.Queries.Quotes; using System; +using System.Threading; using System.Threading.Tasks; namespace Nethereum.eShop.Sqlite.Infrastructure.Data.Config @@ -37,10 +38,10 @@ public void AddQueries(IServiceCollection services, IConfiguration configuration services.AddSingleton(new CatalogQueries(queryConnectionString)); } - public Task EnsureCreatedAsync(IServiceProvider serviceProvider) + public Task EnsureCreatedAsync(IServiceProvider serviceProvider, CancellationToken cancellationToken = default) { var context = serviceProvider.GetRequiredService(); - return context.Database.EnsureCreatedAsync(); + return context.Database.MigrateAsync(cancellationToken); } } } diff --git a/src/Nethereum.eShop.sln b/src/Nethereum.eShop.sln index 6da9230..ccdbc4a 100644 --- a/src/Nethereum.eShop.sln +++ b/src/Nethereum.eShop.sln @@ -35,6 +35,10 @@ Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "apps", "apps", "{826D820C-C EndProject Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Nethereum.eShop.Sqlite", "Nethereum.eShop.Sqlite\Nethereum.eShop.Sqlite.csproj", "{2914543B-FDB7-46A0-BB4D-A192765D4072}" EndProject +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Nethereum.eShop.DbFactory", "Nethereum.eShop.DbFactory\Nethereum.eShop.DbFactory.csproj", "{173B3ACF-DB6E-497C-B778-4BBEB53EFA3A}" +EndProject +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Nethereum.eShop.SqlServer.Migrations", "Nethereum.eShop.SqlServer.Migrations\Nethereum.eShop.SqlServer.Migrations.csproj", "{7EEE2B5F-BD20-4CF3-AD7A-4814BDA23523}" +EndProject Global GlobalSection(SolutionConfigurationPlatforms) = preSolution Debug|Any CPU = Debug|Any CPU @@ -81,6 +85,14 @@ Global {2914543B-FDB7-46A0-BB4D-A192765D4072}.Debug|Any CPU.Build.0 = Debug|Any CPU {2914543B-FDB7-46A0-BB4D-A192765D4072}.Release|Any CPU.ActiveCfg = Release|Any CPU {2914543B-FDB7-46A0-BB4D-A192765D4072}.Release|Any CPU.Build.0 = Release|Any CPU + {173B3ACF-DB6E-497C-B778-4BBEB53EFA3A}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {173B3ACF-DB6E-497C-B778-4BBEB53EFA3A}.Debug|Any CPU.Build.0 = Debug|Any CPU + {173B3ACF-DB6E-497C-B778-4BBEB53EFA3A}.Release|Any CPU.ActiveCfg = Release|Any CPU + {173B3ACF-DB6E-497C-B778-4BBEB53EFA3A}.Release|Any CPU.Build.0 = Release|Any CPU + {7EEE2B5F-BD20-4CF3-AD7A-4814BDA23523}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {7EEE2B5F-BD20-4CF3-AD7A-4814BDA23523}.Debug|Any CPU.Build.0 = Debug|Any CPU + {7EEE2B5F-BD20-4CF3-AD7A-4814BDA23523}.Release|Any CPU.ActiveCfg = Release|Any CPU + {7EEE2B5F-BD20-4CF3-AD7A-4814BDA23523}.Release|Any CPU.Build.0 = Release|Any CPU EndGlobalSection GlobalSection(SolutionProperties) = preSolution HideSolutionNode = FALSE @@ -96,6 +108,8 @@ Global {D7C0A1E5-3867-46AE-86F3-1436E514001B} = {8ABF2EF8-3DBE-4F90-A681-9CBAF211EA6D} {EEE22A14-93DE-4F3D-BE2F-748F40CD2706} = {8ABF2EF8-3DBE-4F90-A681-9CBAF211EA6D} {2914543B-FDB7-46A0-BB4D-A192765D4072} = {8ABF2EF8-3DBE-4F90-A681-9CBAF211EA6D} + {173B3ACF-DB6E-497C-B778-4BBEB53EFA3A} = {8ABF2EF8-3DBE-4F90-A681-9CBAF211EA6D} + {7EEE2B5F-BD20-4CF3-AD7A-4814BDA23523} = {8ABF2EF8-3DBE-4F90-A681-9CBAF211EA6D} EndGlobalSection GlobalSection(ExtensibilityGlobals) = postSolution SolutionGuid = {8BEA2189-D111-472E-BA29-993E206C6CE3} diff --git a/src/Nethereum.eShop/ApplicationCore/Interfaces/IEShopDbBootstrapper.cs b/src/Nethereum.eShop/ApplicationCore/Interfaces/IEShopDbBootstrapper.cs index 4813861..bc69ace 100644 --- a/src/Nethereum.eShop/ApplicationCore/Interfaces/IEShopDbBootstrapper.cs +++ b/src/Nethereum.eShop/ApplicationCore/Interfaces/IEShopDbBootstrapper.cs @@ -1,6 +1,7 @@ using Microsoft.Extensions.Configuration; using Microsoft.Extensions.DependencyInjection; using System; +using System.Threading; using System.Threading.Tasks; namespace Nethereum.eShop.ApplicationCore.Interfaces @@ -12,6 +13,6 @@ public interface IEShopDbBootstrapper void AddQueries(IServiceCollection services, IConfiguration configuration); - Task EnsureCreatedAsync(IServiceProvider serviceProvider); + Task EnsureCreatedAsync(IServiceProvider serviceProvider, CancellationToken cancellationToken = default); } } diff --git a/src/Nethereum.eShop/ApplicationCore/Interfaces/IEShopIdentityDbBootstrapper.cs b/src/Nethereum.eShop/ApplicationCore/Interfaces/IEShopIdentityDbBootstrapper.cs index 0d2065a..1e51692 100644 --- a/src/Nethereum.eShop/ApplicationCore/Interfaces/IEShopIdentityDbBootstrapper.cs +++ b/src/Nethereum.eShop/ApplicationCore/Interfaces/IEShopIdentityDbBootstrapper.cs @@ -1,6 +1,7 @@ using Microsoft.Extensions.Configuration; using Microsoft.Extensions.DependencyInjection; using System; +using System.Threading; using System.Threading.Tasks; namespace Nethereum.eShop.ApplicationCore.Interfaces @@ -9,6 +10,6 @@ public interface IEShopIdentityDbBootstrapper { void AddDbContext(IServiceCollection services, IConfiguration configuration); - Task EnsureCreatedAsync(IServiceProvider serviceProvider); + Task EnsureCreatedAsync(IServiceProvider serviceProvider, CancellationToken cancellationToken = default); } } diff --git a/src/Web/Startup.cs b/src/Web/Startup.cs index 889ade9..abe2f55 100644 --- a/src/Web/Startup.cs +++ b/src/Web/Startup.cs @@ -12,13 +12,11 @@ using Microsoft.Extensions.Hosting; using Nethereum.eShop.ApplicationCore.Interfaces; using Nethereum.eShop.ApplicationCore.Services; +using Nethereum.eShop.DbFactory; using Nethereum.eShop.Infrastructure.Data; using Nethereum.eShop.Infrastructure.Identity; using Nethereum.eShop.Infrastructure.Logging; using Nethereum.eShop.Infrastructure.Services; -using Nethereum.eShop.InMemory.Infrastructure.Data.Config; -using Nethereum.eShop.Sqlite.Infrastructure.Data.Config; -using Nethereum.eShop.SqlServer.Infrastructure.Data.Config; using Nethereum.eShop.Web.Interfaces; using Nethereum.eShop.Web.Services; using Newtonsoft.Json; @@ -43,7 +41,7 @@ public void ConfigureDevelopmentServices(IServiceCollection services) { var inMemoryDbConfig = Configuration["use-in-memory-db"]; // Default to in memory db - // if sql is required - set "use-in-memory-db" to false in appsettings, command line or user secrets + // if sql is required - set "use-in-memory-db" to false in appsettings, command line, user secrets or environmental variables var inMemory = string.IsNullOrEmpty(inMemoryDbConfig) ? true : bool.Parse(inMemoryDbConfig); if (inMemory) @@ -61,11 +59,11 @@ public void ConfigureDevelopmentServices(IServiceCollection services) private void ConfigureInMemoryDatabases(IServiceCollection services) { - IEShopDbBootstrapper dbBootstrapper = new InMemoryEShopDbBootrapper(); + IEShopDbBootstrapper dbBootstrapper = EShopDbBootstrapper.CreateInMemoryDbBootstrapper(); services.AddSingleton(dbBootstrapper); dbBootstrapper.AddDbContext(services, Configuration); - IEShopIdentityDbBootstrapper identityBootstrapper = new InMemoryEShopAppIdentityDbBootrapper(); + IEShopIdentityDbBootstrapper identityBootstrapper = EShopDbBootstrapper.CreateInMemoryAppIdentityDbBootstrapper(); services.AddSingleton(identityBootstrapper); identityBootstrapper.AddDbContext(services, Configuration); @@ -87,11 +85,11 @@ public void ConfigureProductionServices(IServiceCollection services) See CreateAndApplyDbMigrations.bat in the root of the Web project */ - IEShopDbBootstrapper dbBootstrapper = CreateDbBootstrapper(Configuration); + IEShopDbBootstrapper dbBootstrapper = EShopDbBootstrapper.CreateDbBootstrapper(Configuration); services.AddSingleton(dbBootstrapper); dbBootstrapper.AddDbContext(services, Configuration); - IEShopIdentityDbBootstrapper identityDbBootstrapper = CreateAppIdentityDbBootstrapper(Configuration); + IEShopIdentityDbBootstrapper identityDbBootstrapper = EShopDbBootstrapper.CreateAppIdentityDbBootstrapper(Configuration); services.AddSingleton(identityDbBootstrapper); identityDbBootstrapper.AddDbContext(services, Configuration); @@ -189,28 +187,6 @@ public void ConfigureServices( _services = services; // used to debug registered services } - private static IEShopDbBootstrapper CreateDbBootstrapper(IConfiguration configuration) - { - var name = configuration["CatalogDbProvider"]; - return name switch - { - "SqlServer" => new SqlServerEShopDbBootstrapper(), - "Sqlite" => new SqliteEShopDbBootstrapper(), - _ => new InMemoryEShopDbBootrapper() - }; - } - - private static IEShopIdentityDbBootstrapper CreateAppIdentityDbBootstrapper(IConfiguration configuration) - { - var name = configuration["CatalogDbProvider"]; - return name switch - { - "SqlServer" => new SqlServerEShopAppIdentityDbBootstrapper(), - "Sqlite" => new SqliteEShopAppIdentityDbBootstrapper(), - _ => new InMemoryEShopAppIdentityDbBootrapper() - }; - } - private static void CreateIdentityIfNotCreated(IServiceCollection services) { var sp = services.BuildServiceProvider(); diff --git a/src/Web/Web.csproj b/src/Web/Web.csproj index b8887a9..ca3c1a3 100644 --- a/src/Web/Web.csproj +++ b/src/Web/Web.csproj @@ -39,10 +39,7 @@ - - - - + diff --git a/src/WebJobs/WebJobs.csproj b/src/WebJobs/WebJobs.csproj index 3f5f9d5..763f33a 100644 --- a/src/WebJobs/WebJobs.csproj +++ b/src/WebJobs/WebJobs.csproj @@ -26,9 +26,7 @@ - - - + From 57689ff38c5affbff90df18047185f4fbb0c9956 Mon Sep 17 00:00:00 2001 From: Dave Whiffin Date: Wed, 11 Mar 2020 16:13:31 +0000 Subject: [PATCH 13/27] Batch file for Creating DB Scripts --- .../EShopDbBootstrapper.cs | 11 +- .../Data => Catalog/Cache}/RuleTreeCache.cs | 8 +- .../Data => Catalog}/CatalogContext.cs | 9 +- .../Catalog/EShopDbBootstrapperBase.cs | 56 ++ .../EntityBuilders/BasketConfiguration.cs | 2 +- .../EntityBuilders/BasketItemConfiguration.cs | 2 +- .../EntityBuilders/BuyerConfiguration.cs | 2 +- .../BuyerPostalAddressConfiguration.cs | 2 +- .../CatalogBrandConfiguration.cs | 3 +- .../CatalogItemConfiguration.cs | 3 +- .../CatalogItemExcerptBuilder.cs | 2 +- .../CatalogTypeConfiguration.cs | 3 +- .../EntityBuilderExtensions.cs | 2 +- .../EntityBuilders/OrderConfiguration.cs | 2 +- .../EntityBuilders/OrderItemConfiguration.cs | 2 +- .../EntityBuilders/PostalAddressBuilder.cs | 5 +- .../EntityBuilders/QuoteConfiguration.cs | 2 +- .../EntityBuilders/QuoteItemConfiguration.cs | 2 +- .../EntityBuilders/StockItemConfiguration.cs | 3 +- .../Data => Catalog}/MediatorExtension.cs | 2 +- .../Repositories}/BasketRepository.cs | 2 +- .../Repositories}/CatalogItemRepository.cs | 2 +- .../Repositories}/EfRepository.cs | 3 +- .../Repositories}/OrderRepository.cs | 2 +- .../Repositories}/QuoteRepository.cs | 2 +- .../Repositories}/StockItemRepository.cs | 2 +- .../Seed}/CatalogContextSeed.cs | 2 +- .../Data => Catalog/Seed}/CatalogImportDto.cs | 2 +- .../Seed}/JsonCatalogContextSeeder.cs | 5 +- .../Repositories}/SpecificationEvaluator.cs | 0 .../Identity/AppIdentityDbContext.cs | 6 +- .../EShopAppIdentityDbBootstrapperBase.cs | 29 + .../Data/Config/EShopDbBootstrapperBase.cs | 19 - .../Data/IModelBuilderAssemblyHandler.cs | 9 - .../Data/ModelBuilderAssemblyHandler.cs | 15 - .../Catalog/InMemoryCatalogContext.cs | 21 + .../InMemoryEShopDbBootrapper.cs | 18 +- .../Queries}/CatalogQueries.cs | 5 +- .../Queries}/OrderQueries.cs | 5 +- .../Queries/QueriesBase.cs | 4 +- .../Queries}/QuoteQueries.cs | 4 +- .../InMemoryEShopAppIdentityDbBootrapper.cs | 22 + .../Identity/SqliteAppIdentityDbContext.cs | 12 + .../InMemoryEShopAppIdentityDbBootrapper.cs | 22 - .../Nethereum.eShop.InMemory.csproj | 4 + .../AddMigration.bat | 4 + .../Nethereum.eShop.Migrations.csproj} | 4 +- src/Nethereum.eShop.Migrations/Program.cs | 22 + src/Nethereum.eShop.Migrations/ScriptDbs.bat | 4 + .../CreateInitialDbMigration.bat | 3 - .../Program.cs | 12 - ...rverAppIdentityContextDesignTimeFactory.cs | 20 - ...qlServerCatalogContextDesignTimeFactory.cs | 23 - .../EntityBuilders}/BasketConfiguration.cs | 4 +- .../BasketItemConfiguration.cs | 4 +- .../EntityBuilders}/BuyerConfiguration.cs | 4 +- .../BuyerPostalAddressConfiguration.cs | 4 +- .../CatalogBrandConfiguration.cs | 4 +- .../CatalogItemConfiguration.cs | 4 +- .../CatalogTypeConfiguration.cs | 4 +- .../EntityBuilders}/OrderConfiguration.cs | 4 +- .../EntityBuilders}/OrderItemConfiguration.cs | 4 +- .../EntityBuilders}/QuoteConfiguration.cs | 4 +- .../EntityBuilders}/QuoteItemConfiguration.cs | 4 +- .../EntityBuilders}/StockItemConfiguration.cs | 4 +- .../20200311151648_InitialCreate.Designer.cs} | 10 +- .../20200311151648_InitialCreate.cs} | 4 +- .../Migrations/Scripts/CreateCatalogDb.sql | 416 ++++++++ .../SqlServerCatalogContextModelSnapshot.cs} | 8 +- .../Queries}/CatalogQueries.cs | 4 +- .../Queries}/OrderQueries.cs | 6 +- .../Queries}/QuoteQueries.cs | 4 +- .../Catalog/SqlServerCatalogContext.cs | 34 + .../SqlServerEShopDbBootstrapper.cs | 21 +- .../20200311151656_InitialCreate.Designer.cs} | 10 +- .../20200311151656_InitialCreate.cs} | 4 +- .../Migrations/Scripts/CreateIdentityDb.sql | 174 ++++ ...erverAppIdentityDbContextModelSnapshot.cs} | 8 +- .../Identity/SqlServerAppIdentityDbContext.cs | 26 + ...SqlServerEShopAppIdentityDbBootstrapper.cs | 17 + ...SqlServerEShopAppIdentityDbBootstrapper.cs | 26 - .../Nethereum.eShop.SqlServer.csproj | 4 +- .../20200311151703_InitialCreate.Designer.cs | 908 ++++++++++++++++++ .../20200311151703_InitialCreate.cs | 450 +++++++++ .../Migrations/Scripts/CreateCatalogDb.sql | 230 +++++ .../SqliteCatalogContextModelSnapshot.cs | 906 +++++++++++++++++ .../Queries}/CatalogQueries.cs | 3 +- .../Queries}/OrderQueries.cs | 3 +- .../Queries}/QuoteQueries.cs | 3 +- .../Catalog/SqliteCatalogContext.cs | 36 + .../SqliteEShopDbBootstrapper.cs | 23 +- .../TypeHandlers}/DateTimeOffsetHandler.cs | 2 +- .../20200311151709_InitialCreate.Designer.cs | 266 +++++ .../20200311151709_InitialCreate.cs | 217 +++++ .../Migrations/Scripts/CreateIdentityDb.sql | 89 ++ ...SqliteAppIdentityDbContextModelSnapshot.cs | 264 +++++ .../Identity/SqliteAppIdentityDbContext.cs | 28 + .../SqliteEShopAppIdentityDbBootstrapper.cs | 23 + .../SqliteEShopAppIdentityDbBootstrapper.cs | 30 - .../Nethereum.eShop.Sqlite.csproj | 3 +- src/Nethereum.eShop.sln | 19 +- .../Interfaces/IEShopDbBootstrapper.cs | 4 +- .../IEShopIdentityDbBootstrapper.cs | 2 +- .../Infrastructure/Cache}/GeneralCache.cs | 2 +- src/Web/Program.cs | 5 +- src/Web/Startup.cs | 60 +- src/Web/appsettings.json | 14 +- src/WebJobs/appsettings.json | 4 +- 108 files changed, 4428 insertions(+), 422 deletions(-) rename src/Nethereum.eShop.EntityFramework/{Infrastructure/Data => Catalog/Cache}/RuleTreeCache.cs (67%) rename src/Nethereum.eShop.EntityFramework/{Infrastructure/Data => Catalog}/CatalogContext.cs (87%) create mode 100644 src/Nethereum.eShop.EntityFramework/Catalog/EShopDbBootstrapperBase.cs rename src/Nethereum.eShop.EntityFramework/{Infrastructure/Data/Config => Catalog}/EntityBuilders/BasketConfiguration.cs (93%) rename src/Nethereum.eShop.EntityFramework/{Infrastructure/Data/Config => Catalog}/EntityBuilders/BasketItemConfiguration.cs (87%) rename src/Nethereum.eShop.EntityFramework/{Infrastructure/Data/Config => Catalog}/EntityBuilders/BuyerConfiguration.cs (91%) rename src/Nethereum.eShop.EntityFramework/{Infrastructure/Data/Config => Catalog}/EntityBuilders/BuyerPostalAddressConfiguration.cs (86%) rename src/Nethereum.eShop.EntityFramework/{Infrastructure/Data/Config => Catalog}/EntityBuilders/CatalogBrandConfiguration.cs (82%) rename src/Nethereum.eShop.EntityFramework/{Infrastructure/Data/Config => Catalog}/EntityBuilders/CatalogItemConfiguration.cs (93%) rename src/Nethereum.eShop.EntityFramework/{Infrastructure/Data/Config => Catalog}/EntityBuilders/CatalogItemExcerptBuilder.cs (89%) rename src/Nethereum.eShop.EntityFramework/{Infrastructure/Data/Config => Catalog}/EntityBuilders/CatalogTypeConfiguration.cs (83%) rename src/Nethereum.eShop.EntityFramework/{Infrastructure/Data/Config => Catalog/EntityBuilders}/EntityBuilderExtensions.cs (96%) rename src/Nethereum.eShop.EntityFramework/{Infrastructure/Data/Config => Catalog}/EntityBuilders/OrderConfiguration.cs (94%) rename src/Nethereum.eShop.EntityFramework/{Infrastructure/Data/Config => Catalog}/EntityBuilders/OrderItemConfiguration.cs (92%) rename src/Nethereum.eShop.EntityFramework/{Infrastructure/Data/Config => Catalog}/EntityBuilders/PostalAddressBuilder.cs (87%) rename src/Nethereum.eShop.EntityFramework/{Infrastructure/Data/Config => Catalog}/EntityBuilders/QuoteConfiguration.cs (94%) rename src/Nethereum.eShop.EntityFramework/{Infrastructure/Data/Config => Catalog}/EntityBuilders/QuoteItemConfiguration.cs (88%) rename src/Nethereum.eShop.EntityFramework/{Infrastructure/Data/Config => Catalog}/EntityBuilders/StockItemConfiguration.cs (86%) rename src/Nethereum.eShop.EntityFramework/{Infrastructure/Data => Catalog}/MediatorExtension.cs (94%) rename src/Nethereum.eShop.EntityFramework/{Infrastructure/Data => Catalog/Repositories}/BasketRepository.cs (93%) rename src/Nethereum.eShop.EntityFramework/{Infrastructure/Data => Catalog/Repositories}/CatalogItemRepository.cs (82%) rename src/Nethereum.eShop.EntityFramework/{Infrastructure/Data => Catalog/Repositories}/EfRepository.cs (93%) rename src/Nethereum.eShop.EntityFramework/{Infrastructure/Data => Catalog/Repositories}/OrderRepository.cs (96%) rename src/Nethereum.eShop.EntityFramework/{Infrastructure/Data => Catalog/Repositories}/QuoteRepository.cs (93%) rename src/Nethereum.eShop.EntityFramework/{Infrastructure/Data => Catalog/Repositories}/StockItemRepository.cs (82%) rename src/Nethereum.eShop.EntityFramework/{Infrastructure/Data => Catalog/Seed}/CatalogContextSeed.cs (99%) rename src/Nethereum.eShop.EntityFramework/{Infrastructure/Data => Catalog/Seed}/CatalogImportDto.cs (87%) rename src/Nethereum.eShop.EntityFramework/{Infrastructure/Data => Catalog/Seed}/JsonCatalogContextSeeder.cs (96%) rename src/Nethereum.eShop.EntityFramework/{Infrastructure/Data => Common/Repositories}/SpecificationEvaluator.cs (100%) rename src/Nethereum.eShop.EntityFramework/{Infrastructure => }/Identity/AppIdentityDbContext.cs (79%) create mode 100644 src/Nethereum.eShop.EntityFramework/Identity/EShopAppIdentityDbBootstrapperBase.cs delete mode 100644 src/Nethereum.eShop.EntityFramework/Infrastructure/Data/Config/EShopDbBootstrapperBase.cs delete mode 100644 src/Nethereum.eShop.EntityFramework/Infrastructure/Data/IModelBuilderAssemblyHandler.cs delete mode 100644 src/Nethereum.eShop.EntityFramework/Infrastructure/Data/ModelBuilderAssemblyHandler.cs create mode 100644 src/Nethereum.eShop.InMemory/Catalog/InMemoryCatalogContext.cs rename src/Nethereum.eShop.InMemory/{Infrastructure/Data/Config => Catalog}/InMemoryEShopDbBootrapper.cs (53%) rename src/Nethereum.eShop.InMemory/{ApplicationCore/Queries/Catalog => Catalog/Queries}/CatalogQueries.cs (93%) rename src/Nethereum.eShop.InMemory/{ApplicationCore/Queries/Orders => Catalog/Queries}/OrderQueries.cs (95%) rename src/Nethereum.eShop.InMemory/{ApplicationCore => Catalog}/Queries/QueriesBase.cs (67%) rename src/Nethereum.eShop.InMemory/{ApplicationCore/Queries/Quotes => Catalog/Queries}/QuoteQueries.cs (95%) create mode 100644 src/Nethereum.eShop.InMemory/Identity/InMemoryEShopAppIdentityDbBootrapper.cs create mode 100644 src/Nethereum.eShop.InMemory/Identity/SqliteAppIdentityDbContext.cs delete mode 100644 src/Nethereum.eShop.InMemory/Infrastructure/Data/Config/InMemoryEShopAppIdentityDbBootrapper.cs create mode 100644 src/Nethereum.eShop.Migrations/AddMigration.bat rename src/{Nethereum.eShop.SqlServer.Migrations/Nethereum.eShop.SqlServer.Migrations.csproj => Nethereum.eShop.Migrations/Nethereum.eShop.Migrations.csproj} (77%) create mode 100644 src/Nethereum.eShop.Migrations/Program.cs create mode 100644 src/Nethereum.eShop.Migrations/ScriptDbs.bat delete mode 100644 src/Nethereum.eShop.SqlServer.Migrations/CreateInitialDbMigration.bat delete mode 100644 src/Nethereum.eShop.SqlServer.Migrations/Program.cs delete mode 100644 src/Nethereum.eShop.SqlServer.Migrations/SqlServerAppIdentityContextDesignTimeFactory.cs delete mode 100644 src/Nethereum.eShop.SqlServer.Migrations/SqlServerCatalogContextDesignTimeFactory.cs rename src/Nethereum.eShop.SqlServer/{Infrastructure/Data/Config/EntityBuilders/SqlServer => Catalog/EntityBuilders}/BasketConfiguration.cs (71%) rename src/Nethereum.eShop.SqlServer/{Infrastructure/Data/Config/EntityBuilders/SqlServer => Catalog/EntityBuilders}/BasketItemConfiguration.cs (72%) rename src/Nethereum.eShop.SqlServer/{Infrastructure/Data/Config/EntityBuilders/SqlServer => Catalog/EntityBuilders}/BuyerConfiguration.cs (71%) rename src/Nethereum.eShop.SqlServer/{Infrastructure/Data/Config/EntityBuilders/SqlServer => Catalog/EntityBuilders}/BuyerPostalAddressConfiguration.cs (73%) rename src/Nethereum.eShop.SqlServer/{Infrastructure/Data/Config/EntityBuilders/SqlServer => Catalog/EntityBuilders}/CatalogBrandConfiguration.cs (75%) rename src/Nethereum.eShop.SqlServer/{Infrastructure/Data/Config/EntityBuilders/SqlServer => Catalog/EntityBuilders}/CatalogItemConfiguration.cs (75%) rename src/Nethereum.eShop.SqlServer/{Infrastructure/Data/Config/EntityBuilders/SqlServer => Catalog/EntityBuilders}/CatalogTypeConfiguration.cs (80%) rename src/Nethereum.eShop.SqlServer/{Infrastructure/Data/Config/EntityBuilders/SqlServer => Catalog/EntityBuilders}/OrderConfiguration.cs (71%) rename src/Nethereum.eShop.SqlServer/{Infrastructure/Data/Config/EntityBuilders/SqlServer => Catalog/EntityBuilders}/OrderItemConfiguration.cs (71%) rename src/Nethereum.eShop.SqlServer/{Infrastructure/Data/Config/EntityBuilders/SqlServer => Catalog/EntityBuilders}/QuoteConfiguration.cs (71%) rename src/Nethereum.eShop.SqlServer/{Infrastructure/Data/Config/EntityBuilders/SqlServer => Catalog/EntityBuilders}/QuoteItemConfiguration.cs (71%) rename src/Nethereum.eShop.SqlServer/{Infrastructure/Data/Config/EntityBuilders/SqlServer => Catalog/EntityBuilders}/StockItemConfiguration.cs (75%) rename src/Nethereum.eShop.SqlServer/{Infrastructure/Data/Migrations/20200310171921_Catalog_InitialCreate.Designer.cs => Catalog/Migrations/20200311151648_InitialCreate.Designer.cs} (99%) rename src/Nethereum.eShop.SqlServer/{Infrastructure/Data/Migrations/20200310171921_Catalog_InitialCreate.cs => Catalog/Migrations/20200311151648_InitialCreate.cs} (99%) create mode 100644 src/Nethereum.eShop.SqlServer/Catalog/Migrations/Scripts/CreateCatalogDb.sql rename src/Nethereum.eShop.SqlServer/{Infrastructure/Data/Migrations/CatalogContextModelSnapshot.cs => Catalog/Migrations/SqlServerCatalogContextModelSnapshot.cs} (99%) rename src/Nethereum.eShop.SqlServer/{ApplicationCore/Queries/Catalog => Catalog/Queries}/CatalogQueries.cs (94%) rename src/Nethereum.eShop.SqlServer/{ApplicationCore/Queries/Orders => Catalog/Queries}/OrderQueries.cs (93%) rename src/Nethereum.eShop.SqlServer/{ApplicationCore/Queries/Quotes => Catalog/Queries}/QuoteQueries.cs (93%) create mode 100644 src/Nethereum.eShop.SqlServer/Catalog/SqlServerCatalogContext.cs rename src/Nethereum.eShop.SqlServer/{Infrastructure/Data/Config => Catalog}/SqlServerEShopDbBootstrapper.cs (60%) rename src/Nethereum.eShop.SqlServer/{Infrastructure/Identity/Migrations/20200310171925_AppIdentity_InitialCreate.Designer.cs => Identity/Migrations/20200311151656_InitialCreate.Designer.cs} (97%) rename src/Nethereum.eShop.SqlServer/{Infrastructure/Identity/Migrations/20200310171925_AppIdentity_InitialCreate.cs => Identity/Migrations/20200311151656_InitialCreate.cs} (98%) create mode 100644 src/Nethereum.eShop.SqlServer/Identity/Migrations/Scripts/CreateIdentityDb.sql rename src/Nethereum.eShop.SqlServer/{Infrastructure/Identity/Migrations/AppIdentityDbContextModelSnapshot.cs => Identity/Migrations/SqlServerAppIdentityDbContextModelSnapshot.cs} (97%) create mode 100644 src/Nethereum.eShop.SqlServer/Identity/SqlServerAppIdentityDbContext.cs create mode 100644 src/Nethereum.eShop.SqlServer/Identity/SqlServerEShopAppIdentityDbBootstrapper.cs delete mode 100644 src/Nethereum.eShop.SqlServer/Infrastructure/Data/Config/SqlServerEShopAppIdentityDbBootstrapper.cs create mode 100644 src/Nethereum.eShop.Sqlite/Catalog/Migrations/20200311151703_InitialCreate.Designer.cs create mode 100644 src/Nethereum.eShop.Sqlite/Catalog/Migrations/20200311151703_InitialCreate.cs create mode 100644 src/Nethereum.eShop.Sqlite/Catalog/Migrations/Scripts/CreateCatalogDb.sql create mode 100644 src/Nethereum.eShop.Sqlite/Catalog/Migrations/SqliteCatalogContextModelSnapshot.cs rename src/Nethereum.eShop.Sqlite/{ApplicationCore/Queries/Catalog => Catalog/Queries}/CatalogQueries.cs (97%) rename src/Nethereum.eShop.Sqlite/{ApplicationCore/Queries/Orders => Catalog/Queries}/OrderQueries.cs (96%) rename src/Nethereum.eShop.Sqlite/{ApplicationCore/Queries/Quotes => Catalog/Queries}/QuoteQueries.cs (96%) create mode 100644 src/Nethereum.eShop.Sqlite/Catalog/SqliteCatalogContext.cs rename src/Nethereum.eShop.Sqlite/{Infrastructure/Data/Config => Catalog}/SqliteEShopDbBootstrapper.cs (56%) rename src/Nethereum.eShop.Sqlite/{ => Common/Dapper/TypeHandlers}/DateTimeOffsetHandler.cs (93%) create mode 100644 src/Nethereum.eShop.Sqlite/Identity/Migrations/20200311151709_InitialCreate.Designer.cs create mode 100644 src/Nethereum.eShop.Sqlite/Identity/Migrations/20200311151709_InitialCreate.cs create mode 100644 src/Nethereum.eShop.Sqlite/Identity/Migrations/Scripts/CreateIdentityDb.sql create mode 100644 src/Nethereum.eShop.Sqlite/Identity/Migrations/SqliteAppIdentityDbContextModelSnapshot.cs create mode 100644 src/Nethereum.eShop.Sqlite/Identity/SqliteAppIdentityDbContext.cs create mode 100644 src/Nethereum.eShop.Sqlite/Identity/SqliteEShopAppIdentityDbBootstrapper.cs delete mode 100644 src/Nethereum.eShop.Sqlite/Infrastructure/Data/Config/SqliteEShopAppIdentityDbBootstrapper.cs rename src/{Nethereum.eShop.EntityFramework/Infrastructure/Data => Nethereum.eShop/Infrastructure/Cache}/GeneralCache.cs (96%) diff --git a/src/Nethereum.eShop.DbFactory/EShopDbBootstrapper.cs b/src/Nethereum.eShop.DbFactory/EShopDbBootstrapper.cs index 61b78ca..874d755 100644 --- a/src/Nethereum.eShop.DbFactory/EShopDbBootstrapper.cs +++ b/src/Nethereum.eShop.DbFactory/EShopDbBootstrapper.cs @@ -1,8 +1,11 @@ using Microsoft.Extensions.Configuration; using Nethereum.eShop.ApplicationCore.Interfaces; -using Nethereum.eShop.InMemory.Infrastructure.Data.Config; -using Nethereum.eShop.Sqlite.Infrastructure.Data.Config; -using Nethereum.eShop.SqlServer.Infrastructure.Data.Config; +using Nethereum.eShop.InMemory.Catalog; +using Nethereum.eShop.InMemory.Infrastructure.Identity; +using Nethereum.eShop.Sqlite.Catalog; +using Nethereum.eShop.Sqlite.Identity; +using Nethereum.eShop.SqlServer.Catalog; +using Nethereum.eShop.SqlServer.Identity; namespace Nethereum.eShop.DbFactory { @@ -24,7 +27,7 @@ public static IEShopDbBootstrapper CreateDbBootstrapper(IConfiguration configura public static IEShopIdentityDbBootstrapper CreateAppIdentityDbBootstrapper(IConfiguration configuration) { - var name = configuration["CatalogDbProvider"]?.ToLower(); + var name = configuration["AppIdentityDbProvider"]?.ToLower(); return name switch { "sqlserver" => new SqlServerEShopAppIdentityDbBootstrapper(), diff --git a/src/Nethereum.eShop.EntityFramework/Infrastructure/Data/RuleTreeCache.cs b/src/Nethereum.eShop.EntityFramework/Catalog/Cache/RuleTreeCache.cs similarity index 67% rename from src/Nethereum.eShop.EntityFramework/Infrastructure/Data/RuleTreeCache.cs rename to src/Nethereum.eShop.EntityFramework/Catalog/Cache/RuleTreeCache.cs index 185632d..db2aec3 100644 --- a/src/Nethereum.eShop.EntityFramework/Infrastructure/Data/RuleTreeCache.cs +++ b/src/Nethereum.eShop.EntityFramework/Catalog/Cache/RuleTreeCache.cs @@ -1,9 +1,9 @@ -using Nethereum.eShop.ApplicationCore.Interfaces; -using Nethereum.eShop.ApplicationCore.Entities.RulesEngine; -using System.Collections.Generic; +using Nethereum.eShop.ApplicationCore.Entities.RulesEngine; +using Nethereum.eShop.ApplicationCore.Interfaces; +using Nethereum.eShop.Infrastructure.Cache; using System.Threading.Tasks; -namespace Nethereum.eShop.Infrastructure.Data +namespace Nethereum.eShop.EntityFramework.Catalog.Cache { public class RuleTreeCache : GeneralCache, IRuleTreeCache { diff --git a/src/Nethereum.eShop.EntityFramework/Infrastructure/Data/CatalogContext.cs b/src/Nethereum.eShop.EntityFramework/Catalog/CatalogContext.cs similarity index 87% rename from src/Nethereum.eShop.EntityFramework/Infrastructure/Data/CatalogContext.cs rename to src/Nethereum.eShop.EntityFramework/Catalog/CatalogContext.cs index 67b6e20..43a75cf 100644 --- a/src/Nethereum.eShop.EntityFramework/Infrastructure/Data/CatalogContext.cs +++ b/src/Nethereum.eShop.EntityFramework/Catalog/CatalogContext.cs @@ -9,23 +9,20 @@ using Nethereum.eShop.ApplicationCore.Interfaces; using System; using System.Data; -using System.Reflection; using System.Threading; using System.Threading.Tasks; -namespace Nethereum.eShop.Infrastructure.Data +namespace Nethereum.eShop.EntityFramework.Catalog { public class CatalogContext : DbContext, IUnitOfWork { private readonly IMediator _mediator; - private readonly IModelBuilderAssemblyHandler _modelBuilderAssemblyHandler; private IDbContextTransaction _currentTransaction; public CatalogContext( - DbContextOptions options, IMediator mediator, IModelBuilderAssemblyHandler modelBuilderAssemblyHandler) : base(options) + DbContextOptions options, IMediator mediator) : base(options) { _mediator = mediator; - _modelBuilderAssemblyHandler = modelBuilderAssemblyHandler; } public DbSet Buyers { get; set; } @@ -43,8 +40,6 @@ public CatalogContext( protected override void OnModelCreating(ModelBuilder builder) { base.OnModelCreating(builder); - var modelBuilderAssembly = _modelBuilderAssemblyHandler?.GetModelBuilderAssembly() ?? Assembly.GetExecutingAssembly(); - builder.ApplyConfigurationsFromAssembly(modelBuilderAssembly); } public async Task SaveEntitiesAsync(CancellationToken cancellationToken = default(CancellationToken)) diff --git a/src/Nethereum.eShop.EntityFramework/Catalog/EShopDbBootstrapperBase.cs b/src/Nethereum.eShop.EntityFramework/Catalog/EShopDbBootstrapperBase.cs new file mode 100644 index 0000000..212e3e4 --- /dev/null +++ b/src/Nethereum.eShop.EntityFramework/Catalog/EShopDbBootstrapperBase.cs @@ -0,0 +1,56 @@ +using Microsoft.EntityFrameworkCore; +using Microsoft.Extensions.Configuration; +using Microsoft.Extensions.DependencyInjection; +using Nethereum.eShop.ApplicationCore.Interfaces; +using Nethereum.eShop.EntityFramework.Catalog.Cache; +using Nethereum.eShop.EntityFramework.Catalog.Repositories; +using Nethereum.eShop.EntityFramework.Catalog.Seed; +using System; +using System.Threading; +using System.Threading.Tasks; + +namespace Nethereum.eShop.EntityFramework.Catalog +{ + public abstract class EShopDbBootstrapperBase + { + public virtual void AddRepositories(IServiceCollection services, IConfiguration configuration) + { + services.AddScoped(typeof(IAsyncRepository<>), typeof(EfRepository<>)); + services.AddScoped(); + services.AddScoped(); + services.AddScoped(); + services.AddScoped(); + services.AddScoped(); + services.AddScoped(); + } + + public virtual void AddSeeders(IServiceCollection services, IConfiguration configuration) + { + var CatalogSeedJsonFile = configuration["CatalogSeedJsonFile"]; + + if (string.IsNullOrEmpty(CatalogSeedJsonFile)) + { + services.AddScoped(); + } + else + { + services.AddScoped(); + } + } + + public virtual Task EnsureCreatedAsync(IServiceProvider serviceProvider, IConfiguration configuration, CancellationToken cancellationToken = default) + { + if (ApplyMigrationsOnStartup(configuration)) + { + var context = serviceProvider.GetRequiredService(); + return context.Database.MigrateAsync(cancellationToken); + } + return Task.CompletedTask; + } + + protected virtual bool ApplyMigrationsOnStartup(IConfiguration configuration) + { + return configuration.GetValue("CatalogApplyMigrationsOnStartup", false); + } + } +} diff --git a/src/Nethereum.eShop.EntityFramework/Infrastructure/Data/Config/EntityBuilders/BasketConfiguration.cs b/src/Nethereum.eShop.EntityFramework/Catalog/EntityBuilders/BasketConfiguration.cs similarity index 93% rename from src/Nethereum.eShop.EntityFramework/Infrastructure/Data/Config/EntityBuilders/BasketConfiguration.cs rename to src/Nethereum.eShop.EntityFramework/Catalog/EntityBuilders/BasketConfiguration.cs index b0eeb8f..958f374 100644 --- a/src/Nethereum.eShop.EntityFramework/Infrastructure/Data/Config/EntityBuilders/BasketConfiguration.cs +++ b/src/Nethereum.eShop.EntityFramework/Catalog/EntityBuilders/BasketConfiguration.cs @@ -2,7 +2,7 @@ using Microsoft.EntityFrameworkCore.Metadata.Builders; using Nethereum.eShop.ApplicationCore.Entities.BasketAggregate; -namespace Nethereum.eShop.Infrastructure.Data.Config.EntityBuilders +namespace Nethereum.eShop.EntityFramework.Catalog.EntityBuilders { public class BasketConfiguration : IEntityTypeConfiguration { diff --git a/src/Nethereum.eShop.EntityFramework/Infrastructure/Data/Config/EntityBuilders/BasketItemConfiguration.cs b/src/Nethereum.eShop.EntityFramework/Catalog/EntityBuilders/BasketItemConfiguration.cs similarity index 87% rename from src/Nethereum.eShop.EntityFramework/Infrastructure/Data/Config/EntityBuilders/BasketItemConfiguration.cs rename to src/Nethereum.eShop.EntityFramework/Catalog/EntityBuilders/BasketItemConfiguration.cs index 3b56f76..6ade3fe 100644 --- a/src/Nethereum.eShop.EntityFramework/Infrastructure/Data/Config/EntityBuilders/BasketItemConfiguration.cs +++ b/src/Nethereum.eShop.EntityFramework/Catalog/EntityBuilders/BasketItemConfiguration.cs @@ -2,7 +2,7 @@ using Microsoft.EntityFrameworkCore.Metadata.Builders; using Nethereum.eShop.ApplicationCore.Entities.BasketAggregate; -namespace Nethereum.eShop.Infrastructure.Data.Config.EntityBuilders +namespace Nethereum.eShop.EntityFramework.Catalog.EntityBuilders { public class BasketItemConfiguration : IEntityTypeConfiguration { diff --git a/src/Nethereum.eShop.EntityFramework/Infrastructure/Data/Config/EntityBuilders/BuyerConfiguration.cs b/src/Nethereum.eShop.EntityFramework/Catalog/EntityBuilders/BuyerConfiguration.cs similarity index 91% rename from src/Nethereum.eShop.EntityFramework/Infrastructure/Data/Config/EntityBuilders/BuyerConfiguration.cs rename to src/Nethereum.eShop.EntityFramework/Catalog/EntityBuilders/BuyerConfiguration.cs index a32f511..3c3b4fe 100644 --- a/src/Nethereum.eShop.EntityFramework/Infrastructure/Data/Config/EntityBuilders/BuyerConfiguration.cs +++ b/src/Nethereum.eShop.EntityFramework/Catalog/EntityBuilders/BuyerConfiguration.cs @@ -2,7 +2,7 @@ using Microsoft.EntityFrameworkCore.Metadata.Builders; using Nethereum.eShop.ApplicationCore.Entities.BuyerAggregate; -namespace Nethereum.eShop.Infrastructure.Data.Config.EntityBuilders +namespace Nethereum.eShop.EntityFramework.Catalog.EntityBuilders { public class BuyerConfiguration : IEntityTypeConfiguration { diff --git a/src/Nethereum.eShop.EntityFramework/Infrastructure/Data/Config/EntityBuilders/BuyerPostalAddressConfiguration.cs b/src/Nethereum.eShop.EntityFramework/Catalog/EntityBuilders/BuyerPostalAddressConfiguration.cs similarity index 86% rename from src/Nethereum.eShop.EntityFramework/Infrastructure/Data/Config/EntityBuilders/BuyerPostalAddressConfiguration.cs rename to src/Nethereum.eShop.EntityFramework/Catalog/EntityBuilders/BuyerPostalAddressConfiguration.cs index b403ed7..abb3fed 100644 --- a/src/Nethereum.eShop.EntityFramework/Infrastructure/Data/Config/EntityBuilders/BuyerPostalAddressConfiguration.cs +++ b/src/Nethereum.eShop.EntityFramework/Catalog/EntityBuilders/BuyerPostalAddressConfiguration.cs @@ -2,7 +2,7 @@ using Microsoft.EntityFrameworkCore.Metadata.Builders; using Nethereum.eShop.ApplicationCore.Entities.BuyerAggregate; -namespace Nethereum.eShop.Infrastructure.Data.Config.EntityBuilders +namespace Nethereum.eShop.EntityFramework.Catalog.EntityBuilders { public class BuyerPostalAddressConfiguration : IEntityTypeConfiguration { diff --git a/src/Nethereum.eShop.EntityFramework/Infrastructure/Data/Config/EntityBuilders/CatalogBrandConfiguration.cs b/src/Nethereum.eShop.EntityFramework/Catalog/EntityBuilders/CatalogBrandConfiguration.cs similarity index 82% rename from src/Nethereum.eShop.EntityFramework/Infrastructure/Data/Config/EntityBuilders/CatalogBrandConfiguration.cs rename to src/Nethereum.eShop.EntityFramework/Catalog/EntityBuilders/CatalogBrandConfiguration.cs index 2690a53..d0d9b1b 100644 --- a/src/Nethereum.eShop.EntityFramework/Infrastructure/Data/Config/EntityBuilders/CatalogBrandConfiguration.cs +++ b/src/Nethereum.eShop.EntityFramework/Catalog/EntityBuilders/CatalogBrandConfiguration.cs @@ -2,7 +2,7 @@ using Microsoft.EntityFrameworkCore.Metadata.Builders; using Nethereum.eShop.ApplicationCore.Entities; -namespace Nethereum.eShop.Infrastructure.Data.Config.EntityBuilders +namespace Nethereum.eShop.EntityFramework.Catalog.EntityBuilders { public class CatalogBrandConfiguration : IEntityTypeConfiguration { @@ -11,7 +11,6 @@ public virtual void Configure(EntityTypeBuilder builder) builder.HasKey(ci => ci.Id); builder.Property(ci => ci.Id) - // .UseHiLo("catalog_brand_hilo") .IsRequired(); builder.Property(cb => cb.Brand) diff --git a/src/Nethereum.eShop.EntityFramework/Infrastructure/Data/Config/EntityBuilders/CatalogItemConfiguration.cs b/src/Nethereum.eShop.EntityFramework/Catalog/EntityBuilders/CatalogItemConfiguration.cs similarity index 93% rename from src/Nethereum.eShop.EntityFramework/Infrastructure/Data/Config/EntityBuilders/CatalogItemConfiguration.cs rename to src/Nethereum.eShop.EntityFramework/Catalog/EntityBuilders/CatalogItemConfiguration.cs index 5b62f1c..19faf22 100644 --- a/src/Nethereum.eShop.EntityFramework/Infrastructure/Data/Config/EntityBuilders/CatalogItemConfiguration.cs +++ b/src/Nethereum.eShop.EntityFramework/Catalog/EntityBuilders/CatalogItemConfiguration.cs @@ -2,7 +2,7 @@ using Microsoft.EntityFrameworkCore.Metadata.Builders; using Nethereum.eShop.ApplicationCore.Entities; -namespace Nethereum.eShop.Infrastructure.Data.Config.EntityBuilders +namespace Nethereum.eShop.EntityFramework.Catalog.EntityBuilders { public class CatalogItemConfiguration : IEntityTypeConfiguration { @@ -11,7 +11,6 @@ public virtual void Configure(EntityTypeBuilder builder) builder.ToTable("Catalog"); builder.Property(ci => ci.Id) - //.UseHiLo("catalog_hilo") .IsRequired(); builder.Property(ci => ci.Name) diff --git a/src/Nethereum.eShop.EntityFramework/Infrastructure/Data/Config/EntityBuilders/CatalogItemExcerptBuilder.cs b/src/Nethereum.eShop.EntityFramework/Catalog/EntityBuilders/CatalogItemExcerptBuilder.cs similarity index 89% rename from src/Nethereum.eShop.EntityFramework/Infrastructure/Data/Config/EntityBuilders/CatalogItemExcerptBuilder.cs rename to src/Nethereum.eShop.EntityFramework/Catalog/EntityBuilders/CatalogItemExcerptBuilder.cs index dffbc1b..dc97e3a 100644 --- a/src/Nethereum.eShop.EntityFramework/Infrastructure/Data/Config/EntityBuilders/CatalogItemExcerptBuilder.cs +++ b/src/Nethereum.eShop.EntityFramework/Catalog/EntityBuilders/CatalogItemExcerptBuilder.cs @@ -1,7 +1,7 @@ using Microsoft.EntityFrameworkCore.Metadata.Builders; using Nethereum.eShop.ApplicationCore.Entities; -namespace Nethereum.eShop.Infrastructure.Data.Config.EntityBuilders +namespace Nethereum.eShop.EntityFramework.Catalog.EntityBuilders { public static class CatalogItemExcerptBuilder { diff --git a/src/Nethereum.eShop.EntityFramework/Infrastructure/Data/Config/EntityBuilders/CatalogTypeConfiguration.cs b/src/Nethereum.eShop.EntityFramework/Catalog/EntityBuilders/CatalogTypeConfiguration.cs similarity index 83% rename from src/Nethereum.eShop.EntityFramework/Infrastructure/Data/Config/EntityBuilders/CatalogTypeConfiguration.cs rename to src/Nethereum.eShop.EntityFramework/Catalog/EntityBuilders/CatalogTypeConfiguration.cs index 8e84960..0a554fd 100644 --- a/src/Nethereum.eShop.EntityFramework/Infrastructure/Data/Config/EntityBuilders/CatalogTypeConfiguration.cs +++ b/src/Nethereum.eShop.EntityFramework/Catalog/EntityBuilders/CatalogTypeConfiguration.cs @@ -2,7 +2,7 @@ using Microsoft.EntityFrameworkCore.Metadata.Builders; using Nethereum.eShop.ApplicationCore.Entities; -namespace Nethereum.eShop.Infrastructure.Data.Config.EntityBuilders +namespace Nethereum.eShop.EntityFramework.Catalog.EntityBuilders { public class CatalogTypeConfiguration : IEntityTypeConfiguration { @@ -11,7 +11,6 @@ public virtual void Configure(EntityTypeBuilder builder) builder.HasKey(ci => ci.Id); builder.Property(ci => ci.Id) - //.UseHiLo("catalog_type_hilo") .IsRequired(); builder.Property(cb => cb.Type) diff --git a/src/Nethereum.eShop.EntityFramework/Infrastructure/Data/Config/EntityBuilderExtensions.cs b/src/Nethereum.eShop.EntityFramework/Catalog/EntityBuilders/EntityBuilderExtensions.cs similarity index 96% rename from src/Nethereum.eShop.EntityFramework/Infrastructure/Data/Config/EntityBuilderExtensions.cs rename to src/Nethereum.eShop.EntityFramework/Catalog/EntityBuilders/EntityBuilderExtensions.cs index 17eee97..e7303b1 100644 --- a/src/Nethereum.eShop.EntityFramework/Infrastructure/Data/Config/EntityBuilderExtensions.cs +++ b/src/Nethereum.eShop.EntityFramework/Catalog/EntityBuilders/EntityBuilderExtensions.cs @@ -1,7 +1,7 @@ using Microsoft.EntityFrameworkCore; using Microsoft.EntityFrameworkCore.Metadata.Builders; -namespace Nethereum.eShop.Infrastructure.Data.Config +namespace Nethereum.eShop.EntityFramework.Catalog.EntityBuilders { public static class EntityBuilderExtensions { diff --git a/src/Nethereum.eShop.EntityFramework/Infrastructure/Data/Config/EntityBuilders/OrderConfiguration.cs b/src/Nethereum.eShop.EntityFramework/Catalog/EntityBuilders/OrderConfiguration.cs similarity index 94% rename from src/Nethereum.eShop.EntityFramework/Infrastructure/Data/Config/EntityBuilders/OrderConfiguration.cs rename to src/Nethereum.eShop.EntityFramework/Catalog/EntityBuilders/OrderConfiguration.cs index 58cf2cf..11b40f7 100644 --- a/src/Nethereum.eShop.EntityFramework/Infrastructure/Data/Config/EntityBuilders/OrderConfiguration.cs +++ b/src/Nethereum.eShop.EntityFramework/Catalog/EntityBuilders/OrderConfiguration.cs @@ -2,7 +2,7 @@ using Microsoft.EntityFrameworkCore.Metadata.Builders; using Nethereum.eShop.ApplicationCore.Entities.OrderAggregate; -namespace Nethereum.eShop.Infrastructure.Data.Config.EntityBuilders +namespace Nethereum.eShop.EntityFramework.Catalog.EntityBuilders { public class OrderConfiguration : IEntityTypeConfiguration { diff --git a/src/Nethereum.eShop.EntityFramework/Infrastructure/Data/Config/EntityBuilders/OrderItemConfiguration.cs b/src/Nethereum.eShop.EntityFramework/Catalog/EntityBuilders/OrderItemConfiguration.cs similarity index 92% rename from src/Nethereum.eShop.EntityFramework/Infrastructure/Data/Config/EntityBuilders/OrderItemConfiguration.cs rename to src/Nethereum.eShop.EntityFramework/Catalog/EntityBuilders/OrderItemConfiguration.cs index 5d16d64..0b1ff81 100644 --- a/src/Nethereum.eShop.EntityFramework/Infrastructure/Data/Config/EntityBuilders/OrderItemConfiguration.cs +++ b/src/Nethereum.eShop.EntityFramework/Catalog/EntityBuilders/OrderItemConfiguration.cs @@ -2,7 +2,7 @@ using Microsoft.EntityFrameworkCore.Metadata.Builders; using Nethereum.eShop.ApplicationCore.Entities.OrderAggregate; -namespace Nethereum.eShop.Infrastructure.Data.Config.EntityBuilders +namespace Nethereum.eShop.EntityFramework.Catalog.EntityBuilders { public class OrderItemConfiguration : IEntityTypeConfiguration { diff --git a/src/Nethereum.eShop.EntityFramework/Infrastructure/Data/Config/EntityBuilders/PostalAddressBuilder.cs b/src/Nethereum.eShop.EntityFramework/Catalog/EntityBuilders/PostalAddressBuilder.cs similarity index 87% rename from src/Nethereum.eShop.EntityFramework/Infrastructure/Data/Config/EntityBuilders/PostalAddressBuilder.cs rename to src/Nethereum.eShop.EntityFramework/Catalog/EntityBuilders/PostalAddressBuilder.cs index 8731571..cde1ecf 100644 --- a/src/Nethereum.eShop.EntityFramework/Infrastructure/Data/Config/EntityBuilders/PostalAddressBuilder.cs +++ b/src/Nethereum.eShop.EntityFramework/Catalog/EntityBuilders/PostalAddressBuilder.cs @@ -1,10 +1,7 @@ using Microsoft.EntityFrameworkCore.Metadata.Builders; using Nethereum.eShop.ApplicationCore.Entities; -using System; -using System.Collections.Generic; -using System.Text; -namespace Nethereum.eShop.Infrastructure.Data.Config.EntityBuilders +namespace Nethereum.eShop.EntityFramework.Catalog.EntityBuilders { public static class PostalAddressBuilder { diff --git a/src/Nethereum.eShop.EntityFramework/Infrastructure/Data/Config/EntityBuilders/QuoteConfiguration.cs b/src/Nethereum.eShop.EntityFramework/Catalog/EntityBuilders/QuoteConfiguration.cs similarity index 94% rename from src/Nethereum.eShop.EntityFramework/Infrastructure/Data/Config/EntityBuilders/QuoteConfiguration.cs rename to src/Nethereum.eShop.EntityFramework/Catalog/EntityBuilders/QuoteConfiguration.cs index 9d042f5..04844dc 100644 --- a/src/Nethereum.eShop.EntityFramework/Infrastructure/Data/Config/EntityBuilders/QuoteConfiguration.cs +++ b/src/Nethereum.eShop.EntityFramework/Catalog/EntityBuilders/QuoteConfiguration.cs @@ -2,7 +2,7 @@ using Microsoft.EntityFrameworkCore.Metadata.Builders; using Nethereum.eShop.ApplicationCore.Entities.QuoteAggregate; -namespace Nethereum.eShop.Infrastructure.Data.Config.EntityBuilders +namespace Nethereum.eShop.EntityFramework.Catalog.EntityBuilders { public class QuoteConfiguration : IEntityTypeConfiguration { diff --git a/src/Nethereum.eShop.EntityFramework/Infrastructure/Data/Config/EntityBuilders/QuoteItemConfiguration.cs b/src/Nethereum.eShop.EntityFramework/Catalog/EntityBuilders/QuoteItemConfiguration.cs similarity index 88% rename from src/Nethereum.eShop.EntityFramework/Infrastructure/Data/Config/EntityBuilders/QuoteItemConfiguration.cs rename to src/Nethereum.eShop.EntityFramework/Catalog/EntityBuilders/QuoteItemConfiguration.cs index f5c5260..5adeab5 100644 --- a/src/Nethereum.eShop.EntityFramework/Infrastructure/Data/Config/EntityBuilders/QuoteItemConfiguration.cs +++ b/src/Nethereum.eShop.EntityFramework/Catalog/EntityBuilders/QuoteItemConfiguration.cs @@ -2,7 +2,7 @@ using Microsoft.EntityFrameworkCore.Metadata.Builders; using Nethereum.eShop.ApplicationCore.Entities.QuoteAggregate; -namespace Nethereum.eShop.Infrastructure.Data.Config.EntityBuilders +namespace Nethereum.eShop.EntityFramework.Catalog.EntityBuilders { public class QuoteItemConfiguration : IEntityTypeConfiguration { diff --git a/src/Nethereum.eShop.EntityFramework/Infrastructure/Data/Config/EntityBuilders/StockItemConfiguration.cs b/src/Nethereum.eShop.EntityFramework/Catalog/EntityBuilders/StockItemConfiguration.cs similarity index 86% rename from src/Nethereum.eShop.EntityFramework/Infrastructure/Data/Config/EntityBuilders/StockItemConfiguration.cs rename to src/Nethereum.eShop.EntityFramework/Catalog/EntityBuilders/StockItemConfiguration.cs index 02f0e69..9bb531a 100644 --- a/src/Nethereum.eShop.EntityFramework/Infrastructure/Data/Config/EntityBuilders/StockItemConfiguration.cs +++ b/src/Nethereum.eShop.EntityFramework/Catalog/EntityBuilders/StockItemConfiguration.cs @@ -2,7 +2,7 @@ using Microsoft.EntityFrameworkCore.Metadata.Builders; using Nethereum.eShop.ApplicationCore.Entities; -namespace Nethereum.eShop.Infrastructure.Data.Config.EntityBuilders +namespace Nethereum.eShop.EntityFramework.Catalog.EntityBuilders { public class StockItemConfiguration : IEntityTypeConfiguration { @@ -11,7 +11,6 @@ public virtual void Configure(EntityTypeBuilder builder) builder.ToTable("Stock"); builder.Property(ci => ci.Id) - // .UseHiLo("stock_hilo") .IsRequired(); builder.Property(ci => ci.Location) diff --git a/src/Nethereum.eShop.EntityFramework/Infrastructure/Data/MediatorExtension.cs b/src/Nethereum.eShop.EntityFramework/Catalog/MediatorExtension.cs similarity index 94% rename from src/Nethereum.eShop.EntityFramework/Infrastructure/Data/MediatorExtension.cs rename to src/Nethereum.eShop.EntityFramework/Catalog/MediatorExtension.cs index 4319358..597b045 100644 --- a/src/Nethereum.eShop.EntityFramework/Infrastructure/Data/MediatorExtension.cs +++ b/src/Nethereum.eShop.EntityFramework/Catalog/MediatorExtension.cs @@ -4,7 +4,7 @@ using System.Linq; using System.Threading.Tasks; -namespace Nethereum.eShop.Infrastructure.Data +namespace Nethereum.eShop.EntityFramework.Catalog { public static class MediatorExtension { diff --git a/src/Nethereum.eShop.EntityFramework/Infrastructure/Data/BasketRepository.cs b/src/Nethereum.eShop.EntityFramework/Catalog/Repositories/BasketRepository.cs similarity index 93% rename from src/Nethereum.eShop.EntityFramework/Infrastructure/Data/BasketRepository.cs rename to src/Nethereum.eShop.EntityFramework/Catalog/Repositories/BasketRepository.cs index 23b7fdf..9417881 100644 --- a/src/Nethereum.eShop.EntityFramework/Infrastructure/Data/BasketRepository.cs +++ b/src/Nethereum.eShop.EntityFramework/Catalog/Repositories/BasketRepository.cs @@ -4,7 +4,7 @@ using System.Linq; using System.Threading.Tasks; -namespace Nethereum.eShop.Infrastructure.Data +namespace Nethereum.eShop.EntityFramework.Catalog.Repositories { public class BasketRepository : EfRepository, IBasketRepository { diff --git a/src/Nethereum.eShop.EntityFramework/Infrastructure/Data/CatalogItemRepository.cs b/src/Nethereum.eShop.EntityFramework/Catalog/Repositories/CatalogItemRepository.cs similarity index 82% rename from src/Nethereum.eShop.EntityFramework/Infrastructure/Data/CatalogItemRepository.cs rename to src/Nethereum.eShop.EntityFramework/Catalog/Repositories/CatalogItemRepository.cs index bd0dc4e..f2cf728 100644 --- a/src/Nethereum.eShop.EntityFramework/Infrastructure/Data/CatalogItemRepository.cs +++ b/src/Nethereum.eShop.EntityFramework/Catalog/Repositories/CatalogItemRepository.cs @@ -1,7 +1,7 @@ using Nethereum.eShop.ApplicationCore.Entities; using Nethereum.eShop.ApplicationCore.Interfaces; -namespace Nethereum.eShop.Infrastructure.Data +namespace Nethereum.eShop.EntityFramework.Catalog.Repositories { public class CatalogItemRepository : EfRepository, ICatalogItemRepository { diff --git a/src/Nethereum.eShop.EntityFramework/Infrastructure/Data/EfRepository.cs b/src/Nethereum.eShop.EntityFramework/Catalog/Repositories/EfRepository.cs similarity index 93% rename from src/Nethereum.eShop.EntityFramework/Infrastructure/Data/EfRepository.cs rename to src/Nethereum.eShop.EntityFramework/Catalog/Repositories/EfRepository.cs index a792719..0c049aa 100644 --- a/src/Nethereum.eShop.EntityFramework/Infrastructure/Data/EfRepository.cs +++ b/src/Nethereum.eShop.EntityFramework/Catalog/Repositories/EfRepository.cs @@ -1,11 +1,12 @@ using Microsoft.EntityFrameworkCore; using Nethereum.eShop.ApplicationCore.Entities; using Nethereum.eShop.ApplicationCore.Interfaces; +using Nethereum.eShop.Infrastructure.Data; using System.Collections.Generic; using System.Linq; using System.Threading.Tasks; -namespace Nethereum.eShop.Infrastructure.Data +namespace Nethereum.eShop.EntityFramework.Catalog.Repositories { public class EfRepository : IAsyncRepository where T : BaseEntity, IAggregateRoot { diff --git a/src/Nethereum.eShop.EntityFramework/Infrastructure/Data/OrderRepository.cs b/src/Nethereum.eShop.EntityFramework/Catalog/Repositories/OrderRepository.cs similarity index 96% rename from src/Nethereum.eShop.EntityFramework/Infrastructure/Data/OrderRepository.cs rename to src/Nethereum.eShop.EntityFramework/Catalog/Repositories/OrderRepository.cs index f3b717b..1fc2e70 100644 --- a/src/Nethereum.eShop.EntityFramework/Infrastructure/Data/OrderRepository.cs +++ b/src/Nethereum.eShop.EntityFramework/Catalog/Repositories/OrderRepository.cs @@ -3,7 +3,7 @@ using Microsoft.EntityFrameworkCore; using System.Threading.Tasks; -namespace Nethereum.eShop.Infrastructure.Data +namespace Nethereum.eShop.EntityFramework.Catalog.Repositories { public class OrderRepository : EfRepository, IOrderRepository diff --git a/src/Nethereum.eShop.EntityFramework/Infrastructure/Data/QuoteRepository.cs b/src/Nethereum.eShop.EntityFramework/Catalog/Repositories/QuoteRepository.cs similarity index 93% rename from src/Nethereum.eShop.EntityFramework/Infrastructure/Data/QuoteRepository.cs rename to src/Nethereum.eShop.EntityFramework/Catalog/Repositories/QuoteRepository.cs index 7dcc340..02c8766 100644 --- a/src/Nethereum.eShop.EntityFramework/Infrastructure/Data/QuoteRepository.cs +++ b/src/Nethereum.eShop.EntityFramework/Catalog/Repositories/QuoteRepository.cs @@ -5,7 +5,7 @@ using System.Linq; using System.Threading.Tasks; -namespace Nethereum.eShop.Infrastructure.Data +namespace Nethereum.eShop.EntityFramework.Catalog.Repositories { public class QuoteRepository : EfRepository, IQuoteRepository { diff --git a/src/Nethereum.eShop.EntityFramework/Infrastructure/Data/StockItemRepository.cs b/src/Nethereum.eShop.EntityFramework/Catalog/Repositories/StockItemRepository.cs similarity index 82% rename from src/Nethereum.eShop.EntityFramework/Infrastructure/Data/StockItemRepository.cs rename to src/Nethereum.eShop.EntityFramework/Catalog/Repositories/StockItemRepository.cs index 7b6d2d0..0be086b 100644 --- a/src/Nethereum.eShop.EntityFramework/Infrastructure/Data/StockItemRepository.cs +++ b/src/Nethereum.eShop.EntityFramework/Catalog/Repositories/StockItemRepository.cs @@ -1,7 +1,7 @@ using Nethereum.eShop.ApplicationCore.Interfaces; using Nethereum.eShop.ApplicationCore.Entities; -namespace Nethereum.eShop.Infrastructure.Data +namespace Nethereum.eShop.EntityFramework.Catalog.Repositories { public class StockItemRepository : EfRepository, IStockItemRepository { diff --git a/src/Nethereum.eShop.EntityFramework/Infrastructure/Data/CatalogContextSeed.cs b/src/Nethereum.eShop.EntityFramework/Catalog/Seed/CatalogContextSeed.cs similarity index 99% rename from src/Nethereum.eShop.EntityFramework/Infrastructure/Data/CatalogContextSeed.cs rename to src/Nethereum.eShop.EntityFramework/Catalog/Seed/CatalogContextSeed.cs index 8072e9f..09aabad 100644 --- a/src/Nethereum.eShop.EntityFramework/Infrastructure/Data/CatalogContextSeed.cs +++ b/src/Nethereum.eShop.EntityFramework/Catalog/Seed/CatalogContextSeed.cs @@ -6,7 +6,7 @@ using System.Linq; using System.Threading.Tasks; -namespace Nethereum.eShop.Infrastructure.Data +namespace Nethereum.eShop.EntityFramework.Catalog.Seed { public class HardCodedCatalogContextSeeder: ICatalogContextSeeder diff --git a/src/Nethereum.eShop.EntityFramework/Infrastructure/Data/CatalogImportDto.cs b/src/Nethereum.eShop.EntityFramework/Catalog/Seed/CatalogImportDto.cs similarity index 87% rename from src/Nethereum.eShop.EntityFramework/Infrastructure/Data/CatalogImportDto.cs rename to src/Nethereum.eShop.EntityFramework/Catalog/Seed/CatalogImportDto.cs index 606abb2..a01ea9b 100644 --- a/src/Nethereum.eShop.EntityFramework/Infrastructure/Data/CatalogImportDto.cs +++ b/src/Nethereum.eShop.EntityFramework/Catalog/Seed/CatalogImportDto.cs @@ -1,7 +1,7 @@ using Nethereum.eShop.ApplicationCore.Entities; using System.Collections.Generic; -namespace Nethereum.eShop.Infrastructure.Data +namespace Nethereum.eShop.EntityFramework.Catalog.Seed { public class CatalogImportDto { diff --git a/src/Nethereum.eShop.EntityFramework/Infrastructure/Data/JsonCatalogContextSeeder.cs b/src/Nethereum.eShop.EntityFramework/Catalog/Seed/JsonCatalogContextSeeder.cs similarity index 96% rename from src/Nethereum.eShop.EntityFramework/Infrastructure/Data/JsonCatalogContextSeeder.cs rename to src/Nethereum.eShop.EntityFramework/Catalog/Seed/JsonCatalogContextSeeder.cs index 05bb040..2a35e82 100644 --- a/src/Nethereum.eShop.EntityFramework/Infrastructure/Data/JsonCatalogContextSeeder.cs +++ b/src/Nethereum.eShop.EntityFramework/Catalog/Seed/JsonCatalogContextSeeder.cs @@ -1,5 +1,4 @@ -using Microsoft.Extensions.Configuration; -using Microsoft.Extensions.Logging; +using Microsoft.Extensions.Logging; using Nethereum.eShop.ApplicationCore.Interfaces; using Newtonsoft.Json; using System; @@ -7,7 +6,7 @@ using System.Linq; using System.Threading.Tasks; -namespace Nethereum.eShop.Infrastructure.Data +namespace Nethereum.eShop.EntityFramework.Catalog.Seed { public class JsonCatalogContextSeeder : ICatalogContextSeeder diff --git a/src/Nethereum.eShop.EntityFramework/Infrastructure/Data/SpecificationEvaluator.cs b/src/Nethereum.eShop.EntityFramework/Common/Repositories/SpecificationEvaluator.cs similarity index 100% rename from src/Nethereum.eShop.EntityFramework/Infrastructure/Data/SpecificationEvaluator.cs rename to src/Nethereum.eShop.EntityFramework/Common/Repositories/SpecificationEvaluator.cs diff --git a/src/Nethereum.eShop.EntityFramework/Infrastructure/Identity/AppIdentityDbContext.cs b/src/Nethereum.eShop.EntityFramework/Identity/AppIdentityDbContext.cs similarity index 79% rename from src/Nethereum.eShop.EntityFramework/Infrastructure/Identity/AppIdentityDbContext.cs rename to src/Nethereum.eShop.EntityFramework/Identity/AppIdentityDbContext.cs index 4da6439..51a883f 100644 --- a/src/Nethereum.eShop.EntityFramework/Infrastructure/Identity/AppIdentityDbContext.cs +++ b/src/Nethereum.eShop.EntityFramework/Identity/AppIdentityDbContext.cs @@ -1,12 +1,12 @@ using Microsoft.AspNetCore.Identity.EntityFrameworkCore; using Microsoft.EntityFrameworkCore; +using Nethereum.eShop.Infrastructure.Identity; - -namespace Nethereum.eShop.Infrastructure.Identity +namespace Nethereum.eShop.EntityFramework.Identity { public class AppIdentityDbContext : IdentityDbContext { - public AppIdentityDbContext(DbContextOptions options) + public AppIdentityDbContext(DbContextOptions options) : base(options) { } diff --git a/src/Nethereum.eShop.EntityFramework/Identity/EShopAppIdentityDbBootstrapperBase.cs b/src/Nethereum.eShop.EntityFramework/Identity/EShopAppIdentityDbBootstrapperBase.cs new file mode 100644 index 0000000..8f9e300 --- /dev/null +++ b/src/Nethereum.eShop.EntityFramework/Identity/EShopAppIdentityDbBootstrapperBase.cs @@ -0,0 +1,29 @@ +using Microsoft.EntityFrameworkCore; +using Microsoft.Extensions.Configuration; +using Microsoft.Extensions.DependencyInjection; +using System; +using System.Collections.Generic; +using System.Text; +using System.Threading; +using System.Threading.Tasks; + +namespace Nethereum.eShop.EntityFramework.Identity +{ + public abstract class EShopAppIdentityDbBootstrapperBase + { + public virtual Task EnsureCreatedAsync(IServiceProvider serviceProvider, IConfiguration configuration, CancellationToken cancellationToken = default) + { + if (ApplyMigrationsOnStartup(configuration)) + { + var context = serviceProvider.GetRequiredService(); + return context.Database.MigrateAsync(cancellationToken); + } + return Task.CompletedTask; + } + + protected virtual bool ApplyMigrationsOnStartup(IConfiguration configuration) + { + return configuration.GetValue("IdentityApplyMigrationsOnStartup", false); + } + } +} diff --git a/src/Nethereum.eShop.EntityFramework/Infrastructure/Data/Config/EShopDbBootstrapperBase.cs b/src/Nethereum.eShop.EntityFramework/Infrastructure/Data/Config/EShopDbBootstrapperBase.cs deleted file mode 100644 index 7baae4c..0000000 --- a/src/Nethereum.eShop.EntityFramework/Infrastructure/Data/Config/EShopDbBootstrapperBase.cs +++ /dev/null @@ -1,19 +0,0 @@ -using Microsoft.Extensions.Configuration; -using Microsoft.Extensions.DependencyInjection; -using Nethereum.eShop.ApplicationCore.Interfaces; - -namespace Nethereum.eShop.Infrastructure.Data.Config -{ - public abstract class EShopDbBootstrapperBase - { - public virtual void AddRepositories(IServiceCollection services, IConfiguration configuration) - { - services.AddScoped(typeof(IAsyncRepository<>), typeof(EfRepository<>)); - services.AddScoped(); - services.AddScoped(); - services.AddScoped(); - services.AddScoped(); - services.AddScoped(); - } - } -} diff --git a/src/Nethereum.eShop.EntityFramework/Infrastructure/Data/IModelBuilderAssemblyHandler.cs b/src/Nethereum.eShop.EntityFramework/Infrastructure/Data/IModelBuilderAssemblyHandler.cs deleted file mode 100644 index 042ab87..0000000 --- a/src/Nethereum.eShop.EntityFramework/Infrastructure/Data/IModelBuilderAssemblyHandler.cs +++ /dev/null @@ -1,9 +0,0 @@ -using System.Reflection; - -namespace Nethereum.eShop.Infrastructure.Data -{ - public interface IModelBuilderAssemblyHandler - { - Assembly GetModelBuilderAssembly(); - } -} diff --git a/src/Nethereum.eShop.EntityFramework/Infrastructure/Data/ModelBuilderAssemblyHandler.cs b/src/Nethereum.eShop.EntityFramework/Infrastructure/Data/ModelBuilderAssemblyHandler.cs deleted file mode 100644 index ce7e97b..0000000 --- a/src/Nethereum.eShop.EntityFramework/Infrastructure/Data/ModelBuilderAssemblyHandler.cs +++ /dev/null @@ -1,15 +0,0 @@ -using System.Reflection; - -namespace Nethereum.eShop.Infrastructure.Data -{ - public class ModelBuilderAssemblyHandler : IModelBuilderAssemblyHandler - { - private readonly Assembly _assembly; - - public ModelBuilderAssemblyHandler(Assembly assembly) - { - _assembly = assembly; - } - public Assembly GetModelBuilderAssembly() => _assembly; - } -} diff --git a/src/Nethereum.eShop.InMemory/Catalog/InMemoryCatalogContext.cs b/src/Nethereum.eShop.InMemory/Catalog/InMemoryCatalogContext.cs new file mode 100644 index 0000000..07a7091 --- /dev/null +++ b/src/Nethereum.eShop.InMemory/Catalog/InMemoryCatalogContext.cs @@ -0,0 +1,21 @@ +using MediatR; +using Microsoft.EntityFrameworkCore; +using Nethereum.eShop.EntityFramework.Catalog; + +namespace Nethereum.eShop.InMemory.Catalog +{ + public class InMemoryCatalogContext : CatalogContext + { + public InMemoryCatalogContext(DbContextOptions options, IMediator mediator) : base(options, mediator) + { + } + + protected override void OnModelCreating(ModelBuilder builder) + { + base.OnModelCreating(builder); + //config is in EntityFramework project + builder.ApplyConfigurationsFromAssembly(typeof(CatalogContext).Assembly); + } + } +} + diff --git a/src/Nethereum.eShop.InMemory/Infrastructure/Data/Config/InMemoryEShopDbBootrapper.cs b/src/Nethereum.eShop.InMemory/Catalog/InMemoryEShopDbBootrapper.cs similarity index 53% rename from src/Nethereum.eShop.InMemory/Infrastructure/Data/Config/InMemoryEShopDbBootrapper.cs rename to src/Nethereum.eShop.InMemory/Catalog/InMemoryEShopDbBootrapper.cs index 64afa93..ec229c9 100644 --- a/src/Nethereum.eShop.InMemory/Infrastructure/Data/Config/InMemoryEShopDbBootrapper.cs +++ b/src/Nethereum.eShop.InMemory/Catalog/InMemoryEShopDbBootrapper.cs @@ -5,28 +5,20 @@ using Nethereum.eShop.ApplicationCore.Queries.Catalog; using Nethereum.eShop.ApplicationCore.Queries.Orders; using Nethereum.eShop.ApplicationCore.Queries.Quotes; -using Nethereum.eShop.Infrastructure.Data; -using Nethereum.eShop.Infrastructure.Data.Config; -using Nethereum.eShop.Infrastructure.Data.Config.EntityBuilders; -using Nethereum.eShop.InMemory.ApplicationCore.Queries.Catalog; -using Nethereum.eShop.InMemory.ApplicationCore.Queries.Orders; -using Nethereum.eShop.InMemory.ApplicationCore.Queries.Quotes; +using Nethereum.eShop.EntityFramework.Catalog; +using Nethereum.eShop.InMemory.Catalog.Queries; using System; using System.Threading; using System.Threading.Tasks; -namespace Nethereum.eShop.InMemory.Infrastructure.Data.Config +namespace Nethereum.eShop.InMemory.Catalog { public class InMemoryEShopDbBootrapper : EShopDbBootstrapperBase, IEShopDbBootstrapper { public void AddDbContext(IServiceCollection services, IConfiguration configuration) { - services.AddDbContext(c => + services.AddDbContext(c => c.UseInMemoryDatabase("Catalog")); - - // for in-memory, we'll use the basic model builders - services.AddSingleton>( - new ModelBuilderAssemblyHandler(typeof(BasketConfiguration).Assembly)); } public void AddQueries(IServiceCollection services, IConfiguration configuration) @@ -36,6 +28,6 @@ public void AddQueries(IServiceCollection services, IConfiguration configuration services.AddScoped(); } - public Task EnsureCreatedAsync(IServiceProvider serviceProvider, CancellationToken cancellationToken = default) => Task.CompletedTask; + public override Task EnsureCreatedAsync(IServiceProvider serviceProvider, IConfiguration configuration, CancellationToken cancellationToken = default) => Task.CompletedTask; } } diff --git a/src/Nethereum.eShop.InMemory/ApplicationCore/Queries/Catalog/CatalogQueries.cs b/src/Nethereum.eShop.InMemory/Catalog/Queries/CatalogQueries.cs similarity index 93% rename from src/Nethereum.eShop.InMemory/ApplicationCore/Queries/Catalog/CatalogQueries.cs rename to src/Nethereum.eShop.InMemory/Catalog/Queries/CatalogQueries.cs index 0869953..47674ed 100644 --- a/src/Nethereum.eShop.InMemory/ApplicationCore/Queries/Catalog/CatalogQueries.cs +++ b/src/Nethereum.eShop.InMemory/Catalog/Queries/CatalogQueries.cs @@ -2,13 +2,12 @@ using Nethereum.eShop.ApplicationCore.Entities; using Nethereum.eShop.ApplicationCore.Queries; using Nethereum.eShop.ApplicationCore.Queries.Catalog; -using Nethereum.eShop.Infrastructure.Data; +using Nethereum.eShop.EntityFramework.Catalog; using System; using System.Linq; -using System.Linq.Expressions; using System.Threading.Tasks; -namespace Nethereum.eShop.InMemory.ApplicationCore.Queries.Catalog +namespace Nethereum.eShop.InMemory.Catalog.Queries { public class CatalogQueries : QueriesBase, ICatalogQueries { diff --git a/src/Nethereum.eShop.InMemory/ApplicationCore/Queries/Orders/OrderQueries.cs b/src/Nethereum.eShop.InMemory/Catalog/Queries/OrderQueries.cs similarity index 95% rename from src/Nethereum.eShop.InMemory/ApplicationCore/Queries/Orders/OrderQueries.cs rename to src/Nethereum.eShop.InMemory/Catalog/Queries/OrderQueries.cs index 817b065..5318ff4 100644 --- a/src/Nethereum.eShop.InMemory/ApplicationCore/Queries/Orders/OrderQueries.cs +++ b/src/Nethereum.eShop.InMemory/Catalog/Queries/OrderQueries.cs @@ -2,12 +2,11 @@ using Nethereum.eShop.ApplicationCore.Entities.OrderAggregate; using Nethereum.eShop.ApplicationCore.Queries; using Nethereum.eShop.ApplicationCore.Queries.Orders; -using Nethereum.eShop.Infrastructure.Data; -using System; +using Nethereum.eShop.EntityFramework.Catalog; using System.Linq; using System.Threading.Tasks; -namespace Nethereum.eShop.InMemory.ApplicationCore.Queries.Orders +namespace Nethereum.eShop.InMemory.Catalog.Queries { public class OrderQueries : QueriesBase, IOrderQueries { diff --git a/src/Nethereum.eShop.InMemory/ApplicationCore/Queries/QueriesBase.cs b/src/Nethereum.eShop.InMemory/Catalog/Queries/QueriesBase.cs similarity index 67% rename from src/Nethereum.eShop.InMemory/ApplicationCore/Queries/QueriesBase.cs rename to src/Nethereum.eShop.InMemory/Catalog/Queries/QueriesBase.cs index 4fe21c1..f0879c2 100644 --- a/src/Nethereum.eShop.InMemory/ApplicationCore/Queries/QueriesBase.cs +++ b/src/Nethereum.eShop.InMemory/Catalog/Queries/QueriesBase.cs @@ -1,6 +1,6 @@ -using Nethereum.eShop.Infrastructure.Data; +using Nethereum.eShop.EntityFramework.Catalog; -namespace Nethereum.eShop.InMemory.ApplicationCore.Queries +namespace Nethereum.eShop.InMemory.Catalog.Queries { public abstract class QueriesBase { diff --git a/src/Nethereum.eShop.InMemory/ApplicationCore/Queries/Quotes/QuoteQueries.cs b/src/Nethereum.eShop.InMemory/Catalog/Queries/QuoteQueries.cs similarity index 95% rename from src/Nethereum.eShop.InMemory/ApplicationCore/Queries/Quotes/QuoteQueries.cs rename to src/Nethereum.eShop.InMemory/Catalog/Queries/QuoteQueries.cs index c017099..0baed72 100644 --- a/src/Nethereum.eShop.InMemory/ApplicationCore/Queries/Quotes/QuoteQueries.cs +++ b/src/Nethereum.eShop.InMemory/Catalog/Queries/QuoteQueries.cs @@ -2,11 +2,11 @@ using Nethereum.eShop.ApplicationCore.Entities.QuoteAggregate; using Nethereum.eShop.ApplicationCore.Queries; using Nethereum.eShop.ApplicationCore.Queries.Quotes; -using Nethereum.eShop.Infrastructure.Data; +using Nethereum.eShop.EntityFramework.Catalog; using System.Linq; using System.Threading.Tasks; -namespace Nethereum.eShop.InMemory.ApplicationCore.Queries.Quotes +namespace Nethereum.eShop.InMemory.Catalog.Queries { public class QuoteQueries : QueriesBase, IQuoteQueries { diff --git a/src/Nethereum.eShop.InMemory/Identity/InMemoryEShopAppIdentityDbBootrapper.cs b/src/Nethereum.eShop.InMemory/Identity/InMemoryEShopAppIdentityDbBootrapper.cs new file mode 100644 index 0000000..8d58229 --- /dev/null +++ b/src/Nethereum.eShop.InMemory/Identity/InMemoryEShopAppIdentityDbBootrapper.cs @@ -0,0 +1,22 @@ +using Microsoft.EntityFrameworkCore; +using Microsoft.Extensions.Configuration; +using Microsoft.Extensions.DependencyInjection; +using Nethereum.eShop.ApplicationCore.Interfaces; +using Nethereum.eShop.EntityFramework.Identity; +using System; +using System.Threading; +using System.Threading.Tasks; + +namespace Nethereum.eShop.InMemory.Infrastructure.Identity +{ + public class InMemoryEShopAppIdentityDbBootrapper : EShopAppIdentityDbBootstrapperBase, IEShopIdentityDbBootstrapper + { + public void AddDbContext(IServiceCollection services, IConfiguration configuration) + { + services.AddDbContext(options => + options.UseInMemoryDatabase("Identity")); + } + + public override Task EnsureCreatedAsync(IServiceProvider serviceProvider, IConfiguration configuration, CancellationToken cancellationToken = default) => Task.CompletedTask; + } +} diff --git a/src/Nethereum.eShop.InMemory/Identity/SqliteAppIdentityDbContext.cs b/src/Nethereum.eShop.InMemory/Identity/SqliteAppIdentityDbContext.cs new file mode 100644 index 0000000..ca2a030 --- /dev/null +++ b/src/Nethereum.eShop.InMemory/Identity/SqliteAppIdentityDbContext.cs @@ -0,0 +1,12 @@ +using Microsoft.EntityFrameworkCore; +using Nethereum.eShop.EntityFramework.Identity; + +namespace Nethereum.eShop.InMemory.Infrastructure.Identity +{ + public class InMemoryAppIdentityDbContext : AppIdentityDbContext + { + public InMemoryAppIdentityDbContext(DbContextOptions options) : base(options) + { + } + } +} diff --git a/src/Nethereum.eShop.InMemory/Infrastructure/Data/Config/InMemoryEShopAppIdentityDbBootrapper.cs b/src/Nethereum.eShop.InMemory/Infrastructure/Data/Config/InMemoryEShopAppIdentityDbBootrapper.cs deleted file mode 100644 index a2e2f1d..0000000 --- a/src/Nethereum.eShop.InMemory/Infrastructure/Data/Config/InMemoryEShopAppIdentityDbBootrapper.cs +++ /dev/null @@ -1,22 +0,0 @@ -using Microsoft.EntityFrameworkCore; -using Microsoft.Extensions.Configuration; -using Microsoft.Extensions.DependencyInjection; -using Nethereum.eShop.ApplicationCore.Interfaces; -using Nethereum.eShop.Infrastructure.Identity; -using System; -using System.Threading; -using System.Threading.Tasks; - -namespace Nethereum.eShop.InMemory.Infrastructure.Data.Config -{ - public class InMemoryEShopAppIdentityDbBootrapper : IEShopIdentityDbBootstrapper - { - public void AddDbContext(IServiceCollection services, IConfiguration configuration) - { - services.AddDbContext(options => - options.UseInMemoryDatabase("Identity")); - } - - public Task EnsureCreatedAsync(IServiceProvider serviceProvider, CancellationToken cancellationToken = default) => Task.CompletedTask; - } -} diff --git a/src/Nethereum.eShop.InMemory/Nethereum.eShop.InMemory.csproj b/src/Nethereum.eShop.InMemory/Nethereum.eShop.InMemory.csproj index 87d2b4b..ece7edc 100644 --- a/src/Nethereum.eShop.InMemory/Nethereum.eShop.InMemory.csproj +++ b/src/Nethereum.eShop.InMemory/Nethereum.eShop.InMemory.csproj @@ -12,5 +12,9 @@ + + + + diff --git a/src/Nethereum.eShop.Migrations/AddMigration.bat b/src/Nethereum.eShop.Migrations/AddMigration.bat new file mode 100644 index 0000000..3097371 --- /dev/null +++ b/src/Nethereum.eShop.Migrations/AddMigration.bat @@ -0,0 +1,4 @@ +dotnet ef migrations add %1 --project ..\Nethereum.eShop.SqlServer --context Nethereum.eShop.SqlServer.Catalog.SqlServerCatalogContext --output-dir ..\Nethereum.eShop.SqlServer\Catalog\Migrations +dotnet ef migrations add %1 --project ..\Nethereum.eShop.SqlServer --context Nethereum.eShop.SqlServer.Identity.SqlServerAppIdentityDbContext --output-dir ..\Nethereum.eShop.SqlServer\Identity\Migrations +dotnet ef migrations add %1 --project ..\Nethereum.eShop.Sqlite --context Nethereum.eShop.Sqlite.Catalog.SqliteCatalogContext --output-dir ..\Nethereum.eShop.Sqlite\Catalog\Migrations +dotnet ef migrations add %1 --project ..\Nethereum.eShop.Sqlite --context Nethereum.eShop.Sqlite.Identity.SqliteAppIdentityDbContext --output-dir ..\Nethereum.eShop.Sqlite\Identity\Migrations \ No newline at end of file diff --git a/src/Nethereum.eShop.SqlServer.Migrations/Nethereum.eShop.SqlServer.Migrations.csproj b/src/Nethereum.eShop.Migrations/Nethereum.eShop.Migrations.csproj similarity index 77% rename from src/Nethereum.eShop.SqlServer.Migrations/Nethereum.eShop.SqlServer.Migrations.csproj rename to src/Nethereum.eShop.Migrations/Nethereum.eShop.Migrations.csproj index fd66359..fdcfd73 100644 --- a/src/Nethereum.eShop.SqlServer.Migrations/Nethereum.eShop.SqlServer.Migrations.csproj +++ b/src/Nethereum.eShop.Migrations/Nethereum.eShop.Migrations.csproj @@ -1,4 +1,4 @@ - + Exe @@ -13,7 +13,7 @@ - + diff --git a/src/Nethereum.eShop.Migrations/Program.cs b/src/Nethereum.eShop.Migrations/Program.cs new file mode 100644 index 0000000..8dbfa3f --- /dev/null +++ b/src/Nethereum.eShop.Migrations/Program.cs @@ -0,0 +1,22 @@ +using System; + +namespace Nethereum.eShop.Migrations +{ + class Program + { + static void Main(string[] args) + { + Console.WriteLine("IMPORTANT!"); + Console.WriteLine("This 'Nethereum.eShop.Migrations' console is only for generating Entity Framework Migrations"); + Console.WriteLine("It is ONLY intended to be run as the startup project for the dotnet-ef tool to add a migration or create a script"); + Console.WriteLine(); + Console.WriteLine("To add a name migration - go to command line and run AddMigration.bat {name}"); + Console.WriteLine("This will create migrations for each DB provider (e.g. SqlServer, Sqlite)"); + Console.WriteLine(" e.g. AddMigration.bat InitialCreate"); + Console.ReadLine(); + Console.WriteLine("To create a SQL Script for DB Creation (e.g. SqlServer, Sqlite)"); + Console.WriteLine(" e.g. ScriptDbs.bat"); + Console.ReadLine(); + } + } +} diff --git a/src/Nethereum.eShop.Migrations/ScriptDbs.bat b/src/Nethereum.eShop.Migrations/ScriptDbs.bat new file mode 100644 index 0000000..10b7b96 --- /dev/null +++ b/src/Nethereum.eShop.Migrations/ScriptDbs.bat @@ -0,0 +1,4 @@ +dotnet ef migrations script --idempotent --project ..\Nethereum.eShop.SqlServer --context Nethereum.eShop.SqlServer.Catalog.SqlServerCatalogContext --output ..\Nethereum.eShop.SqlServer\Catalog\Migrations\Scripts\CreateCatalogDb.sql +dotnet ef migrations script --idempotent --project ..\Nethereum.eShop.SqlServer --context Nethereum.eShop.SqlServer.Identity.SqlServerAppIdentityDbContext --output ..\Nethereum.eShop.SqlServer\Identity\Migrations\Scripts\CreateIdentityDb.sql +dotnet ef migrations script --project ..\Nethereum.eShop.Sqlite --context Nethereum.eShop.Sqlite.Catalog.SqliteCatalogContext --output ..\Nethereum.eShop.Sqlite\Catalog\Migrations\Scripts\CreateCatalogDb.sql +dotnet ef migrations script --project ..\Nethereum.eShop.Sqlite --context Nethereum.eShop.Sqlite.Identity.SqliteAppIdentityDbContext --output ..\Nethereum.eShop.Sqlite\Identity\Migrations\Scripts\CreateIdentityDb.sql \ No newline at end of file diff --git a/src/Nethereum.eShop.SqlServer.Migrations/CreateInitialDbMigration.bat b/src/Nethereum.eShop.SqlServer.Migrations/CreateInitialDbMigration.bat deleted file mode 100644 index 4e712fd..0000000 --- a/src/Nethereum.eShop.SqlServer.Migrations/CreateInitialDbMigration.bat +++ /dev/null @@ -1,3 +0,0 @@ -rem Create First Migration aka InitialCreate -dotnet ef migrations add Catalog_InitialCreate --context Nethereum.eShop.Infrastructure.Data.CatalogContext --output-dir ..\Nethereum.eShop.SqlServer\Infrastructure\Data\Migrations -dotnet ef migrations add AppIdentity_InitialCreate --context Nethereum.eShop.Infrastructure.Identity.AppIdentityDbContext --output-dir ..\Nethereum.eShop.SqlServer\Infrastructure\Identity\Migrations \ No newline at end of file diff --git a/src/Nethereum.eShop.SqlServer.Migrations/Program.cs b/src/Nethereum.eShop.SqlServer.Migrations/Program.cs deleted file mode 100644 index 8608ad9..0000000 --- a/src/Nethereum.eShop.SqlServer.Migrations/Program.cs +++ /dev/null @@ -1,12 +0,0 @@ -using System; - -namespace Nethereum.eShop.SqlServer.Migrations -{ - class Program - { - static void Main(string[] args) - { - Console.WriteLine("Hello World!"); - } - } -} diff --git a/src/Nethereum.eShop.SqlServer.Migrations/SqlServerAppIdentityContextDesignTimeFactory.cs b/src/Nethereum.eShop.SqlServer.Migrations/SqlServerAppIdentityContextDesignTimeFactory.cs deleted file mode 100644 index 75c2f37..0000000 --- a/src/Nethereum.eShop.SqlServer.Migrations/SqlServerAppIdentityContextDesignTimeFactory.cs +++ /dev/null @@ -1,20 +0,0 @@ -using Microsoft.EntityFrameworkCore; -using Microsoft.EntityFrameworkCore.Design; -using Nethereum.eShop.Infrastructure.Identity; - -namespace Nethereum.eShop.SqlServer.Infrastructure.Data.Config -{ - public class SqlServerAppIdentityContextDesignTimeFactory : IDesignTimeDbContextFactory - { - public AppIdentityDbContext CreateDbContext(string[] args) - { - var optionsBuilder = new DbContextOptionsBuilder(); - optionsBuilder.UseSqlServer( - "Server=localhost\\sqldev;Integrated Security=true;Initial Catalog=eShop;", - b => b.MigrationsAssembly("Nethereum.eShop.SqlServer.Migrations")); - - return new AppIdentityDbContext( - optionsBuilder.Options); - } - } -} diff --git a/src/Nethereum.eShop.SqlServer.Migrations/SqlServerCatalogContextDesignTimeFactory.cs b/src/Nethereum.eShop.SqlServer.Migrations/SqlServerCatalogContextDesignTimeFactory.cs deleted file mode 100644 index bbc9ea2..0000000 --- a/src/Nethereum.eShop.SqlServer.Migrations/SqlServerCatalogContextDesignTimeFactory.cs +++ /dev/null @@ -1,23 +0,0 @@ -using Microsoft.EntityFrameworkCore; -using Microsoft.EntityFrameworkCore.Design; -using Nethereum.eShop.Infrastructure.Data; -using Nethereum.eShop.Infrastructure.Data.Config.EntityBuilders.SqlServer; - -namespace Nethereum.eShop.SqlServer.Infrastructure.Data.Config -{ - public class SqlServerCatalogContextDesignTimeFactory: IDesignTimeDbContextFactory - { - public CatalogContext CreateDbContext(string[] args) - { - var optionsBuilder = new DbContextOptionsBuilder(); - optionsBuilder.UseSqlServer( - "Server=localhost\\sqldev;Integrated Security=true;Initial Catalog=eShop;", - b => b.MigrationsAssembly("Nethereum.eShop.SqlServer.Migrations")); - - return new CatalogContext( - optionsBuilder.Options, - null, - new ModelBuilderAssemblyHandler(typeof(BasketConfiguration).Assembly)); - } - } -} diff --git a/src/Nethereum.eShop.SqlServer/Infrastructure/Data/Config/EntityBuilders/SqlServer/BasketConfiguration.cs b/src/Nethereum.eShop.SqlServer/Catalog/EntityBuilders/BasketConfiguration.cs similarity index 71% rename from src/Nethereum.eShop.SqlServer/Infrastructure/Data/Config/EntityBuilders/SqlServer/BasketConfiguration.cs rename to src/Nethereum.eShop.SqlServer/Catalog/EntityBuilders/BasketConfiguration.cs index b0661bb..8aad972 100644 --- a/src/Nethereum.eShop.SqlServer/Infrastructure/Data/Config/EntityBuilders/SqlServer/BasketConfiguration.cs +++ b/src/Nethereum.eShop.SqlServer/Catalog/EntityBuilders/BasketConfiguration.cs @@ -1,9 +1,9 @@ using Microsoft.EntityFrameworkCore; using Microsoft.EntityFrameworkCore.Metadata.Builders; using Nethereum.eShop.ApplicationCore.Entities.BasketAggregate; -using b = Nethereum.eShop.Infrastructure.Data.Config.EntityBuilders; +using b = Nethereum.eShop.EntityFramework.Catalog.EntityBuilders; -namespace Nethereum.eShop.Infrastructure.Data.Config.EntityBuilders.SqlServer +namespace Nethereum.eShop.SqlServer.Catalog.EntityBuilders { public class BasketConfiguration : b.BasketConfiguration { diff --git a/src/Nethereum.eShop.SqlServer/Infrastructure/Data/Config/EntityBuilders/SqlServer/BasketItemConfiguration.cs b/src/Nethereum.eShop.SqlServer/Catalog/EntityBuilders/BasketItemConfiguration.cs similarity index 72% rename from src/Nethereum.eShop.SqlServer/Infrastructure/Data/Config/EntityBuilders/SqlServer/BasketItemConfiguration.cs rename to src/Nethereum.eShop.SqlServer/Catalog/EntityBuilders/BasketItemConfiguration.cs index 93b7a9a..3527e9f 100644 --- a/src/Nethereum.eShop.SqlServer/Infrastructure/Data/Config/EntityBuilders/SqlServer/BasketItemConfiguration.cs +++ b/src/Nethereum.eShop.SqlServer/Catalog/EntityBuilders/BasketItemConfiguration.cs @@ -1,9 +1,9 @@ using Microsoft.EntityFrameworkCore; using Microsoft.EntityFrameworkCore.Metadata.Builders; using Nethereum.eShop.ApplicationCore.Entities.BasketAggregate; -using b = Nethereum.eShop.Infrastructure.Data.Config.EntityBuilders; +using b = Nethereum.eShop.EntityFramework.Catalog.EntityBuilders; -namespace Nethereum.eShop.Infrastructure.Data.Config.EntityBuilders.SqlServer +namespace Nethereum.eShop.SqlServer.Catalog.EntityBuilders { public class BasketItemConfiguration : b.BasketItemConfiguration { diff --git a/src/Nethereum.eShop.SqlServer/Infrastructure/Data/Config/EntityBuilders/SqlServer/BuyerConfiguration.cs b/src/Nethereum.eShop.SqlServer/Catalog/EntityBuilders/BuyerConfiguration.cs similarity index 71% rename from src/Nethereum.eShop.SqlServer/Infrastructure/Data/Config/EntityBuilders/SqlServer/BuyerConfiguration.cs rename to src/Nethereum.eShop.SqlServer/Catalog/EntityBuilders/BuyerConfiguration.cs index 44e7192..e8a7ea3 100644 --- a/src/Nethereum.eShop.SqlServer/Infrastructure/Data/Config/EntityBuilders/SqlServer/BuyerConfiguration.cs +++ b/src/Nethereum.eShop.SqlServer/Catalog/EntityBuilders/BuyerConfiguration.cs @@ -1,9 +1,9 @@ using Microsoft.EntityFrameworkCore; using Microsoft.EntityFrameworkCore.Metadata.Builders; using Nethereum.eShop.ApplicationCore.Entities.BuyerAggregate; -using b = Nethereum.eShop.Infrastructure.Data.Config.EntityBuilders; +using b = Nethereum.eShop.EntityFramework.Catalog.EntityBuilders; -namespace Nethereum.eShop.Infrastructure.Data.Config.EntityBuilders.SqlServer +namespace Nethereum.eShop.SqlServer.Catalog.EntityBuilders { public class BuyerConfiguration : b.BuyerConfiguration { diff --git a/src/Nethereum.eShop.SqlServer/Infrastructure/Data/Config/EntityBuilders/SqlServer/BuyerPostalAddressConfiguration.cs b/src/Nethereum.eShop.SqlServer/Catalog/EntityBuilders/BuyerPostalAddressConfiguration.cs similarity index 73% rename from src/Nethereum.eShop.SqlServer/Infrastructure/Data/Config/EntityBuilders/SqlServer/BuyerPostalAddressConfiguration.cs rename to src/Nethereum.eShop.SqlServer/Catalog/EntityBuilders/BuyerPostalAddressConfiguration.cs index 6f765f5..e870ee5 100644 --- a/src/Nethereum.eShop.SqlServer/Infrastructure/Data/Config/EntityBuilders/SqlServer/BuyerPostalAddressConfiguration.cs +++ b/src/Nethereum.eShop.SqlServer/Catalog/EntityBuilders/BuyerPostalAddressConfiguration.cs @@ -1,9 +1,9 @@ using Microsoft.EntityFrameworkCore; using Microsoft.EntityFrameworkCore.Metadata.Builders; using Nethereum.eShop.ApplicationCore.Entities.BuyerAggregate; -using b = Nethereum.eShop.Infrastructure.Data.Config.EntityBuilders; +using b = Nethereum.eShop.EntityFramework.Catalog.EntityBuilders; -namespace Nethereum.eShop.Infrastructure.Data.Config.EntityBuilders.SqlServer +namespace Nethereum.eShop.SqlServer.Catalog.EntityBuilders { public class BuyerPostalAddressConfiguration : b.BuyerPostalAddressConfiguration { diff --git a/src/Nethereum.eShop.SqlServer/Infrastructure/Data/Config/EntityBuilders/SqlServer/CatalogBrandConfiguration.cs b/src/Nethereum.eShop.SqlServer/Catalog/EntityBuilders/CatalogBrandConfiguration.cs similarity index 75% rename from src/Nethereum.eShop.SqlServer/Infrastructure/Data/Config/EntityBuilders/SqlServer/CatalogBrandConfiguration.cs rename to src/Nethereum.eShop.SqlServer/Catalog/EntityBuilders/CatalogBrandConfiguration.cs index fef1bb0..c9b80a6 100644 --- a/src/Nethereum.eShop.SqlServer/Infrastructure/Data/Config/EntityBuilders/SqlServer/CatalogBrandConfiguration.cs +++ b/src/Nethereum.eShop.SqlServer/Catalog/EntityBuilders/CatalogBrandConfiguration.cs @@ -1,9 +1,9 @@ using Microsoft.EntityFrameworkCore; using Microsoft.EntityFrameworkCore.Metadata.Builders; using Nethereum.eShop.ApplicationCore.Entities; -using b = Nethereum.eShop.Infrastructure.Data.Config.EntityBuilders; +using b = Nethereum.eShop.EntityFramework.Catalog.EntityBuilders; -namespace Nethereum.eShop.Infrastructure.Data.Config.EntityBuilders.SqlServer +namespace Nethereum.eShop.SqlServer.Catalog.EntityBuilders { public class CatalogBrandConfiguration : b.CatalogBrandConfiguration { diff --git a/src/Nethereum.eShop.SqlServer/Infrastructure/Data/Config/EntityBuilders/SqlServer/CatalogItemConfiguration.cs b/src/Nethereum.eShop.SqlServer/Catalog/EntityBuilders/CatalogItemConfiguration.cs similarity index 75% rename from src/Nethereum.eShop.SqlServer/Infrastructure/Data/Config/EntityBuilders/SqlServer/CatalogItemConfiguration.cs rename to src/Nethereum.eShop.SqlServer/Catalog/EntityBuilders/CatalogItemConfiguration.cs index 9d75725..b815133 100644 --- a/src/Nethereum.eShop.SqlServer/Infrastructure/Data/Config/EntityBuilders/SqlServer/CatalogItemConfiguration.cs +++ b/src/Nethereum.eShop.SqlServer/Catalog/EntityBuilders/CatalogItemConfiguration.cs @@ -1,9 +1,9 @@ using Microsoft.EntityFrameworkCore; using Microsoft.EntityFrameworkCore.Metadata.Builders; using Nethereum.eShop.ApplicationCore.Entities; -using b = Nethereum.eShop.Infrastructure.Data.Config.EntityBuilders; +using b = Nethereum.eShop.EntityFramework.Catalog.EntityBuilders; -namespace Nethereum.eShop.Infrastructure.Data.Config.EntityBuilders.SqlServer +namespace Nethereum.eShop.SqlServer.Catalog.EntityBuilders { public class CatalogItemConfiguration : b.CatalogItemConfiguration { diff --git a/src/Nethereum.eShop.SqlServer/Infrastructure/Data/Config/EntityBuilders/SqlServer/CatalogTypeConfiguration.cs b/src/Nethereum.eShop.SqlServer/Catalog/EntityBuilders/CatalogTypeConfiguration.cs similarity index 80% rename from src/Nethereum.eShop.SqlServer/Infrastructure/Data/Config/EntityBuilders/SqlServer/CatalogTypeConfiguration.cs rename to src/Nethereum.eShop.SqlServer/Catalog/EntityBuilders/CatalogTypeConfiguration.cs index 1eb0be4..957617d 100644 --- a/src/Nethereum.eShop.SqlServer/Infrastructure/Data/Config/EntityBuilders/SqlServer/CatalogTypeConfiguration.cs +++ b/src/Nethereum.eShop.SqlServer/Catalog/EntityBuilders/CatalogTypeConfiguration.cs @@ -1,9 +1,9 @@ using Microsoft.EntityFrameworkCore; using Microsoft.EntityFrameworkCore.Metadata.Builders; using Nethereum.eShop.ApplicationCore.Entities; -using b = Nethereum.eShop.Infrastructure.Data.Config.EntityBuilders; +using b = Nethereum.eShop.EntityFramework.Catalog.EntityBuilders; -namespace Nethereum.eShop.Infrastructure.Data.Config.EntityBuilders.SqlServer +namespace Nethereum.eShop.SqlServer.Catalog.EntityBuilders { public class CatalogTypeConfiguration : IEntityTypeConfiguration { diff --git a/src/Nethereum.eShop.SqlServer/Infrastructure/Data/Config/EntityBuilders/SqlServer/OrderConfiguration.cs b/src/Nethereum.eShop.SqlServer/Catalog/EntityBuilders/OrderConfiguration.cs similarity index 71% rename from src/Nethereum.eShop.SqlServer/Infrastructure/Data/Config/EntityBuilders/SqlServer/OrderConfiguration.cs rename to src/Nethereum.eShop.SqlServer/Catalog/EntityBuilders/OrderConfiguration.cs index 3dfbe70..3232248 100644 --- a/src/Nethereum.eShop.SqlServer/Infrastructure/Data/Config/EntityBuilders/SqlServer/OrderConfiguration.cs +++ b/src/Nethereum.eShop.SqlServer/Catalog/EntityBuilders/OrderConfiguration.cs @@ -1,9 +1,9 @@ using Microsoft.EntityFrameworkCore; using Microsoft.EntityFrameworkCore.Metadata.Builders; using Nethereum.eShop.ApplicationCore.Entities.OrderAggregate; -using b = Nethereum.eShop.Infrastructure.Data.Config.EntityBuilders; +using b = Nethereum.eShop.EntityFramework.Catalog.EntityBuilders; -namespace Nethereum.eShop.Infrastructure.Data.Config.EntityBuilders.SqlServer +namespace Nethereum.eShop.SqlServer.Catalog.EntityBuilders { public class OrderConfiguration : b.OrderConfiguration { diff --git a/src/Nethereum.eShop.SqlServer/Infrastructure/Data/Config/EntityBuilders/SqlServer/OrderItemConfiguration.cs b/src/Nethereum.eShop.SqlServer/Catalog/EntityBuilders/OrderItemConfiguration.cs similarity index 71% rename from src/Nethereum.eShop.SqlServer/Infrastructure/Data/Config/EntityBuilders/SqlServer/OrderItemConfiguration.cs rename to src/Nethereum.eShop.SqlServer/Catalog/EntityBuilders/OrderItemConfiguration.cs index 43e06c1..f89f2bf 100644 --- a/src/Nethereum.eShop.SqlServer/Infrastructure/Data/Config/EntityBuilders/SqlServer/OrderItemConfiguration.cs +++ b/src/Nethereum.eShop.SqlServer/Catalog/EntityBuilders/OrderItemConfiguration.cs @@ -1,9 +1,9 @@ using Microsoft.EntityFrameworkCore; using Microsoft.EntityFrameworkCore.Metadata.Builders; using Nethereum.eShop.ApplicationCore.Entities.OrderAggregate; -using b = Nethereum.eShop.Infrastructure.Data.Config.EntityBuilders; +using b = Nethereum.eShop.EntityFramework.Catalog.EntityBuilders; -namespace Nethereum.eShop.Infrastructure.Data.Config.EntityBuilders.SqlServer +namespace Nethereum.eShop.SqlServer.Catalog.EntityBuilders { public class OrderItemConfiguration : b.OrderItemConfiguration { diff --git a/src/Nethereum.eShop.SqlServer/Infrastructure/Data/Config/EntityBuilders/SqlServer/QuoteConfiguration.cs b/src/Nethereum.eShop.SqlServer/Catalog/EntityBuilders/QuoteConfiguration.cs similarity index 71% rename from src/Nethereum.eShop.SqlServer/Infrastructure/Data/Config/EntityBuilders/SqlServer/QuoteConfiguration.cs rename to src/Nethereum.eShop.SqlServer/Catalog/EntityBuilders/QuoteConfiguration.cs index 9320b10..4c8a7fe 100644 --- a/src/Nethereum.eShop.SqlServer/Infrastructure/Data/Config/EntityBuilders/SqlServer/QuoteConfiguration.cs +++ b/src/Nethereum.eShop.SqlServer/Catalog/EntityBuilders/QuoteConfiguration.cs @@ -1,9 +1,9 @@ using Microsoft.EntityFrameworkCore; using Microsoft.EntityFrameworkCore.Metadata.Builders; using Nethereum.eShop.ApplicationCore.Entities.QuoteAggregate; -using b = Nethereum.eShop.Infrastructure.Data.Config.EntityBuilders; +using b = Nethereum.eShop.EntityFramework.Catalog.EntityBuilders; -namespace Nethereum.eShop.Infrastructure.Data.Config.EntityBuilders.SqlServer +namespace Nethereum.eShop.SqlServer.Catalog.EntityBuilders { public class QuoteConfiguration : b.QuoteConfiguration { diff --git a/src/Nethereum.eShop.SqlServer/Infrastructure/Data/Config/EntityBuilders/SqlServer/QuoteItemConfiguration.cs b/src/Nethereum.eShop.SqlServer/Catalog/EntityBuilders/QuoteItemConfiguration.cs similarity index 71% rename from src/Nethereum.eShop.SqlServer/Infrastructure/Data/Config/EntityBuilders/SqlServer/QuoteItemConfiguration.cs rename to src/Nethereum.eShop.SqlServer/Catalog/EntityBuilders/QuoteItemConfiguration.cs index a0630d0..10e8429 100644 --- a/src/Nethereum.eShop.SqlServer/Infrastructure/Data/Config/EntityBuilders/SqlServer/QuoteItemConfiguration.cs +++ b/src/Nethereum.eShop.SqlServer/Catalog/EntityBuilders/QuoteItemConfiguration.cs @@ -1,9 +1,9 @@ using Microsoft.EntityFrameworkCore; using Microsoft.EntityFrameworkCore.Metadata.Builders; using Nethereum.eShop.ApplicationCore.Entities.QuoteAggregate; -using b = Nethereum.eShop.Infrastructure.Data.Config.EntityBuilders; +using b = Nethereum.eShop.EntityFramework.Catalog.EntityBuilders; -namespace Nethereum.eShop.Infrastructure.Data.Config.EntityBuilders.SqlServer +namespace Nethereum.eShop.SqlServer.Catalog.EntityBuilders { public class QuoteItemConfiguration : b.QuoteItemConfiguration { diff --git a/src/Nethereum.eShop.SqlServer/Infrastructure/Data/Config/EntityBuilders/SqlServer/StockItemConfiguration.cs b/src/Nethereum.eShop.SqlServer/Catalog/EntityBuilders/StockItemConfiguration.cs similarity index 75% rename from src/Nethereum.eShop.SqlServer/Infrastructure/Data/Config/EntityBuilders/SqlServer/StockItemConfiguration.cs rename to src/Nethereum.eShop.SqlServer/Catalog/EntityBuilders/StockItemConfiguration.cs index f0ccdff..2ceea67 100644 --- a/src/Nethereum.eShop.SqlServer/Infrastructure/Data/Config/EntityBuilders/SqlServer/StockItemConfiguration.cs +++ b/src/Nethereum.eShop.SqlServer/Catalog/EntityBuilders/StockItemConfiguration.cs @@ -1,9 +1,9 @@ using Microsoft.EntityFrameworkCore; using Microsoft.EntityFrameworkCore.Metadata.Builders; using Nethereum.eShop.ApplicationCore.Entities; -using b = Nethereum.eShop.Infrastructure.Data.Config.EntityBuilders; +using b = Nethereum.eShop.EntityFramework.Catalog.EntityBuilders; -namespace Nethereum.eShop.Infrastructure.Data.Config.EntityBuilders.SqlServer +namespace Nethereum.eShop.SqlServer.Catalog.EntityBuilders { public class StockItemConfiguration : b.StockItemConfiguration { diff --git a/src/Nethereum.eShop.SqlServer/Infrastructure/Data/Migrations/20200310171921_Catalog_InitialCreate.Designer.cs b/src/Nethereum.eShop.SqlServer/Catalog/Migrations/20200311151648_InitialCreate.Designer.cs similarity index 99% rename from src/Nethereum.eShop.SqlServer/Infrastructure/Data/Migrations/20200310171921_Catalog_InitialCreate.Designer.cs rename to src/Nethereum.eShop.SqlServer/Catalog/Migrations/20200311151648_InitialCreate.Designer.cs index 16269df..905f24a 100644 --- a/src/Nethereum.eShop.SqlServer/Infrastructure/Data/Migrations/20200310171921_Catalog_InitialCreate.Designer.cs +++ b/src/Nethereum.eShop.SqlServer/Catalog/Migrations/20200311151648_InitialCreate.Designer.cs @@ -5,13 +5,13 @@ using Microsoft.EntityFrameworkCore.Metadata; using Microsoft.EntityFrameworkCore.Migrations; using Microsoft.EntityFrameworkCore.Storage.ValueConversion; -using Nethereum.eShop.Infrastructure.Data; +using Nethereum.eShop.SqlServer.Catalog; -namespace Nethereum.eShop.SqlServer.Migrations.Migrations +namespace Nethereum.eShop.SqlServer.Catalog.Migrations { - [DbContext(typeof(CatalogContext))] - [Migration("20200310171921_Catalog_InitialCreate")] - partial class Catalog_InitialCreate + [DbContext(typeof(SqlServerCatalogContext))] + [Migration("20200311151648_InitialCreate")] + partial class InitialCreate { protected override void BuildTargetModel(ModelBuilder modelBuilder) { diff --git a/src/Nethereum.eShop.SqlServer/Infrastructure/Data/Migrations/20200310171921_Catalog_InitialCreate.cs b/src/Nethereum.eShop.SqlServer/Catalog/Migrations/20200311151648_InitialCreate.cs similarity index 99% rename from src/Nethereum.eShop.SqlServer/Infrastructure/Data/Migrations/20200310171921_Catalog_InitialCreate.cs rename to src/Nethereum.eShop.SqlServer/Catalog/Migrations/20200311151648_InitialCreate.cs index 6fc4c8e..3be81b1 100644 --- a/src/Nethereum.eShop.SqlServer/Infrastructure/Data/Migrations/20200310171921_Catalog_InitialCreate.cs +++ b/src/Nethereum.eShop.SqlServer/Catalog/Migrations/20200311151648_InitialCreate.cs @@ -1,9 +1,9 @@ using System; using Microsoft.EntityFrameworkCore.Migrations; -namespace Nethereum.eShop.SqlServer.Migrations.Migrations +namespace Nethereum.eShop.SqlServer.Catalog.Migrations { - public partial class Catalog_InitialCreate : Migration + public partial class InitialCreate : Migration { protected override void Up(MigrationBuilder migrationBuilder) { diff --git a/src/Nethereum.eShop.SqlServer/Catalog/Migrations/Scripts/CreateCatalogDb.sql b/src/Nethereum.eShop.SqlServer/Catalog/Migrations/Scripts/CreateCatalogDb.sql new file mode 100644 index 0000000..da83c0e --- /dev/null +++ b/src/Nethereum.eShop.SqlServer/Catalog/Migrations/Scripts/CreateCatalogDb.sql @@ -0,0 +1,416 @@ +IF OBJECT_ID(N'[__EFMigrationsHistory]') IS NULL +BEGIN + CREATE TABLE [__EFMigrationsHistory] ( + [MigrationId] nvarchar(150) NOT NULL, + [ProductVersion] nvarchar(32) NOT NULL, + CONSTRAINT [PK___EFMigrationsHistory] PRIMARY KEY ([MigrationId]) + ); +END; + +GO + +IF NOT EXISTS(SELECT * FROM [__EFMigrationsHistory] WHERE [MigrationId] = N'20200311151648_InitialCreate') +BEGIN + CREATE SEQUENCE [catalog_brand_hilo] START WITH 1 INCREMENT BY 10 NO MINVALUE NO MAXVALUE NO CYCLE; +END; + +GO + +IF NOT EXISTS(SELECT * FROM [__EFMigrationsHistory] WHERE [MigrationId] = N'20200311151648_InitialCreate') +BEGIN + CREATE SEQUENCE [catalog_hilo] START WITH 1 INCREMENT BY 10 NO MINVALUE NO MAXVALUE NO CYCLE; +END; + +GO + +IF NOT EXISTS(SELECT * FROM [__EFMigrationsHistory] WHERE [MigrationId] = N'20200311151648_InitialCreate') +BEGIN + CREATE SEQUENCE [catalog_type_hilo] START WITH 1 INCREMENT BY 10 NO MINVALUE NO MAXVALUE NO CYCLE; +END; + +GO + +IF NOT EXISTS(SELECT * FROM [__EFMigrationsHistory] WHERE [MigrationId] = N'20200311151648_InitialCreate') +BEGIN + CREATE SEQUENCE [stock_hilo] START WITH 1 INCREMENT BY 10 NO MINVALUE NO MAXVALUE NO CYCLE; +END; + +GO + +IF NOT EXISTS(SELECT * FROM [__EFMigrationsHistory] WHERE [MigrationId] = N'20200311151648_InitialCreate') +BEGIN + CREATE TABLE [Baskets] ( + [Id] int NOT NULL IDENTITY, + [BuyerId] nvarchar(256) NOT NULL, + [BuyerAddress] nvarchar(43) NOT NULL, + [BillTo_RecipientName] nvarchar(255) NULL, + [BillTo_Street] nvarchar(180) NULL, + [BillTo_City] nvarchar(100) NULL, + [BillTo_State] nvarchar(60) NULL, + [BillTo_Country] nvarchar(90) NULL, + [BillTo_ZipCode] nvarchar(18) NULL, + [ShipTo_RecipientName] nvarchar(255) NULL, + [ShipTo_Street] nvarchar(180) NULL, + [ShipTo_City] nvarchar(100) NULL, + [ShipTo_State] nvarchar(60) NULL, + [ShipTo_Country] nvarchar(90) NULL, + [ShipTo_ZipCode] nvarchar(18) NULL, + [TransactionHash] nvarchar(67) NULL, + CONSTRAINT [PK_Baskets] PRIMARY KEY ([Id]) + ); +END; + +GO + +IF NOT EXISTS(SELECT * FROM [__EFMigrationsHistory] WHERE [MigrationId] = N'20200311151648_InitialCreate') +BEGIN + CREATE TABLE [Buyers] ( + [Id] int NOT NULL IDENTITY, + [BuyerId] nvarchar(256) NOT NULL, + [BuyerAddress] nvarchar(43) NULL, + CONSTRAINT [PK_Buyers] PRIMARY KEY ([Id]) + ); +END; + +GO + +IF NOT EXISTS(SELECT * FROM [__EFMigrationsHistory] WHERE [MigrationId] = N'20200311151648_InitialCreate') +BEGIN + CREATE TABLE [CatalogBrands] ( + [Id] int NOT NULL, + [Brand] nvarchar(100) NOT NULL, + CONSTRAINT [PK_CatalogBrands] PRIMARY KEY ([Id]) + ); +END; + +GO + +IF NOT EXISTS(SELECT * FROM [__EFMigrationsHistory] WHERE [MigrationId] = N'20200311151648_InitialCreate') +BEGIN + CREATE TABLE [CatalogTypes] ( + [Id] int NOT NULL, + [Type] nvarchar(100) NOT NULL, + CONSTRAINT [PK_CatalogTypes] PRIMARY KEY ([Id]) + ); +END; + +GO + +IF NOT EXISTS(SELECT * FROM [__EFMigrationsHistory] WHERE [MigrationId] = N'20200311151648_InitialCreate') +BEGIN + CREATE TABLE [Orders] ( + [Id] int NOT NULL IDENTITY, + [QuoteId] int NULL, + [Status] int NOT NULL, + [TransactionHash] nvarchar(67) NULL, + [BuyerId] nvarchar(256) NOT NULL, + [BuyerAddress] nvarchar(43) NULL, + [CurrencyAddress] nvarchar(43) NULL, + [CurrencySymbol] nvarchar(32) NULL, + [ApproverAddress] nvarchar(43) NULL, + [PoNumber] bigint NULL, + [PoType] int NOT NULL, + [BuyerWalletAddress] nvarchar(43) NULL, + [SellerId] nvarchar(32) NULL, + [PoDate] datetimeoffset NULL, + [OrderDate] datetimeoffset NOT NULL, + [BillTo_RecipientName] nvarchar(255) NULL, + [BillTo_Street] nvarchar(180) NULL, + [BillTo_City] nvarchar(100) NULL, + [BillTo_State] nvarchar(60) NULL, + [BillTo_Country] nvarchar(90) NULL, + [BillTo_ZipCode] nvarchar(18) NULL, + [ShipTo_RecipientName] nvarchar(255) NULL, + [ShipTo_Street] nvarchar(180) NULL, + [ShipTo_City] nvarchar(100) NULL, + [ShipTo_State] nvarchar(60) NULL, + [ShipTo_Country] nvarchar(90) NULL, + [ShipTo_ZipCode] nvarchar(18) NULL, + CONSTRAINT [PK_Orders] PRIMARY KEY ([Id]) + ); +END; + +GO + +IF NOT EXISTS(SELECT * FROM [__EFMigrationsHistory] WHERE [MigrationId] = N'20200311151648_InitialCreate') +BEGIN + CREATE TABLE [Quotes] ( + [Id] int NOT NULL IDENTITY, + [Status] int NOT NULL, + [Date] datetimeoffset NOT NULL, + [Expiry] datetimeoffset NOT NULL, + [TransactionHash] nvarchar(67) NULL, + [BuyerAddress] nvarchar(43) NULL, + [CurrencySymbol] nvarchar(32) NULL, + [CurrencyAddress] nvarchar(43) NULL, + [ApproverAddress] nvarchar(43) NULL, + [PoNumber] bigint NULL, + [PoType] int NOT NULL, + [BuyerWalletAddress] nvarchar(43) NULL, + [SellerId] nvarchar(32) NULL, + [BuyerId] nvarchar(256) NOT NULL, + [BillTo_RecipientName] nvarchar(255) NULL, + [BillTo_Street] nvarchar(180) NULL, + [BillTo_City] nvarchar(100) NULL, + [BillTo_State] nvarchar(60) NULL, + [BillTo_Country] nvarchar(90) NULL, + [BillTo_ZipCode] nvarchar(18) NULL, + [ShipTo_RecipientName] nvarchar(255) NULL, + [ShipTo_Street] nvarchar(180) NULL, + [ShipTo_City] nvarchar(100) NULL, + [ShipTo_State] nvarchar(60) NULL, + [ShipTo_Country] nvarchar(90) NULL, + [ShipTo_ZipCode] nvarchar(18) NULL, + CONSTRAINT [PK_Quotes] PRIMARY KEY ([Id]) + ); +END; + +GO + +IF NOT EXISTS(SELECT * FROM [__EFMigrationsHistory] WHERE [MigrationId] = N'20200311151648_InitialCreate') +BEGIN + CREATE TABLE [BasketItems] ( + [Id] int NOT NULL IDENTITY, + [UnitPrice] decimal(18,2) NOT NULL, + [Quantity] int NOT NULL, + [CatalogItemId] int NOT NULL, + [BasketId] int NOT NULL, + CONSTRAINT [PK_BasketItems] PRIMARY KEY ([Id]), + CONSTRAINT [FK_BasketItems_Baskets_BasketId] FOREIGN KEY ([BasketId]) REFERENCES [Baskets] ([Id]) ON DELETE CASCADE + ); +END; + +GO + +IF NOT EXISTS(SELECT * FROM [__EFMigrationsHistory] WHERE [MigrationId] = N'20200311151648_InitialCreate') +BEGIN + CREATE TABLE [BuyerPostalAddress] ( + [Id] int NOT NULL IDENTITY, + [Name] nvarchar(max) NULL, + [PostalAddress_RecipientName] nvarchar(255) NULL, + [PostalAddress_Street] nvarchar(180) NULL, + [PostalAddress_City] nvarchar(100) NULL, + [PostalAddress_State] nvarchar(60) NULL, + [PostalAddress_Country] nvarchar(90) NULL, + [PostalAddress_ZipCode] nvarchar(18) NULL, + [BuyerId] int NULL, + CONSTRAINT [PK_BuyerPostalAddress] PRIMARY KEY ([Id]), + CONSTRAINT [FK_BuyerPostalAddress_Buyers_BuyerId] FOREIGN KEY ([BuyerId]) REFERENCES [Buyers] ([Id]) ON DELETE NO ACTION + ); +END; + +GO + +IF NOT EXISTS(SELECT * FROM [__EFMigrationsHistory] WHERE [MigrationId] = N'20200311151648_InitialCreate') +BEGIN + CREATE TABLE [Catalog] ( + [Id] int NOT NULL, + [Status] int NOT NULL, + [Gtin] nvarchar(14) NOT NULL, + [GtinRegistryId] int NULL, + [Name] nvarchar(50) NOT NULL, + [Description] nvarchar(max) NULL, + [Price] decimal(18,2) NOT NULL, + [Unit] nvarchar(8) NULL, + [CatalogTypeId] int NOT NULL, + [CatalogBrandId] int NOT NULL, + [PictureUri] nvarchar(512) NULL, + [PictureSmallUri] nvarchar(512) NULL, + [PictureMediumUri] nvarchar(512) NULL, + [PictureLargeUri] nvarchar(512) NULL, + [AttributeJson] nvarchar(max) NULL, + [Rank] int NOT NULL, + [Height] int NOT NULL, + [Width] int NOT NULL, + [Depth] int NOT NULL, + [Weight] int NOT NULL, + CONSTRAINT [PK_Catalog] PRIMARY KEY ([Id]), + CONSTRAINT [FK_Catalog_CatalogBrands_CatalogBrandId] FOREIGN KEY ([CatalogBrandId]) REFERENCES [CatalogBrands] ([Id]) ON DELETE CASCADE, + CONSTRAINT [FK_Catalog_CatalogTypes_CatalogTypeId] FOREIGN KEY ([CatalogTypeId]) REFERENCES [CatalogTypes] ([Id]) ON DELETE CASCADE + ); +END; + +GO + +IF NOT EXISTS(SELECT * FROM [__EFMigrationsHistory] WHERE [MigrationId] = N'20200311151648_InitialCreate') +BEGIN + CREATE TABLE [OrderItems] ( + [Id] int NOT NULL IDENTITY, + [Status] int NOT NULL, + [ItemOrdered_CatalogItemId] int NULL, + [ItemOrdered_Gtin] nvarchar(14) NULL, + [ItemOrdered_GtinRegistryId] int NULL, + [ItemOrdered_ProductName] nvarchar(50) NULL, + [ItemOrdered_PictureUri] nvarchar(512) NULL, + [UnitPrice] decimal(18,2) NOT NULL, + [Quantity] int NOT NULL, + [Unit] nvarchar(50) NULL, + [PoItemStatus] int NULL, + [PoItemNumber] int NULL, + [GoodsIssueDate] datetimeoffset NULL, + [ActualEscrowReleaseDate] datetimeoffset NULL, + [PlannedEscrowReleaseDate] datetimeoffset NULL, + [IsEscrowReleased] bit NULL, + [QuantitySymbol] nvarchar(32) NULL, + [QuantityAddress] nvarchar(43) NULL, + [CurrencyValue] nvarchar(100) NULL, + [OrderId] int NULL, + CONSTRAINT [PK_OrderItems] PRIMARY KEY ([Id]), + CONSTRAINT [FK_OrderItems_Orders_OrderId] FOREIGN KEY ([OrderId]) REFERENCES [Orders] ([Id]) ON DELETE NO ACTION + ); +END; + +GO + +IF NOT EXISTS(SELECT * FROM [__EFMigrationsHistory] WHERE [MigrationId] = N'20200311151648_InitialCreate') +BEGIN + CREATE TABLE [QuoteItems] ( + [Id] int NOT NULL IDENTITY, + [ItemOrdered_CatalogItemId] int NULL, + [ItemOrdered_Gtin] nvarchar(14) NULL, + [ItemOrdered_GtinRegistryId] int NULL, + [ItemOrdered_ProductName] nvarchar(50) NULL, + [ItemOrdered_PictureUri] nvarchar(512) NULL, + [UnitPrice] decimal(18,2) NOT NULL, + [Quantity] int NOT NULL, + [Unit] nvarchar(max) NULL, + [PoItemNumber] int NULL, + [EscrowReleaseDate] datetimeoffset NULL, + [QuantitySymbol] nvarchar(max) NULL, + [QuantityAddress] nvarchar(max) NULL, + [CurrencyValue] nvarchar(max) NULL, + [QuoteId] int NULL, + CONSTRAINT [PK_QuoteItems] PRIMARY KEY ([Id]), + CONSTRAINT [FK_QuoteItems_Quotes_QuoteId] FOREIGN KEY ([QuoteId]) REFERENCES [Quotes] ([Id]) ON DELETE NO ACTION + ); +END; + +GO + +IF NOT EXISTS(SELECT * FROM [__EFMigrationsHistory] WHERE [MigrationId] = N'20200311151648_InitialCreate') +BEGIN + CREATE TABLE [Stock] ( + [Id] int NOT NULL, + [CatalogItemId] int NOT NULL, + [Location] nvarchar(50) NOT NULL, + [Quantity] int NOT NULL, + CONSTRAINT [PK_Stock] PRIMARY KEY ([Id]), + CONSTRAINT [FK_Stock_Catalog_CatalogItemId] FOREIGN KEY ([CatalogItemId]) REFERENCES [Catalog] ([Id]) ON DELETE CASCADE + ); +END; + +GO + +IF NOT EXISTS(SELECT * FROM [__EFMigrationsHistory] WHERE [MigrationId] = N'20200311151648_InitialCreate') +BEGIN + CREATE INDEX [IX_BasketItems_BasketId] ON [BasketItems] ([BasketId]); +END; + +GO + +IF NOT EXISTS(SELECT * FROM [__EFMigrationsHistory] WHERE [MigrationId] = N'20200311151648_InitialCreate') +BEGIN + CREATE INDEX [IX_Baskets_BuyerAddress] ON [Baskets] ([BuyerAddress]); +END; + +GO + +IF NOT EXISTS(SELECT * FROM [__EFMigrationsHistory] WHERE [MigrationId] = N'20200311151648_InitialCreate') +BEGIN + CREATE INDEX [IX_Baskets_BuyerId] ON [Baskets] ([BuyerId]); +END; + +GO + +IF NOT EXISTS(SELECT * FROM [__EFMigrationsHistory] WHERE [MigrationId] = N'20200311151648_InitialCreate') +BEGIN + CREATE INDEX [IX_BuyerPostalAddress_BuyerId] ON [BuyerPostalAddress] ([BuyerId]); +END; + +GO + +IF NOT EXISTS(SELECT * FROM [__EFMigrationsHistory] WHERE [MigrationId] = N'20200311151648_InitialCreate') +BEGIN + CREATE UNIQUE INDEX [IX_Buyers_BuyerAddress] ON [Buyers] ([BuyerAddress]) WHERE [BuyerAddress] IS NOT NULL; +END; + +GO + +IF NOT EXISTS(SELECT * FROM [__EFMigrationsHistory] WHERE [MigrationId] = N'20200311151648_InitialCreate') +BEGIN + CREATE UNIQUE INDEX [IX_Buyers_BuyerId] ON [Buyers] ([BuyerId]); +END; + +GO + +IF NOT EXISTS(SELECT * FROM [__EFMigrationsHistory] WHERE [MigrationId] = N'20200311151648_InitialCreate') +BEGIN + CREATE INDEX [IX_Catalog_CatalogBrandId] ON [Catalog] ([CatalogBrandId]); +END; + +GO + +IF NOT EXISTS(SELECT * FROM [__EFMigrationsHistory] WHERE [MigrationId] = N'20200311151648_InitialCreate') +BEGIN + CREATE INDEX [IX_Catalog_CatalogTypeId] ON [Catalog] ([CatalogTypeId]); +END; + +GO + +IF NOT EXISTS(SELECT * FROM [__EFMigrationsHistory] WHERE [MigrationId] = N'20200311151648_InitialCreate') +BEGIN + CREATE INDEX [IX_OrderItems_OrderId] ON [OrderItems] ([OrderId]); +END; + +GO + +IF NOT EXISTS(SELECT * FROM [__EFMigrationsHistory] WHERE [MigrationId] = N'20200311151648_InitialCreate') +BEGIN + CREATE INDEX [IX_Orders_BuyerAddress] ON [Orders] ([BuyerAddress]); +END; + +GO + +IF NOT EXISTS(SELECT * FROM [__EFMigrationsHistory] WHERE [MigrationId] = N'20200311151648_InitialCreate') +BEGIN + CREATE INDEX [IX_Orders_BuyerId] ON [Orders] ([BuyerId]); +END; + +GO + +IF NOT EXISTS(SELECT * FROM [__EFMigrationsHistory] WHERE [MigrationId] = N'20200311151648_InitialCreate') +BEGIN + CREATE INDEX [IX_QuoteItems_QuoteId] ON [QuoteItems] ([QuoteId]); +END; + +GO + +IF NOT EXISTS(SELECT * FROM [__EFMigrationsHistory] WHERE [MigrationId] = N'20200311151648_InitialCreate') +BEGIN + CREATE INDEX [IX_Quotes_BuyerAddress] ON [Quotes] ([BuyerAddress]); +END; + +GO + +IF NOT EXISTS(SELECT * FROM [__EFMigrationsHistory] WHERE [MigrationId] = N'20200311151648_InitialCreate') +BEGIN + CREATE INDEX [IX_Quotes_BuyerId] ON [Quotes] ([BuyerId]); +END; + +GO + +IF NOT EXISTS(SELECT * FROM [__EFMigrationsHistory] WHERE [MigrationId] = N'20200311151648_InitialCreate') +BEGIN + CREATE INDEX [IX_Stock_CatalogItemId] ON [Stock] ([CatalogItemId]); +END; + +GO + +IF NOT EXISTS(SELECT * FROM [__EFMigrationsHistory] WHERE [MigrationId] = N'20200311151648_InitialCreate') +BEGIN + INSERT INTO [__EFMigrationsHistory] ([MigrationId], [ProductVersion]) + VALUES (N'20200311151648_InitialCreate', N'3.1.2'); +END; + +GO + diff --git a/src/Nethereum.eShop.SqlServer/Infrastructure/Data/Migrations/CatalogContextModelSnapshot.cs b/src/Nethereum.eShop.SqlServer/Catalog/Migrations/SqlServerCatalogContextModelSnapshot.cs similarity index 99% rename from src/Nethereum.eShop.SqlServer/Infrastructure/Data/Migrations/CatalogContextModelSnapshot.cs rename to src/Nethereum.eShop.SqlServer/Catalog/Migrations/SqlServerCatalogContextModelSnapshot.cs index ab128cc..9e9521d 100644 --- a/src/Nethereum.eShop.SqlServer/Infrastructure/Data/Migrations/CatalogContextModelSnapshot.cs +++ b/src/Nethereum.eShop.SqlServer/Catalog/Migrations/SqlServerCatalogContextModelSnapshot.cs @@ -4,12 +4,12 @@ using Microsoft.EntityFrameworkCore.Infrastructure; using Microsoft.EntityFrameworkCore.Metadata; using Microsoft.EntityFrameworkCore.Storage.ValueConversion; -using Nethereum.eShop.Infrastructure.Data; +using Nethereum.eShop.SqlServer.Catalog; -namespace Nethereum.eShop.SqlServer.Migrations.Migrations +namespace Nethereum.eShop.SqlServer.Catalog.Migrations { - [DbContext(typeof(CatalogContext))] - partial class CatalogContextModelSnapshot : ModelSnapshot + [DbContext(typeof(SqlServerCatalogContext))] + partial class SqlServerCatalogContextModelSnapshot : ModelSnapshot { protected override void BuildModel(ModelBuilder modelBuilder) { diff --git a/src/Nethereum.eShop.SqlServer/ApplicationCore/Queries/Catalog/CatalogQueries.cs b/src/Nethereum.eShop.SqlServer/Catalog/Queries/CatalogQueries.cs similarity index 94% rename from src/Nethereum.eShop.SqlServer/ApplicationCore/Queries/Catalog/CatalogQueries.cs rename to src/Nethereum.eShop.SqlServer/Catalog/Queries/CatalogQueries.cs index d5570b9..1d82498 100644 --- a/src/Nethereum.eShop.SqlServer/ApplicationCore/Queries/Catalog/CatalogQueries.cs +++ b/src/Nethereum.eShop.SqlServer/Catalog/Queries/CatalogQueries.cs @@ -1,11 +1,13 @@ using Dapper; using Microsoft.Data.SqlClient; +using Nethereum.eShop.ApplicationCore.Queries; +using Nethereum.eShop.ApplicationCore.Queries.Catalog; using System; using System.Data; using System.Linq; using System.Threading.Tasks; -namespace Nethereum.eShop.ApplicationCore.Queries.Catalog +namespace Nethereum.eShop.SqlServer.Catalog.Queries { public class CatalogQueries : ICatalogQueries { diff --git a/src/Nethereum.eShop.SqlServer/ApplicationCore/Queries/Orders/OrderQueries.cs b/src/Nethereum.eShop.SqlServer/Catalog/Queries/OrderQueries.cs similarity index 93% rename from src/Nethereum.eShop.SqlServer/ApplicationCore/Queries/Orders/OrderQueries.cs rename to src/Nethereum.eShop.SqlServer/Catalog/Queries/OrderQueries.cs index c01d338..bbaca6a 100644 --- a/src/Nethereum.eShop.SqlServer/ApplicationCore/Queries/Orders/OrderQueries.cs +++ b/src/Nethereum.eShop.SqlServer/Catalog/Queries/OrderQueries.cs @@ -1,12 +1,14 @@ using Dapper; using Microsoft.Data.SqlClient; +using Nethereum.eShop.ApplicationCore.Queries; +using Nethereum.eShop.ApplicationCore.Queries.Orders; using System; using System.Data; using System.Linq; using System.Threading.Tasks; -namespace Nethereum.eShop.ApplicationCore.Queries.Orders -{ +namespace Nethereum.eShop.SqlServer.Catalog.Queries +{ public class OrderQueries: IOrderQueries { private readonly string _connectionString; diff --git a/src/Nethereum.eShop.SqlServer/ApplicationCore/Queries/Quotes/QuoteQueries.cs b/src/Nethereum.eShop.SqlServer/Catalog/Queries/QuoteQueries.cs similarity index 93% rename from src/Nethereum.eShop.SqlServer/ApplicationCore/Queries/Quotes/QuoteQueries.cs rename to src/Nethereum.eShop.SqlServer/Catalog/Queries/QuoteQueries.cs index 23a396f..8d06f0e 100644 --- a/src/Nethereum.eShop.SqlServer/ApplicationCore/Queries/Quotes/QuoteQueries.cs +++ b/src/Nethereum.eShop.SqlServer/Catalog/Queries/QuoteQueries.cs @@ -1,11 +1,13 @@ using Dapper; using Microsoft.Data.SqlClient; +using Nethereum.eShop.ApplicationCore.Queries; +using Nethereum.eShop.ApplicationCore.Queries.Quotes; using System; using System.Data; using System.Linq; using System.Threading.Tasks; -namespace Nethereum.eShop.ApplicationCore.Queries.Quotes +namespace Nethereum.eShop.SqlServer.Catalog.Queries { public class QuoteQueries: IQuoteQueries { diff --git a/src/Nethereum.eShop.SqlServer/Catalog/SqlServerCatalogContext.cs b/src/Nethereum.eShop.SqlServer/Catalog/SqlServerCatalogContext.cs new file mode 100644 index 0000000..3bb7c72 --- /dev/null +++ b/src/Nethereum.eShop.SqlServer/Catalog/SqlServerCatalogContext.cs @@ -0,0 +1,34 @@ +using MediatR; +using Microsoft.EntityFrameworkCore; +using Microsoft.EntityFrameworkCore.Design; +using Nethereum.eShop.EntityFramework.Catalog; + +namespace Nethereum.eShop.SqlServer.Catalog +{ + public class SqlServerCatalogContext : CatalogContext + { + public SqlServerCatalogContext(DbContextOptions options, IMediator mediator) : base(options, mediator) + { + } + + protected override void OnModelCreating(ModelBuilder builder) + { + base.OnModelCreating(builder); + builder.ApplyConfigurationsFromAssembly(this.GetType().Assembly); + } + } + + public class SqlServerCatalogContextDesignTimeFactory : IDesignTimeDbContextFactory + { + public SqlServerCatalogContext CreateDbContext(string[] args) + { + var optionsBuilder = new DbContextOptionsBuilder(); + optionsBuilder.UseSqlServer( + "Server=localhost\\sqldev;Integrated Security=true;Initial Catalog=eShop;"); + + return new SqlServerCatalogContext( + optionsBuilder.Options, + null); + } + } +} diff --git a/src/Nethereum.eShop.SqlServer/Infrastructure/Data/Config/SqlServerEShopDbBootstrapper.cs b/src/Nethereum.eShop.SqlServer/Catalog/SqlServerEShopDbBootstrapper.cs similarity index 60% rename from src/Nethereum.eShop.SqlServer/Infrastructure/Data/Config/SqlServerEShopDbBootstrapper.cs rename to src/Nethereum.eShop.SqlServer/Catalog/SqlServerEShopDbBootstrapper.cs index 64871d4..7e6f1f0 100644 --- a/src/Nethereum.eShop.SqlServer/Infrastructure/Data/Config/SqlServerEShopDbBootstrapper.cs +++ b/src/Nethereum.eShop.SqlServer/Catalog/SqlServerEShopDbBootstrapper.cs @@ -5,27 +5,22 @@ using Nethereum.eShop.ApplicationCore.Queries.Catalog; using Nethereum.eShop.ApplicationCore.Queries.Orders; using Nethereum.eShop.ApplicationCore.Queries.Quotes; -using Nethereum.eShop.Infrastructure.Data; -using Nethereum.eShop.Infrastructure.Data.Config; +using Nethereum.eShop.EntityFramework.Catalog; +using Nethereum.eShop.SqlServer.Catalog.Queries; using System; using System.Threading; using System.Threading.Tasks; -namespace Nethereum.eShop.SqlServer.Infrastructure.Data.Config +namespace Nethereum.eShop.SqlServer.Catalog { public class SqlServerEShopDbBootstrapper : EShopDbBootstrapperBase, IEShopDbBootstrapper { - private const string ConnectionName = "CatalogConnection"; + private const string ConnectionName = "CatalogConnection_SqlServer"; public void AddDbContext(IServiceCollection services, IConfiguration configuration) { - services.AddDbContext((serviceProvider, options) => + services.AddDbContext((serviceProvider, options) => options.UseSqlServer(configuration.GetConnectionString(ConnectionName))); - - // Point the CatalogContext at this assembly for the Model Builder Configurations - // these have some SQL specific tweaks - services.AddSingleton>( - new ModelBuilderAssemblyHandler(this.GetType().Assembly)); } public void AddQueries(IServiceCollection services, IConfiguration configuration) @@ -35,11 +30,5 @@ public void AddQueries(IServiceCollection services, IConfiguration configuration services.AddSingleton(new OrderQueries(queryConnectionString)); services.AddSingleton(new CatalogQueries(queryConnectionString)); } - - public Task EnsureCreatedAsync(IServiceProvider serviceProvider, CancellationToken cancellationToken = default) - { - var context = serviceProvider.GetRequiredService(); - return context.Database.MigrateAsync(cancellationToken); - } } } diff --git a/src/Nethereum.eShop.SqlServer/Infrastructure/Identity/Migrations/20200310171925_AppIdentity_InitialCreate.Designer.cs b/src/Nethereum.eShop.SqlServer/Identity/Migrations/20200311151656_InitialCreate.Designer.cs similarity index 97% rename from src/Nethereum.eShop.SqlServer/Infrastructure/Identity/Migrations/20200310171925_AppIdentity_InitialCreate.Designer.cs rename to src/Nethereum.eShop.SqlServer/Identity/Migrations/20200311151656_InitialCreate.Designer.cs index 702b10f..7a2c2e2 100644 --- a/src/Nethereum.eShop.SqlServer/Infrastructure/Identity/Migrations/20200310171925_AppIdentity_InitialCreate.Designer.cs +++ b/src/Nethereum.eShop.SqlServer/Identity/Migrations/20200311151656_InitialCreate.Designer.cs @@ -5,13 +5,13 @@ using Microsoft.EntityFrameworkCore.Metadata; using Microsoft.EntityFrameworkCore.Migrations; using Microsoft.EntityFrameworkCore.Storage.ValueConversion; -using Nethereum.eShop.Infrastructure.Identity; +using Nethereum.eShop.SqlServer.Identity; -namespace Nethereum.eShop.SqlServer.Migrations.Migrations +namespace Nethereum.eShop.SqlServer.Identity.Migrations { - [DbContext(typeof(AppIdentityDbContext))] - [Migration("20200310171925_AppIdentity_InitialCreate")] - partial class AppIdentity_InitialCreate + [DbContext(typeof(SqlServerAppIdentityDbContext))] + [Migration("20200311151656_InitialCreate")] + partial class InitialCreate { protected override void BuildTargetModel(ModelBuilder modelBuilder) { diff --git a/src/Nethereum.eShop.SqlServer/Infrastructure/Identity/Migrations/20200310171925_AppIdentity_InitialCreate.cs b/src/Nethereum.eShop.SqlServer/Identity/Migrations/20200311151656_InitialCreate.cs similarity index 98% rename from src/Nethereum.eShop.SqlServer/Infrastructure/Identity/Migrations/20200310171925_AppIdentity_InitialCreate.cs rename to src/Nethereum.eShop.SqlServer/Identity/Migrations/20200311151656_InitialCreate.cs index 6a5c186..642ab94 100644 --- a/src/Nethereum.eShop.SqlServer/Infrastructure/Identity/Migrations/20200310171925_AppIdentity_InitialCreate.cs +++ b/src/Nethereum.eShop.SqlServer/Identity/Migrations/20200311151656_InitialCreate.cs @@ -1,9 +1,9 @@ using System; using Microsoft.EntityFrameworkCore.Migrations; -namespace Nethereum.eShop.SqlServer.Migrations.Migrations +namespace Nethereum.eShop.SqlServer.Identity.Migrations { - public partial class AppIdentity_InitialCreate : Migration + public partial class InitialCreate : Migration { protected override void Up(MigrationBuilder migrationBuilder) { diff --git a/src/Nethereum.eShop.SqlServer/Identity/Migrations/Scripts/CreateIdentityDb.sql b/src/Nethereum.eShop.SqlServer/Identity/Migrations/Scripts/CreateIdentityDb.sql new file mode 100644 index 0000000..d051dc5 --- /dev/null +++ b/src/Nethereum.eShop.SqlServer/Identity/Migrations/Scripts/CreateIdentityDb.sql @@ -0,0 +1,174 @@ +IF OBJECT_ID(N'[__EFMigrationsHistory]') IS NULL +BEGIN + CREATE TABLE [__EFMigrationsHistory] ( + [MigrationId] nvarchar(150) NOT NULL, + [ProductVersion] nvarchar(32) NOT NULL, + CONSTRAINT [PK___EFMigrationsHistory] PRIMARY KEY ([MigrationId]) + ); +END; + +GO + +IF NOT EXISTS(SELECT * FROM [__EFMigrationsHistory] WHERE [MigrationId] = N'20200311151656_InitialCreate') +BEGIN + CREATE TABLE [AspNetRoles] ( + [Id] nvarchar(450) NOT NULL, + [Name] nvarchar(256) NULL, + [NormalizedName] nvarchar(256) NULL, + [ConcurrencyStamp] nvarchar(max) NULL, + CONSTRAINT [PK_AspNetRoles] PRIMARY KEY ([Id]) + ); +END; + +GO + +IF NOT EXISTS(SELECT * FROM [__EFMigrationsHistory] WHERE [MigrationId] = N'20200311151656_InitialCreate') +BEGIN + CREATE TABLE [AspNetUsers] ( + [Id] nvarchar(450) NOT NULL, + [UserName] nvarchar(256) NULL, + [NormalizedUserName] nvarchar(256) NULL, + [Email] nvarchar(256) NULL, + [NormalizedEmail] nvarchar(256) NULL, + [EmailConfirmed] bit NOT NULL, + [PasswordHash] nvarchar(max) NULL, + [SecurityStamp] nvarchar(max) NULL, + [ConcurrencyStamp] nvarchar(max) NULL, + [PhoneNumber] nvarchar(max) NULL, + [PhoneNumberConfirmed] bit NOT NULL, + [TwoFactorEnabled] bit NOT NULL, + [LockoutEnd] datetimeoffset NULL, + [LockoutEnabled] bit NOT NULL, + [AccessFailedCount] int NOT NULL, + CONSTRAINT [PK_AspNetUsers] PRIMARY KEY ([Id]) + ); +END; + +GO + +IF NOT EXISTS(SELECT * FROM [__EFMigrationsHistory] WHERE [MigrationId] = N'20200311151656_InitialCreate') +BEGIN + CREATE TABLE [AspNetRoleClaims] ( + [Id] int NOT NULL IDENTITY, + [RoleId] nvarchar(450) NOT NULL, + [ClaimType] nvarchar(max) NULL, + [ClaimValue] nvarchar(max) NULL, + CONSTRAINT [PK_AspNetRoleClaims] PRIMARY KEY ([Id]), + CONSTRAINT [FK_AspNetRoleClaims_AspNetRoles_RoleId] FOREIGN KEY ([RoleId]) REFERENCES [AspNetRoles] ([Id]) ON DELETE CASCADE + ); +END; + +GO + +IF NOT EXISTS(SELECT * FROM [__EFMigrationsHistory] WHERE [MigrationId] = N'20200311151656_InitialCreate') +BEGIN + CREATE TABLE [AspNetUserClaims] ( + [Id] int NOT NULL IDENTITY, + [UserId] nvarchar(450) NOT NULL, + [ClaimType] nvarchar(max) NULL, + [ClaimValue] nvarchar(max) NULL, + CONSTRAINT [PK_AspNetUserClaims] PRIMARY KEY ([Id]), + CONSTRAINT [FK_AspNetUserClaims_AspNetUsers_UserId] FOREIGN KEY ([UserId]) REFERENCES [AspNetUsers] ([Id]) ON DELETE CASCADE + ); +END; + +GO + +IF NOT EXISTS(SELECT * FROM [__EFMigrationsHistory] WHERE [MigrationId] = N'20200311151656_InitialCreate') +BEGIN + CREATE TABLE [AspNetUserLogins] ( + [LoginProvider] nvarchar(450) NOT NULL, + [ProviderKey] nvarchar(450) NOT NULL, + [ProviderDisplayName] nvarchar(max) NULL, + [UserId] nvarchar(450) NOT NULL, + CONSTRAINT [PK_AspNetUserLogins] PRIMARY KEY ([LoginProvider], [ProviderKey]), + CONSTRAINT [FK_AspNetUserLogins_AspNetUsers_UserId] FOREIGN KEY ([UserId]) REFERENCES [AspNetUsers] ([Id]) ON DELETE CASCADE + ); +END; + +GO + +IF NOT EXISTS(SELECT * FROM [__EFMigrationsHistory] WHERE [MigrationId] = N'20200311151656_InitialCreate') +BEGIN + CREATE TABLE [AspNetUserRoles] ( + [UserId] nvarchar(450) NOT NULL, + [RoleId] nvarchar(450) NOT NULL, + CONSTRAINT [PK_AspNetUserRoles] PRIMARY KEY ([UserId], [RoleId]), + CONSTRAINT [FK_AspNetUserRoles_AspNetRoles_RoleId] FOREIGN KEY ([RoleId]) REFERENCES [AspNetRoles] ([Id]) ON DELETE CASCADE, + CONSTRAINT [FK_AspNetUserRoles_AspNetUsers_UserId] FOREIGN KEY ([UserId]) REFERENCES [AspNetUsers] ([Id]) ON DELETE CASCADE + ); +END; + +GO + +IF NOT EXISTS(SELECT * FROM [__EFMigrationsHistory] WHERE [MigrationId] = N'20200311151656_InitialCreate') +BEGIN + CREATE TABLE [AspNetUserTokens] ( + [UserId] nvarchar(450) NOT NULL, + [LoginProvider] nvarchar(450) NOT NULL, + [Name] nvarchar(450) NOT NULL, + [Value] nvarchar(max) NULL, + CONSTRAINT [PK_AspNetUserTokens] PRIMARY KEY ([UserId], [LoginProvider], [Name]), + CONSTRAINT [FK_AspNetUserTokens_AspNetUsers_UserId] FOREIGN KEY ([UserId]) REFERENCES [AspNetUsers] ([Id]) ON DELETE CASCADE + ); +END; + +GO + +IF NOT EXISTS(SELECT * FROM [__EFMigrationsHistory] WHERE [MigrationId] = N'20200311151656_InitialCreate') +BEGIN + CREATE INDEX [IX_AspNetRoleClaims_RoleId] ON [AspNetRoleClaims] ([RoleId]); +END; + +GO + +IF NOT EXISTS(SELECT * FROM [__EFMigrationsHistory] WHERE [MigrationId] = N'20200311151656_InitialCreate') +BEGIN + CREATE UNIQUE INDEX [RoleNameIndex] ON [AspNetRoles] ([NormalizedName]) WHERE [NormalizedName] IS NOT NULL; +END; + +GO + +IF NOT EXISTS(SELECT * FROM [__EFMigrationsHistory] WHERE [MigrationId] = N'20200311151656_InitialCreate') +BEGIN + CREATE INDEX [IX_AspNetUserClaims_UserId] ON [AspNetUserClaims] ([UserId]); +END; + +GO + +IF NOT EXISTS(SELECT * FROM [__EFMigrationsHistory] WHERE [MigrationId] = N'20200311151656_InitialCreate') +BEGIN + CREATE INDEX [IX_AspNetUserLogins_UserId] ON [AspNetUserLogins] ([UserId]); +END; + +GO + +IF NOT EXISTS(SELECT * FROM [__EFMigrationsHistory] WHERE [MigrationId] = N'20200311151656_InitialCreate') +BEGIN + CREATE INDEX [IX_AspNetUserRoles_RoleId] ON [AspNetUserRoles] ([RoleId]); +END; + +GO + +IF NOT EXISTS(SELECT * FROM [__EFMigrationsHistory] WHERE [MigrationId] = N'20200311151656_InitialCreate') +BEGIN + CREATE INDEX [EmailIndex] ON [AspNetUsers] ([NormalizedEmail]); +END; + +GO + +IF NOT EXISTS(SELECT * FROM [__EFMigrationsHistory] WHERE [MigrationId] = N'20200311151656_InitialCreate') +BEGIN + CREATE UNIQUE INDEX [UserNameIndex] ON [AspNetUsers] ([NormalizedUserName]) WHERE [NormalizedUserName] IS NOT NULL; +END; + +GO + +IF NOT EXISTS(SELECT * FROM [__EFMigrationsHistory] WHERE [MigrationId] = N'20200311151656_InitialCreate') +BEGIN + INSERT INTO [__EFMigrationsHistory] ([MigrationId], [ProductVersion]) + VALUES (N'20200311151656_InitialCreate', N'3.1.2'); +END; + +GO + diff --git a/src/Nethereum.eShop.SqlServer/Infrastructure/Identity/Migrations/AppIdentityDbContextModelSnapshot.cs b/src/Nethereum.eShop.SqlServer/Identity/Migrations/SqlServerAppIdentityDbContextModelSnapshot.cs similarity index 97% rename from src/Nethereum.eShop.SqlServer/Infrastructure/Identity/Migrations/AppIdentityDbContextModelSnapshot.cs rename to src/Nethereum.eShop.SqlServer/Identity/Migrations/SqlServerAppIdentityDbContextModelSnapshot.cs index 31c334e..3105be0 100644 --- a/src/Nethereum.eShop.SqlServer/Infrastructure/Identity/Migrations/AppIdentityDbContextModelSnapshot.cs +++ b/src/Nethereum.eShop.SqlServer/Identity/Migrations/SqlServerAppIdentityDbContextModelSnapshot.cs @@ -4,12 +4,12 @@ using Microsoft.EntityFrameworkCore.Infrastructure; using Microsoft.EntityFrameworkCore.Metadata; using Microsoft.EntityFrameworkCore.Storage.ValueConversion; -using Nethereum.eShop.Infrastructure.Identity; +using Nethereum.eShop.SqlServer.Identity; -namespace Nethereum.eShop.SqlServer.Migrations.Migrations +namespace Nethereum.eShop.SqlServer.Identity.Migrations { - [DbContext(typeof(AppIdentityDbContext))] - partial class AppIdentityDbContextModelSnapshot : ModelSnapshot + [DbContext(typeof(SqlServerAppIdentityDbContext))] + partial class SqlServerAppIdentityDbContextModelSnapshot : ModelSnapshot { protected override void BuildModel(ModelBuilder modelBuilder) { diff --git a/src/Nethereum.eShop.SqlServer/Identity/SqlServerAppIdentityDbContext.cs b/src/Nethereum.eShop.SqlServer/Identity/SqlServerAppIdentityDbContext.cs new file mode 100644 index 0000000..d90af41 --- /dev/null +++ b/src/Nethereum.eShop.SqlServer/Identity/SqlServerAppIdentityDbContext.cs @@ -0,0 +1,26 @@ +using Microsoft.EntityFrameworkCore; +using Microsoft.EntityFrameworkCore.Design; +using Nethereum.eShop.EntityFramework.Identity; + +namespace Nethereum.eShop.SqlServer.Identity +{ + public class SqlServerAppIdentityDbContext : AppIdentityDbContext + { + public SqlServerAppIdentityDbContext(DbContextOptions options) : base(options) + { + } + } + + public class SqlServerAppIdentityContextDesignTimeFactory : IDesignTimeDbContextFactory + { + public SqlServerAppIdentityDbContext CreateDbContext(string[] args) + { + var optionsBuilder = new DbContextOptionsBuilder(); + optionsBuilder.UseSqlServer( + "Server=localhost\\sqldev;Integrated Security=true;Initial Catalog=eShop;"); + + return new SqlServerAppIdentityDbContext( + optionsBuilder.Options); + } + } +} diff --git a/src/Nethereum.eShop.SqlServer/Identity/SqlServerEShopAppIdentityDbBootstrapper.cs b/src/Nethereum.eShop.SqlServer/Identity/SqlServerEShopAppIdentityDbBootstrapper.cs new file mode 100644 index 0000000..088bb58 --- /dev/null +++ b/src/Nethereum.eShop.SqlServer/Identity/SqlServerEShopAppIdentityDbBootstrapper.cs @@ -0,0 +1,17 @@ +using Microsoft.EntityFrameworkCore; +using Microsoft.Extensions.Configuration; +using Microsoft.Extensions.DependencyInjection; +using Nethereum.eShop.ApplicationCore.Interfaces; +using Nethereum.eShop.EntityFramework.Identity; + +namespace Nethereum.eShop.SqlServer.Identity +{ + public class SqlServerEShopAppIdentityDbBootstrapper : EShopAppIdentityDbBootstrapperBase, IEShopIdentityDbBootstrapper + { + public void AddDbContext(IServiceCollection services, IConfiguration configuration) + { + services.AddDbContext(options => + options.UseSqlServer(configuration.GetConnectionString("IdentityConnection_SqlServer"))); + } + } +} diff --git a/src/Nethereum.eShop.SqlServer/Infrastructure/Data/Config/SqlServerEShopAppIdentityDbBootstrapper.cs b/src/Nethereum.eShop.SqlServer/Infrastructure/Data/Config/SqlServerEShopAppIdentityDbBootstrapper.cs deleted file mode 100644 index d4465b0..0000000 --- a/src/Nethereum.eShop.SqlServer/Infrastructure/Data/Config/SqlServerEShopAppIdentityDbBootstrapper.cs +++ /dev/null @@ -1,26 +0,0 @@ -using Microsoft.EntityFrameworkCore; -using Microsoft.Extensions.Configuration; -using Microsoft.Extensions.DependencyInjection; -using Nethereum.eShop.ApplicationCore.Interfaces; -using Nethereum.eShop.Infrastructure.Identity; -using System; -using System.Threading; -using System.Threading.Tasks; - -namespace Nethereum.eShop.SqlServer.Infrastructure.Data.Config -{ - public class SqlServerEShopAppIdentityDbBootstrapper : IEShopIdentityDbBootstrapper - { - public void AddDbContext(IServiceCollection services, IConfiguration configuration) - { - services.AddDbContext(options => - options.UseSqlServer(configuration.GetConnectionString("IdentityConnection"))); - } - - public Task EnsureCreatedAsync(IServiceProvider serviceProvider, CancellationToken cancellationToken = default) - { - var context = serviceProvider.GetRequiredService(); - return context.Database.MigrateAsync(cancellationToken); - } - } -} diff --git a/src/Nethereum.eShop.SqlServer/Nethereum.eShop.SqlServer.csproj b/src/Nethereum.eShop.SqlServer/Nethereum.eShop.SqlServer.csproj index 8844c00..9d151d0 100644 --- a/src/Nethereum.eShop.SqlServer/Nethereum.eShop.SqlServer.csproj +++ b/src/Nethereum.eShop.SqlServer/Nethereum.eShop.SqlServer.csproj @@ -20,8 +20,8 @@ - - + + diff --git a/src/Nethereum.eShop.Sqlite/Catalog/Migrations/20200311151703_InitialCreate.Designer.cs b/src/Nethereum.eShop.Sqlite/Catalog/Migrations/20200311151703_InitialCreate.Designer.cs new file mode 100644 index 0000000..b0b59db --- /dev/null +++ b/src/Nethereum.eShop.Sqlite/Catalog/Migrations/20200311151703_InitialCreate.Designer.cs @@ -0,0 +1,908 @@ +// +using System; +using Microsoft.EntityFrameworkCore; +using Microsoft.EntityFrameworkCore.Infrastructure; +using Microsoft.EntityFrameworkCore.Migrations; +using Microsoft.EntityFrameworkCore.Storage.ValueConversion; +using Nethereum.eShop.Sqlite.Catalog; + +namespace Nethereum.eShop.Sqlite.Catalog.Migrations +{ + [DbContext(typeof(SqliteCatalogContext))] + [Migration("20200311151703_InitialCreate")] + partial class InitialCreate + { + protected override void BuildTargetModel(ModelBuilder modelBuilder) + { +#pragma warning disable 612, 618 + modelBuilder + .HasAnnotation("ProductVersion", "3.1.2"); + + modelBuilder.Entity("Nethereum.eShop.ApplicationCore.Entities.BasketAggregate.Basket", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("INTEGER"); + + b.Property("BuyerAddress") + .IsRequired() + .HasColumnType("TEXT") + .HasMaxLength(43); + + b.Property("BuyerId") + .IsRequired() + .HasColumnType("TEXT") + .HasMaxLength(256); + + b.Property("TransactionHash") + .HasColumnType("TEXT") + .HasMaxLength(67); + + b.HasKey("Id"); + + b.HasIndex("BuyerAddress"); + + b.HasIndex("BuyerId"); + + b.ToTable("Baskets"); + }); + + modelBuilder.Entity("Nethereum.eShop.ApplicationCore.Entities.BasketAggregate.BasketItem", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("INTEGER"); + + b.Property("BasketId") + .HasColumnType("INTEGER"); + + b.Property("CatalogItemId") + .HasColumnType("INTEGER"); + + b.Property("Quantity") + .HasColumnType("INTEGER"); + + b.Property("UnitPrice") + .HasColumnType("decimal(18,2)"); + + b.HasKey("Id"); + + b.HasIndex("BasketId"); + + b.ToTable("BasketItems"); + }); + + modelBuilder.Entity("Nethereum.eShop.ApplicationCore.Entities.BuyerAggregate.Buyer", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("INTEGER"); + + b.Property("BuyerAddress") + .HasColumnType("TEXT") + .HasMaxLength(43); + + b.Property("BuyerId") + .IsRequired() + .HasColumnType("TEXT") + .HasMaxLength(256); + + b.HasKey("Id"); + + b.HasIndex("BuyerAddress") + .IsUnique(); + + b.HasIndex("BuyerId") + .IsUnique(); + + b.ToTable("Buyers"); + }); + + modelBuilder.Entity("Nethereum.eShop.ApplicationCore.Entities.BuyerAggregate.BuyerPostalAddress", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("INTEGER"); + + b.Property("BuyerId") + .HasColumnType("INTEGER"); + + b.Property("Name") + .HasColumnType("TEXT"); + + b.HasKey("Id"); + + b.HasIndex("BuyerId"); + + b.ToTable("BuyerPostalAddress"); + }); + + modelBuilder.Entity("Nethereum.eShop.ApplicationCore.Entities.CatalogBrand", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("INTEGER"); + + b.Property("Brand") + .IsRequired() + .HasColumnType("TEXT") + .HasMaxLength(100); + + b.HasKey("Id"); + + b.ToTable("CatalogBrands"); + }); + + modelBuilder.Entity("Nethereum.eShop.ApplicationCore.Entities.CatalogItem", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("INTEGER"); + + b.Property("AttributeJson") + .HasColumnType("TEXT"); + + b.Property("CatalogBrandId") + .HasColumnType("INTEGER"); + + b.Property("CatalogTypeId") + .HasColumnType("INTEGER"); + + b.Property("Depth") + .HasColumnType("INTEGER"); + + b.Property("Description") + .HasColumnType("TEXT"); + + b.Property("Gtin") + .IsRequired() + .HasColumnType("TEXT") + .HasMaxLength(14); + + b.Property("GtinRegistryId") + .HasColumnType("INTEGER"); + + b.Property("Height") + .HasColumnType("INTEGER"); + + b.Property("Name") + .IsRequired() + .HasColumnType("TEXT") + .HasMaxLength(50); + + b.Property("PictureLargeUri") + .HasColumnType("TEXT") + .HasMaxLength(512); + + b.Property("PictureMediumUri") + .HasColumnType("TEXT") + .HasMaxLength(512); + + b.Property("PictureSmallUri") + .HasColumnType("TEXT") + .HasMaxLength(512); + + b.Property("PictureUri") + .HasColumnType("TEXT") + .HasMaxLength(512); + + b.Property("Price") + .HasColumnType("decimal(18,2)"); + + b.Property("Rank") + .HasColumnType("INTEGER"); + + b.Property("Status") + .HasColumnType("INTEGER"); + + b.Property("Unit") + .HasColumnType("TEXT") + .HasMaxLength(8); + + b.Property("Weight") + .HasColumnType("INTEGER"); + + b.Property("Width") + .HasColumnType("INTEGER"); + + b.HasKey("Id"); + + b.HasIndex("CatalogBrandId"); + + b.HasIndex("CatalogTypeId"); + + b.ToTable("Catalog"); + }); + + modelBuilder.Entity("Nethereum.eShop.ApplicationCore.Entities.CatalogType", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("INTEGER"); + + b.Property("Type") + .IsRequired() + .HasColumnType("TEXT") + .HasMaxLength(100); + + b.HasKey("Id"); + + b.ToTable("CatalogTypes"); + }); + + modelBuilder.Entity("Nethereum.eShop.ApplicationCore.Entities.OrderAggregate.Order", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("INTEGER"); + + b.Property("ApproverAddress") + .HasColumnType("TEXT") + .HasMaxLength(43); + + b.Property("BuyerAddress") + .HasColumnType("TEXT") + .HasMaxLength(43); + + b.Property("BuyerId") + .IsRequired() + .HasColumnType("TEXT") + .HasMaxLength(256); + + b.Property("BuyerWalletAddress") + .HasColumnType("TEXT") + .HasMaxLength(43); + + b.Property("CurrencyAddress") + .HasColumnType("TEXT") + .HasMaxLength(43); + + b.Property("CurrencySymbol") + .HasColumnType("TEXT") + .HasMaxLength(32); + + b.Property("OrderDate") + .HasColumnType("TEXT"); + + b.Property("PoDate") + .HasColumnType("TEXT"); + + b.Property("PoNumber") + .HasColumnType("INTEGER"); + + b.Property("PoType") + .HasColumnType("INTEGER"); + + b.Property("QuoteId") + .HasColumnType("INTEGER"); + + b.Property("SellerId") + .HasColumnType("TEXT") + .HasMaxLength(32); + + b.Property("Status") + .HasColumnType("INTEGER"); + + b.Property("TransactionHash") + .HasColumnType("TEXT") + .HasMaxLength(67); + + b.HasKey("Id"); + + b.HasIndex("BuyerAddress"); + + b.HasIndex("BuyerId"); + + b.ToTable("Orders"); + }); + + modelBuilder.Entity("Nethereum.eShop.ApplicationCore.Entities.OrderAggregate.OrderItem", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("INTEGER"); + + b.Property("ActualEscrowReleaseDate") + .HasColumnType("TEXT"); + + b.Property("CurrencyValue") + .HasColumnType("TEXT") + .HasMaxLength(100); + + b.Property("GoodsIssueDate") + .HasColumnType("TEXT"); + + b.Property("IsEscrowReleased") + .HasColumnType("INTEGER"); + + b.Property("OrderId") + .HasColumnType("INTEGER"); + + b.Property("PlannedEscrowReleaseDate") + .HasColumnType("TEXT"); + + b.Property("PoItemNumber") + .HasColumnType("INTEGER"); + + b.Property("PoItemStatus") + .HasColumnType("INTEGER"); + + b.Property("Quantity") + .HasColumnType("INTEGER"); + + b.Property("QuantityAddress") + .HasColumnType("TEXT") + .HasMaxLength(43); + + b.Property("QuantitySymbol") + .HasColumnType("TEXT") + .HasMaxLength(32); + + b.Property("Status") + .HasColumnType("INTEGER"); + + b.Property("Unit") + .HasColumnType("TEXT") + .HasMaxLength(50); + + b.Property("UnitPrice") + .HasColumnType("decimal(18,2)"); + + b.HasKey("Id"); + + b.HasIndex("OrderId"); + + b.ToTable("OrderItems"); + }); + + modelBuilder.Entity("Nethereum.eShop.ApplicationCore.Entities.QuoteAggregate.Quote", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("INTEGER"); + + b.Property("ApproverAddress") + .HasColumnType("TEXT") + .HasMaxLength(43); + + b.Property("BuyerAddress") + .HasColumnType("TEXT") + .HasMaxLength(43); + + b.Property("BuyerId") + .IsRequired() + .HasColumnType("TEXT") + .HasMaxLength(256); + + b.Property("BuyerWalletAddress") + .HasColumnType("TEXT") + .HasMaxLength(43); + + b.Property("CurrencyAddress") + .HasColumnType("TEXT") + .HasMaxLength(43); + + b.Property("CurrencySymbol") + .HasColumnType("TEXT") + .HasMaxLength(32); + + b.Property("Date") + .HasColumnType("TEXT"); + + b.Property("Expiry") + .HasColumnType("TEXT"); + + b.Property("PoNumber") + .HasColumnType("INTEGER"); + + b.Property("PoType") + .HasColumnType("INTEGER"); + + b.Property("SellerId") + .HasColumnType("TEXT") + .HasMaxLength(32); + + b.Property("Status") + .HasColumnType("INTEGER"); + + b.Property("TransactionHash") + .HasColumnType("TEXT") + .HasMaxLength(67); + + b.HasKey("Id"); + + b.HasIndex("BuyerAddress"); + + b.HasIndex("BuyerId"); + + b.ToTable("Quotes"); + }); + + modelBuilder.Entity("Nethereum.eShop.ApplicationCore.Entities.QuoteAggregate.QuoteItem", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("INTEGER"); + + b.Property("CurrencyValue") + .HasColumnType("TEXT"); + + b.Property("EscrowReleaseDate") + .HasColumnType("TEXT"); + + b.Property("PoItemNumber") + .HasColumnType("INTEGER"); + + b.Property("Quantity") + .HasColumnType("INTEGER"); + + b.Property("QuantityAddress") + .HasColumnType("TEXT"); + + b.Property("QuantitySymbol") + .HasColumnType("TEXT"); + + b.Property("QuoteId") + .HasColumnType("INTEGER"); + + b.Property("Unit") + .HasColumnType("TEXT"); + + b.Property("UnitPrice") + .HasColumnType("decimal(18,2)"); + + b.HasKey("Id"); + + b.HasIndex("QuoteId"); + + b.ToTable("QuoteItems"); + }); + + modelBuilder.Entity("Nethereum.eShop.ApplicationCore.Entities.StockItem", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("INTEGER"); + + b.Property("CatalogItemId") + .HasColumnType("INTEGER"); + + b.Property("Location") + .IsRequired() + .HasColumnType("TEXT") + .HasMaxLength(50); + + b.Property("Quantity") + .HasColumnType("INTEGER"); + + b.HasKey("Id"); + + b.HasIndex("CatalogItemId"); + + b.ToTable("Stock"); + }); + + modelBuilder.Entity("Nethereum.eShop.ApplicationCore.Entities.BasketAggregate.Basket", b => + { + b.OwnsOne("Nethereum.eShop.ApplicationCore.Entities.PostalAddress", "BillTo", b1 => + { + b1.Property("BasketId") + .HasColumnType("INTEGER"); + + b1.Property("City") + .IsRequired() + .HasColumnType("TEXT") + .HasMaxLength(100); + + b1.Property("Country") + .IsRequired() + .HasColumnType("TEXT") + .HasMaxLength(90); + + b1.Property("RecipientName") + .IsRequired() + .HasColumnType("TEXT") + .HasMaxLength(255); + + b1.Property("State") + .HasColumnType("TEXT") + .HasMaxLength(60); + + b1.Property("Street") + .IsRequired() + .HasColumnType("TEXT") + .HasMaxLength(180); + + b1.Property("ZipCode") + .IsRequired() + .HasColumnType("TEXT") + .HasMaxLength(18); + + b1.HasKey("BasketId"); + + b1.ToTable("Baskets"); + + b1.WithOwner() + .HasForeignKey("BasketId"); + }); + + b.OwnsOne("Nethereum.eShop.ApplicationCore.Entities.PostalAddress", "ShipTo", b1 => + { + b1.Property("BasketId") + .HasColumnType("INTEGER"); + + b1.Property("City") + .IsRequired() + .HasColumnType("TEXT") + .HasMaxLength(100); + + b1.Property("Country") + .IsRequired() + .HasColumnType("TEXT") + .HasMaxLength(90); + + b1.Property("RecipientName") + .IsRequired() + .HasColumnType("TEXT") + .HasMaxLength(255); + + b1.Property("State") + .HasColumnType("TEXT") + .HasMaxLength(60); + + b1.Property("Street") + .IsRequired() + .HasColumnType("TEXT") + .HasMaxLength(180); + + b1.Property("ZipCode") + .IsRequired() + .HasColumnType("TEXT") + .HasMaxLength(18); + + b1.HasKey("BasketId"); + + b1.ToTable("Baskets"); + + b1.WithOwner() + .HasForeignKey("BasketId"); + }); + }); + + modelBuilder.Entity("Nethereum.eShop.ApplicationCore.Entities.BasketAggregate.BasketItem", b => + { + b.HasOne("Nethereum.eShop.ApplicationCore.Entities.BasketAggregate.Basket", null) + .WithMany("Items") + .HasForeignKey("BasketId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + }); + + modelBuilder.Entity("Nethereum.eShop.ApplicationCore.Entities.BuyerAggregate.BuyerPostalAddress", b => + { + b.HasOne("Nethereum.eShop.ApplicationCore.Entities.BuyerAggregate.Buyer", null) + .WithMany("PostalAddresses") + .HasForeignKey("BuyerId"); + + b.OwnsOne("Nethereum.eShop.ApplicationCore.Entities.PostalAddress", "PostalAddress", b1 => + { + b1.Property("BuyerPostalAddressId") + .HasColumnType("INTEGER"); + + b1.Property("City") + .IsRequired() + .HasColumnType("TEXT") + .HasMaxLength(100); + + b1.Property("Country") + .IsRequired() + .HasColumnType("TEXT") + .HasMaxLength(90); + + b1.Property("RecipientName") + .IsRequired() + .HasColumnType("TEXT") + .HasMaxLength(255); + + b1.Property("State") + .HasColumnType("TEXT") + .HasMaxLength(60); + + b1.Property("Street") + .IsRequired() + .HasColumnType("TEXT") + .HasMaxLength(180); + + b1.Property("ZipCode") + .IsRequired() + .HasColumnType("TEXT") + .HasMaxLength(18); + + b1.HasKey("BuyerPostalAddressId"); + + b1.ToTable("BuyerPostalAddress"); + + b1.WithOwner() + .HasForeignKey("BuyerPostalAddressId"); + }); + }); + + modelBuilder.Entity("Nethereum.eShop.ApplicationCore.Entities.CatalogItem", b => + { + b.HasOne("Nethereum.eShop.ApplicationCore.Entities.CatalogBrand", "CatalogBrand") + .WithMany() + .HasForeignKey("CatalogBrandId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.HasOne("Nethereum.eShop.ApplicationCore.Entities.CatalogType", "CatalogType") + .WithMany() + .HasForeignKey("CatalogTypeId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + }); + + modelBuilder.Entity("Nethereum.eShop.ApplicationCore.Entities.OrderAggregate.Order", b => + { + b.OwnsOne("Nethereum.eShop.ApplicationCore.Entities.PostalAddress", "BillTo", b1 => + { + b1.Property("OrderId") + .HasColumnType("INTEGER"); + + b1.Property("City") + .IsRequired() + .HasColumnType("TEXT") + .HasMaxLength(100); + + b1.Property("Country") + .IsRequired() + .HasColumnType("TEXT") + .HasMaxLength(90); + + b1.Property("RecipientName") + .IsRequired() + .HasColumnType("TEXT") + .HasMaxLength(255); + + b1.Property("State") + .HasColumnType("TEXT") + .HasMaxLength(60); + + b1.Property("Street") + .IsRequired() + .HasColumnType("TEXT") + .HasMaxLength(180); + + b1.Property("ZipCode") + .IsRequired() + .HasColumnType("TEXT") + .HasMaxLength(18); + + b1.HasKey("OrderId"); + + b1.ToTable("Orders"); + + b1.WithOwner() + .HasForeignKey("OrderId"); + }); + + b.OwnsOne("Nethereum.eShop.ApplicationCore.Entities.PostalAddress", "ShipTo", b1 => + { + b1.Property("OrderId") + .HasColumnType("INTEGER"); + + b1.Property("City") + .IsRequired() + .HasColumnType("TEXT") + .HasMaxLength(100); + + b1.Property("Country") + .IsRequired() + .HasColumnType("TEXT") + .HasMaxLength(90); + + b1.Property("RecipientName") + .IsRequired() + .HasColumnType("TEXT") + .HasMaxLength(255); + + b1.Property("State") + .HasColumnType("TEXT") + .HasMaxLength(60); + + b1.Property("Street") + .IsRequired() + .HasColumnType("TEXT") + .HasMaxLength(180); + + b1.Property("ZipCode") + .IsRequired() + .HasColumnType("TEXT") + .HasMaxLength(18); + + b1.HasKey("OrderId"); + + b1.ToTable("Orders"); + + b1.WithOwner() + .HasForeignKey("OrderId"); + }); + }); + + modelBuilder.Entity("Nethereum.eShop.ApplicationCore.Entities.OrderAggregate.OrderItem", b => + { + b.HasOne("Nethereum.eShop.ApplicationCore.Entities.OrderAggregate.Order", null) + .WithMany("OrderItems") + .HasForeignKey("OrderId"); + + b.OwnsOne("Nethereum.eShop.ApplicationCore.Entities.CatalogItemExcerpt", "ItemOrdered", b1 => + { + b1.Property("OrderItemId") + .HasColumnType("INTEGER"); + + b1.Property("CatalogItemId") + .HasColumnType("INTEGER"); + + b1.Property("Gtin") + .HasColumnType("TEXT") + .HasMaxLength(14); + + b1.Property("GtinRegistryId") + .HasColumnType("INTEGER"); + + b1.Property("PictureUri") + .HasColumnType("TEXT") + .HasMaxLength(512); + + b1.Property("ProductName") + .IsRequired() + .HasColumnType("TEXT") + .HasMaxLength(50); + + b1.HasKey("OrderItemId"); + + b1.ToTable("OrderItems"); + + b1.WithOwner() + .HasForeignKey("OrderItemId"); + }); + }); + + modelBuilder.Entity("Nethereum.eShop.ApplicationCore.Entities.QuoteAggregate.Quote", b => + { + b.OwnsOne("Nethereum.eShop.ApplicationCore.Entities.PostalAddress", "BillTo", b1 => + { + b1.Property("QuoteId") + .HasColumnType("INTEGER"); + + b1.Property("City") + .IsRequired() + .HasColumnType("TEXT") + .HasMaxLength(100); + + b1.Property("Country") + .IsRequired() + .HasColumnType("TEXT") + .HasMaxLength(90); + + b1.Property("RecipientName") + .IsRequired() + .HasColumnType("TEXT") + .HasMaxLength(255); + + b1.Property("State") + .HasColumnType("TEXT") + .HasMaxLength(60); + + b1.Property("Street") + .IsRequired() + .HasColumnType("TEXT") + .HasMaxLength(180); + + b1.Property("ZipCode") + .IsRequired() + .HasColumnType("TEXT") + .HasMaxLength(18); + + b1.HasKey("QuoteId"); + + b1.ToTable("Quotes"); + + b1.WithOwner() + .HasForeignKey("QuoteId"); + }); + + b.OwnsOne("Nethereum.eShop.ApplicationCore.Entities.PostalAddress", "ShipTo", b1 => + { + b1.Property("QuoteId") + .HasColumnType("INTEGER"); + + b1.Property("City") + .IsRequired() + .HasColumnType("TEXT") + .HasMaxLength(100); + + b1.Property("Country") + .IsRequired() + .HasColumnType("TEXT") + .HasMaxLength(90); + + b1.Property("RecipientName") + .IsRequired() + .HasColumnType("TEXT") + .HasMaxLength(255); + + b1.Property("State") + .HasColumnType("TEXT") + .HasMaxLength(60); + + b1.Property("Street") + .IsRequired() + .HasColumnType("TEXT") + .HasMaxLength(180); + + b1.Property("ZipCode") + .IsRequired() + .HasColumnType("TEXT") + .HasMaxLength(18); + + b1.HasKey("QuoteId"); + + b1.ToTable("Quotes"); + + b1.WithOwner() + .HasForeignKey("QuoteId"); + }); + }); + + modelBuilder.Entity("Nethereum.eShop.ApplicationCore.Entities.QuoteAggregate.QuoteItem", b => + { + b.HasOne("Nethereum.eShop.ApplicationCore.Entities.QuoteAggregate.Quote", null) + .WithMany("QuoteItems") + .HasForeignKey("QuoteId"); + + b.OwnsOne("Nethereum.eShop.ApplicationCore.Entities.CatalogItemExcerpt", "ItemOrdered", b1 => + { + b1.Property("QuoteItemId") + .HasColumnType("INTEGER"); + + b1.Property("CatalogItemId") + .HasColumnType("INTEGER"); + + b1.Property("Gtin") + .HasColumnType("TEXT") + .HasMaxLength(14); + + b1.Property("GtinRegistryId") + .HasColumnType("INTEGER"); + + b1.Property("PictureUri") + .HasColumnType("TEXT") + .HasMaxLength(512); + + b1.Property("ProductName") + .IsRequired() + .HasColumnType("TEXT") + .HasMaxLength(50); + + b1.HasKey("QuoteItemId"); + + b1.ToTable("QuoteItems"); + + b1.WithOwner() + .HasForeignKey("QuoteItemId"); + }); + }); + + modelBuilder.Entity("Nethereum.eShop.ApplicationCore.Entities.StockItem", b => + { + b.HasOne("Nethereum.eShop.ApplicationCore.Entities.CatalogItem", "CatalogItem") + .WithMany() + .HasForeignKey("CatalogItemId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + }); +#pragma warning restore 612, 618 + } + } +} diff --git a/src/Nethereum.eShop.Sqlite/Catalog/Migrations/20200311151703_InitialCreate.cs b/src/Nethereum.eShop.Sqlite/Catalog/Migrations/20200311151703_InitialCreate.cs new file mode 100644 index 0000000..73c9a09 --- /dev/null +++ b/src/Nethereum.eShop.Sqlite/Catalog/Migrations/20200311151703_InitialCreate.cs @@ -0,0 +1,450 @@ +using System; +using Microsoft.EntityFrameworkCore.Migrations; + +namespace Nethereum.eShop.Sqlite.Catalog.Migrations +{ + public partial class InitialCreate : Migration + { + protected override void Up(MigrationBuilder migrationBuilder) + { + migrationBuilder.CreateTable( + name: "Baskets", + columns: table => new + { + Id = table.Column(nullable: false) + .Annotation("Sqlite:Autoincrement", true), + BuyerId = table.Column(maxLength: 256, nullable: false), + BuyerAddress = table.Column(maxLength: 43, nullable: false), + BillTo_RecipientName = table.Column(maxLength: 255, nullable: true), + BillTo_Street = table.Column(maxLength: 180, nullable: true), + BillTo_City = table.Column(maxLength: 100, nullable: true), + BillTo_State = table.Column(maxLength: 60, nullable: true), + BillTo_Country = table.Column(maxLength: 90, nullable: true), + BillTo_ZipCode = table.Column(maxLength: 18, nullable: true), + ShipTo_RecipientName = table.Column(maxLength: 255, nullable: true), + ShipTo_Street = table.Column(maxLength: 180, nullable: true), + ShipTo_City = table.Column(maxLength: 100, nullable: true), + ShipTo_State = table.Column(maxLength: 60, nullable: true), + ShipTo_Country = table.Column(maxLength: 90, nullable: true), + ShipTo_ZipCode = table.Column(maxLength: 18, nullable: true), + TransactionHash = table.Column(maxLength: 67, nullable: true) + }, + constraints: table => + { + table.PrimaryKey("PK_Baskets", x => x.Id); + }); + + migrationBuilder.CreateTable( + name: "Buyers", + columns: table => new + { + Id = table.Column(nullable: false) + .Annotation("Sqlite:Autoincrement", true), + BuyerId = table.Column(maxLength: 256, nullable: false), + BuyerAddress = table.Column(maxLength: 43, nullable: true) + }, + constraints: table => + { + table.PrimaryKey("PK_Buyers", x => x.Id); + }); + + migrationBuilder.CreateTable( + name: "CatalogBrands", + columns: table => new + { + Id = table.Column(nullable: false) + .Annotation("Sqlite:Autoincrement", true), + Brand = table.Column(maxLength: 100, nullable: false) + }, + constraints: table => + { + table.PrimaryKey("PK_CatalogBrands", x => x.Id); + }); + + migrationBuilder.CreateTable( + name: "CatalogTypes", + columns: table => new + { + Id = table.Column(nullable: false) + .Annotation("Sqlite:Autoincrement", true), + Type = table.Column(maxLength: 100, nullable: false) + }, + constraints: table => + { + table.PrimaryKey("PK_CatalogTypes", x => x.Id); + }); + + migrationBuilder.CreateTable( + name: "Orders", + columns: table => new + { + Id = table.Column(nullable: false) + .Annotation("Sqlite:Autoincrement", true), + QuoteId = table.Column(nullable: true), + Status = table.Column(nullable: false), + TransactionHash = table.Column(maxLength: 67, nullable: true), + BuyerId = table.Column(maxLength: 256, nullable: false), + BuyerAddress = table.Column(maxLength: 43, nullable: true), + CurrencyAddress = table.Column(maxLength: 43, nullable: true), + CurrencySymbol = table.Column(maxLength: 32, nullable: true), + ApproverAddress = table.Column(maxLength: 43, nullable: true), + PoNumber = table.Column(nullable: true), + PoType = table.Column(nullable: false), + BuyerWalletAddress = table.Column(maxLength: 43, nullable: true), + SellerId = table.Column(maxLength: 32, nullable: true), + PoDate = table.Column(nullable: true), + OrderDate = table.Column(nullable: false), + BillTo_RecipientName = table.Column(maxLength: 255, nullable: true), + BillTo_Street = table.Column(maxLength: 180, nullable: true), + BillTo_City = table.Column(maxLength: 100, nullable: true), + BillTo_State = table.Column(maxLength: 60, nullable: true), + BillTo_Country = table.Column(maxLength: 90, nullable: true), + BillTo_ZipCode = table.Column(maxLength: 18, nullable: true), + ShipTo_RecipientName = table.Column(maxLength: 255, nullable: true), + ShipTo_Street = table.Column(maxLength: 180, nullable: true), + ShipTo_City = table.Column(maxLength: 100, nullable: true), + ShipTo_State = table.Column(maxLength: 60, nullable: true), + ShipTo_Country = table.Column(maxLength: 90, nullable: true), + ShipTo_ZipCode = table.Column(maxLength: 18, nullable: true) + }, + constraints: table => + { + table.PrimaryKey("PK_Orders", x => x.Id); + }); + + migrationBuilder.CreateTable( + name: "Quotes", + columns: table => new + { + Id = table.Column(nullable: false) + .Annotation("Sqlite:Autoincrement", true), + Status = table.Column(nullable: false), + Date = table.Column(nullable: false), + Expiry = table.Column(nullable: false), + TransactionHash = table.Column(maxLength: 67, nullable: true), + BuyerAddress = table.Column(maxLength: 43, nullable: true), + CurrencySymbol = table.Column(maxLength: 32, nullable: true), + CurrencyAddress = table.Column(maxLength: 43, nullable: true), + ApproverAddress = table.Column(maxLength: 43, nullable: true), + PoNumber = table.Column(nullable: true), + PoType = table.Column(nullable: false), + BuyerWalletAddress = table.Column(maxLength: 43, nullable: true), + SellerId = table.Column(maxLength: 32, nullable: true), + BuyerId = table.Column(maxLength: 256, nullable: false), + BillTo_RecipientName = table.Column(maxLength: 255, nullable: true), + BillTo_Street = table.Column(maxLength: 180, nullable: true), + BillTo_City = table.Column(maxLength: 100, nullable: true), + BillTo_State = table.Column(maxLength: 60, nullable: true), + BillTo_Country = table.Column(maxLength: 90, nullable: true), + BillTo_ZipCode = table.Column(maxLength: 18, nullable: true), + ShipTo_RecipientName = table.Column(maxLength: 255, nullable: true), + ShipTo_Street = table.Column(maxLength: 180, nullable: true), + ShipTo_City = table.Column(maxLength: 100, nullable: true), + ShipTo_State = table.Column(maxLength: 60, nullable: true), + ShipTo_Country = table.Column(maxLength: 90, nullable: true), + ShipTo_ZipCode = table.Column(maxLength: 18, nullable: true) + }, + constraints: table => + { + table.PrimaryKey("PK_Quotes", x => x.Id); + }); + + migrationBuilder.CreateTable( + name: "BasketItems", + columns: table => new + { + Id = table.Column(nullable: false) + .Annotation("Sqlite:Autoincrement", true), + UnitPrice = table.Column(type: "decimal(18,2)", nullable: false), + Quantity = table.Column(nullable: false), + CatalogItemId = table.Column(nullable: false), + BasketId = table.Column(nullable: false) + }, + constraints: table => + { + table.PrimaryKey("PK_BasketItems", x => x.Id); + table.ForeignKey( + name: "FK_BasketItems_Baskets_BasketId", + column: x => x.BasketId, + principalTable: "Baskets", + principalColumn: "Id", + onDelete: ReferentialAction.Cascade); + }); + + migrationBuilder.CreateTable( + name: "BuyerPostalAddress", + columns: table => new + { + Id = table.Column(nullable: false) + .Annotation("Sqlite:Autoincrement", true), + Name = table.Column(nullable: true), + PostalAddress_RecipientName = table.Column(maxLength: 255, nullable: true), + PostalAddress_Street = table.Column(maxLength: 180, nullable: true), + PostalAddress_City = table.Column(maxLength: 100, nullable: true), + PostalAddress_State = table.Column(maxLength: 60, nullable: true), + PostalAddress_Country = table.Column(maxLength: 90, nullable: true), + PostalAddress_ZipCode = table.Column(maxLength: 18, nullable: true), + BuyerId = table.Column(nullable: true) + }, + constraints: table => + { + table.PrimaryKey("PK_BuyerPostalAddress", x => x.Id); + table.ForeignKey( + name: "FK_BuyerPostalAddress_Buyers_BuyerId", + column: x => x.BuyerId, + principalTable: "Buyers", + principalColumn: "Id", + onDelete: ReferentialAction.Restrict); + }); + + migrationBuilder.CreateTable( + name: "Catalog", + columns: table => new + { + Id = table.Column(nullable: false) + .Annotation("Sqlite:Autoincrement", true), + Status = table.Column(nullable: false), + Gtin = table.Column(maxLength: 14, nullable: false), + GtinRegistryId = table.Column(nullable: true), + Name = table.Column(maxLength: 50, nullable: false), + Description = table.Column(nullable: true), + Price = table.Column(type: "decimal(18,2)", nullable: false), + Unit = table.Column(maxLength: 8, nullable: true), + CatalogTypeId = table.Column(nullable: false), + CatalogBrandId = table.Column(nullable: false), + PictureUri = table.Column(maxLength: 512, nullable: true), + PictureSmallUri = table.Column(maxLength: 512, nullable: true), + PictureMediumUri = table.Column(maxLength: 512, nullable: true), + PictureLargeUri = table.Column(maxLength: 512, nullable: true), + AttributeJson = table.Column(nullable: true), + Rank = table.Column(nullable: false), + Height = table.Column(nullable: false), + Width = table.Column(nullable: false), + Depth = table.Column(nullable: false), + Weight = table.Column(nullable: false) + }, + constraints: table => + { + table.PrimaryKey("PK_Catalog", x => x.Id); + table.ForeignKey( + name: "FK_Catalog_CatalogBrands_CatalogBrandId", + column: x => x.CatalogBrandId, + principalTable: "CatalogBrands", + principalColumn: "Id", + onDelete: ReferentialAction.Cascade); + table.ForeignKey( + name: "FK_Catalog_CatalogTypes_CatalogTypeId", + column: x => x.CatalogTypeId, + principalTable: "CatalogTypes", + principalColumn: "Id", + onDelete: ReferentialAction.Cascade); + }); + + migrationBuilder.CreateTable( + name: "OrderItems", + columns: table => new + { + Id = table.Column(nullable: false) + .Annotation("Sqlite:Autoincrement", true), + Status = table.Column(nullable: false), + ItemOrdered_CatalogItemId = table.Column(nullable: true), + ItemOrdered_Gtin = table.Column(maxLength: 14, nullable: true), + ItemOrdered_GtinRegistryId = table.Column(nullable: true), + ItemOrdered_ProductName = table.Column(maxLength: 50, nullable: true), + ItemOrdered_PictureUri = table.Column(maxLength: 512, nullable: true), + UnitPrice = table.Column(type: "decimal(18,2)", nullable: false), + Quantity = table.Column(nullable: false), + Unit = table.Column(maxLength: 50, nullable: true), + PoItemStatus = table.Column(nullable: true), + PoItemNumber = table.Column(nullable: true), + GoodsIssueDate = table.Column(nullable: true), + ActualEscrowReleaseDate = table.Column(nullable: true), + PlannedEscrowReleaseDate = table.Column(nullable: true), + IsEscrowReleased = table.Column(nullable: true), + QuantitySymbol = table.Column(maxLength: 32, nullable: true), + QuantityAddress = table.Column(maxLength: 43, nullable: true), + CurrencyValue = table.Column(maxLength: 100, nullable: true), + OrderId = table.Column(nullable: true) + }, + constraints: table => + { + table.PrimaryKey("PK_OrderItems", x => x.Id); + table.ForeignKey( + name: "FK_OrderItems_Orders_OrderId", + column: x => x.OrderId, + principalTable: "Orders", + principalColumn: "Id", + onDelete: ReferentialAction.Restrict); + }); + + migrationBuilder.CreateTable( + name: "QuoteItems", + columns: table => new + { + Id = table.Column(nullable: false) + .Annotation("Sqlite:Autoincrement", true), + ItemOrdered_CatalogItemId = table.Column(nullable: true), + ItemOrdered_Gtin = table.Column(maxLength: 14, nullable: true), + ItemOrdered_GtinRegistryId = table.Column(nullable: true), + ItemOrdered_ProductName = table.Column(maxLength: 50, nullable: true), + ItemOrdered_PictureUri = table.Column(maxLength: 512, nullable: true), + UnitPrice = table.Column(type: "decimal(18,2)", nullable: false), + Quantity = table.Column(nullable: false), + Unit = table.Column(nullable: true), + PoItemNumber = table.Column(nullable: true), + EscrowReleaseDate = table.Column(nullable: true), + QuantitySymbol = table.Column(nullable: true), + QuantityAddress = table.Column(nullable: true), + CurrencyValue = table.Column(nullable: true), + QuoteId = table.Column(nullable: true) + }, + constraints: table => + { + table.PrimaryKey("PK_QuoteItems", x => x.Id); + table.ForeignKey( + name: "FK_QuoteItems_Quotes_QuoteId", + column: x => x.QuoteId, + principalTable: "Quotes", + principalColumn: "Id", + onDelete: ReferentialAction.Restrict); + }); + + migrationBuilder.CreateTable( + name: "Stock", + columns: table => new + { + Id = table.Column(nullable: false) + .Annotation("Sqlite:Autoincrement", true), + CatalogItemId = table.Column(nullable: false), + Location = table.Column(maxLength: 50, nullable: false), + Quantity = table.Column(nullable: false) + }, + constraints: table => + { + table.PrimaryKey("PK_Stock", x => x.Id); + table.ForeignKey( + name: "FK_Stock_Catalog_CatalogItemId", + column: x => x.CatalogItemId, + principalTable: "Catalog", + principalColumn: "Id", + onDelete: ReferentialAction.Cascade); + }); + + migrationBuilder.CreateIndex( + name: "IX_BasketItems_BasketId", + table: "BasketItems", + column: "BasketId"); + + migrationBuilder.CreateIndex( + name: "IX_Baskets_BuyerAddress", + table: "Baskets", + column: "BuyerAddress"); + + migrationBuilder.CreateIndex( + name: "IX_Baskets_BuyerId", + table: "Baskets", + column: "BuyerId"); + + migrationBuilder.CreateIndex( + name: "IX_BuyerPostalAddress_BuyerId", + table: "BuyerPostalAddress", + column: "BuyerId"); + + migrationBuilder.CreateIndex( + name: "IX_Buyers_BuyerAddress", + table: "Buyers", + column: "BuyerAddress", + unique: true); + + migrationBuilder.CreateIndex( + name: "IX_Buyers_BuyerId", + table: "Buyers", + column: "BuyerId", + unique: true); + + migrationBuilder.CreateIndex( + name: "IX_Catalog_CatalogBrandId", + table: "Catalog", + column: "CatalogBrandId"); + + migrationBuilder.CreateIndex( + name: "IX_Catalog_CatalogTypeId", + table: "Catalog", + column: "CatalogTypeId"); + + migrationBuilder.CreateIndex( + name: "IX_OrderItems_OrderId", + table: "OrderItems", + column: "OrderId"); + + migrationBuilder.CreateIndex( + name: "IX_Orders_BuyerAddress", + table: "Orders", + column: "BuyerAddress"); + + migrationBuilder.CreateIndex( + name: "IX_Orders_BuyerId", + table: "Orders", + column: "BuyerId"); + + migrationBuilder.CreateIndex( + name: "IX_QuoteItems_QuoteId", + table: "QuoteItems", + column: "QuoteId"); + + migrationBuilder.CreateIndex( + name: "IX_Quotes_BuyerAddress", + table: "Quotes", + column: "BuyerAddress"); + + migrationBuilder.CreateIndex( + name: "IX_Quotes_BuyerId", + table: "Quotes", + column: "BuyerId"); + + migrationBuilder.CreateIndex( + name: "IX_Stock_CatalogItemId", + table: "Stock", + column: "CatalogItemId"); + } + + protected override void Down(MigrationBuilder migrationBuilder) + { + migrationBuilder.DropTable( + name: "BasketItems"); + + migrationBuilder.DropTable( + name: "BuyerPostalAddress"); + + migrationBuilder.DropTable( + name: "OrderItems"); + + migrationBuilder.DropTable( + name: "QuoteItems"); + + migrationBuilder.DropTable( + name: "Stock"); + + migrationBuilder.DropTable( + name: "Baskets"); + + migrationBuilder.DropTable( + name: "Buyers"); + + migrationBuilder.DropTable( + name: "Orders"); + + migrationBuilder.DropTable( + name: "Quotes"); + + migrationBuilder.DropTable( + name: "Catalog"); + + migrationBuilder.DropTable( + name: "CatalogBrands"); + + migrationBuilder.DropTable( + name: "CatalogTypes"); + } + } +} diff --git a/src/Nethereum.eShop.Sqlite/Catalog/Migrations/Scripts/CreateCatalogDb.sql b/src/Nethereum.eShop.Sqlite/Catalog/Migrations/Scripts/CreateCatalogDb.sql new file mode 100644 index 0000000..9b5e163 --- /dev/null +++ b/src/Nethereum.eShop.Sqlite/Catalog/Migrations/Scripts/CreateCatalogDb.sql @@ -0,0 +1,230 @@ +CREATE TABLE IF NOT EXISTS "__EFMigrationsHistory" ( + "MigrationId" TEXT NOT NULL CONSTRAINT "PK___EFMigrationsHistory" PRIMARY KEY, + "ProductVersion" TEXT NOT NULL +); + +CREATE TABLE "Baskets" ( + "Id" INTEGER NOT NULL CONSTRAINT "PK_Baskets" PRIMARY KEY AUTOINCREMENT, + "BuyerId" TEXT NOT NULL, + "BuyerAddress" TEXT NOT NULL, + "BillTo_RecipientName" TEXT NULL, + "BillTo_Street" TEXT NULL, + "BillTo_City" TEXT NULL, + "BillTo_State" TEXT NULL, + "BillTo_Country" TEXT NULL, + "BillTo_ZipCode" TEXT NULL, + "ShipTo_RecipientName" TEXT NULL, + "ShipTo_Street" TEXT NULL, + "ShipTo_City" TEXT NULL, + "ShipTo_State" TEXT NULL, + "ShipTo_Country" TEXT NULL, + "ShipTo_ZipCode" TEXT NULL, + "TransactionHash" TEXT NULL +); + +CREATE TABLE "Buyers" ( + "Id" INTEGER NOT NULL CONSTRAINT "PK_Buyers" PRIMARY KEY AUTOINCREMENT, + "BuyerId" TEXT NOT NULL, + "BuyerAddress" TEXT NULL +); + +CREATE TABLE "CatalogBrands" ( + "Id" INTEGER NOT NULL CONSTRAINT "PK_CatalogBrands" PRIMARY KEY AUTOINCREMENT, + "Brand" TEXT NOT NULL +); + +CREATE TABLE "CatalogTypes" ( + "Id" INTEGER NOT NULL CONSTRAINT "PK_CatalogTypes" PRIMARY KEY AUTOINCREMENT, + "Type" TEXT NOT NULL +); + +CREATE TABLE "Orders" ( + "Id" INTEGER NOT NULL CONSTRAINT "PK_Orders" PRIMARY KEY AUTOINCREMENT, + "QuoteId" INTEGER NULL, + "Status" INTEGER NOT NULL, + "TransactionHash" TEXT NULL, + "BuyerId" TEXT NOT NULL, + "BuyerAddress" TEXT NULL, + "CurrencyAddress" TEXT NULL, + "CurrencySymbol" TEXT NULL, + "ApproverAddress" TEXT NULL, + "PoNumber" INTEGER NULL, + "PoType" INTEGER NOT NULL, + "BuyerWalletAddress" TEXT NULL, + "SellerId" TEXT NULL, + "PoDate" TEXT NULL, + "OrderDate" TEXT NOT NULL, + "BillTo_RecipientName" TEXT NULL, + "BillTo_Street" TEXT NULL, + "BillTo_City" TEXT NULL, + "BillTo_State" TEXT NULL, + "BillTo_Country" TEXT NULL, + "BillTo_ZipCode" TEXT NULL, + "ShipTo_RecipientName" TEXT NULL, + "ShipTo_Street" TEXT NULL, + "ShipTo_City" TEXT NULL, + "ShipTo_State" TEXT NULL, + "ShipTo_Country" TEXT NULL, + "ShipTo_ZipCode" TEXT NULL +); + +CREATE TABLE "Quotes" ( + "Id" INTEGER NOT NULL CONSTRAINT "PK_Quotes" PRIMARY KEY AUTOINCREMENT, + "Status" INTEGER NOT NULL, + "Date" TEXT NOT NULL, + "Expiry" TEXT NOT NULL, + "TransactionHash" TEXT NULL, + "BuyerAddress" TEXT NULL, + "CurrencySymbol" TEXT NULL, + "CurrencyAddress" TEXT NULL, + "ApproverAddress" TEXT NULL, + "PoNumber" INTEGER NULL, + "PoType" INTEGER NOT NULL, + "BuyerWalletAddress" TEXT NULL, + "SellerId" TEXT NULL, + "BuyerId" TEXT NOT NULL, + "BillTo_RecipientName" TEXT NULL, + "BillTo_Street" TEXT NULL, + "BillTo_City" TEXT NULL, + "BillTo_State" TEXT NULL, + "BillTo_Country" TEXT NULL, + "BillTo_ZipCode" TEXT NULL, + "ShipTo_RecipientName" TEXT NULL, + "ShipTo_Street" TEXT NULL, + "ShipTo_City" TEXT NULL, + "ShipTo_State" TEXT NULL, + "ShipTo_Country" TEXT NULL, + "ShipTo_ZipCode" TEXT NULL +); + +CREATE TABLE "BasketItems" ( + "Id" INTEGER NOT NULL CONSTRAINT "PK_BasketItems" PRIMARY KEY AUTOINCREMENT, + "UnitPrice" decimal(18,2) NOT NULL, + "Quantity" INTEGER NOT NULL, + "CatalogItemId" INTEGER NOT NULL, + "BasketId" INTEGER NOT NULL, + CONSTRAINT "FK_BasketItems_Baskets_BasketId" FOREIGN KEY ("BasketId") REFERENCES "Baskets" ("Id") ON DELETE CASCADE +); + +CREATE TABLE "BuyerPostalAddress" ( + "Id" INTEGER NOT NULL CONSTRAINT "PK_BuyerPostalAddress" PRIMARY KEY AUTOINCREMENT, + "Name" TEXT NULL, + "PostalAddress_RecipientName" TEXT NULL, + "PostalAddress_Street" TEXT NULL, + "PostalAddress_City" TEXT NULL, + "PostalAddress_State" TEXT NULL, + "PostalAddress_Country" TEXT NULL, + "PostalAddress_ZipCode" TEXT NULL, + "BuyerId" INTEGER NULL, + CONSTRAINT "FK_BuyerPostalAddress_Buyers_BuyerId" FOREIGN KEY ("BuyerId") REFERENCES "Buyers" ("Id") ON DELETE RESTRICT +); + +CREATE TABLE "Catalog" ( + "Id" INTEGER NOT NULL CONSTRAINT "PK_Catalog" PRIMARY KEY AUTOINCREMENT, + "Status" INTEGER NOT NULL, + "Gtin" TEXT NOT NULL, + "GtinRegistryId" INTEGER NULL, + "Name" TEXT NOT NULL, + "Description" TEXT NULL, + "Price" decimal(18,2) NOT NULL, + "Unit" TEXT NULL, + "CatalogTypeId" INTEGER NOT NULL, + "CatalogBrandId" INTEGER NOT NULL, + "PictureUri" TEXT NULL, + "PictureSmallUri" TEXT NULL, + "PictureMediumUri" TEXT NULL, + "PictureLargeUri" TEXT NULL, + "AttributeJson" TEXT NULL, + "Rank" INTEGER NOT NULL, + "Height" INTEGER NOT NULL, + "Width" INTEGER NOT NULL, + "Depth" INTEGER NOT NULL, + "Weight" INTEGER NOT NULL, + CONSTRAINT "FK_Catalog_CatalogBrands_CatalogBrandId" FOREIGN KEY ("CatalogBrandId") REFERENCES "CatalogBrands" ("Id") ON DELETE CASCADE, + CONSTRAINT "FK_Catalog_CatalogTypes_CatalogTypeId" FOREIGN KEY ("CatalogTypeId") REFERENCES "CatalogTypes" ("Id") ON DELETE CASCADE +); + +CREATE TABLE "OrderItems" ( + "Id" INTEGER NOT NULL CONSTRAINT "PK_OrderItems" PRIMARY KEY AUTOINCREMENT, + "Status" INTEGER NOT NULL, + "ItemOrdered_CatalogItemId" INTEGER NULL, + "ItemOrdered_Gtin" TEXT NULL, + "ItemOrdered_GtinRegistryId" INTEGER NULL, + "ItemOrdered_ProductName" TEXT NULL, + "ItemOrdered_PictureUri" TEXT NULL, + "UnitPrice" decimal(18,2) NOT NULL, + "Quantity" INTEGER NOT NULL, + "Unit" TEXT NULL, + "PoItemStatus" INTEGER NULL, + "PoItemNumber" INTEGER NULL, + "GoodsIssueDate" TEXT NULL, + "ActualEscrowReleaseDate" TEXT NULL, + "PlannedEscrowReleaseDate" TEXT NULL, + "IsEscrowReleased" INTEGER NULL, + "QuantitySymbol" TEXT NULL, + "QuantityAddress" TEXT NULL, + "CurrencyValue" TEXT NULL, + "OrderId" INTEGER NULL, + CONSTRAINT "FK_OrderItems_Orders_OrderId" FOREIGN KEY ("OrderId") REFERENCES "Orders" ("Id") ON DELETE RESTRICT +); + +CREATE TABLE "QuoteItems" ( + "Id" INTEGER NOT NULL CONSTRAINT "PK_QuoteItems" PRIMARY KEY AUTOINCREMENT, + "ItemOrdered_CatalogItemId" INTEGER NULL, + "ItemOrdered_Gtin" TEXT NULL, + "ItemOrdered_GtinRegistryId" INTEGER NULL, + "ItemOrdered_ProductName" TEXT NULL, + "ItemOrdered_PictureUri" TEXT NULL, + "UnitPrice" decimal(18,2) NOT NULL, + "Quantity" INTEGER NOT NULL, + "Unit" TEXT NULL, + "PoItemNumber" INTEGER NULL, + "EscrowReleaseDate" TEXT NULL, + "QuantitySymbol" TEXT NULL, + "QuantityAddress" TEXT NULL, + "CurrencyValue" TEXT NULL, + "QuoteId" INTEGER NULL, + CONSTRAINT "FK_QuoteItems_Quotes_QuoteId" FOREIGN KEY ("QuoteId") REFERENCES "Quotes" ("Id") ON DELETE RESTRICT +); + +CREATE TABLE "Stock" ( + "Id" INTEGER NOT NULL CONSTRAINT "PK_Stock" PRIMARY KEY AUTOINCREMENT, + "CatalogItemId" INTEGER NOT NULL, + "Location" TEXT NOT NULL, + "Quantity" INTEGER NOT NULL, + CONSTRAINT "FK_Stock_Catalog_CatalogItemId" FOREIGN KEY ("CatalogItemId") REFERENCES "Catalog" ("Id") ON DELETE CASCADE +); + +CREATE INDEX "IX_BasketItems_BasketId" ON "BasketItems" ("BasketId"); + +CREATE INDEX "IX_Baskets_BuyerAddress" ON "Baskets" ("BuyerAddress"); + +CREATE INDEX "IX_Baskets_BuyerId" ON "Baskets" ("BuyerId"); + +CREATE INDEX "IX_BuyerPostalAddress_BuyerId" ON "BuyerPostalAddress" ("BuyerId"); + +CREATE UNIQUE INDEX "IX_Buyers_BuyerAddress" ON "Buyers" ("BuyerAddress"); + +CREATE UNIQUE INDEX "IX_Buyers_BuyerId" ON "Buyers" ("BuyerId"); + +CREATE INDEX "IX_Catalog_CatalogBrandId" ON "Catalog" ("CatalogBrandId"); + +CREATE INDEX "IX_Catalog_CatalogTypeId" ON "Catalog" ("CatalogTypeId"); + +CREATE INDEX "IX_OrderItems_OrderId" ON "OrderItems" ("OrderId"); + +CREATE INDEX "IX_Orders_BuyerAddress" ON "Orders" ("BuyerAddress"); + +CREATE INDEX "IX_Orders_BuyerId" ON "Orders" ("BuyerId"); + +CREATE INDEX "IX_QuoteItems_QuoteId" ON "QuoteItems" ("QuoteId"); + +CREATE INDEX "IX_Quotes_BuyerAddress" ON "Quotes" ("BuyerAddress"); + +CREATE INDEX "IX_Quotes_BuyerId" ON "Quotes" ("BuyerId"); + +CREATE INDEX "IX_Stock_CatalogItemId" ON "Stock" ("CatalogItemId"); + +INSERT INTO "__EFMigrationsHistory" ("MigrationId", "ProductVersion") +VALUES ('20200311151703_InitialCreate', '3.1.2'); + diff --git a/src/Nethereum.eShop.Sqlite/Catalog/Migrations/SqliteCatalogContextModelSnapshot.cs b/src/Nethereum.eShop.Sqlite/Catalog/Migrations/SqliteCatalogContextModelSnapshot.cs new file mode 100644 index 0000000..4b248ed --- /dev/null +++ b/src/Nethereum.eShop.Sqlite/Catalog/Migrations/SqliteCatalogContextModelSnapshot.cs @@ -0,0 +1,906 @@ +// +using System; +using Microsoft.EntityFrameworkCore; +using Microsoft.EntityFrameworkCore.Infrastructure; +using Microsoft.EntityFrameworkCore.Storage.ValueConversion; +using Nethereum.eShop.Sqlite.Catalog; + +namespace Nethereum.eShop.Sqlite.Catalog.Migrations +{ + [DbContext(typeof(SqliteCatalogContext))] + partial class SqliteCatalogContextModelSnapshot : ModelSnapshot + { + protected override void BuildModel(ModelBuilder modelBuilder) + { +#pragma warning disable 612, 618 + modelBuilder + .HasAnnotation("ProductVersion", "3.1.2"); + + modelBuilder.Entity("Nethereum.eShop.ApplicationCore.Entities.BasketAggregate.Basket", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("INTEGER"); + + b.Property("BuyerAddress") + .IsRequired() + .HasColumnType("TEXT") + .HasMaxLength(43); + + b.Property("BuyerId") + .IsRequired() + .HasColumnType("TEXT") + .HasMaxLength(256); + + b.Property("TransactionHash") + .HasColumnType("TEXT") + .HasMaxLength(67); + + b.HasKey("Id"); + + b.HasIndex("BuyerAddress"); + + b.HasIndex("BuyerId"); + + b.ToTable("Baskets"); + }); + + modelBuilder.Entity("Nethereum.eShop.ApplicationCore.Entities.BasketAggregate.BasketItem", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("INTEGER"); + + b.Property("BasketId") + .HasColumnType("INTEGER"); + + b.Property("CatalogItemId") + .HasColumnType("INTEGER"); + + b.Property("Quantity") + .HasColumnType("INTEGER"); + + b.Property("UnitPrice") + .HasColumnType("decimal(18,2)"); + + b.HasKey("Id"); + + b.HasIndex("BasketId"); + + b.ToTable("BasketItems"); + }); + + modelBuilder.Entity("Nethereum.eShop.ApplicationCore.Entities.BuyerAggregate.Buyer", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("INTEGER"); + + b.Property("BuyerAddress") + .HasColumnType("TEXT") + .HasMaxLength(43); + + b.Property("BuyerId") + .IsRequired() + .HasColumnType("TEXT") + .HasMaxLength(256); + + b.HasKey("Id"); + + b.HasIndex("BuyerAddress") + .IsUnique(); + + b.HasIndex("BuyerId") + .IsUnique(); + + b.ToTable("Buyers"); + }); + + modelBuilder.Entity("Nethereum.eShop.ApplicationCore.Entities.BuyerAggregate.BuyerPostalAddress", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("INTEGER"); + + b.Property("BuyerId") + .HasColumnType("INTEGER"); + + b.Property("Name") + .HasColumnType("TEXT"); + + b.HasKey("Id"); + + b.HasIndex("BuyerId"); + + b.ToTable("BuyerPostalAddress"); + }); + + modelBuilder.Entity("Nethereum.eShop.ApplicationCore.Entities.CatalogBrand", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("INTEGER"); + + b.Property("Brand") + .IsRequired() + .HasColumnType("TEXT") + .HasMaxLength(100); + + b.HasKey("Id"); + + b.ToTable("CatalogBrands"); + }); + + modelBuilder.Entity("Nethereum.eShop.ApplicationCore.Entities.CatalogItem", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("INTEGER"); + + b.Property("AttributeJson") + .HasColumnType("TEXT"); + + b.Property("CatalogBrandId") + .HasColumnType("INTEGER"); + + b.Property("CatalogTypeId") + .HasColumnType("INTEGER"); + + b.Property("Depth") + .HasColumnType("INTEGER"); + + b.Property("Description") + .HasColumnType("TEXT"); + + b.Property("Gtin") + .IsRequired() + .HasColumnType("TEXT") + .HasMaxLength(14); + + b.Property("GtinRegistryId") + .HasColumnType("INTEGER"); + + b.Property("Height") + .HasColumnType("INTEGER"); + + b.Property("Name") + .IsRequired() + .HasColumnType("TEXT") + .HasMaxLength(50); + + b.Property("PictureLargeUri") + .HasColumnType("TEXT") + .HasMaxLength(512); + + b.Property("PictureMediumUri") + .HasColumnType("TEXT") + .HasMaxLength(512); + + b.Property("PictureSmallUri") + .HasColumnType("TEXT") + .HasMaxLength(512); + + b.Property("PictureUri") + .HasColumnType("TEXT") + .HasMaxLength(512); + + b.Property("Price") + .HasColumnType("decimal(18,2)"); + + b.Property("Rank") + .HasColumnType("INTEGER"); + + b.Property("Status") + .HasColumnType("INTEGER"); + + b.Property("Unit") + .HasColumnType("TEXT") + .HasMaxLength(8); + + b.Property("Weight") + .HasColumnType("INTEGER"); + + b.Property("Width") + .HasColumnType("INTEGER"); + + b.HasKey("Id"); + + b.HasIndex("CatalogBrandId"); + + b.HasIndex("CatalogTypeId"); + + b.ToTable("Catalog"); + }); + + modelBuilder.Entity("Nethereum.eShop.ApplicationCore.Entities.CatalogType", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("INTEGER"); + + b.Property("Type") + .IsRequired() + .HasColumnType("TEXT") + .HasMaxLength(100); + + b.HasKey("Id"); + + b.ToTable("CatalogTypes"); + }); + + modelBuilder.Entity("Nethereum.eShop.ApplicationCore.Entities.OrderAggregate.Order", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("INTEGER"); + + b.Property("ApproverAddress") + .HasColumnType("TEXT") + .HasMaxLength(43); + + b.Property("BuyerAddress") + .HasColumnType("TEXT") + .HasMaxLength(43); + + b.Property("BuyerId") + .IsRequired() + .HasColumnType("TEXT") + .HasMaxLength(256); + + b.Property("BuyerWalletAddress") + .HasColumnType("TEXT") + .HasMaxLength(43); + + b.Property("CurrencyAddress") + .HasColumnType("TEXT") + .HasMaxLength(43); + + b.Property("CurrencySymbol") + .HasColumnType("TEXT") + .HasMaxLength(32); + + b.Property("OrderDate") + .HasColumnType("TEXT"); + + b.Property("PoDate") + .HasColumnType("TEXT"); + + b.Property("PoNumber") + .HasColumnType("INTEGER"); + + b.Property("PoType") + .HasColumnType("INTEGER"); + + b.Property("QuoteId") + .HasColumnType("INTEGER"); + + b.Property("SellerId") + .HasColumnType("TEXT") + .HasMaxLength(32); + + b.Property("Status") + .HasColumnType("INTEGER"); + + b.Property("TransactionHash") + .HasColumnType("TEXT") + .HasMaxLength(67); + + b.HasKey("Id"); + + b.HasIndex("BuyerAddress"); + + b.HasIndex("BuyerId"); + + b.ToTable("Orders"); + }); + + modelBuilder.Entity("Nethereum.eShop.ApplicationCore.Entities.OrderAggregate.OrderItem", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("INTEGER"); + + b.Property("ActualEscrowReleaseDate") + .HasColumnType("TEXT"); + + b.Property("CurrencyValue") + .HasColumnType("TEXT") + .HasMaxLength(100); + + b.Property("GoodsIssueDate") + .HasColumnType("TEXT"); + + b.Property("IsEscrowReleased") + .HasColumnType("INTEGER"); + + b.Property("OrderId") + .HasColumnType("INTEGER"); + + b.Property("PlannedEscrowReleaseDate") + .HasColumnType("TEXT"); + + b.Property("PoItemNumber") + .HasColumnType("INTEGER"); + + b.Property("PoItemStatus") + .HasColumnType("INTEGER"); + + b.Property("Quantity") + .HasColumnType("INTEGER"); + + b.Property("QuantityAddress") + .HasColumnType("TEXT") + .HasMaxLength(43); + + b.Property("QuantitySymbol") + .HasColumnType("TEXT") + .HasMaxLength(32); + + b.Property("Status") + .HasColumnType("INTEGER"); + + b.Property("Unit") + .HasColumnType("TEXT") + .HasMaxLength(50); + + b.Property("UnitPrice") + .HasColumnType("decimal(18,2)"); + + b.HasKey("Id"); + + b.HasIndex("OrderId"); + + b.ToTable("OrderItems"); + }); + + modelBuilder.Entity("Nethereum.eShop.ApplicationCore.Entities.QuoteAggregate.Quote", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("INTEGER"); + + b.Property("ApproverAddress") + .HasColumnType("TEXT") + .HasMaxLength(43); + + b.Property("BuyerAddress") + .HasColumnType("TEXT") + .HasMaxLength(43); + + b.Property("BuyerId") + .IsRequired() + .HasColumnType("TEXT") + .HasMaxLength(256); + + b.Property("BuyerWalletAddress") + .HasColumnType("TEXT") + .HasMaxLength(43); + + b.Property("CurrencyAddress") + .HasColumnType("TEXT") + .HasMaxLength(43); + + b.Property("CurrencySymbol") + .HasColumnType("TEXT") + .HasMaxLength(32); + + b.Property("Date") + .HasColumnType("TEXT"); + + b.Property("Expiry") + .HasColumnType("TEXT"); + + b.Property("PoNumber") + .HasColumnType("INTEGER"); + + b.Property("PoType") + .HasColumnType("INTEGER"); + + b.Property("SellerId") + .HasColumnType("TEXT") + .HasMaxLength(32); + + b.Property("Status") + .HasColumnType("INTEGER"); + + b.Property("TransactionHash") + .HasColumnType("TEXT") + .HasMaxLength(67); + + b.HasKey("Id"); + + b.HasIndex("BuyerAddress"); + + b.HasIndex("BuyerId"); + + b.ToTable("Quotes"); + }); + + modelBuilder.Entity("Nethereum.eShop.ApplicationCore.Entities.QuoteAggregate.QuoteItem", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("INTEGER"); + + b.Property("CurrencyValue") + .HasColumnType("TEXT"); + + b.Property("EscrowReleaseDate") + .HasColumnType("TEXT"); + + b.Property("PoItemNumber") + .HasColumnType("INTEGER"); + + b.Property("Quantity") + .HasColumnType("INTEGER"); + + b.Property("QuantityAddress") + .HasColumnType("TEXT"); + + b.Property("QuantitySymbol") + .HasColumnType("TEXT"); + + b.Property("QuoteId") + .HasColumnType("INTEGER"); + + b.Property("Unit") + .HasColumnType("TEXT"); + + b.Property("UnitPrice") + .HasColumnType("decimal(18,2)"); + + b.HasKey("Id"); + + b.HasIndex("QuoteId"); + + b.ToTable("QuoteItems"); + }); + + modelBuilder.Entity("Nethereum.eShop.ApplicationCore.Entities.StockItem", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("INTEGER"); + + b.Property("CatalogItemId") + .HasColumnType("INTEGER"); + + b.Property("Location") + .IsRequired() + .HasColumnType("TEXT") + .HasMaxLength(50); + + b.Property("Quantity") + .HasColumnType("INTEGER"); + + b.HasKey("Id"); + + b.HasIndex("CatalogItemId"); + + b.ToTable("Stock"); + }); + + modelBuilder.Entity("Nethereum.eShop.ApplicationCore.Entities.BasketAggregate.Basket", b => + { + b.OwnsOne("Nethereum.eShop.ApplicationCore.Entities.PostalAddress", "BillTo", b1 => + { + b1.Property("BasketId") + .HasColumnType("INTEGER"); + + b1.Property("City") + .IsRequired() + .HasColumnType("TEXT") + .HasMaxLength(100); + + b1.Property("Country") + .IsRequired() + .HasColumnType("TEXT") + .HasMaxLength(90); + + b1.Property("RecipientName") + .IsRequired() + .HasColumnType("TEXT") + .HasMaxLength(255); + + b1.Property("State") + .HasColumnType("TEXT") + .HasMaxLength(60); + + b1.Property("Street") + .IsRequired() + .HasColumnType("TEXT") + .HasMaxLength(180); + + b1.Property("ZipCode") + .IsRequired() + .HasColumnType("TEXT") + .HasMaxLength(18); + + b1.HasKey("BasketId"); + + b1.ToTable("Baskets"); + + b1.WithOwner() + .HasForeignKey("BasketId"); + }); + + b.OwnsOne("Nethereum.eShop.ApplicationCore.Entities.PostalAddress", "ShipTo", b1 => + { + b1.Property("BasketId") + .HasColumnType("INTEGER"); + + b1.Property("City") + .IsRequired() + .HasColumnType("TEXT") + .HasMaxLength(100); + + b1.Property("Country") + .IsRequired() + .HasColumnType("TEXT") + .HasMaxLength(90); + + b1.Property("RecipientName") + .IsRequired() + .HasColumnType("TEXT") + .HasMaxLength(255); + + b1.Property("State") + .HasColumnType("TEXT") + .HasMaxLength(60); + + b1.Property("Street") + .IsRequired() + .HasColumnType("TEXT") + .HasMaxLength(180); + + b1.Property("ZipCode") + .IsRequired() + .HasColumnType("TEXT") + .HasMaxLength(18); + + b1.HasKey("BasketId"); + + b1.ToTable("Baskets"); + + b1.WithOwner() + .HasForeignKey("BasketId"); + }); + }); + + modelBuilder.Entity("Nethereum.eShop.ApplicationCore.Entities.BasketAggregate.BasketItem", b => + { + b.HasOne("Nethereum.eShop.ApplicationCore.Entities.BasketAggregate.Basket", null) + .WithMany("Items") + .HasForeignKey("BasketId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + }); + + modelBuilder.Entity("Nethereum.eShop.ApplicationCore.Entities.BuyerAggregate.BuyerPostalAddress", b => + { + b.HasOne("Nethereum.eShop.ApplicationCore.Entities.BuyerAggregate.Buyer", null) + .WithMany("PostalAddresses") + .HasForeignKey("BuyerId"); + + b.OwnsOne("Nethereum.eShop.ApplicationCore.Entities.PostalAddress", "PostalAddress", b1 => + { + b1.Property("BuyerPostalAddressId") + .HasColumnType("INTEGER"); + + b1.Property("City") + .IsRequired() + .HasColumnType("TEXT") + .HasMaxLength(100); + + b1.Property("Country") + .IsRequired() + .HasColumnType("TEXT") + .HasMaxLength(90); + + b1.Property("RecipientName") + .IsRequired() + .HasColumnType("TEXT") + .HasMaxLength(255); + + b1.Property("State") + .HasColumnType("TEXT") + .HasMaxLength(60); + + b1.Property("Street") + .IsRequired() + .HasColumnType("TEXT") + .HasMaxLength(180); + + b1.Property("ZipCode") + .IsRequired() + .HasColumnType("TEXT") + .HasMaxLength(18); + + b1.HasKey("BuyerPostalAddressId"); + + b1.ToTable("BuyerPostalAddress"); + + b1.WithOwner() + .HasForeignKey("BuyerPostalAddressId"); + }); + }); + + modelBuilder.Entity("Nethereum.eShop.ApplicationCore.Entities.CatalogItem", b => + { + b.HasOne("Nethereum.eShop.ApplicationCore.Entities.CatalogBrand", "CatalogBrand") + .WithMany() + .HasForeignKey("CatalogBrandId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.HasOne("Nethereum.eShop.ApplicationCore.Entities.CatalogType", "CatalogType") + .WithMany() + .HasForeignKey("CatalogTypeId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + }); + + modelBuilder.Entity("Nethereum.eShop.ApplicationCore.Entities.OrderAggregate.Order", b => + { + b.OwnsOne("Nethereum.eShop.ApplicationCore.Entities.PostalAddress", "BillTo", b1 => + { + b1.Property("OrderId") + .HasColumnType("INTEGER"); + + b1.Property("City") + .IsRequired() + .HasColumnType("TEXT") + .HasMaxLength(100); + + b1.Property("Country") + .IsRequired() + .HasColumnType("TEXT") + .HasMaxLength(90); + + b1.Property("RecipientName") + .IsRequired() + .HasColumnType("TEXT") + .HasMaxLength(255); + + b1.Property("State") + .HasColumnType("TEXT") + .HasMaxLength(60); + + b1.Property("Street") + .IsRequired() + .HasColumnType("TEXT") + .HasMaxLength(180); + + b1.Property("ZipCode") + .IsRequired() + .HasColumnType("TEXT") + .HasMaxLength(18); + + b1.HasKey("OrderId"); + + b1.ToTable("Orders"); + + b1.WithOwner() + .HasForeignKey("OrderId"); + }); + + b.OwnsOne("Nethereum.eShop.ApplicationCore.Entities.PostalAddress", "ShipTo", b1 => + { + b1.Property("OrderId") + .HasColumnType("INTEGER"); + + b1.Property("City") + .IsRequired() + .HasColumnType("TEXT") + .HasMaxLength(100); + + b1.Property("Country") + .IsRequired() + .HasColumnType("TEXT") + .HasMaxLength(90); + + b1.Property("RecipientName") + .IsRequired() + .HasColumnType("TEXT") + .HasMaxLength(255); + + b1.Property("State") + .HasColumnType("TEXT") + .HasMaxLength(60); + + b1.Property("Street") + .IsRequired() + .HasColumnType("TEXT") + .HasMaxLength(180); + + b1.Property("ZipCode") + .IsRequired() + .HasColumnType("TEXT") + .HasMaxLength(18); + + b1.HasKey("OrderId"); + + b1.ToTable("Orders"); + + b1.WithOwner() + .HasForeignKey("OrderId"); + }); + }); + + modelBuilder.Entity("Nethereum.eShop.ApplicationCore.Entities.OrderAggregate.OrderItem", b => + { + b.HasOne("Nethereum.eShop.ApplicationCore.Entities.OrderAggregate.Order", null) + .WithMany("OrderItems") + .HasForeignKey("OrderId"); + + b.OwnsOne("Nethereum.eShop.ApplicationCore.Entities.CatalogItemExcerpt", "ItemOrdered", b1 => + { + b1.Property("OrderItemId") + .HasColumnType("INTEGER"); + + b1.Property("CatalogItemId") + .HasColumnType("INTEGER"); + + b1.Property("Gtin") + .HasColumnType("TEXT") + .HasMaxLength(14); + + b1.Property("GtinRegistryId") + .HasColumnType("INTEGER"); + + b1.Property("PictureUri") + .HasColumnType("TEXT") + .HasMaxLength(512); + + b1.Property("ProductName") + .IsRequired() + .HasColumnType("TEXT") + .HasMaxLength(50); + + b1.HasKey("OrderItemId"); + + b1.ToTable("OrderItems"); + + b1.WithOwner() + .HasForeignKey("OrderItemId"); + }); + }); + + modelBuilder.Entity("Nethereum.eShop.ApplicationCore.Entities.QuoteAggregate.Quote", b => + { + b.OwnsOne("Nethereum.eShop.ApplicationCore.Entities.PostalAddress", "BillTo", b1 => + { + b1.Property("QuoteId") + .HasColumnType("INTEGER"); + + b1.Property("City") + .IsRequired() + .HasColumnType("TEXT") + .HasMaxLength(100); + + b1.Property("Country") + .IsRequired() + .HasColumnType("TEXT") + .HasMaxLength(90); + + b1.Property("RecipientName") + .IsRequired() + .HasColumnType("TEXT") + .HasMaxLength(255); + + b1.Property("State") + .HasColumnType("TEXT") + .HasMaxLength(60); + + b1.Property("Street") + .IsRequired() + .HasColumnType("TEXT") + .HasMaxLength(180); + + b1.Property("ZipCode") + .IsRequired() + .HasColumnType("TEXT") + .HasMaxLength(18); + + b1.HasKey("QuoteId"); + + b1.ToTable("Quotes"); + + b1.WithOwner() + .HasForeignKey("QuoteId"); + }); + + b.OwnsOne("Nethereum.eShop.ApplicationCore.Entities.PostalAddress", "ShipTo", b1 => + { + b1.Property("QuoteId") + .HasColumnType("INTEGER"); + + b1.Property("City") + .IsRequired() + .HasColumnType("TEXT") + .HasMaxLength(100); + + b1.Property("Country") + .IsRequired() + .HasColumnType("TEXT") + .HasMaxLength(90); + + b1.Property("RecipientName") + .IsRequired() + .HasColumnType("TEXT") + .HasMaxLength(255); + + b1.Property("State") + .HasColumnType("TEXT") + .HasMaxLength(60); + + b1.Property("Street") + .IsRequired() + .HasColumnType("TEXT") + .HasMaxLength(180); + + b1.Property("ZipCode") + .IsRequired() + .HasColumnType("TEXT") + .HasMaxLength(18); + + b1.HasKey("QuoteId"); + + b1.ToTable("Quotes"); + + b1.WithOwner() + .HasForeignKey("QuoteId"); + }); + }); + + modelBuilder.Entity("Nethereum.eShop.ApplicationCore.Entities.QuoteAggregate.QuoteItem", b => + { + b.HasOne("Nethereum.eShop.ApplicationCore.Entities.QuoteAggregate.Quote", null) + .WithMany("QuoteItems") + .HasForeignKey("QuoteId"); + + b.OwnsOne("Nethereum.eShop.ApplicationCore.Entities.CatalogItemExcerpt", "ItemOrdered", b1 => + { + b1.Property("QuoteItemId") + .HasColumnType("INTEGER"); + + b1.Property("CatalogItemId") + .HasColumnType("INTEGER"); + + b1.Property("Gtin") + .HasColumnType("TEXT") + .HasMaxLength(14); + + b1.Property("GtinRegistryId") + .HasColumnType("INTEGER"); + + b1.Property("PictureUri") + .HasColumnType("TEXT") + .HasMaxLength(512); + + b1.Property("ProductName") + .IsRequired() + .HasColumnType("TEXT") + .HasMaxLength(50); + + b1.HasKey("QuoteItemId"); + + b1.ToTable("QuoteItems"); + + b1.WithOwner() + .HasForeignKey("QuoteItemId"); + }); + }); + + modelBuilder.Entity("Nethereum.eShop.ApplicationCore.Entities.StockItem", b => + { + b.HasOne("Nethereum.eShop.ApplicationCore.Entities.CatalogItem", "CatalogItem") + .WithMany() + .HasForeignKey("CatalogItemId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + }); +#pragma warning restore 612, 618 + } + } +} diff --git a/src/Nethereum.eShop.Sqlite/ApplicationCore/Queries/Catalog/CatalogQueries.cs b/src/Nethereum.eShop.Sqlite/Catalog/Queries/CatalogQueries.cs similarity index 97% rename from src/Nethereum.eShop.Sqlite/ApplicationCore/Queries/Catalog/CatalogQueries.cs rename to src/Nethereum.eShop.Sqlite/Catalog/Queries/CatalogQueries.cs index 620529e..2f7e567 100644 --- a/src/Nethereum.eShop.Sqlite/ApplicationCore/Queries/Catalog/CatalogQueries.cs +++ b/src/Nethereum.eShop.Sqlite/Catalog/Queries/CatalogQueries.cs @@ -3,11 +3,10 @@ using Nethereum.eShop.ApplicationCore.Queries; using Nethereum.eShop.ApplicationCore.Queries.Catalog; using System; -using System.Data; using System.Linq; using System.Threading.Tasks; -namespace Nethereum.eShop.Sqlite.ApplicationCore.Queries.Catalog +namespace Nethereum.eShop.Sqlite.Catalog.Queries { public class CatalogQueries : ICatalogQueries { diff --git a/src/Nethereum.eShop.Sqlite/ApplicationCore/Queries/Orders/OrderQueries.cs b/src/Nethereum.eShop.Sqlite/Catalog/Queries/OrderQueries.cs similarity index 96% rename from src/Nethereum.eShop.Sqlite/ApplicationCore/Queries/Orders/OrderQueries.cs rename to src/Nethereum.eShop.Sqlite/Catalog/Queries/OrderQueries.cs index 49c5947..0d0eb6a 100644 --- a/src/Nethereum.eShop.Sqlite/ApplicationCore/Queries/Orders/OrderQueries.cs +++ b/src/Nethereum.eShop.Sqlite/Catalog/Queries/OrderQueries.cs @@ -3,11 +3,10 @@ using Nethereum.eShop.ApplicationCore.Queries; using Nethereum.eShop.ApplicationCore.Queries.Orders; using System; -using System.Data; using System.Linq; using System.Threading.Tasks; -namespace Nethereum.eShop.Sqlite.ApplicationCore.Queries.Orders +namespace Nethereum.eShop.Sqlite.Catalog.Queries { public class OrderQueries: IOrderQueries { diff --git a/src/Nethereum.eShop.Sqlite/ApplicationCore/Queries/Quotes/QuoteQueries.cs b/src/Nethereum.eShop.Sqlite/Catalog/Queries/QuoteQueries.cs similarity index 96% rename from src/Nethereum.eShop.Sqlite/ApplicationCore/Queries/Quotes/QuoteQueries.cs rename to src/Nethereum.eShop.Sqlite/Catalog/Queries/QuoteQueries.cs index 0056b1e..8bd134d 100644 --- a/src/Nethereum.eShop.Sqlite/ApplicationCore/Queries/Quotes/QuoteQueries.cs +++ b/src/Nethereum.eShop.Sqlite/Catalog/Queries/QuoteQueries.cs @@ -3,11 +3,10 @@ using Nethereum.eShop.ApplicationCore.Queries; using Nethereum.eShop.ApplicationCore.Queries.Quotes; using System; -using System.Data; using System.Linq; using System.Threading.Tasks; -namespace Nethereum.eShop.Sqlite.ApplicationCore.Queries.Quotes +namespace Nethereum.eShop.Sqlite.Catalog.Queries { public class QuoteQueries: IQuoteQueries { diff --git a/src/Nethereum.eShop.Sqlite/Catalog/SqliteCatalogContext.cs b/src/Nethereum.eShop.Sqlite/Catalog/SqliteCatalogContext.cs new file mode 100644 index 0000000..86dd79c --- /dev/null +++ b/src/Nethereum.eShop.Sqlite/Catalog/SqliteCatalogContext.cs @@ -0,0 +1,36 @@ +using MediatR; +using Microsoft.EntityFrameworkCore; +using Microsoft.EntityFrameworkCore.Design; +using Nethereum.eShop.EntityFramework.Catalog; + +namespace Nethereum.eShop.Sqlite.Catalog +{ + public class SqliteCatalogContext : CatalogContext + { + public SqliteCatalogContext(DbContextOptions options, IMediator mediator) : base(options, mediator) + { + } + + protected override void OnModelCreating(ModelBuilder builder) + { + base.OnModelCreating(builder); + //config is in EntityFramework project + builder.ApplyConfigurationsFromAssembly(typeof(CatalogContext).Assembly); + } + } + + public class SqliteCatalogContextDesignTimeFactory : IDesignTimeDbContextFactory + { + public SqliteCatalogContext CreateDbContext(string[] args) + { + var optionsBuilder = new DbContextOptionsBuilder(); + optionsBuilder.UseSqlite( + "Data Source=C:/temp/designtime_eshop_catalog.db;"); + + return new SqliteCatalogContext( + optionsBuilder.Options, + null); + } + } +} + diff --git a/src/Nethereum.eShop.Sqlite/Infrastructure/Data/Config/SqliteEShopDbBootstrapper.cs b/src/Nethereum.eShop.Sqlite/Catalog/SqliteEShopDbBootstrapper.cs similarity index 56% rename from src/Nethereum.eShop.Sqlite/Infrastructure/Data/Config/SqliteEShopDbBootstrapper.cs rename to src/Nethereum.eShop.Sqlite/Catalog/SqliteEShopDbBootstrapper.cs index 1c89357..87c2296 100644 --- a/src/Nethereum.eShop.Sqlite/Infrastructure/Data/Config/SqliteEShopDbBootstrapper.cs +++ b/src/Nethereum.eShop.Sqlite/Catalog/SqliteEShopDbBootstrapper.cs @@ -5,29 +5,22 @@ using Nethereum.eShop.ApplicationCore.Queries.Catalog; using Nethereum.eShop.ApplicationCore.Queries.Orders; using Nethereum.eShop.ApplicationCore.Queries.Quotes; -using Nethereum.eShop.Infrastructure.Data; -using Nethereum.eShop.Infrastructure.Data.Config; -using Nethereum.eShop.Sqlite.ApplicationCore.Queries.Catalog; -using Nethereum.eShop.Sqlite.ApplicationCore.Queries.Orders; -using Nethereum.eShop.Sqlite.ApplicationCore.Queries.Quotes; +using Nethereum.eShop.EntityFramework.Catalog; +using Nethereum.eShop.Sqlite.Catalog.Queries; using System; using System.Threading; using System.Threading.Tasks; -namespace Nethereum.eShop.Sqlite.Infrastructure.Data.Config +namespace Nethereum.eShop.Sqlite.Catalog { public class SqliteEShopDbBootstrapper : EShopDbBootstrapperBase, IEShopDbBootstrapper { - private const string ConnectionName = "CatalogConnection"; + private const string ConnectionName = "CatalogConnection_Sqlite"; public void AddDbContext(IServiceCollection services, IConfiguration configuration) { - services.AddDbContext((serviceProvider, options) => + services.AddDbContext((serviceProvider, options) => options.UseSqlite(configuration.GetConnectionString(ConnectionName))); - - // Point the CatalogContext at this assembly for the Model Builder Configurations - services.AddSingleton>( - new ModelBuilderAssemblyHandler(typeof(CatalogContext).Assembly)); } public void AddQueries(IServiceCollection services, IConfiguration configuration) @@ -37,11 +30,5 @@ public void AddQueries(IServiceCollection services, IConfiguration configuration services.AddSingleton(new OrderQueries(queryConnectionString)); services.AddSingleton(new CatalogQueries(queryConnectionString)); } - - public Task EnsureCreatedAsync(IServiceProvider serviceProvider, CancellationToken cancellationToken = default) - { - var context = serviceProvider.GetRequiredService(); - return context.Database.MigrateAsync(cancellationToken); - } } } diff --git a/src/Nethereum.eShop.Sqlite/DateTimeOffsetHandler.cs b/src/Nethereum.eShop.Sqlite/Common/Dapper/TypeHandlers/DateTimeOffsetHandler.cs similarity index 93% rename from src/Nethereum.eShop.Sqlite/DateTimeOffsetHandler.cs rename to src/Nethereum.eShop.Sqlite/Common/Dapper/TypeHandlers/DateTimeOffsetHandler.cs index ef38f0a..76d7e5c 100644 --- a/src/Nethereum.eShop.Sqlite/DateTimeOffsetHandler.cs +++ b/src/Nethereum.eShop.Sqlite/Common/Dapper/TypeHandlers/DateTimeOffsetHandler.cs @@ -2,7 +2,7 @@ using System; using System.Data; -namespace Nethereum.eShop.Sqlite +namespace Nethereum.eShop.Sqlite.Common.Dapper.TypeHandlers { public class DateTimeOffsetHandler : SqlMapper.TypeHandler { diff --git a/src/Nethereum.eShop.Sqlite/Identity/Migrations/20200311151709_InitialCreate.Designer.cs b/src/Nethereum.eShop.Sqlite/Identity/Migrations/20200311151709_InitialCreate.Designer.cs new file mode 100644 index 0000000..84b1788 --- /dev/null +++ b/src/Nethereum.eShop.Sqlite/Identity/Migrations/20200311151709_InitialCreate.Designer.cs @@ -0,0 +1,266 @@ +// +using System; +using Microsoft.EntityFrameworkCore; +using Microsoft.EntityFrameworkCore.Infrastructure; +using Microsoft.EntityFrameworkCore.Migrations; +using Microsoft.EntityFrameworkCore.Storage.ValueConversion; +using Nethereum.eShop.Sqlite.Identity; + +namespace Nethereum.eShop.Sqlite.Identity.Migrations +{ + [DbContext(typeof(SqliteAppIdentityDbContext))] + [Migration("20200311151709_InitialCreate")] + partial class InitialCreate + { + protected override void BuildTargetModel(ModelBuilder modelBuilder) + { +#pragma warning disable 612, 618 + modelBuilder + .HasAnnotation("ProductVersion", "3.1.2"); + + modelBuilder.Entity("Microsoft.AspNetCore.Identity.IdentityRole", b => + { + b.Property("Id") + .HasColumnType("TEXT"); + + b.Property("ConcurrencyStamp") + .IsConcurrencyToken() + .HasColumnType("TEXT"); + + b.Property("Name") + .HasColumnType("TEXT") + .HasMaxLength(256); + + b.Property("NormalizedName") + .HasColumnType("TEXT") + .HasMaxLength(256); + + b.HasKey("Id"); + + b.HasIndex("NormalizedName") + .IsUnique() + .HasName("RoleNameIndex"); + + b.ToTable("AspNetRoles"); + }); + + modelBuilder.Entity("Microsoft.AspNetCore.Identity.IdentityRoleClaim", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("INTEGER"); + + b.Property("ClaimType") + .HasColumnType("TEXT"); + + b.Property("ClaimValue") + .HasColumnType("TEXT"); + + b.Property("RoleId") + .IsRequired() + .HasColumnType("TEXT"); + + b.HasKey("Id"); + + b.HasIndex("RoleId"); + + b.ToTable("AspNetRoleClaims"); + }); + + modelBuilder.Entity("Microsoft.AspNetCore.Identity.IdentityUserClaim", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("INTEGER"); + + b.Property("ClaimType") + .HasColumnType("TEXT"); + + b.Property("ClaimValue") + .HasColumnType("TEXT"); + + b.Property("UserId") + .IsRequired() + .HasColumnType("TEXT"); + + b.HasKey("Id"); + + b.HasIndex("UserId"); + + b.ToTable("AspNetUserClaims"); + }); + + modelBuilder.Entity("Microsoft.AspNetCore.Identity.IdentityUserLogin", b => + { + b.Property("LoginProvider") + .HasColumnType("TEXT"); + + b.Property("ProviderKey") + .HasColumnType("TEXT"); + + b.Property("ProviderDisplayName") + .HasColumnType("TEXT"); + + b.Property("UserId") + .IsRequired() + .HasColumnType("TEXT"); + + b.HasKey("LoginProvider", "ProviderKey"); + + b.HasIndex("UserId"); + + b.ToTable("AspNetUserLogins"); + }); + + modelBuilder.Entity("Microsoft.AspNetCore.Identity.IdentityUserRole", b => + { + b.Property("UserId") + .HasColumnType("TEXT"); + + b.Property("RoleId") + .HasColumnType("TEXT"); + + b.HasKey("UserId", "RoleId"); + + b.HasIndex("RoleId"); + + b.ToTable("AspNetUserRoles"); + }); + + modelBuilder.Entity("Microsoft.AspNetCore.Identity.IdentityUserToken", b => + { + b.Property("UserId") + .HasColumnType("TEXT"); + + b.Property("LoginProvider") + .HasColumnType("TEXT"); + + b.Property("Name") + .HasColumnType("TEXT"); + + b.Property("Value") + .HasColumnType("TEXT"); + + b.HasKey("UserId", "LoginProvider", "Name"); + + b.ToTable("AspNetUserTokens"); + }); + + modelBuilder.Entity("Nethereum.eShop.Infrastructure.Identity.ApplicationUser", b => + { + b.Property("Id") + .HasColumnType("TEXT"); + + b.Property("AccessFailedCount") + .HasColumnType("INTEGER"); + + b.Property("ConcurrencyStamp") + .IsConcurrencyToken() + .HasColumnType("TEXT"); + + b.Property("Email") + .HasColumnType("TEXT") + .HasMaxLength(256); + + b.Property("EmailConfirmed") + .HasColumnType("INTEGER"); + + b.Property("LockoutEnabled") + .HasColumnType("INTEGER"); + + b.Property("LockoutEnd") + .HasColumnType("TEXT"); + + b.Property("NormalizedEmail") + .HasColumnType("TEXT") + .HasMaxLength(256); + + b.Property("NormalizedUserName") + .HasColumnType("TEXT") + .HasMaxLength(256); + + b.Property("PasswordHash") + .HasColumnType("TEXT"); + + b.Property("PhoneNumber") + .HasColumnType("TEXT"); + + b.Property("PhoneNumberConfirmed") + .HasColumnType("INTEGER"); + + b.Property("SecurityStamp") + .HasColumnType("TEXT"); + + b.Property("TwoFactorEnabled") + .HasColumnType("INTEGER"); + + b.Property("UserName") + .HasColumnType("TEXT") + .HasMaxLength(256); + + b.HasKey("Id"); + + b.HasIndex("NormalizedEmail") + .HasName("EmailIndex"); + + b.HasIndex("NormalizedUserName") + .IsUnique() + .HasName("UserNameIndex"); + + b.ToTable("AspNetUsers"); + }); + + modelBuilder.Entity("Microsoft.AspNetCore.Identity.IdentityRoleClaim", b => + { + b.HasOne("Microsoft.AspNetCore.Identity.IdentityRole", null) + .WithMany() + .HasForeignKey("RoleId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + }); + + modelBuilder.Entity("Microsoft.AspNetCore.Identity.IdentityUserClaim", b => + { + b.HasOne("Nethereum.eShop.Infrastructure.Identity.ApplicationUser", null) + .WithMany() + .HasForeignKey("UserId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + }); + + modelBuilder.Entity("Microsoft.AspNetCore.Identity.IdentityUserLogin", b => + { + b.HasOne("Nethereum.eShop.Infrastructure.Identity.ApplicationUser", null) + .WithMany() + .HasForeignKey("UserId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + }); + + modelBuilder.Entity("Microsoft.AspNetCore.Identity.IdentityUserRole", b => + { + b.HasOne("Microsoft.AspNetCore.Identity.IdentityRole", null) + .WithMany() + .HasForeignKey("RoleId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.HasOne("Nethereum.eShop.Infrastructure.Identity.ApplicationUser", null) + .WithMany() + .HasForeignKey("UserId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + }); + + modelBuilder.Entity("Microsoft.AspNetCore.Identity.IdentityUserToken", b => + { + b.HasOne("Nethereum.eShop.Infrastructure.Identity.ApplicationUser", null) + .WithMany() + .HasForeignKey("UserId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + }); +#pragma warning restore 612, 618 + } + } +} diff --git a/src/Nethereum.eShop.Sqlite/Identity/Migrations/20200311151709_InitialCreate.cs b/src/Nethereum.eShop.Sqlite/Identity/Migrations/20200311151709_InitialCreate.cs new file mode 100644 index 0000000..e7d13ca --- /dev/null +++ b/src/Nethereum.eShop.Sqlite/Identity/Migrations/20200311151709_InitialCreate.cs @@ -0,0 +1,217 @@ +using System; +using Microsoft.EntityFrameworkCore.Migrations; + +namespace Nethereum.eShop.Sqlite.Identity.Migrations +{ + public partial class InitialCreate : Migration + { + protected override void Up(MigrationBuilder migrationBuilder) + { + migrationBuilder.CreateTable( + name: "AspNetRoles", + columns: table => new + { + Id = table.Column(nullable: false), + Name = table.Column(maxLength: 256, nullable: true), + NormalizedName = table.Column(maxLength: 256, nullable: true), + ConcurrencyStamp = table.Column(nullable: true) + }, + constraints: table => + { + table.PrimaryKey("PK_AspNetRoles", x => x.Id); + }); + + migrationBuilder.CreateTable( + name: "AspNetUsers", + columns: table => new + { + Id = table.Column(nullable: false), + UserName = table.Column(maxLength: 256, nullable: true), + NormalizedUserName = table.Column(maxLength: 256, nullable: true), + Email = table.Column(maxLength: 256, nullable: true), + NormalizedEmail = table.Column(maxLength: 256, nullable: true), + EmailConfirmed = table.Column(nullable: false), + PasswordHash = table.Column(nullable: true), + SecurityStamp = table.Column(nullable: true), + ConcurrencyStamp = table.Column(nullable: true), + PhoneNumber = table.Column(nullable: true), + PhoneNumberConfirmed = table.Column(nullable: false), + TwoFactorEnabled = table.Column(nullable: false), + LockoutEnd = table.Column(nullable: true), + LockoutEnabled = table.Column(nullable: false), + AccessFailedCount = table.Column(nullable: false) + }, + constraints: table => + { + table.PrimaryKey("PK_AspNetUsers", x => x.Id); + }); + + migrationBuilder.CreateTable( + name: "AspNetRoleClaims", + columns: table => new + { + Id = table.Column(nullable: false) + .Annotation("Sqlite:Autoincrement", true), + RoleId = table.Column(nullable: false), + ClaimType = table.Column(nullable: true), + ClaimValue = table.Column(nullable: true) + }, + constraints: table => + { + table.PrimaryKey("PK_AspNetRoleClaims", x => x.Id); + table.ForeignKey( + name: "FK_AspNetRoleClaims_AspNetRoles_RoleId", + column: x => x.RoleId, + principalTable: "AspNetRoles", + principalColumn: "Id", + onDelete: ReferentialAction.Cascade); + }); + + migrationBuilder.CreateTable( + name: "AspNetUserClaims", + columns: table => new + { + Id = table.Column(nullable: false) + .Annotation("Sqlite:Autoincrement", true), + UserId = table.Column(nullable: false), + ClaimType = table.Column(nullable: true), + ClaimValue = table.Column(nullable: true) + }, + constraints: table => + { + table.PrimaryKey("PK_AspNetUserClaims", x => x.Id); + table.ForeignKey( + name: "FK_AspNetUserClaims_AspNetUsers_UserId", + column: x => x.UserId, + principalTable: "AspNetUsers", + principalColumn: "Id", + onDelete: ReferentialAction.Cascade); + }); + + migrationBuilder.CreateTable( + name: "AspNetUserLogins", + columns: table => new + { + LoginProvider = table.Column(nullable: false), + ProviderKey = table.Column(nullable: false), + ProviderDisplayName = table.Column(nullable: true), + UserId = table.Column(nullable: false) + }, + constraints: table => + { + table.PrimaryKey("PK_AspNetUserLogins", x => new { x.LoginProvider, x.ProviderKey }); + table.ForeignKey( + name: "FK_AspNetUserLogins_AspNetUsers_UserId", + column: x => x.UserId, + principalTable: "AspNetUsers", + principalColumn: "Id", + onDelete: ReferentialAction.Cascade); + }); + + migrationBuilder.CreateTable( + name: "AspNetUserRoles", + columns: table => new + { + UserId = table.Column(nullable: false), + RoleId = table.Column(nullable: false) + }, + constraints: table => + { + table.PrimaryKey("PK_AspNetUserRoles", x => new { x.UserId, x.RoleId }); + table.ForeignKey( + name: "FK_AspNetUserRoles_AspNetRoles_RoleId", + column: x => x.RoleId, + principalTable: "AspNetRoles", + principalColumn: "Id", + onDelete: ReferentialAction.Cascade); + table.ForeignKey( + name: "FK_AspNetUserRoles_AspNetUsers_UserId", + column: x => x.UserId, + principalTable: "AspNetUsers", + principalColumn: "Id", + onDelete: ReferentialAction.Cascade); + }); + + migrationBuilder.CreateTable( + name: "AspNetUserTokens", + columns: table => new + { + UserId = table.Column(nullable: false), + LoginProvider = table.Column(nullable: false), + Name = table.Column(nullable: false), + Value = table.Column(nullable: true) + }, + constraints: table => + { + table.PrimaryKey("PK_AspNetUserTokens", x => new { x.UserId, x.LoginProvider, x.Name }); + table.ForeignKey( + name: "FK_AspNetUserTokens_AspNetUsers_UserId", + column: x => x.UserId, + principalTable: "AspNetUsers", + principalColumn: "Id", + onDelete: ReferentialAction.Cascade); + }); + + migrationBuilder.CreateIndex( + name: "IX_AspNetRoleClaims_RoleId", + table: "AspNetRoleClaims", + column: "RoleId"); + + migrationBuilder.CreateIndex( + name: "RoleNameIndex", + table: "AspNetRoles", + column: "NormalizedName", + unique: true); + + migrationBuilder.CreateIndex( + name: "IX_AspNetUserClaims_UserId", + table: "AspNetUserClaims", + column: "UserId"); + + migrationBuilder.CreateIndex( + name: "IX_AspNetUserLogins_UserId", + table: "AspNetUserLogins", + column: "UserId"); + + migrationBuilder.CreateIndex( + name: "IX_AspNetUserRoles_RoleId", + table: "AspNetUserRoles", + column: "RoleId"); + + migrationBuilder.CreateIndex( + name: "EmailIndex", + table: "AspNetUsers", + column: "NormalizedEmail"); + + migrationBuilder.CreateIndex( + name: "UserNameIndex", + table: "AspNetUsers", + column: "NormalizedUserName", + unique: true); + } + + protected override void Down(MigrationBuilder migrationBuilder) + { + migrationBuilder.DropTable( + name: "AspNetRoleClaims"); + + migrationBuilder.DropTable( + name: "AspNetUserClaims"); + + migrationBuilder.DropTable( + name: "AspNetUserLogins"); + + migrationBuilder.DropTable( + name: "AspNetUserRoles"); + + migrationBuilder.DropTable( + name: "AspNetUserTokens"); + + migrationBuilder.DropTable( + name: "AspNetRoles"); + + migrationBuilder.DropTable( + name: "AspNetUsers"); + } + } +} diff --git a/src/Nethereum.eShop.Sqlite/Identity/Migrations/Scripts/CreateIdentityDb.sql b/src/Nethereum.eShop.Sqlite/Identity/Migrations/Scripts/CreateIdentityDb.sql new file mode 100644 index 0000000..8d5bd1d --- /dev/null +++ b/src/Nethereum.eShop.Sqlite/Identity/Migrations/Scripts/CreateIdentityDb.sql @@ -0,0 +1,89 @@ +CREATE TABLE IF NOT EXISTS "__EFMigrationsHistory" ( + "MigrationId" TEXT NOT NULL CONSTRAINT "PK___EFMigrationsHistory" PRIMARY KEY, + "ProductVersion" TEXT NOT NULL +); + +CREATE TABLE "AspNetRoles" ( + "Id" TEXT NOT NULL CONSTRAINT "PK_AspNetRoles" PRIMARY KEY, + "Name" TEXT NULL, + "NormalizedName" TEXT NULL, + "ConcurrencyStamp" TEXT NULL +); + +CREATE TABLE "AspNetUsers" ( + "Id" TEXT NOT NULL CONSTRAINT "PK_AspNetUsers" PRIMARY KEY, + "UserName" TEXT NULL, + "NormalizedUserName" TEXT NULL, + "Email" TEXT NULL, + "NormalizedEmail" TEXT NULL, + "EmailConfirmed" INTEGER NOT NULL, + "PasswordHash" TEXT NULL, + "SecurityStamp" TEXT NULL, + "ConcurrencyStamp" TEXT NULL, + "PhoneNumber" TEXT NULL, + "PhoneNumberConfirmed" INTEGER NOT NULL, + "TwoFactorEnabled" INTEGER NOT NULL, + "LockoutEnd" TEXT NULL, + "LockoutEnabled" INTEGER NOT NULL, + "AccessFailedCount" INTEGER NOT NULL +); + +CREATE TABLE "AspNetRoleClaims" ( + "Id" INTEGER NOT NULL CONSTRAINT "PK_AspNetRoleClaims" PRIMARY KEY AUTOINCREMENT, + "RoleId" TEXT NOT NULL, + "ClaimType" TEXT NULL, + "ClaimValue" TEXT NULL, + CONSTRAINT "FK_AspNetRoleClaims_AspNetRoles_RoleId" FOREIGN KEY ("RoleId") REFERENCES "AspNetRoles" ("Id") ON DELETE CASCADE +); + +CREATE TABLE "AspNetUserClaims" ( + "Id" INTEGER NOT NULL CONSTRAINT "PK_AspNetUserClaims" PRIMARY KEY AUTOINCREMENT, + "UserId" TEXT NOT NULL, + "ClaimType" TEXT NULL, + "ClaimValue" TEXT NULL, + CONSTRAINT "FK_AspNetUserClaims_AspNetUsers_UserId" FOREIGN KEY ("UserId") REFERENCES "AspNetUsers" ("Id") ON DELETE CASCADE +); + +CREATE TABLE "AspNetUserLogins" ( + "LoginProvider" TEXT NOT NULL, + "ProviderKey" TEXT NOT NULL, + "ProviderDisplayName" TEXT NULL, + "UserId" TEXT NOT NULL, + CONSTRAINT "PK_AspNetUserLogins" PRIMARY KEY ("LoginProvider", "ProviderKey"), + CONSTRAINT "FK_AspNetUserLogins_AspNetUsers_UserId" FOREIGN KEY ("UserId") REFERENCES "AspNetUsers" ("Id") ON DELETE CASCADE +); + +CREATE TABLE "AspNetUserRoles" ( + "UserId" TEXT NOT NULL, + "RoleId" TEXT NOT NULL, + CONSTRAINT "PK_AspNetUserRoles" PRIMARY KEY ("UserId", "RoleId"), + CONSTRAINT "FK_AspNetUserRoles_AspNetRoles_RoleId" FOREIGN KEY ("RoleId") REFERENCES "AspNetRoles" ("Id") ON DELETE CASCADE, + CONSTRAINT "FK_AspNetUserRoles_AspNetUsers_UserId" FOREIGN KEY ("UserId") REFERENCES "AspNetUsers" ("Id") ON DELETE CASCADE +); + +CREATE TABLE "AspNetUserTokens" ( + "UserId" TEXT NOT NULL, + "LoginProvider" TEXT NOT NULL, + "Name" TEXT NOT NULL, + "Value" TEXT NULL, + CONSTRAINT "PK_AspNetUserTokens" PRIMARY KEY ("UserId", "LoginProvider", "Name"), + CONSTRAINT "FK_AspNetUserTokens_AspNetUsers_UserId" FOREIGN KEY ("UserId") REFERENCES "AspNetUsers" ("Id") ON DELETE CASCADE +); + +CREATE INDEX "IX_AspNetRoleClaims_RoleId" ON "AspNetRoleClaims" ("RoleId"); + +CREATE UNIQUE INDEX "RoleNameIndex" ON "AspNetRoles" ("NormalizedName"); + +CREATE INDEX "IX_AspNetUserClaims_UserId" ON "AspNetUserClaims" ("UserId"); + +CREATE INDEX "IX_AspNetUserLogins_UserId" ON "AspNetUserLogins" ("UserId"); + +CREATE INDEX "IX_AspNetUserRoles_RoleId" ON "AspNetUserRoles" ("RoleId"); + +CREATE INDEX "EmailIndex" ON "AspNetUsers" ("NormalizedEmail"); + +CREATE UNIQUE INDEX "UserNameIndex" ON "AspNetUsers" ("NormalizedUserName"); + +INSERT INTO "__EFMigrationsHistory" ("MigrationId", "ProductVersion") +VALUES ('20200311151709_InitialCreate', '3.1.2'); + diff --git a/src/Nethereum.eShop.Sqlite/Identity/Migrations/SqliteAppIdentityDbContextModelSnapshot.cs b/src/Nethereum.eShop.Sqlite/Identity/Migrations/SqliteAppIdentityDbContextModelSnapshot.cs new file mode 100644 index 0000000..e84871a --- /dev/null +++ b/src/Nethereum.eShop.Sqlite/Identity/Migrations/SqliteAppIdentityDbContextModelSnapshot.cs @@ -0,0 +1,264 @@ +// +using System; +using Microsoft.EntityFrameworkCore; +using Microsoft.EntityFrameworkCore.Infrastructure; +using Microsoft.EntityFrameworkCore.Storage.ValueConversion; +using Nethereum.eShop.Sqlite.Identity; + +namespace Nethereum.eShop.Sqlite.Identity.Migrations +{ + [DbContext(typeof(SqliteAppIdentityDbContext))] + partial class SqliteAppIdentityDbContextModelSnapshot : ModelSnapshot + { + protected override void BuildModel(ModelBuilder modelBuilder) + { +#pragma warning disable 612, 618 + modelBuilder + .HasAnnotation("ProductVersion", "3.1.2"); + + modelBuilder.Entity("Microsoft.AspNetCore.Identity.IdentityRole", b => + { + b.Property("Id") + .HasColumnType("TEXT"); + + b.Property("ConcurrencyStamp") + .IsConcurrencyToken() + .HasColumnType("TEXT"); + + b.Property("Name") + .HasColumnType("TEXT") + .HasMaxLength(256); + + b.Property("NormalizedName") + .HasColumnType("TEXT") + .HasMaxLength(256); + + b.HasKey("Id"); + + b.HasIndex("NormalizedName") + .IsUnique() + .HasName("RoleNameIndex"); + + b.ToTable("AspNetRoles"); + }); + + modelBuilder.Entity("Microsoft.AspNetCore.Identity.IdentityRoleClaim", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("INTEGER"); + + b.Property("ClaimType") + .HasColumnType("TEXT"); + + b.Property("ClaimValue") + .HasColumnType("TEXT"); + + b.Property("RoleId") + .IsRequired() + .HasColumnType("TEXT"); + + b.HasKey("Id"); + + b.HasIndex("RoleId"); + + b.ToTable("AspNetRoleClaims"); + }); + + modelBuilder.Entity("Microsoft.AspNetCore.Identity.IdentityUserClaim", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("INTEGER"); + + b.Property("ClaimType") + .HasColumnType("TEXT"); + + b.Property("ClaimValue") + .HasColumnType("TEXT"); + + b.Property("UserId") + .IsRequired() + .HasColumnType("TEXT"); + + b.HasKey("Id"); + + b.HasIndex("UserId"); + + b.ToTable("AspNetUserClaims"); + }); + + modelBuilder.Entity("Microsoft.AspNetCore.Identity.IdentityUserLogin", b => + { + b.Property("LoginProvider") + .HasColumnType("TEXT"); + + b.Property("ProviderKey") + .HasColumnType("TEXT"); + + b.Property("ProviderDisplayName") + .HasColumnType("TEXT"); + + b.Property("UserId") + .IsRequired() + .HasColumnType("TEXT"); + + b.HasKey("LoginProvider", "ProviderKey"); + + b.HasIndex("UserId"); + + b.ToTable("AspNetUserLogins"); + }); + + modelBuilder.Entity("Microsoft.AspNetCore.Identity.IdentityUserRole", b => + { + b.Property("UserId") + .HasColumnType("TEXT"); + + b.Property("RoleId") + .HasColumnType("TEXT"); + + b.HasKey("UserId", "RoleId"); + + b.HasIndex("RoleId"); + + b.ToTable("AspNetUserRoles"); + }); + + modelBuilder.Entity("Microsoft.AspNetCore.Identity.IdentityUserToken", b => + { + b.Property("UserId") + .HasColumnType("TEXT"); + + b.Property("LoginProvider") + .HasColumnType("TEXT"); + + b.Property("Name") + .HasColumnType("TEXT"); + + b.Property("Value") + .HasColumnType("TEXT"); + + b.HasKey("UserId", "LoginProvider", "Name"); + + b.ToTable("AspNetUserTokens"); + }); + + modelBuilder.Entity("Nethereum.eShop.Infrastructure.Identity.ApplicationUser", b => + { + b.Property("Id") + .HasColumnType("TEXT"); + + b.Property("AccessFailedCount") + .HasColumnType("INTEGER"); + + b.Property("ConcurrencyStamp") + .IsConcurrencyToken() + .HasColumnType("TEXT"); + + b.Property("Email") + .HasColumnType("TEXT") + .HasMaxLength(256); + + b.Property("EmailConfirmed") + .HasColumnType("INTEGER"); + + b.Property("LockoutEnabled") + .HasColumnType("INTEGER"); + + b.Property("LockoutEnd") + .HasColumnType("TEXT"); + + b.Property("NormalizedEmail") + .HasColumnType("TEXT") + .HasMaxLength(256); + + b.Property("NormalizedUserName") + .HasColumnType("TEXT") + .HasMaxLength(256); + + b.Property("PasswordHash") + .HasColumnType("TEXT"); + + b.Property("PhoneNumber") + .HasColumnType("TEXT"); + + b.Property("PhoneNumberConfirmed") + .HasColumnType("INTEGER"); + + b.Property("SecurityStamp") + .HasColumnType("TEXT"); + + b.Property("TwoFactorEnabled") + .HasColumnType("INTEGER"); + + b.Property("UserName") + .HasColumnType("TEXT") + .HasMaxLength(256); + + b.HasKey("Id"); + + b.HasIndex("NormalizedEmail") + .HasName("EmailIndex"); + + b.HasIndex("NormalizedUserName") + .IsUnique() + .HasName("UserNameIndex"); + + b.ToTable("AspNetUsers"); + }); + + modelBuilder.Entity("Microsoft.AspNetCore.Identity.IdentityRoleClaim", b => + { + b.HasOne("Microsoft.AspNetCore.Identity.IdentityRole", null) + .WithMany() + .HasForeignKey("RoleId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + }); + + modelBuilder.Entity("Microsoft.AspNetCore.Identity.IdentityUserClaim", b => + { + b.HasOne("Nethereum.eShop.Infrastructure.Identity.ApplicationUser", null) + .WithMany() + .HasForeignKey("UserId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + }); + + modelBuilder.Entity("Microsoft.AspNetCore.Identity.IdentityUserLogin", b => + { + b.HasOne("Nethereum.eShop.Infrastructure.Identity.ApplicationUser", null) + .WithMany() + .HasForeignKey("UserId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + }); + + modelBuilder.Entity("Microsoft.AspNetCore.Identity.IdentityUserRole", b => + { + b.HasOne("Microsoft.AspNetCore.Identity.IdentityRole", null) + .WithMany() + .HasForeignKey("RoleId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.HasOne("Nethereum.eShop.Infrastructure.Identity.ApplicationUser", null) + .WithMany() + .HasForeignKey("UserId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + }); + + modelBuilder.Entity("Microsoft.AspNetCore.Identity.IdentityUserToken", b => + { + b.HasOne("Nethereum.eShop.Infrastructure.Identity.ApplicationUser", null) + .WithMany() + .HasForeignKey("UserId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + }); +#pragma warning restore 612, 618 + } + } +} diff --git a/src/Nethereum.eShop.Sqlite/Identity/SqliteAppIdentityDbContext.cs b/src/Nethereum.eShop.Sqlite/Identity/SqliteAppIdentityDbContext.cs new file mode 100644 index 0000000..062a30c --- /dev/null +++ b/src/Nethereum.eShop.Sqlite/Identity/SqliteAppIdentityDbContext.cs @@ -0,0 +1,28 @@ +using Microsoft.EntityFrameworkCore; +using Microsoft.EntityFrameworkCore.Design; +using Nethereum.eShop.EntityFramework.Identity; + +namespace Nethereum.eShop.Sqlite.Identity +{ + public class SqliteAppIdentityDbContext : AppIdentityDbContext + { + public SqliteAppIdentityDbContext(DbContextOptions options) : base(options) + { + } + } + + public class SqliteAppIdentityContextDesignTimeFactory : IDesignTimeDbContextFactory + { + public SqliteAppIdentityDbContext CreateDbContext(string[] args) + { + var optionsBuilder = new DbContextOptionsBuilder(); + optionsBuilder.UseSqlite( + "Data Source=C:/temp/designtime_eshop_app_identity.db;"); + + return new SqliteAppIdentityDbContext( + optionsBuilder.Options); + } + } + + +} diff --git a/src/Nethereum.eShop.Sqlite/Identity/SqliteEShopAppIdentityDbBootstrapper.cs b/src/Nethereum.eShop.Sqlite/Identity/SqliteEShopAppIdentityDbBootstrapper.cs new file mode 100644 index 0000000..ba3e6bc --- /dev/null +++ b/src/Nethereum.eShop.Sqlite/Identity/SqliteEShopAppIdentityDbBootstrapper.cs @@ -0,0 +1,23 @@ +using Dapper; +using Microsoft.EntityFrameworkCore; +using Microsoft.Extensions.Configuration; +using Microsoft.Extensions.DependencyInjection; +using Nethereum.eShop.ApplicationCore.Interfaces; +using Nethereum.eShop.EntityFramework.Identity; +using Nethereum.eShop.Sqlite.Common.Dapper.TypeHandlers; +using System; + +namespace Nethereum.eShop.Sqlite.Identity +{ + public class SqliteEShopAppIdentityDbBootstrapper : EShopAppIdentityDbBootstrapperBase, IEShopIdentityDbBootstrapper + { + public void AddDbContext(IServiceCollection services, IConfiguration configuration) + { + SqlMapper.RemoveTypeMap(typeof(DateTimeOffset)); + SqlMapper.AddTypeHandler(DateTimeOffsetHandler.Instance); + + services.AddDbContext(options => + options.UseSqlite(configuration.GetConnectionString("IdentityConnection_Sqlite"))); + } + } +} diff --git a/src/Nethereum.eShop.Sqlite/Infrastructure/Data/Config/SqliteEShopAppIdentityDbBootstrapper.cs b/src/Nethereum.eShop.Sqlite/Infrastructure/Data/Config/SqliteEShopAppIdentityDbBootstrapper.cs deleted file mode 100644 index 8ca3d1a..0000000 --- a/src/Nethereum.eShop.Sqlite/Infrastructure/Data/Config/SqliteEShopAppIdentityDbBootstrapper.cs +++ /dev/null @@ -1,30 +0,0 @@ -using Dapper; -using Microsoft.EntityFrameworkCore; -using Microsoft.Extensions.Configuration; -using Microsoft.Extensions.DependencyInjection; -using Nethereum.eShop.ApplicationCore.Interfaces; -using Nethereum.eShop.Infrastructure.Identity; -using System; -using System.Threading; -using System.Threading.Tasks; - -namespace Nethereum.eShop.Sqlite.Infrastructure.Data.Config -{ - public class SqliteEShopAppIdentityDbBootstrapper : IEShopIdentityDbBootstrapper - { - public void AddDbContext(IServiceCollection services, IConfiguration configuration) - { - SqlMapper.RemoveTypeMap(typeof(DateTimeOffset)); - SqlMapper.AddTypeHandler(DateTimeOffsetHandler.Instance); - - services.AddDbContext(options => - options.UseSqlite(configuration.GetConnectionString("IdentityConnection"))); - } - - public Task EnsureCreatedAsync(IServiceProvider serviceProvider, CancellationToken cancellationToken = default) - { - var context = serviceProvider.GetRequiredService(); - return context.Database.MigrateAsync(cancellationToken); - } - } -} diff --git a/src/Nethereum.eShop.Sqlite/Nethereum.eShop.Sqlite.csproj b/src/Nethereum.eShop.Sqlite/Nethereum.eShop.Sqlite.csproj index 1ee9ae0..4010510 100644 --- a/src/Nethereum.eShop.Sqlite/Nethereum.eShop.Sqlite.csproj +++ b/src/Nethereum.eShop.Sqlite/Nethereum.eShop.Sqlite.csproj @@ -13,7 +13,8 @@ - + + diff --git a/src/Nethereum.eShop.sln b/src/Nethereum.eShop.sln index ccdbc4a..854e448 100644 --- a/src/Nethereum.eShop.sln +++ b/src/Nethereum.eShop.sln @@ -33,11 +33,13 @@ Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "core", "core", "{757AB3ED-2 EndProject Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "apps", "apps", "{826D820C-C91E-4FBC-804E-1773C372CCA3}" EndProject -Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Nethereum.eShop.Sqlite", "Nethereum.eShop.Sqlite\Nethereum.eShop.Sqlite.csproj", "{2914543B-FDB7-46A0-BB4D-A192765D4072}" +Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Nethereum.eShop.Sqlite", "Nethereum.eShop.Sqlite\Nethereum.eShop.Sqlite.csproj", "{2914543B-FDB7-46A0-BB4D-A192765D4072}" EndProject -Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Nethereum.eShop.DbFactory", "Nethereum.eShop.DbFactory\Nethereum.eShop.DbFactory.csproj", "{173B3ACF-DB6E-497C-B778-4BBEB53EFA3A}" +Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Nethereum.eShop.DbFactory", "Nethereum.eShop.DbFactory\Nethereum.eShop.DbFactory.csproj", "{173B3ACF-DB6E-497C-B778-4BBEB53EFA3A}" EndProject -Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Nethereum.eShop.SqlServer.Migrations", "Nethereum.eShop.SqlServer.Migrations\Nethereum.eShop.SqlServer.Migrations.csproj", "{7EEE2B5F-BD20-4CF3-AD7A-4814BDA23523}" +Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Nethereum.eShop.Migrations", "Nethereum.eShop.Migrations\Nethereum.eShop.Migrations.csproj", "{0E47F900-DBE4-4AFB-86A1-376303CECDFB}" +EndProject +Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "migration", "migration", "{487D2931-4813-4280-9FE1-E1AA7EA6ED34}" EndProject Global GlobalSection(SolutionConfigurationPlatforms) = preSolution @@ -89,10 +91,10 @@ Global {173B3ACF-DB6E-497C-B778-4BBEB53EFA3A}.Debug|Any CPU.Build.0 = Debug|Any CPU {173B3ACF-DB6E-497C-B778-4BBEB53EFA3A}.Release|Any CPU.ActiveCfg = Release|Any CPU {173B3ACF-DB6E-497C-B778-4BBEB53EFA3A}.Release|Any CPU.Build.0 = Release|Any CPU - {7EEE2B5F-BD20-4CF3-AD7A-4814BDA23523}.Debug|Any CPU.ActiveCfg = Debug|Any CPU - {7EEE2B5F-BD20-4CF3-AD7A-4814BDA23523}.Debug|Any CPU.Build.0 = Debug|Any CPU - {7EEE2B5F-BD20-4CF3-AD7A-4814BDA23523}.Release|Any CPU.ActiveCfg = Release|Any CPU - {7EEE2B5F-BD20-4CF3-AD7A-4814BDA23523}.Release|Any CPU.Build.0 = Release|Any CPU + {0E47F900-DBE4-4AFB-86A1-376303CECDFB}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {0E47F900-DBE4-4AFB-86A1-376303CECDFB}.Debug|Any CPU.Build.0 = Debug|Any CPU + {0E47F900-DBE4-4AFB-86A1-376303CECDFB}.Release|Any CPU.ActiveCfg = Release|Any CPU + {0E47F900-DBE4-4AFB-86A1-376303CECDFB}.Release|Any CPU.Build.0 = Release|Any CPU EndGlobalSection GlobalSection(SolutionProperties) = preSolution HideSolutionNode = FALSE @@ -109,7 +111,8 @@ Global {EEE22A14-93DE-4F3D-BE2F-748F40CD2706} = {8ABF2EF8-3DBE-4F90-A681-9CBAF211EA6D} {2914543B-FDB7-46A0-BB4D-A192765D4072} = {8ABF2EF8-3DBE-4F90-A681-9CBAF211EA6D} {173B3ACF-DB6E-497C-B778-4BBEB53EFA3A} = {8ABF2EF8-3DBE-4F90-A681-9CBAF211EA6D} - {7EEE2B5F-BD20-4CF3-AD7A-4814BDA23523} = {8ABF2EF8-3DBE-4F90-A681-9CBAF211EA6D} + {0E47F900-DBE4-4AFB-86A1-376303CECDFB} = {487D2931-4813-4280-9FE1-E1AA7EA6ED34} + {487D2931-4813-4280-9FE1-E1AA7EA6ED34} = {8ABF2EF8-3DBE-4F90-A681-9CBAF211EA6D} EndGlobalSection GlobalSection(ExtensibilityGlobals) = postSolution SolutionGuid = {8BEA2189-D111-472E-BA29-993E206C6CE3} diff --git a/src/Nethereum.eShop/ApplicationCore/Interfaces/IEShopDbBootstrapper.cs b/src/Nethereum.eShop/ApplicationCore/Interfaces/IEShopDbBootstrapper.cs index bc69ace..f921020 100644 --- a/src/Nethereum.eShop/ApplicationCore/Interfaces/IEShopDbBootstrapper.cs +++ b/src/Nethereum.eShop/ApplicationCore/Interfaces/IEShopDbBootstrapper.cs @@ -13,6 +13,8 @@ public interface IEShopDbBootstrapper void AddQueries(IServiceCollection services, IConfiguration configuration); - Task EnsureCreatedAsync(IServiceProvider serviceProvider, CancellationToken cancellationToken = default); + Task EnsureCreatedAsync(IServiceProvider serviceProvider, IConfiguration configuration, CancellationToken cancellationToken = default); + + void AddSeeders(IServiceCollection services, IConfiguration configuration); } } diff --git a/src/Nethereum.eShop/ApplicationCore/Interfaces/IEShopIdentityDbBootstrapper.cs b/src/Nethereum.eShop/ApplicationCore/Interfaces/IEShopIdentityDbBootstrapper.cs index 1e51692..4618d7a 100644 --- a/src/Nethereum.eShop/ApplicationCore/Interfaces/IEShopIdentityDbBootstrapper.cs +++ b/src/Nethereum.eShop/ApplicationCore/Interfaces/IEShopIdentityDbBootstrapper.cs @@ -10,6 +10,6 @@ public interface IEShopIdentityDbBootstrapper { void AddDbContext(IServiceCollection services, IConfiguration configuration); - Task EnsureCreatedAsync(IServiceProvider serviceProvider, CancellationToken cancellationToken = default); + Task EnsureCreatedAsync(IServiceProvider serviceProvider, IConfiguration configuration, CancellationToken cancellationToken = default); } } diff --git a/src/Nethereum.eShop.EntityFramework/Infrastructure/Data/GeneralCache.cs b/src/Nethereum.eShop/Infrastructure/Cache/GeneralCache.cs similarity index 96% rename from src/Nethereum.eShop.EntityFramework/Infrastructure/Data/GeneralCache.cs rename to src/Nethereum.eShop/Infrastructure/Cache/GeneralCache.cs index 7032e5f..ac73f18 100644 --- a/src/Nethereum.eShop.EntityFramework/Infrastructure/Data/GeneralCache.cs +++ b/src/Nethereum.eShop/Infrastructure/Cache/GeneralCache.cs @@ -4,7 +4,7 @@ using System.Linq; using System.Threading.Tasks; -namespace Nethereum.eShop.Infrastructure.Data +namespace Nethereum.eShop.Infrastructure.Cache { /// /// diff --git a/src/Web/Program.cs b/src/Web/Program.cs index 4f8fd13..308605e 100644 --- a/src/Web/Program.cs +++ b/src/Web/Program.cs @@ -8,6 +8,7 @@ using System; using System.Threading.Tasks; using Nethereum.eShop.ApplicationCore.Interfaces; +using Microsoft.Extensions.Configuration; namespace Nethereum.eShop.Web { @@ -25,8 +26,8 @@ public async static Task Main(string[] args) var loggerFactory = services.GetRequiredService(); try { - await services.GetRequiredService().EnsureCreatedAsync(services); - await services.GetRequiredService().EnsureCreatedAsync(services); + await services.GetRequiredService().EnsureCreatedAsync(services, scope.ServiceProvider.GetRequiredService()); + await services.GetRequiredService().EnsureCreatedAsync(services, scope.ServiceProvider.GetRequiredService()); var catalogContextSeeder = services.GetRequiredService(); await catalogContextSeeder.SeedAsync(loggerFactory); diff --git a/src/Web/Startup.cs b/src/Web/Startup.cs index abe2f55..03dc275 100644 --- a/src/Web/Startup.cs +++ b/src/Web/Startup.cs @@ -13,7 +13,8 @@ using Nethereum.eShop.ApplicationCore.Interfaces; using Nethereum.eShop.ApplicationCore.Services; using Nethereum.eShop.DbFactory; -using Nethereum.eShop.Infrastructure.Data; +using Nethereum.eShop.EntityFramework.Identity; +using Nethereum.eShop.Infrastructure.Cache; using Nethereum.eShop.Infrastructure.Identity; using Nethereum.eShop.Infrastructure.Logging; using Nethereum.eShop.Infrastructure.Services; @@ -39,52 +40,11 @@ public Startup(IConfiguration configuration) public void ConfigureDevelopmentServices(IServiceCollection services) { - var inMemoryDbConfig = Configuration["use-in-memory-db"]; - // Default to in memory db - // if sql is required - set "use-in-memory-db" to false in appsettings, command line, user secrets or environmental variables - var inMemory = string.IsNullOrEmpty(inMemoryDbConfig) ? true : bool.Parse(inMemoryDbConfig); - - if (inMemory) - { - // use in-memory database - ConfigureInMemoryDatabases(services); - } - else - { - // use real database - ConfigureProductionServices(services); - } - - } - - private void ConfigureInMemoryDatabases(IServiceCollection services) - { - IEShopDbBootstrapper dbBootstrapper = EShopDbBootstrapper.CreateInMemoryDbBootstrapper(); - services.AddSingleton(dbBootstrapper); - dbBootstrapper.AddDbContext(services, Configuration); - - IEShopIdentityDbBootstrapper identityBootstrapper = EShopDbBootstrapper.CreateInMemoryAppIdentityDbBootstrapper(); - services.AddSingleton(identityBootstrapper); - identityBootstrapper.AddDbContext(services, Configuration); - - ConfigureServices(services, dbBootstrapper); + ConfigureProductionServices(services); } public void ConfigureProductionServices(IServiceCollection services) { - // use real database - // Requires LocalDB which can be installed with SQL Server Express 2016 - // https://www.microsoft.com/en-us/download/details.aspx?id=54284 - - // migrations require a .net tool - // ensure to install the dotnet-ef tool - 3.1.1 - // dotnet tool install --global dotnet-ef --version 3.1.1 - - /* - * A batch file can be run to create the migration and update the DB - See CreateAndApplyDbMigrations.bat in the root of the Web project - */ - IEShopDbBootstrapper dbBootstrapper = EShopDbBootstrapper.CreateDbBootstrapper(Configuration); services.AddSingleton(dbBootstrapper); dbBootstrapper.AddDbContext(services, Configuration); @@ -98,7 +58,9 @@ See CreateAndApplyDbMigrations.bat in the root of the Web project public void ConfigureTestingServices(IServiceCollection services) { - ConfigureInMemoryDatabases(services); + Configuration["CatalogDbProvider"] = "InMemory"; + Configuration["AppIdentityDbProvider"] = "InMemory"; + ConfigureProductionServices(services); } @@ -122,7 +84,6 @@ public void ConfigureServices( services.AddScoped(); services.AddScoped(); services.AddScoped(); - services.AddScoped(); services.AddScoped(); services.AddScoped(); services.Configure(Configuration); @@ -132,14 +93,7 @@ public void ConfigureServices( services.AddSingleton(new UriComposer(catalogSettings)); - if(string.IsNullOrEmpty(catalogSettings.CatalogSeedJsonFile)) - { - services.AddScoped(); - } - else - { - services.AddScoped(); - } + dbBootstrapper.AddSeeders(services, Configuration); var rulesEngineSettings = Configuration.Get(); diff --git a/src/Web/appsettings.json b/src/Web/appsettings.json index 37dd66b..54df1cb 100644 --- a/src/Web/appsettings.json +++ b/src/Web/appsettings.json @@ -2,12 +2,16 @@ // In the development environments, connection strings and keys are normally loaded from user-secrets // Right click Project and "Manage User Secrets" "ConnectionStrings": { - "CatalogConnection": "Server=localhost;Integrated Security=true;Initial Catalog=eShop;", - "IdentityConnection": "Server=localhost;Integrated Security=true;Initial Catalog=eShop;" + "CatalogConnection_SqlServer": "Server=localhost;Integrated Security=true;Initial Catalog=eShop;", + "IdentityConnection_SqlServer": "Server=localhost;Integrated Security=true;Initial Catalog=eShop;", + "CatalogConnection_Sqlite": "Data Source=C:/temp/eshop_catalog.db", + "IdentityConnection_Sqlite": "Data Source=C:/temp/eshop_app_identity.db" }, - // SqlServer, Sqlite - if empty defaults to in-memory - "CatalogDbProvider": "SqlServer", - "AppIdentityDbProvider": "SqlServer", + // SqlServer, Sqlite, InMemory (default) + "CatalogDbProvider": "InMemory", + "AppIdentityDbProvider": "InMemory", + "CatalogApplyMigrationsOnStartup": true, + "IdentityApplyMigrationsOnStartup": true, "CatalogSeedJsonFile": "../../resources/data/TopRankBooks/ImportData/TopRankBooksForCatalogImport.json", "CatalogBaseUrl": "", "QuoteBizRulesFileUrl": "https://ipfs.infura.io/ipfs/QmXcsGDQthxbGW8C3Sx9r4tV9PGSj4MxJmtXF7dnXN5XUT", diff --git a/src/WebJobs/appsettings.json b/src/WebJobs/appsettings.json index 936800e..661a752 100644 --- a/src/WebJobs/appsettings.json +++ b/src/WebJobs/appsettings.json @@ -2,9 +2,11 @@ // In the development environments, connection strings and keys are normally loaded from user-secrets // Right click Project and "Manage User Secrets" "ConnectionStrings": { - "CatalogConnection": "Server=localhost;Integrated Security=true;Initial Catalog=eShop;", + "CatalogConnection_SqlServer": "Server=localhost;Integrated Security=true;Initial Catalog=eShop;", + "CatalogConnection_Sqlite": "Data Source=C:/temp/eshop_catalog.db", "BlockchainProcessingProgressDb": "Server=localhost;Integrated Security=true;Initial Catalog=eShopWebJobs;" }, + // SqlServer, Sqlite (InMemory is no use - as the main Web app can't share the same db state) "CatalogDbProvider": "SqlServer", "AzureWebJobsStorage": "", "EshopConfiguration": { From 37cf236cde84897f75d78a38e1a3f1b8fc52fda8 Mon Sep 17 00:00:00 2001 From: Dave Whiffin Date: Wed, 11 Mar 2020 16:28:16 +0000 Subject: [PATCH 14/27] Fixing async related compilation warnings --- .../Catalog/Cache/RuleTreeCache.cs | 8 ++++---- .../Catalog/EShopDbBootstrapperBase.cs | 1 + .../Catalog/Repositories}/ReportRepository.cs | 9 ++++----- .../Entities/RulesEngine/RuleTreeSeed.cs | 5 +++++ .../ApplicationCore/Services/QuoteService.cs | 2 +- .../Services/RulesEngineService.cs | 15 +++++++------- .../Infrastructure/Cache/GeneralCache.cs | 20 ++++++++++--------- src/Web/Startup.cs | 4 ++-- 8 files changed, 35 insertions(+), 29 deletions(-) rename src/{Nethereum.eShop/Infrastructure/Data => Nethereum.eShop.EntityFramework/Catalog/Repositories}/ReportRepository.cs (68%) diff --git a/src/Nethereum.eShop.EntityFramework/Catalog/Cache/RuleTreeCache.cs b/src/Nethereum.eShop.EntityFramework/Catalog/Cache/RuleTreeCache.cs index db2aec3..62a3ee3 100644 --- a/src/Nethereum.eShop.EntityFramework/Catalog/Cache/RuleTreeCache.cs +++ b/src/Nethereum.eShop.EntityFramework/Catalog/Cache/RuleTreeCache.cs @@ -10,14 +10,14 @@ public class RuleTreeCache : GeneralCache, IRuleTreeCache public RuleTreeCache() {} - public async Task GetByIdAsync(string id) + public Task GetByIdAsync(string id) { - return new RuleTree(new RuleTreeSeed()); + return Task.FromResult(new RuleTree(new RuleTreeSeed())); } - public async Task GetLastRuleTreeCreatedAsync() + public Task GetLastRuleTreeCreatedAsync() { - return new RuleTree(new RuleTreeSeed()); + return Task.FromResult(new RuleTree(new RuleTreeSeed())); } } } diff --git a/src/Nethereum.eShop.EntityFramework/Catalog/EShopDbBootstrapperBase.cs b/src/Nethereum.eShop.EntityFramework/Catalog/EShopDbBootstrapperBase.cs index 212e3e4..e5094a6 100644 --- a/src/Nethereum.eShop.EntityFramework/Catalog/EShopDbBootstrapperBase.cs +++ b/src/Nethereum.eShop.EntityFramework/Catalog/EShopDbBootstrapperBase.cs @@ -21,6 +21,7 @@ public virtual void AddRepositories(IServiceCollection services, IConfiguration services.AddScoped(); services.AddScoped(); services.AddScoped(); + services.AddScoped(); services.AddScoped(); } diff --git a/src/Nethereum.eShop/Infrastructure/Data/ReportRepository.cs b/src/Nethereum.eShop.EntityFramework/Catalog/Repositories/ReportRepository.cs similarity index 68% rename from src/Nethereum.eShop/Infrastructure/Data/ReportRepository.cs rename to src/Nethereum.eShop.EntityFramework/Catalog/Repositories/ReportRepository.cs index 0eb092e..fd38fc3 100644 --- a/src/Nethereum.eShop/Infrastructure/Data/ReportRepository.cs +++ b/src/Nethereum.eShop.EntityFramework/Catalog/Repositories/ReportRepository.cs @@ -1,10 +1,9 @@ -using Microsoft.EntityFrameworkCore; -using Nethereum.eShop.ApplicationCore.Entities.RulesEngine; +using Nethereum.eShop.ApplicationCore.Entities.RulesEngine; using Nethereum.eShop.ApplicationCore.Interfaces; using System.Collections.Generic; using System.Threading.Tasks; -namespace Nethereum.eShop.Infrastructure.Data +namespace Nethereum.eShop.EntityFramework.Catalog.Repositories { // NOTE: To be determined where reports will be stored in the database, if at all - // We may either need to 1.) alter EFRepository so that it has a DBContext supporting @@ -15,9 +14,9 @@ public ReportRepository(CatalogContext dbContext) : base(dbContext) { } - public async Task> GetByRuleTreeIdAsync(int ruleTreeId) + public Task> GetByRuleTreeIdAsync(int ruleTreeId) { - return new List(); + return Task.FromResult(new List()); } } } \ No newline at end of file diff --git a/src/Nethereum.eShop/ApplicationCore/Entities/RulesEngine/RuleTreeSeed.cs b/src/Nethereum.eShop/ApplicationCore/Entities/RulesEngine/RuleTreeSeed.cs index 5c13a36..1e02a79 100644 --- a/src/Nethereum.eShop/ApplicationCore/Entities/RulesEngine/RuleTreeSeed.cs +++ b/src/Nethereum.eShop/ApplicationCore/Entities/RulesEngine/RuleTreeSeed.cs @@ -11,6 +11,11 @@ public RuleTreeSeed() Owner = null; } + public RuleTreeSeed(int id) + { + Id = id; + } + public RuleTreeSeed(int id, string psRuleTreeId, string psOriginUrl, string psOwner) { Id = id; diff --git a/src/Nethereum.eShop/ApplicationCore/Services/QuoteService.cs b/src/Nethereum.eShop/ApplicationCore/Services/QuoteService.cs index 272ed98..ea8042b 100644 --- a/src/Nethereum.eShop/ApplicationCore/Services/QuoteService.cs +++ b/src/Nethereum.eShop/ApplicationCore/Services/QuoteService.cs @@ -64,7 +64,7 @@ public async Task CreateQuoteAsync(int basketId) // NOTE: Should there be any indication of minor issues to the user? } } - catch (RuleTreeException ruleTreeEx) + catch (RuleTreeException) { // NOTE: Should we redirect the user to an error page? } diff --git a/src/Nethereum.eShop/ApplicationCore/Services/RulesEngineService.cs b/src/Nethereum.eShop/ApplicationCore/Services/RulesEngineService.cs index e8c2258..dd2fc19 100644 --- a/src/Nethereum.eShop/ApplicationCore/Services/RulesEngineService.cs +++ b/src/Nethereum.eShop/ApplicationCore/Services/RulesEngineService.cs @@ -29,11 +29,10 @@ public RulesEngineService(IRuleTreeCache ruleTreeRepo, _reportRepository = reportRepo; } - public async Task CreateRulesDomainAsync(RulesDomainSeed domainSeed) + public Task CreateRulesDomainAsync(RulesDomainSeed domainSeed) { // TODO: Do all the work to help initialize the RuleTree - - return new RulesDomain(domainSeed); + return Task.FromResult(new RulesDomain(domainSeed)); } public async Task CreateRuleTreeAsync(RulesDomain domain, RuleTreeSeed origin) @@ -47,17 +46,17 @@ public async Task CreateRuleTreeAsync(RulesDomain domain, RuleTreeSeed return new RuleTree(origin); } - public async Task ExecuteAsync(RuleTree targetRuleTree, RuleTreeRecord targetRecord) + public Task ExecuteAsync(RuleTree targetRuleTree, RuleTreeRecord targetRecord) { // TODO: Do all the work to execute the RuleTree - and return a report? Random rnd = new Random(); - var Report = new RuleTreeReport(new RuleTreeSeed()) { Id = rnd.Next() }; + var Report = new RuleTreeReport(new RuleTreeSeed( rnd.Next())); // NOTE: To be determined where reports will be stored in the database, if at all // await _reportRepository.AddAsync(Report).ConfigureAwait(false); - return Report; + return Task.FromResult(Report); } public async Task GetQuoteRuleTree() @@ -107,11 +106,11 @@ public async Task> ListRuleTreeCacheAsync() return await _ruleTreeRepository.ListAllAsync().ConfigureAwait(false); } - public async Task Transform(object originalObject) + public Task Transform(object originalObject) { // TODO: Convert the object to a RuleTreeRecord - using reflection? - return new RuleTreeRecord(); + return Task.FromResult(new RuleTreeRecord()); } } } diff --git a/src/Nethereum.eShop/Infrastructure/Cache/GeneralCache.cs b/src/Nethereum.eShop/Infrastructure/Cache/GeneralCache.cs index ac73f18..9b36c13 100644 --- a/src/Nethereum.eShop/Infrastructure/Cache/GeneralCache.cs +++ b/src/Nethereum.eShop/Infrastructure/Cache/GeneralCache.cs @@ -23,31 +23,33 @@ public GeneralCache() _cache = new Dictionary(); } - public virtual async Task ContainsAsync(int id) + public virtual Task ContainsAsync(int id) { - return _cache.ContainsKey(id); + return Task.FromResult(_cache.ContainsKey(id)); } - public virtual async Task GetByIdAsync(int id) + public virtual Task GetByIdAsync(int id) { - return _cache[id]; + return Task.FromResult(_cache[id]); } - public async Task> ListAllAsync() + public virtual Task> ListAllAsync() { - return _cache.Values.ToList(); + IReadOnlyList list = _cache.Values.ToList().AsReadOnly(); + return Task.FromResult(list); } - public async Task AddAsync(T entity) + public virtual Task AddAsync(T entity) { _cache[entity.Id] = entity; - return entity; + return Task.FromResult(entity); } - public async Task DeleteAsync(T entity) + public Task DeleteAsync(T entity) { if (_cache.ContainsKey(entity.Id)) _cache.Remove(entity.Id); + return Task.CompletedTask; } } } \ No newline at end of file diff --git a/src/Web/Startup.cs b/src/Web/Startup.cs index c0d445b..b8ee550 100644 --- a/src/Web/Startup.cs +++ b/src/Web/Startup.cs @@ -13,6 +13,7 @@ using Nethereum.eShop.ApplicationCore.Interfaces; using Nethereum.eShop.ApplicationCore.Services; using Nethereum.eShop.DbFactory; +using Nethereum.eShop.EntityFramework.Catalog.Cache; using Nethereum.eShop.EntityFramework.Identity; using Nethereum.eShop.Infrastructure.Cache; using Nethereum.eShop.Infrastructure.Identity; @@ -84,8 +85,7 @@ public void ConfigureServices( services.AddScoped(); services.AddScoped(); services.AddScoped(); - services.AddScoped(); - services.AddScoped(); + services.AddScoped(); services.AddScoped(); services.Configure(Configuration); From 8051e88b3aacae76a22a5a3a399b820b8b070fcb Mon Sep 17 00:00:00 2001 From: Dave Whiffin Date: Wed, 11 Mar 2020 16:31:38 +0000 Subject: [PATCH 15/27] Tidying Startup --- src/Web/Program.cs | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/src/Web/Program.cs b/src/Web/Program.cs index 308605e..64595dc 100644 --- a/src/Web/Program.cs +++ b/src/Web/Program.cs @@ -24,10 +24,11 @@ public async static Task Main(string[] args) var services = scope.ServiceProvider; var loggerFactory = services.GetRequiredService(); + var configuration = scope.ServiceProvider.GetRequiredService(); try { - await services.GetRequiredService().EnsureCreatedAsync(services, scope.ServiceProvider.GetRequiredService()); - await services.GetRequiredService().EnsureCreatedAsync(services, scope.ServiceProvider.GetRequiredService()); + await services.GetRequiredService().EnsureCreatedAsync(services, configuration); + await services.GetRequiredService().EnsureCreatedAsync(services, configuration); var catalogContextSeeder = services.GetRequiredService(); await catalogContextSeeder.SeedAsync(loggerFactory); From 0c53151874baa61a716f68583c76be0704f349ea Mon Sep 17 00:00:00 2001 From: Dave Whiffin Date: Wed, 11 Mar 2020 17:20:34 +0000 Subject: [PATCH 16/27] Removing old batch files and updating db setup docs --- docs/eShop-Db-Setup.md | 125 ++++++++++++++++---------- src/Web/ApplyDbMigrations.bat | 4 - src/Web/CreateInitialDbMigration.bat | 4 - src/Web/GenerateDbCreationScripts.bat | 4 - 4 files changed, 77 insertions(+), 60 deletions(-) delete mode 100644 src/Web/ApplyDbMigrations.bat delete mode 100644 src/Web/CreateInitialDbMigration.bat delete mode 100644 src/Web/GenerateDbCreationScripts.bat diff --git a/docs/eShop-Db-Setup.md b/docs/eShop-Db-Setup.md index e3a024f..3bced88 100644 --- a/docs/eShop-Db-Setup.md +++ b/docs/eShop-Db-Setup.md @@ -2,7 +2,7 @@ ## Configuration -Connection strings are loaded from configuration in the following order. Each source will potentially overwrite settings in previous sources. +Connection strings and settings are loaded from configuration in the following order. Each source will potentially overwrite settings in previous sources. * appsettings.json * appsettings.{environment}.json @@ -12,61 +12,90 @@ Connection strings are loaded from configuration in the following order. Each s For access keys and connection strings, user secrets is preferred for the development environment. It ensures they are excluded from source control and are able to differ from one developer to another. +## Supported DB's + +* SqlServer (tested against 15.0.2000.5 (2019), SQL Server Developer Edition running locally) +* Sqlite +* InMemory + ## Initial Db Setup -### Prerequisites -* Access to a SQL Server (tested against 15.0.2000.5 (2019), SQL Server Developer Edition running locally) -* A Connection string which allows a Database to be created on server - * In a windows environment the current windows user would typically be setup as as sysadmin on the SQL Server and the connection strings would use Integrated Security to map the windows user to SQL Server. This avoids setting a password in the connection string. The initial setup involves the migration creating a database so the connection must be for a user with create db access. -* Install the most recent dotnet-ef tool (necessary to create and run migrations) -``` -dotnet tool install --global dotnet-ef --version 3.1.1 -``` +### Options + +* Automatic migration at Startup. + * During startup of the main "Web" app migrations will be applied to create and update the database. + * This can be enabled with the following settings in appsettings.json + * "CatalogApplyMigrationsOnStartup": true, + * "IdentityApplyMigrationsOnStartup": true, + * *Warning* For SQL Server this will may require a user with necessary permissions to create a DB. +* Manually applying SQL Scripts + * You need to create the DB First (e.g. ``` create database EShop ```) then apply the appropriate scripts below to create the schema. + * src\Nethereum.eShop.SqlServer\Catalog\Migrations\Scripts + * src\Nethereum.eShop.SqlServer\Identity\Migrations\Scripts + * src\Nethereum.eShop.Sqlite\Catalog\Migrations\Scripts + * src\Nethereum.eShop.Sqlite\Identity\Migrations\Scripts ### DB Connections -* CatalogConnection - the main DB containing products, quotes, orders etc + +Database providers are dictated by the ``` CatalogDbProvider ``` and `` AppIdentityDbProvider` ``` settings. + +Supported values are: +* InMemory +* SqlServer +* Sqlite + +``` json + "ConnectionStrings": { + "CatalogConnection_SqlServer": "Server=localhost;Integrated Security=true;Initial Catalog=eShop;", + "IdentityConnection_SqlServer": "Server=localhost;Integrated Security=true;Initial Catalog=eShop;", + "CatalogConnection_Sqlite": "Data Source=C:/temp/eshop_catalog.db", + "IdentityConnection_Sqlite": "Data Source=C:/temp/eshop_app_identity.db", + "BlockchainProcessingProgressDb": "Server=localhost\\sqldev;Integrated Security=true;Initial Catalog=eShopWebJobs;" + }, + "CatalogDbProvider": "SqlServer", + "AppIdentityDbProvider": "SqlServer", + "CatalogApplyMigrationsOnStartup": true, + "IdentityApplyMigrationsOnStartup": true +``` + +* CatalogConnection_{DbProvider} - the main DB containing products, quotes, orders etc * This connection is used by both the Web and WebJob projects -* IdentityConnection - authentication DB +* IdentityConnection_{DbProvider} - authentication DB (web login) * Only used by the Web project at present * BlockchainProcessingProgressDb - stores event log processing progress (last processed block number etc) * Only used by the WebJobs project -### Steps - -* Set up user-secrets - - * Main Web Project: - * Right Click the "Web" project and select "Manage User-Secrets", add the settings below and amend as necessary. - * By default the Web project runs with an in-memory database. To use a real database, the "use-in-memory-db" setting must be set to false. - ``` json - { - "use-in-memory-db": false, - "ConnectionStrings": { - "CatalogConnection": "Server=;Integrated Security=true;Initial Catalog=eShop;", - "IdentityConnection": "Server=;Integrated Security=true;Initial Catalog=eShop;" - } - } - ``` - * Web Jobs Project: - * Right Click the "Web" project and select "Manage User-Secrets", add the settings below and amend as necessary. - ``` json - { - "AzureWebJobsStorage": "DefaultEndpointsProtocol=https;AccountName=;AccountKey=;EndpointSuffix=core.windows.net", - "ConnectionStrings": { - "CatalogConnection": "Server=;Integrated Security=true;Initial Catalog=eShop;", - "IdentityConnection": "Server=;Integrated Security=true;Initial Catalog=eShop;", - "BlockchainProcessingProgressDb": "Server=;Integrated Security=true;Initial Catalog=eShopWebJobs;" - } - } - ``` -* Ensure the Web Project builds! (essential for running the initial migration) -* Ensure the SQL Server is running -* Ensure the database you require HAS NOT already been created -* Run a script to create the DB - * In a command prompt - navigate to the root of the "Web" Project - * Run ApplyDbMigrations.bat - * This will create the DB and the necessary tables for the Catalog and Identity - * The "BlockchainProcessingProgressDb" referenced by the WebJobs project is setup differently, it is setup at run-time and created if it does not exist - * Run the Web project to ensure it works as expected +Connection strings names are suffixed with the provider name (e.g. CatalogConnection_SqlServer) to allow easy switching between providers. The developer can multiple connection strings in settings and swap over using only the "CatalogDbProvider" and "AppIdentityDbProvider" settings. + +### User Secrets + +The "Web" and "WebJobs" project share the same User Secrets Id. This is because they are expected to share the same persistence stores. To set or change user secrets, right click the project and select "manage user-secrets". + +### Adding Migrations and DB Creation Scripts + +When schema changes have been made, migrations should be created so that DB's can be created or updated to the most recent schema. +The solution is setup so that migrations for multiple DB providers can be managed from one place which ensures they are in sync. Note: creating or adding a migration does not update the database, it simply creates code or scripts which can be run later. + +Migrations are created using the "dotnet-ef" tool with a specific start up project ('Nethereum.eShop.Migrations'). The migration process requires a start up project and it is not practical to use the main "Web" or "WebApp" projects as these are only configured for one Db provider at any one time. The goal here is to create migrations for each DB provider at once. + +* Installing dotnet-ef tool (you may need to update to .Net Core 3.1.2 first) +``` +dotnet tool install --global dotnet-ef --version 3.1.2 +``` + +#### Adding a migration + +``` +AddMigration.bat +``` + +Creates a new migration in each DB provider project. + +#### Creating Db Scripts + +``` +ScriptDbs.bat +``` +Generates a complete DB creation script for each supported Db Provider for both the Catalog connection and Identity connection. This script can be run manually against the chosen database. \ No newline at end of file diff --git a/src/Web/ApplyDbMigrations.bat b/src/Web/ApplyDbMigrations.bat deleted file mode 100644 index cdca914..0000000 --- a/src/Web/ApplyDbMigrations.bat +++ /dev/null @@ -1,4 +0,0 @@ -rem Applying Migrations (update db) -dotnet build -dotnet ef database update --project ..\Nethereum.eShop --context Nethereum.eShop.Infrastructure.Data.CatalogContext --no-build -dotnet ef database update --project ..\Nethereum.eShop --context Nethereum.eShop.Infrastructure.Identity.AppIdentityDbContext --no-build \ No newline at end of file diff --git a/src/Web/CreateInitialDbMigration.bat b/src/Web/CreateInitialDbMigration.bat deleted file mode 100644 index ff41e43..0000000 --- a/src/Web/CreateInitialDbMigration.bat +++ /dev/null @@ -1,4 +0,0 @@ -rem Create First Migration aka InitialCreate -dotnet build -dotnet ef migrations add InitialCreate --project ..\Nethereum.eShop --context Nethereum.eShop.Infrastructure.Data.CatalogContext --output-dir ..\Nethereum.eShop\Infrastructure\Data\Migrations --no-build -dotnet ef migrations add InitialCreate --project ..\Nethereum.eShop --context Nethereum.eShop.Infrastructure.Identity.AppIdentityDbContext --output-dir ..\Nethereum.eShop\Infrastructure\Identity\Migrations --no-build \ No newline at end of file diff --git a/src/Web/GenerateDbCreationScripts.bat b/src/Web/GenerateDbCreationScripts.bat deleted file mode 100644 index d629c90..0000000 --- a/src/Web/GenerateDbCreationScripts.bat +++ /dev/null @@ -1,4 +0,0 @@ -rem Create First Migration aka InitialCreate -dotnet build -dotnet ef migrations script -o c:\temp\CreateCatalogDb.sql --project ..\Nethereum.eShop --context Nethereum.eShop.Infrastructure.Data.CatalogContext --no-build -dotnet ef migrations script -o c:\temp\CreateAppIdentityContextDb.sql --project ..\Nethereum.eShop --context Nethereum.eShop.Infrastructure.Identity.AppIdentityDbContext --no-build \ No newline at end of file From aa34ba20eb47b8566b692d7aa2cee63a00e840c7 Mon Sep 17 00:00:00 2001 From: Dave Whiffin Date: Wed, 11 Mar 2020 17:26:05 +0000 Subject: [PATCH 17/27] Adding BuyerWalletAddress with migrations --- .../EntityBuilders/BuyerConfiguration.cs | 2 + ...00311172359_BuyerWalletAddress.Designer.cs | 958 ++++++++++++++++++ .../20200311172359_BuyerWalletAddress.cs | 34 + .../Migrations/Scripts/CreateCatalogDb.sql | 22 + .../SqlServerCatalogContextModelSnapshot.cs | 8 + ...00311172406_BuyerWalletAddress.Designer.cs | 273 +++++ .../20200311172406_BuyerWalletAddress.cs | 17 + .../Migrations/Scripts/CreateIdentityDb.sql | 8 + ...00311172413_BuyerWalletAddress.Designer.cs | 915 +++++++++++++++++ .../20200311172413_BuyerWalletAddress.cs | 33 + .../Migrations/Scripts/CreateCatalogDb.sql | 7 + .../SqliteCatalogContextModelSnapshot.cs | 7 + ...00311172419_BuyerWalletAddress.Designer.cs | 266 +++++ .../20200311172419_BuyerWalletAddress.cs | 17 + .../Migrations/Scripts/CreateIdentityDb.sql | 3 + .../Entities/BuyerAggregate/Buyer.cs | 7 + 16 files changed, 2577 insertions(+) create mode 100644 src/Nethereum.eShop.SqlServer/Catalog/Migrations/20200311172359_BuyerWalletAddress.Designer.cs create mode 100644 src/Nethereum.eShop.SqlServer/Catalog/Migrations/20200311172359_BuyerWalletAddress.cs create mode 100644 src/Nethereum.eShop.SqlServer/Identity/Migrations/20200311172406_BuyerWalletAddress.Designer.cs create mode 100644 src/Nethereum.eShop.SqlServer/Identity/Migrations/20200311172406_BuyerWalletAddress.cs create mode 100644 src/Nethereum.eShop.Sqlite/Catalog/Migrations/20200311172413_BuyerWalletAddress.Designer.cs create mode 100644 src/Nethereum.eShop.Sqlite/Catalog/Migrations/20200311172413_BuyerWalletAddress.cs create mode 100644 src/Nethereum.eShop.Sqlite/Identity/Migrations/20200311172419_BuyerWalletAddress.Designer.cs create mode 100644 src/Nethereum.eShop.Sqlite/Identity/Migrations/20200311172419_BuyerWalletAddress.cs diff --git a/src/Nethereum.eShop.EntityFramework/Catalog/EntityBuilders/BuyerConfiguration.cs b/src/Nethereum.eShop.EntityFramework/Catalog/EntityBuilders/BuyerConfiguration.cs index 3c3b4fe..2a6b02b 100644 --- a/src/Nethereum.eShop.EntityFramework/Catalog/EntityBuilders/BuyerConfiguration.cs +++ b/src/Nethereum.eShop.EntityFramework/Catalog/EntityBuilders/BuyerConfiguration.cs @@ -13,9 +13,11 @@ public virtual void Configure(EntityTypeBuilder builder) builder.Property(b => b.BuyerId).HasMaxLength(256).IsRequired(); builder.Property(b => b.BuyerAddress).IsAddress(); + builder.Property(b => b.BuyerWalletAddress).IsAddress(); builder.HasIndex(b => b.BuyerId).IsUnique(); builder.HasIndex(b => b.BuyerAddress).IsUnique(); + builder.HasIndex(b => b.BuyerWalletAddress).IsUnique(); } } } diff --git a/src/Nethereum.eShop.SqlServer/Catalog/Migrations/20200311172359_BuyerWalletAddress.Designer.cs b/src/Nethereum.eShop.SqlServer/Catalog/Migrations/20200311172359_BuyerWalletAddress.Designer.cs new file mode 100644 index 0000000..0955c80 --- /dev/null +++ b/src/Nethereum.eShop.SqlServer/Catalog/Migrations/20200311172359_BuyerWalletAddress.Designer.cs @@ -0,0 +1,958 @@ +// +using System; +using Microsoft.EntityFrameworkCore; +using Microsoft.EntityFrameworkCore.Infrastructure; +using Microsoft.EntityFrameworkCore.Metadata; +using Microsoft.EntityFrameworkCore.Migrations; +using Microsoft.EntityFrameworkCore.Storage.ValueConversion; +using Nethereum.eShop.SqlServer.Catalog; + +namespace Nethereum.eShop.SqlServer.Catalog.Migrations +{ + [DbContext(typeof(SqlServerCatalogContext))] + [Migration("20200311172359_BuyerWalletAddress")] + partial class BuyerWalletAddress + { + protected override void BuildTargetModel(ModelBuilder modelBuilder) + { +#pragma warning disable 612, 618 + modelBuilder + .HasAnnotation("ProductVersion", "3.1.2") + .HasAnnotation("Relational:MaxIdentifierLength", 128) + .HasAnnotation("Relational:Sequence:.catalog_brand_hilo", "'catalog_brand_hilo', '', '1', '10', '', '', 'Int64', 'False'") + .HasAnnotation("Relational:Sequence:.catalog_hilo", "'catalog_hilo', '', '1', '10', '', '', 'Int64', 'False'") + .HasAnnotation("Relational:Sequence:.catalog_type_hilo", "'catalog_type_hilo', '', '1', '10', '', '', 'Int64', 'False'") + .HasAnnotation("Relational:Sequence:.stock_hilo", "'stock_hilo', '', '1', '10', '', '', 'Int64', 'False'") + .HasAnnotation("SqlServer:ValueGenerationStrategy", SqlServerValueGenerationStrategy.IdentityColumn); + + modelBuilder.Entity("Nethereum.eShop.ApplicationCore.Entities.BasketAggregate.Basket", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("int") + .HasAnnotation("SqlServer:ValueGenerationStrategy", SqlServerValueGenerationStrategy.IdentityColumn); + + b.Property("BuyerAddress") + .IsRequired() + .HasColumnType("nvarchar(43)") + .HasMaxLength(43); + + b.Property("BuyerId") + .IsRequired() + .HasColumnType("nvarchar(256)") + .HasMaxLength(256); + + b.Property("TransactionHash") + .HasColumnType("nvarchar(67)") + .HasMaxLength(67); + + b.HasKey("Id"); + + b.HasIndex("BuyerAddress"); + + b.HasIndex("BuyerId"); + + b.ToTable("Baskets"); + }); + + modelBuilder.Entity("Nethereum.eShop.ApplicationCore.Entities.BasketAggregate.BasketItem", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("int") + .HasAnnotation("SqlServer:ValueGenerationStrategy", SqlServerValueGenerationStrategy.IdentityColumn); + + b.Property("BasketId") + .HasColumnType("int"); + + b.Property("CatalogItemId") + .HasColumnType("int"); + + b.Property("Quantity") + .HasColumnType("int"); + + b.Property("UnitPrice") + .HasColumnType("decimal(18,2)"); + + b.HasKey("Id"); + + b.HasIndex("BasketId"); + + b.ToTable("BasketItems"); + }); + + modelBuilder.Entity("Nethereum.eShop.ApplicationCore.Entities.BuyerAggregate.Buyer", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("int") + .HasAnnotation("SqlServer:ValueGenerationStrategy", SqlServerValueGenerationStrategy.IdentityColumn); + + b.Property("BuyerAddress") + .HasColumnType("nvarchar(43)") + .HasMaxLength(43); + + b.Property("BuyerId") + .IsRequired() + .HasColumnType("nvarchar(256)") + .HasMaxLength(256); + + b.Property("BuyerWalletAddress") + .HasColumnType("nvarchar(43)") + .HasMaxLength(43); + + b.HasKey("Id"); + + b.HasIndex("BuyerAddress") + .IsUnique() + .HasFilter("[BuyerAddress] IS NOT NULL"); + + b.HasIndex("BuyerId") + .IsUnique(); + + b.HasIndex("BuyerWalletAddress") + .IsUnique() + .HasFilter("[BuyerWalletAddress] IS NOT NULL"); + + b.ToTable("Buyers"); + }); + + modelBuilder.Entity("Nethereum.eShop.ApplicationCore.Entities.BuyerAggregate.BuyerPostalAddress", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("int") + .HasAnnotation("SqlServer:ValueGenerationStrategy", SqlServerValueGenerationStrategy.IdentityColumn); + + b.Property("BuyerId") + .HasColumnType("int"); + + b.Property("Name") + .HasColumnType("nvarchar(max)"); + + b.HasKey("Id"); + + b.HasIndex("BuyerId"); + + b.ToTable("BuyerPostalAddress"); + }); + + modelBuilder.Entity("Nethereum.eShop.ApplicationCore.Entities.CatalogBrand", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("int") + .HasAnnotation("SqlServer:HiLoSequenceName", "catalog_brand_hilo") + .HasAnnotation("SqlServer:ValueGenerationStrategy", SqlServerValueGenerationStrategy.SequenceHiLo); + + b.Property("Brand") + .IsRequired() + .HasColumnType("nvarchar(100)") + .HasMaxLength(100); + + b.HasKey("Id"); + + b.ToTable("CatalogBrands"); + }); + + modelBuilder.Entity("Nethereum.eShop.ApplicationCore.Entities.CatalogItem", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("int") + .HasAnnotation("SqlServer:HiLoSequenceName", "catalog_hilo") + .HasAnnotation("SqlServer:ValueGenerationStrategy", SqlServerValueGenerationStrategy.SequenceHiLo); + + b.Property("AttributeJson") + .HasColumnType("nvarchar(max)"); + + b.Property("CatalogBrandId") + .HasColumnType("int"); + + b.Property("CatalogTypeId") + .HasColumnType("int"); + + b.Property("Depth") + .HasColumnType("int"); + + b.Property("Description") + .HasColumnType("nvarchar(max)"); + + b.Property("Gtin") + .IsRequired() + .HasColumnType("nvarchar(14)") + .HasMaxLength(14); + + b.Property("GtinRegistryId") + .HasColumnType("int"); + + b.Property("Height") + .HasColumnType("int"); + + b.Property("Name") + .IsRequired() + .HasColumnType("nvarchar(50)") + .HasMaxLength(50); + + b.Property("PictureLargeUri") + .HasColumnType("nvarchar(512)") + .HasMaxLength(512); + + b.Property("PictureMediumUri") + .HasColumnType("nvarchar(512)") + .HasMaxLength(512); + + b.Property("PictureSmallUri") + .HasColumnType("nvarchar(512)") + .HasMaxLength(512); + + b.Property("PictureUri") + .HasColumnType("nvarchar(512)") + .HasMaxLength(512); + + b.Property("Price") + .HasColumnType("decimal(18,2)"); + + b.Property("Rank") + .HasColumnType("int"); + + b.Property("Status") + .HasColumnType("int"); + + b.Property("Unit") + .HasColumnType("nvarchar(8)") + .HasMaxLength(8); + + b.Property("Weight") + .HasColumnType("int"); + + b.Property("Width") + .HasColumnType("int"); + + b.HasKey("Id"); + + b.HasIndex("CatalogBrandId"); + + b.HasIndex("CatalogTypeId"); + + b.ToTable("Catalog"); + }); + + modelBuilder.Entity("Nethereum.eShop.ApplicationCore.Entities.CatalogType", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("int") + .HasAnnotation("SqlServer:HiLoSequenceName", "catalog_type_hilo") + .HasAnnotation("SqlServer:ValueGenerationStrategy", SqlServerValueGenerationStrategy.SequenceHiLo); + + b.Property("Type") + .IsRequired() + .HasColumnType("nvarchar(100)") + .HasMaxLength(100); + + b.HasKey("Id"); + + b.ToTable("CatalogTypes"); + }); + + modelBuilder.Entity("Nethereum.eShop.ApplicationCore.Entities.OrderAggregate.Order", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("int") + .HasAnnotation("SqlServer:ValueGenerationStrategy", SqlServerValueGenerationStrategy.IdentityColumn); + + b.Property("ApproverAddress") + .HasColumnType("nvarchar(43)") + .HasMaxLength(43); + + b.Property("BuyerAddress") + .HasColumnType("nvarchar(43)") + .HasMaxLength(43); + + b.Property("BuyerId") + .IsRequired() + .HasColumnType("nvarchar(256)") + .HasMaxLength(256); + + b.Property("BuyerWalletAddress") + .HasColumnType("nvarchar(43)") + .HasMaxLength(43); + + b.Property("CurrencyAddress") + .HasColumnType("nvarchar(43)") + .HasMaxLength(43); + + b.Property("CurrencySymbol") + .HasColumnType("nvarchar(32)") + .HasMaxLength(32); + + b.Property("OrderDate") + .HasColumnType("datetimeoffset"); + + b.Property("PoDate") + .HasColumnType("datetimeoffset"); + + b.Property("PoNumber") + .HasColumnType("bigint"); + + b.Property("PoType") + .HasColumnType("int"); + + b.Property("QuoteId") + .HasColumnType("int"); + + b.Property("SellerId") + .HasColumnType("nvarchar(32)") + .HasMaxLength(32); + + b.Property("Status") + .HasColumnType("int"); + + b.Property("TransactionHash") + .HasColumnType("nvarchar(67)") + .HasMaxLength(67); + + b.HasKey("Id"); + + b.HasIndex("BuyerAddress"); + + b.HasIndex("BuyerId"); + + b.ToTable("Orders"); + }); + + modelBuilder.Entity("Nethereum.eShop.ApplicationCore.Entities.OrderAggregate.OrderItem", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("int") + .HasAnnotation("SqlServer:ValueGenerationStrategy", SqlServerValueGenerationStrategy.IdentityColumn); + + b.Property("ActualEscrowReleaseDate") + .HasColumnType("datetimeoffset"); + + b.Property("CurrencyValue") + .HasColumnType("nvarchar(100)") + .HasMaxLength(100); + + b.Property("GoodsIssueDate") + .HasColumnType("datetimeoffset"); + + b.Property("IsEscrowReleased") + .HasColumnType("bit"); + + b.Property("OrderId") + .HasColumnType("int"); + + b.Property("PlannedEscrowReleaseDate") + .HasColumnType("datetimeoffset"); + + b.Property("PoItemNumber") + .HasColumnType("int"); + + b.Property("PoItemStatus") + .HasColumnType("int"); + + b.Property("Quantity") + .HasColumnType("int"); + + b.Property("QuantityAddress") + .HasColumnType("nvarchar(43)") + .HasMaxLength(43); + + b.Property("QuantitySymbol") + .HasColumnType("nvarchar(32)") + .HasMaxLength(32); + + b.Property("Status") + .HasColumnType("int"); + + b.Property("Unit") + .HasColumnType("nvarchar(50)") + .HasMaxLength(50); + + b.Property("UnitPrice") + .HasColumnType("decimal(18,2)"); + + b.HasKey("Id"); + + b.HasIndex("OrderId"); + + b.ToTable("OrderItems"); + }); + + modelBuilder.Entity("Nethereum.eShop.ApplicationCore.Entities.QuoteAggregate.Quote", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("int") + .HasAnnotation("SqlServer:ValueGenerationStrategy", SqlServerValueGenerationStrategy.IdentityColumn); + + b.Property("ApproverAddress") + .HasColumnType("nvarchar(43)") + .HasMaxLength(43); + + b.Property("BuyerAddress") + .HasColumnType("nvarchar(43)") + .HasMaxLength(43); + + b.Property("BuyerId") + .IsRequired() + .HasColumnType("nvarchar(256)") + .HasMaxLength(256); + + b.Property("BuyerWalletAddress") + .HasColumnType("nvarchar(43)") + .HasMaxLength(43); + + b.Property("CurrencyAddress") + .HasColumnType("nvarchar(43)") + .HasMaxLength(43); + + b.Property("CurrencySymbol") + .HasColumnType("nvarchar(32)") + .HasMaxLength(32); + + b.Property("Date") + .HasColumnType("datetimeoffset"); + + b.Property("Expiry") + .HasColumnType("datetimeoffset"); + + b.Property("PoNumber") + .HasColumnType("bigint"); + + b.Property("PoType") + .HasColumnType("int"); + + b.Property("SellerId") + .HasColumnType("nvarchar(32)") + .HasMaxLength(32); + + b.Property("Status") + .HasColumnType("int"); + + b.Property("TransactionHash") + .HasColumnType("nvarchar(67)") + .HasMaxLength(67); + + b.HasKey("Id"); + + b.HasIndex("BuyerAddress"); + + b.HasIndex("BuyerId"); + + b.ToTable("Quotes"); + }); + + modelBuilder.Entity("Nethereum.eShop.ApplicationCore.Entities.QuoteAggregate.QuoteItem", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("int") + .HasAnnotation("SqlServer:ValueGenerationStrategy", SqlServerValueGenerationStrategy.IdentityColumn); + + b.Property("CurrencyValue") + .HasColumnType("nvarchar(max)"); + + b.Property("EscrowReleaseDate") + .HasColumnType("datetimeoffset"); + + b.Property("PoItemNumber") + .HasColumnType("int"); + + b.Property("Quantity") + .HasColumnType("int"); + + b.Property("QuantityAddress") + .HasColumnType("nvarchar(max)"); + + b.Property("QuantitySymbol") + .HasColumnType("nvarchar(max)"); + + b.Property("QuoteId") + .HasColumnType("int"); + + b.Property("Unit") + .HasColumnType("nvarchar(max)"); + + b.Property("UnitPrice") + .HasColumnType("decimal(18,2)"); + + b.HasKey("Id"); + + b.HasIndex("QuoteId"); + + b.ToTable("QuoteItems"); + }); + + modelBuilder.Entity("Nethereum.eShop.ApplicationCore.Entities.StockItem", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("int") + .HasAnnotation("SqlServer:HiLoSequenceName", "stock_hilo") + .HasAnnotation("SqlServer:ValueGenerationStrategy", SqlServerValueGenerationStrategy.SequenceHiLo); + + b.Property("CatalogItemId") + .HasColumnType("int"); + + b.Property("Location") + .IsRequired() + .HasColumnType("nvarchar(50)") + .HasMaxLength(50); + + b.Property("Quantity") + .HasColumnType("int"); + + b.HasKey("Id"); + + b.HasIndex("CatalogItemId"); + + b.ToTable("Stock"); + }); + + modelBuilder.Entity("Nethereum.eShop.ApplicationCore.Entities.BasketAggregate.Basket", b => + { + b.OwnsOne("Nethereum.eShop.ApplicationCore.Entities.PostalAddress", "BillTo", b1 => + { + b1.Property("BasketId") + .ValueGeneratedOnAdd() + .HasColumnType("int") + .HasAnnotation("SqlServer:ValueGenerationStrategy", SqlServerValueGenerationStrategy.IdentityColumn); + + b1.Property("City") + .IsRequired() + .HasColumnType("nvarchar(100)") + .HasMaxLength(100); + + b1.Property("Country") + .IsRequired() + .HasColumnType("nvarchar(90)") + .HasMaxLength(90); + + b1.Property("RecipientName") + .IsRequired() + .HasColumnType("nvarchar(255)") + .HasMaxLength(255); + + b1.Property("State") + .HasColumnType("nvarchar(60)") + .HasMaxLength(60); + + b1.Property("Street") + .IsRequired() + .HasColumnType("nvarchar(180)") + .HasMaxLength(180); + + b1.Property("ZipCode") + .IsRequired() + .HasColumnType("nvarchar(18)") + .HasMaxLength(18); + + b1.HasKey("BasketId"); + + b1.ToTable("Baskets"); + + b1.WithOwner() + .HasForeignKey("BasketId"); + }); + + b.OwnsOne("Nethereum.eShop.ApplicationCore.Entities.PostalAddress", "ShipTo", b1 => + { + b1.Property("BasketId") + .ValueGeneratedOnAdd() + .HasColumnType("int") + .HasAnnotation("SqlServer:ValueGenerationStrategy", SqlServerValueGenerationStrategy.IdentityColumn); + + b1.Property("City") + .IsRequired() + .HasColumnType("nvarchar(100)") + .HasMaxLength(100); + + b1.Property("Country") + .IsRequired() + .HasColumnType("nvarchar(90)") + .HasMaxLength(90); + + b1.Property("RecipientName") + .IsRequired() + .HasColumnType("nvarchar(255)") + .HasMaxLength(255); + + b1.Property("State") + .HasColumnType("nvarchar(60)") + .HasMaxLength(60); + + b1.Property("Street") + .IsRequired() + .HasColumnType("nvarchar(180)") + .HasMaxLength(180); + + b1.Property("ZipCode") + .IsRequired() + .HasColumnType("nvarchar(18)") + .HasMaxLength(18); + + b1.HasKey("BasketId"); + + b1.ToTable("Baskets"); + + b1.WithOwner() + .HasForeignKey("BasketId"); + }); + }); + + modelBuilder.Entity("Nethereum.eShop.ApplicationCore.Entities.BasketAggregate.BasketItem", b => + { + b.HasOne("Nethereum.eShop.ApplicationCore.Entities.BasketAggregate.Basket", null) + .WithMany("Items") + .HasForeignKey("BasketId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + }); + + modelBuilder.Entity("Nethereum.eShop.ApplicationCore.Entities.BuyerAggregate.BuyerPostalAddress", b => + { + b.HasOne("Nethereum.eShop.ApplicationCore.Entities.BuyerAggregate.Buyer", null) + .WithMany("PostalAddresses") + .HasForeignKey("BuyerId"); + + b.OwnsOne("Nethereum.eShop.ApplicationCore.Entities.PostalAddress", "PostalAddress", b1 => + { + b1.Property("BuyerPostalAddressId") + .ValueGeneratedOnAdd() + .HasColumnType("int") + .HasAnnotation("SqlServer:ValueGenerationStrategy", SqlServerValueGenerationStrategy.IdentityColumn); + + b1.Property("City") + .IsRequired() + .HasColumnType("nvarchar(100)") + .HasMaxLength(100); + + b1.Property("Country") + .IsRequired() + .HasColumnType("nvarchar(90)") + .HasMaxLength(90); + + b1.Property("RecipientName") + .IsRequired() + .HasColumnType("nvarchar(255)") + .HasMaxLength(255); + + b1.Property("State") + .HasColumnType("nvarchar(60)") + .HasMaxLength(60); + + b1.Property("Street") + .IsRequired() + .HasColumnType("nvarchar(180)") + .HasMaxLength(180); + + b1.Property("ZipCode") + .IsRequired() + .HasColumnType("nvarchar(18)") + .HasMaxLength(18); + + b1.HasKey("BuyerPostalAddressId"); + + b1.ToTable("BuyerPostalAddress"); + + b1.WithOwner() + .HasForeignKey("BuyerPostalAddressId"); + }); + }); + + modelBuilder.Entity("Nethereum.eShop.ApplicationCore.Entities.CatalogItem", b => + { + b.HasOne("Nethereum.eShop.ApplicationCore.Entities.CatalogBrand", "CatalogBrand") + .WithMany() + .HasForeignKey("CatalogBrandId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.HasOne("Nethereum.eShop.ApplicationCore.Entities.CatalogType", "CatalogType") + .WithMany() + .HasForeignKey("CatalogTypeId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + }); + + modelBuilder.Entity("Nethereum.eShop.ApplicationCore.Entities.OrderAggregate.Order", b => + { + b.OwnsOne("Nethereum.eShop.ApplicationCore.Entities.PostalAddress", "BillTo", b1 => + { + b1.Property("OrderId") + .ValueGeneratedOnAdd() + .HasColumnType("int") + .HasAnnotation("SqlServer:ValueGenerationStrategy", SqlServerValueGenerationStrategy.IdentityColumn); + + b1.Property("City") + .IsRequired() + .HasColumnType("nvarchar(100)") + .HasMaxLength(100); + + b1.Property("Country") + .IsRequired() + .HasColumnType("nvarchar(90)") + .HasMaxLength(90); + + b1.Property("RecipientName") + .IsRequired() + .HasColumnType("nvarchar(255)") + .HasMaxLength(255); + + b1.Property("State") + .HasColumnType("nvarchar(60)") + .HasMaxLength(60); + + b1.Property("Street") + .IsRequired() + .HasColumnType("nvarchar(180)") + .HasMaxLength(180); + + b1.Property("ZipCode") + .IsRequired() + .HasColumnType("nvarchar(18)") + .HasMaxLength(18); + + b1.HasKey("OrderId"); + + b1.ToTable("Orders"); + + b1.WithOwner() + .HasForeignKey("OrderId"); + }); + + b.OwnsOne("Nethereum.eShop.ApplicationCore.Entities.PostalAddress", "ShipTo", b1 => + { + b1.Property("OrderId") + .ValueGeneratedOnAdd() + .HasColumnType("int") + .HasAnnotation("SqlServer:ValueGenerationStrategy", SqlServerValueGenerationStrategy.IdentityColumn); + + b1.Property("City") + .IsRequired() + .HasColumnType("nvarchar(100)") + .HasMaxLength(100); + + b1.Property("Country") + .IsRequired() + .HasColumnType("nvarchar(90)") + .HasMaxLength(90); + + b1.Property("RecipientName") + .IsRequired() + .HasColumnType("nvarchar(255)") + .HasMaxLength(255); + + b1.Property("State") + .HasColumnType("nvarchar(60)") + .HasMaxLength(60); + + b1.Property("Street") + .IsRequired() + .HasColumnType("nvarchar(180)") + .HasMaxLength(180); + + b1.Property("ZipCode") + .IsRequired() + .HasColumnType("nvarchar(18)") + .HasMaxLength(18); + + b1.HasKey("OrderId"); + + b1.ToTable("Orders"); + + b1.WithOwner() + .HasForeignKey("OrderId"); + }); + }); + + modelBuilder.Entity("Nethereum.eShop.ApplicationCore.Entities.OrderAggregate.OrderItem", b => + { + b.HasOne("Nethereum.eShop.ApplicationCore.Entities.OrderAggregate.Order", null) + .WithMany("OrderItems") + .HasForeignKey("OrderId"); + + b.OwnsOne("Nethereum.eShop.ApplicationCore.Entities.CatalogItemExcerpt", "ItemOrdered", b1 => + { + b1.Property("OrderItemId") + .ValueGeneratedOnAdd() + .HasColumnType("int") + .HasAnnotation("SqlServer:ValueGenerationStrategy", SqlServerValueGenerationStrategy.IdentityColumn); + + b1.Property("CatalogItemId") + .HasColumnType("int"); + + b1.Property("Gtin") + .HasColumnType("nvarchar(14)") + .HasMaxLength(14); + + b1.Property("GtinRegistryId") + .HasColumnType("int"); + + b1.Property("PictureUri") + .HasColumnType("nvarchar(512)") + .HasMaxLength(512); + + b1.Property("ProductName") + .IsRequired() + .HasColumnType("nvarchar(50)") + .HasMaxLength(50); + + b1.HasKey("OrderItemId"); + + b1.ToTable("OrderItems"); + + b1.WithOwner() + .HasForeignKey("OrderItemId"); + }); + }); + + modelBuilder.Entity("Nethereum.eShop.ApplicationCore.Entities.QuoteAggregate.Quote", b => + { + b.OwnsOne("Nethereum.eShop.ApplicationCore.Entities.PostalAddress", "BillTo", b1 => + { + b1.Property("QuoteId") + .ValueGeneratedOnAdd() + .HasColumnType("int") + .HasAnnotation("SqlServer:ValueGenerationStrategy", SqlServerValueGenerationStrategy.IdentityColumn); + + b1.Property("City") + .IsRequired() + .HasColumnType("nvarchar(100)") + .HasMaxLength(100); + + b1.Property("Country") + .IsRequired() + .HasColumnType("nvarchar(90)") + .HasMaxLength(90); + + b1.Property("RecipientName") + .IsRequired() + .HasColumnType("nvarchar(255)") + .HasMaxLength(255); + + b1.Property("State") + .HasColumnType("nvarchar(60)") + .HasMaxLength(60); + + b1.Property("Street") + .IsRequired() + .HasColumnType("nvarchar(180)") + .HasMaxLength(180); + + b1.Property("ZipCode") + .IsRequired() + .HasColumnType("nvarchar(18)") + .HasMaxLength(18); + + b1.HasKey("QuoteId"); + + b1.ToTable("Quotes"); + + b1.WithOwner() + .HasForeignKey("QuoteId"); + }); + + b.OwnsOne("Nethereum.eShop.ApplicationCore.Entities.PostalAddress", "ShipTo", b1 => + { + b1.Property("QuoteId") + .ValueGeneratedOnAdd() + .HasColumnType("int") + .HasAnnotation("SqlServer:ValueGenerationStrategy", SqlServerValueGenerationStrategy.IdentityColumn); + + b1.Property("City") + .IsRequired() + .HasColumnType("nvarchar(100)") + .HasMaxLength(100); + + b1.Property("Country") + .IsRequired() + .HasColumnType("nvarchar(90)") + .HasMaxLength(90); + + b1.Property("RecipientName") + .IsRequired() + .HasColumnType("nvarchar(255)") + .HasMaxLength(255); + + b1.Property("State") + .HasColumnType("nvarchar(60)") + .HasMaxLength(60); + + b1.Property("Street") + .IsRequired() + .HasColumnType("nvarchar(180)") + .HasMaxLength(180); + + b1.Property("ZipCode") + .IsRequired() + .HasColumnType("nvarchar(18)") + .HasMaxLength(18); + + b1.HasKey("QuoteId"); + + b1.ToTable("Quotes"); + + b1.WithOwner() + .HasForeignKey("QuoteId"); + }); + }); + + modelBuilder.Entity("Nethereum.eShop.ApplicationCore.Entities.QuoteAggregate.QuoteItem", b => + { + b.HasOne("Nethereum.eShop.ApplicationCore.Entities.QuoteAggregate.Quote", null) + .WithMany("QuoteItems") + .HasForeignKey("QuoteId"); + + b.OwnsOne("Nethereum.eShop.ApplicationCore.Entities.CatalogItemExcerpt", "ItemOrdered", b1 => + { + b1.Property("QuoteItemId") + .ValueGeneratedOnAdd() + .HasColumnType("int") + .HasAnnotation("SqlServer:ValueGenerationStrategy", SqlServerValueGenerationStrategy.IdentityColumn); + + b1.Property("CatalogItemId") + .HasColumnType("int"); + + b1.Property("Gtin") + .HasColumnType("nvarchar(14)") + .HasMaxLength(14); + + b1.Property("GtinRegistryId") + .HasColumnType("int"); + + b1.Property("PictureUri") + .HasColumnType("nvarchar(512)") + .HasMaxLength(512); + + b1.Property("ProductName") + .IsRequired() + .HasColumnType("nvarchar(50)") + .HasMaxLength(50); + + b1.HasKey("QuoteItemId"); + + b1.ToTable("QuoteItems"); + + b1.WithOwner() + .HasForeignKey("QuoteItemId"); + }); + }); + + modelBuilder.Entity("Nethereum.eShop.ApplicationCore.Entities.StockItem", b => + { + b.HasOne("Nethereum.eShop.ApplicationCore.Entities.CatalogItem", "CatalogItem") + .WithMany() + .HasForeignKey("CatalogItemId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + }); +#pragma warning restore 612, 618 + } + } +} diff --git a/src/Nethereum.eShop.SqlServer/Catalog/Migrations/20200311172359_BuyerWalletAddress.cs b/src/Nethereum.eShop.SqlServer/Catalog/Migrations/20200311172359_BuyerWalletAddress.cs new file mode 100644 index 0000000..d211cca --- /dev/null +++ b/src/Nethereum.eShop.SqlServer/Catalog/Migrations/20200311172359_BuyerWalletAddress.cs @@ -0,0 +1,34 @@ +using Microsoft.EntityFrameworkCore.Migrations; + +namespace Nethereum.eShop.SqlServer.Catalog.Migrations +{ + public partial class BuyerWalletAddress : Migration + { + protected override void Up(MigrationBuilder migrationBuilder) + { + migrationBuilder.AddColumn( + name: "BuyerWalletAddress", + table: "Buyers", + maxLength: 43, + nullable: true); + + migrationBuilder.CreateIndex( + name: "IX_Buyers_BuyerWalletAddress", + table: "Buyers", + column: "BuyerWalletAddress", + unique: true, + filter: "[BuyerWalletAddress] IS NOT NULL"); + } + + protected override void Down(MigrationBuilder migrationBuilder) + { + migrationBuilder.DropIndex( + name: "IX_Buyers_BuyerWalletAddress", + table: "Buyers"); + + migrationBuilder.DropColumn( + name: "BuyerWalletAddress", + table: "Buyers"); + } + } +} diff --git a/src/Nethereum.eShop.SqlServer/Catalog/Migrations/Scripts/CreateCatalogDb.sql b/src/Nethereum.eShop.SqlServer/Catalog/Migrations/Scripts/CreateCatalogDb.sql index da83c0e..2a769d5 100644 --- a/src/Nethereum.eShop.SqlServer/Catalog/Migrations/Scripts/CreateCatalogDb.sql +++ b/src/Nethereum.eShop.SqlServer/Catalog/Migrations/Scripts/CreateCatalogDb.sql @@ -414,3 +414,25 @@ END; GO +IF NOT EXISTS(SELECT * FROM [__EFMigrationsHistory] WHERE [MigrationId] = N'20200311172359_BuyerWalletAddress') +BEGIN + ALTER TABLE [Buyers] ADD [BuyerWalletAddress] nvarchar(43) NULL; +END; + +GO + +IF NOT EXISTS(SELECT * FROM [__EFMigrationsHistory] WHERE [MigrationId] = N'20200311172359_BuyerWalletAddress') +BEGIN + CREATE UNIQUE INDEX [IX_Buyers_BuyerWalletAddress] ON [Buyers] ([BuyerWalletAddress]) WHERE [BuyerWalletAddress] IS NOT NULL; +END; + +GO + +IF NOT EXISTS(SELECT * FROM [__EFMigrationsHistory] WHERE [MigrationId] = N'20200311172359_BuyerWalletAddress') +BEGIN + INSERT INTO [__EFMigrationsHistory] ([MigrationId], [ProductVersion]) + VALUES (N'20200311172359_BuyerWalletAddress', N'3.1.2'); +END; + +GO + diff --git a/src/Nethereum.eShop.SqlServer/Catalog/Migrations/SqlServerCatalogContextModelSnapshot.cs b/src/Nethereum.eShop.SqlServer/Catalog/Migrations/SqlServerCatalogContextModelSnapshot.cs index 9e9521d..caed0dc 100644 --- a/src/Nethereum.eShop.SqlServer/Catalog/Migrations/SqlServerCatalogContextModelSnapshot.cs +++ b/src/Nethereum.eShop.SqlServer/Catalog/Migrations/SqlServerCatalogContextModelSnapshot.cs @@ -95,6 +95,10 @@ protected override void BuildModel(ModelBuilder modelBuilder) .HasColumnType("nvarchar(256)") .HasMaxLength(256); + b.Property("BuyerWalletAddress") + .HasColumnType("nvarchar(43)") + .HasMaxLength(43); + b.HasKey("Id"); b.HasIndex("BuyerAddress") @@ -104,6 +108,10 @@ protected override void BuildModel(ModelBuilder modelBuilder) b.HasIndex("BuyerId") .IsUnique(); + b.HasIndex("BuyerWalletAddress") + .IsUnique() + .HasFilter("[BuyerWalletAddress] IS NOT NULL"); + b.ToTable("Buyers"); }); diff --git a/src/Nethereum.eShop.SqlServer/Identity/Migrations/20200311172406_BuyerWalletAddress.Designer.cs b/src/Nethereum.eShop.SqlServer/Identity/Migrations/20200311172406_BuyerWalletAddress.Designer.cs new file mode 100644 index 0000000..f011da8 --- /dev/null +++ b/src/Nethereum.eShop.SqlServer/Identity/Migrations/20200311172406_BuyerWalletAddress.Designer.cs @@ -0,0 +1,273 @@ +// +using System; +using Microsoft.EntityFrameworkCore; +using Microsoft.EntityFrameworkCore.Infrastructure; +using Microsoft.EntityFrameworkCore.Metadata; +using Microsoft.EntityFrameworkCore.Migrations; +using Microsoft.EntityFrameworkCore.Storage.ValueConversion; +using Nethereum.eShop.SqlServer.Identity; + +namespace Nethereum.eShop.SqlServer.Identity.Migrations +{ + [DbContext(typeof(SqlServerAppIdentityDbContext))] + [Migration("20200311172406_BuyerWalletAddress")] + partial class BuyerWalletAddress + { + protected override void BuildTargetModel(ModelBuilder modelBuilder) + { +#pragma warning disable 612, 618 + modelBuilder + .HasAnnotation("ProductVersion", "3.1.2") + .HasAnnotation("Relational:MaxIdentifierLength", 128) + .HasAnnotation("SqlServer:ValueGenerationStrategy", SqlServerValueGenerationStrategy.IdentityColumn); + + modelBuilder.Entity("Microsoft.AspNetCore.Identity.IdentityRole", b => + { + b.Property("Id") + .HasColumnType("nvarchar(450)"); + + b.Property("ConcurrencyStamp") + .IsConcurrencyToken() + .HasColumnType("nvarchar(max)"); + + b.Property("Name") + .HasColumnType("nvarchar(256)") + .HasMaxLength(256); + + b.Property("NormalizedName") + .HasColumnType("nvarchar(256)") + .HasMaxLength(256); + + b.HasKey("Id"); + + b.HasIndex("NormalizedName") + .IsUnique() + .HasName("RoleNameIndex") + .HasFilter("[NormalizedName] IS NOT NULL"); + + b.ToTable("AspNetRoles"); + }); + + modelBuilder.Entity("Microsoft.AspNetCore.Identity.IdentityRoleClaim", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("int") + .HasAnnotation("SqlServer:ValueGenerationStrategy", SqlServerValueGenerationStrategy.IdentityColumn); + + b.Property("ClaimType") + .HasColumnType("nvarchar(max)"); + + b.Property("ClaimValue") + .HasColumnType("nvarchar(max)"); + + b.Property("RoleId") + .IsRequired() + .HasColumnType("nvarchar(450)"); + + b.HasKey("Id"); + + b.HasIndex("RoleId"); + + b.ToTable("AspNetRoleClaims"); + }); + + modelBuilder.Entity("Microsoft.AspNetCore.Identity.IdentityUserClaim", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("int") + .HasAnnotation("SqlServer:ValueGenerationStrategy", SqlServerValueGenerationStrategy.IdentityColumn); + + b.Property("ClaimType") + .HasColumnType("nvarchar(max)"); + + b.Property("ClaimValue") + .HasColumnType("nvarchar(max)"); + + b.Property("UserId") + .IsRequired() + .HasColumnType("nvarchar(450)"); + + b.HasKey("Id"); + + b.HasIndex("UserId"); + + b.ToTable("AspNetUserClaims"); + }); + + modelBuilder.Entity("Microsoft.AspNetCore.Identity.IdentityUserLogin", b => + { + b.Property("LoginProvider") + .HasColumnType("nvarchar(450)"); + + b.Property("ProviderKey") + .HasColumnType("nvarchar(450)"); + + b.Property("ProviderDisplayName") + .HasColumnType("nvarchar(max)"); + + b.Property("UserId") + .IsRequired() + .HasColumnType("nvarchar(450)"); + + b.HasKey("LoginProvider", "ProviderKey"); + + b.HasIndex("UserId"); + + b.ToTable("AspNetUserLogins"); + }); + + modelBuilder.Entity("Microsoft.AspNetCore.Identity.IdentityUserRole", b => + { + b.Property("UserId") + .HasColumnType("nvarchar(450)"); + + b.Property("RoleId") + .HasColumnType("nvarchar(450)"); + + b.HasKey("UserId", "RoleId"); + + b.HasIndex("RoleId"); + + b.ToTable("AspNetUserRoles"); + }); + + modelBuilder.Entity("Microsoft.AspNetCore.Identity.IdentityUserToken", b => + { + b.Property("UserId") + .HasColumnType("nvarchar(450)"); + + b.Property("LoginProvider") + .HasColumnType("nvarchar(450)"); + + b.Property("Name") + .HasColumnType("nvarchar(450)"); + + b.Property("Value") + .HasColumnType("nvarchar(max)"); + + b.HasKey("UserId", "LoginProvider", "Name"); + + b.ToTable("AspNetUserTokens"); + }); + + modelBuilder.Entity("Nethereum.eShop.Infrastructure.Identity.ApplicationUser", b => + { + b.Property("Id") + .HasColumnType("nvarchar(450)"); + + b.Property("AccessFailedCount") + .HasColumnType("int"); + + b.Property("ConcurrencyStamp") + .IsConcurrencyToken() + .HasColumnType("nvarchar(max)"); + + b.Property("Email") + .HasColumnType("nvarchar(256)") + .HasMaxLength(256); + + b.Property("EmailConfirmed") + .HasColumnType("bit"); + + b.Property("LockoutEnabled") + .HasColumnType("bit"); + + b.Property("LockoutEnd") + .HasColumnType("datetimeoffset"); + + b.Property("NormalizedEmail") + .HasColumnType("nvarchar(256)") + .HasMaxLength(256); + + b.Property("NormalizedUserName") + .HasColumnType("nvarchar(256)") + .HasMaxLength(256); + + b.Property("PasswordHash") + .HasColumnType("nvarchar(max)"); + + b.Property("PhoneNumber") + .HasColumnType("nvarchar(max)"); + + b.Property("PhoneNumberConfirmed") + .HasColumnType("bit"); + + b.Property("SecurityStamp") + .HasColumnType("nvarchar(max)"); + + b.Property("TwoFactorEnabled") + .HasColumnType("bit"); + + b.Property("UserName") + .HasColumnType("nvarchar(256)") + .HasMaxLength(256); + + b.HasKey("Id"); + + b.HasIndex("NormalizedEmail") + .HasName("EmailIndex"); + + b.HasIndex("NormalizedUserName") + .IsUnique() + .HasName("UserNameIndex") + .HasFilter("[NormalizedUserName] IS NOT NULL"); + + b.ToTable("AspNetUsers"); + }); + + modelBuilder.Entity("Microsoft.AspNetCore.Identity.IdentityRoleClaim", b => + { + b.HasOne("Microsoft.AspNetCore.Identity.IdentityRole", null) + .WithMany() + .HasForeignKey("RoleId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + }); + + modelBuilder.Entity("Microsoft.AspNetCore.Identity.IdentityUserClaim", b => + { + b.HasOne("Nethereum.eShop.Infrastructure.Identity.ApplicationUser", null) + .WithMany() + .HasForeignKey("UserId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + }); + + modelBuilder.Entity("Microsoft.AspNetCore.Identity.IdentityUserLogin", b => + { + b.HasOne("Nethereum.eShop.Infrastructure.Identity.ApplicationUser", null) + .WithMany() + .HasForeignKey("UserId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + }); + + modelBuilder.Entity("Microsoft.AspNetCore.Identity.IdentityUserRole", b => + { + b.HasOne("Microsoft.AspNetCore.Identity.IdentityRole", null) + .WithMany() + .HasForeignKey("RoleId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.HasOne("Nethereum.eShop.Infrastructure.Identity.ApplicationUser", null) + .WithMany() + .HasForeignKey("UserId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + }); + + modelBuilder.Entity("Microsoft.AspNetCore.Identity.IdentityUserToken", b => + { + b.HasOne("Nethereum.eShop.Infrastructure.Identity.ApplicationUser", null) + .WithMany() + .HasForeignKey("UserId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + }); +#pragma warning restore 612, 618 + } + } +} diff --git a/src/Nethereum.eShop.SqlServer/Identity/Migrations/20200311172406_BuyerWalletAddress.cs b/src/Nethereum.eShop.SqlServer/Identity/Migrations/20200311172406_BuyerWalletAddress.cs new file mode 100644 index 0000000..0e65a84 --- /dev/null +++ b/src/Nethereum.eShop.SqlServer/Identity/Migrations/20200311172406_BuyerWalletAddress.cs @@ -0,0 +1,17 @@ +using Microsoft.EntityFrameworkCore.Migrations; + +namespace Nethereum.eShop.SqlServer.Identity.Migrations +{ + public partial class BuyerWalletAddress : Migration + { + protected override void Up(MigrationBuilder migrationBuilder) + { + + } + + protected override void Down(MigrationBuilder migrationBuilder) + { + + } + } +} diff --git a/src/Nethereum.eShop.SqlServer/Identity/Migrations/Scripts/CreateIdentityDb.sql b/src/Nethereum.eShop.SqlServer/Identity/Migrations/Scripts/CreateIdentityDb.sql index d051dc5..65efef8 100644 --- a/src/Nethereum.eShop.SqlServer/Identity/Migrations/Scripts/CreateIdentityDb.sql +++ b/src/Nethereum.eShop.SqlServer/Identity/Migrations/Scripts/CreateIdentityDb.sql @@ -172,3 +172,11 @@ END; GO +IF NOT EXISTS(SELECT * FROM [__EFMigrationsHistory] WHERE [MigrationId] = N'20200311172406_BuyerWalletAddress') +BEGIN + INSERT INTO [__EFMigrationsHistory] ([MigrationId], [ProductVersion]) + VALUES (N'20200311172406_BuyerWalletAddress', N'3.1.2'); +END; + +GO + diff --git a/src/Nethereum.eShop.Sqlite/Catalog/Migrations/20200311172413_BuyerWalletAddress.Designer.cs b/src/Nethereum.eShop.Sqlite/Catalog/Migrations/20200311172413_BuyerWalletAddress.Designer.cs new file mode 100644 index 0000000..3a63067 --- /dev/null +++ b/src/Nethereum.eShop.Sqlite/Catalog/Migrations/20200311172413_BuyerWalletAddress.Designer.cs @@ -0,0 +1,915 @@ +// +using System; +using Microsoft.EntityFrameworkCore; +using Microsoft.EntityFrameworkCore.Infrastructure; +using Microsoft.EntityFrameworkCore.Migrations; +using Microsoft.EntityFrameworkCore.Storage.ValueConversion; +using Nethereum.eShop.Sqlite.Catalog; + +namespace Nethereum.eShop.Sqlite.Catalog.Migrations +{ + [DbContext(typeof(SqliteCatalogContext))] + [Migration("20200311172413_BuyerWalletAddress")] + partial class BuyerWalletAddress + { + protected override void BuildTargetModel(ModelBuilder modelBuilder) + { +#pragma warning disable 612, 618 + modelBuilder + .HasAnnotation("ProductVersion", "3.1.2"); + + modelBuilder.Entity("Nethereum.eShop.ApplicationCore.Entities.BasketAggregate.Basket", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("INTEGER"); + + b.Property("BuyerAddress") + .IsRequired() + .HasColumnType("TEXT") + .HasMaxLength(43); + + b.Property("BuyerId") + .IsRequired() + .HasColumnType("TEXT") + .HasMaxLength(256); + + b.Property("TransactionHash") + .HasColumnType("TEXT") + .HasMaxLength(67); + + b.HasKey("Id"); + + b.HasIndex("BuyerAddress"); + + b.HasIndex("BuyerId"); + + b.ToTable("Baskets"); + }); + + modelBuilder.Entity("Nethereum.eShop.ApplicationCore.Entities.BasketAggregate.BasketItem", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("INTEGER"); + + b.Property("BasketId") + .HasColumnType("INTEGER"); + + b.Property("CatalogItemId") + .HasColumnType("INTEGER"); + + b.Property("Quantity") + .HasColumnType("INTEGER"); + + b.Property("UnitPrice") + .HasColumnType("decimal(18,2)"); + + b.HasKey("Id"); + + b.HasIndex("BasketId"); + + b.ToTable("BasketItems"); + }); + + modelBuilder.Entity("Nethereum.eShop.ApplicationCore.Entities.BuyerAggregate.Buyer", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("INTEGER"); + + b.Property("BuyerAddress") + .HasColumnType("TEXT") + .HasMaxLength(43); + + b.Property("BuyerId") + .IsRequired() + .HasColumnType("TEXT") + .HasMaxLength(256); + + b.Property("BuyerWalletAddress") + .HasColumnType("TEXT") + .HasMaxLength(43); + + b.HasKey("Id"); + + b.HasIndex("BuyerAddress") + .IsUnique(); + + b.HasIndex("BuyerId") + .IsUnique(); + + b.HasIndex("BuyerWalletAddress") + .IsUnique(); + + b.ToTable("Buyers"); + }); + + modelBuilder.Entity("Nethereum.eShop.ApplicationCore.Entities.BuyerAggregate.BuyerPostalAddress", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("INTEGER"); + + b.Property("BuyerId") + .HasColumnType("INTEGER"); + + b.Property("Name") + .HasColumnType("TEXT"); + + b.HasKey("Id"); + + b.HasIndex("BuyerId"); + + b.ToTable("BuyerPostalAddress"); + }); + + modelBuilder.Entity("Nethereum.eShop.ApplicationCore.Entities.CatalogBrand", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("INTEGER"); + + b.Property("Brand") + .IsRequired() + .HasColumnType("TEXT") + .HasMaxLength(100); + + b.HasKey("Id"); + + b.ToTable("CatalogBrands"); + }); + + modelBuilder.Entity("Nethereum.eShop.ApplicationCore.Entities.CatalogItem", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("INTEGER"); + + b.Property("AttributeJson") + .HasColumnType("TEXT"); + + b.Property("CatalogBrandId") + .HasColumnType("INTEGER"); + + b.Property("CatalogTypeId") + .HasColumnType("INTEGER"); + + b.Property("Depth") + .HasColumnType("INTEGER"); + + b.Property("Description") + .HasColumnType("TEXT"); + + b.Property("Gtin") + .IsRequired() + .HasColumnType("TEXT") + .HasMaxLength(14); + + b.Property("GtinRegistryId") + .HasColumnType("INTEGER"); + + b.Property("Height") + .HasColumnType("INTEGER"); + + b.Property("Name") + .IsRequired() + .HasColumnType("TEXT") + .HasMaxLength(50); + + b.Property("PictureLargeUri") + .HasColumnType("TEXT") + .HasMaxLength(512); + + b.Property("PictureMediumUri") + .HasColumnType("TEXT") + .HasMaxLength(512); + + b.Property("PictureSmallUri") + .HasColumnType("TEXT") + .HasMaxLength(512); + + b.Property("PictureUri") + .HasColumnType("TEXT") + .HasMaxLength(512); + + b.Property("Price") + .HasColumnType("decimal(18,2)"); + + b.Property("Rank") + .HasColumnType("INTEGER"); + + b.Property("Status") + .HasColumnType("INTEGER"); + + b.Property("Unit") + .HasColumnType("TEXT") + .HasMaxLength(8); + + b.Property("Weight") + .HasColumnType("INTEGER"); + + b.Property("Width") + .HasColumnType("INTEGER"); + + b.HasKey("Id"); + + b.HasIndex("CatalogBrandId"); + + b.HasIndex("CatalogTypeId"); + + b.ToTable("Catalog"); + }); + + modelBuilder.Entity("Nethereum.eShop.ApplicationCore.Entities.CatalogType", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("INTEGER"); + + b.Property("Type") + .IsRequired() + .HasColumnType("TEXT") + .HasMaxLength(100); + + b.HasKey("Id"); + + b.ToTable("CatalogTypes"); + }); + + modelBuilder.Entity("Nethereum.eShop.ApplicationCore.Entities.OrderAggregate.Order", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("INTEGER"); + + b.Property("ApproverAddress") + .HasColumnType("TEXT") + .HasMaxLength(43); + + b.Property("BuyerAddress") + .HasColumnType("TEXT") + .HasMaxLength(43); + + b.Property("BuyerId") + .IsRequired() + .HasColumnType("TEXT") + .HasMaxLength(256); + + b.Property("BuyerWalletAddress") + .HasColumnType("TEXT") + .HasMaxLength(43); + + b.Property("CurrencyAddress") + .HasColumnType("TEXT") + .HasMaxLength(43); + + b.Property("CurrencySymbol") + .HasColumnType("TEXT") + .HasMaxLength(32); + + b.Property("OrderDate") + .HasColumnType("TEXT"); + + b.Property("PoDate") + .HasColumnType("TEXT"); + + b.Property("PoNumber") + .HasColumnType("INTEGER"); + + b.Property("PoType") + .HasColumnType("INTEGER"); + + b.Property("QuoteId") + .HasColumnType("INTEGER"); + + b.Property("SellerId") + .HasColumnType("TEXT") + .HasMaxLength(32); + + b.Property("Status") + .HasColumnType("INTEGER"); + + b.Property("TransactionHash") + .HasColumnType("TEXT") + .HasMaxLength(67); + + b.HasKey("Id"); + + b.HasIndex("BuyerAddress"); + + b.HasIndex("BuyerId"); + + b.ToTable("Orders"); + }); + + modelBuilder.Entity("Nethereum.eShop.ApplicationCore.Entities.OrderAggregate.OrderItem", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("INTEGER"); + + b.Property("ActualEscrowReleaseDate") + .HasColumnType("TEXT"); + + b.Property("CurrencyValue") + .HasColumnType("TEXT") + .HasMaxLength(100); + + b.Property("GoodsIssueDate") + .HasColumnType("TEXT"); + + b.Property("IsEscrowReleased") + .HasColumnType("INTEGER"); + + b.Property("OrderId") + .HasColumnType("INTEGER"); + + b.Property("PlannedEscrowReleaseDate") + .HasColumnType("TEXT"); + + b.Property("PoItemNumber") + .HasColumnType("INTEGER"); + + b.Property("PoItemStatus") + .HasColumnType("INTEGER"); + + b.Property("Quantity") + .HasColumnType("INTEGER"); + + b.Property("QuantityAddress") + .HasColumnType("TEXT") + .HasMaxLength(43); + + b.Property("QuantitySymbol") + .HasColumnType("TEXT") + .HasMaxLength(32); + + b.Property("Status") + .HasColumnType("INTEGER"); + + b.Property("Unit") + .HasColumnType("TEXT") + .HasMaxLength(50); + + b.Property("UnitPrice") + .HasColumnType("decimal(18,2)"); + + b.HasKey("Id"); + + b.HasIndex("OrderId"); + + b.ToTable("OrderItems"); + }); + + modelBuilder.Entity("Nethereum.eShop.ApplicationCore.Entities.QuoteAggregate.Quote", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("INTEGER"); + + b.Property("ApproverAddress") + .HasColumnType("TEXT") + .HasMaxLength(43); + + b.Property("BuyerAddress") + .HasColumnType("TEXT") + .HasMaxLength(43); + + b.Property("BuyerId") + .IsRequired() + .HasColumnType("TEXT") + .HasMaxLength(256); + + b.Property("BuyerWalletAddress") + .HasColumnType("TEXT") + .HasMaxLength(43); + + b.Property("CurrencyAddress") + .HasColumnType("TEXT") + .HasMaxLength(43); + + b.Property("CurrencySymbol") + .HasColumnType("TEXT") + .HasMaxLength(32); + + b.Property("Date") + .HasColumnType("TEXT"); + + b.Property("Expiry") + .HasColumnType("TEXT"); + + b.Property("PoNumber") + .HasColumnType("INTEGER"); + + b.Property("PoType") + .HasColumnType("INTEGER"); + + b.Property("SellerId") + .HasColumnType("TEXT") + .HasMaxLength(32); + + b.Property("Status") + .HasColumnType("INTEGER"); + + b.Property("TransactionHash") + .HasColumnType("TEXT") + .HasMaxLength(67); + + b.HasKey("Id"); + + b.HasIndex("BuyerAddress"); + + b.HasIndex("BuyerId"); + + b.ToTable("Quotes"); + }); + + modelBuilder.Entity("Nethereum.eShop.ApplicationCore.Entities.QuoteAggregate.QuoteItem", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("INTEGER"); + + b.Property("CurrencyValue") + .HasColumnType("TEXT"); + + b.Property("EscrowReleaseDate") + .HasColumnType("TEXT"); + + b.Property("PoItemNumber") + .HasColumnType("INTEGER"); + + b.Property("Quantity") + .HasColumnType("INTEGER"); + + b.Property("QuantityAddress") + .HasColumnType("TEXT"); + + b.Property("QuantitySymbol") + .HasColumnType("TEXT"); + + b.Property("QuoteId") + .HasColumnType("INTEGER"); + + b.Property("Unit") + .HasColumnType("TEXT"); + + b.Property("UnitPrice") + .HasColumnType("decimal(18,2)"); + + b.HasKey("Id"); + + b.HasIndex("QuoteId"); + + b.ToTable("QuoteItems"); + }); + + modelBuilder.Entity("Nethereum.eShop.ApplicationCore.Entities.StockItem", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("INTEGER"); + + b.Property("CatalogItemId") + .HasColumnType("INTEGER"); + + b.Property("Location") + .IsRequired() + .HasColumnType("TEXT") + .HasMaxLength(50); + + b.Property("Quantity") + .HasColumnType("INTEGER"); + + b.HasKey("Id"); + + b.HasIndex("CatalogItemId"); + + b.ToTable("Stock"); + }); + + modelBuilder.Entity("Nethereum.eShop.ApplicationCore.Entities.BasketAggregate.Basket", b => + { + b.OwnsOne("Nethereum.eShop.ApplicationCore.Entities.PostalAddress", "BillTo", b1 => + { + b1.Property("BasketId") + .HasColumnType("INTEGER"); + + b1.Property("City") + .IsRequired() + .HasColumnType("TEXT") + .HasMaxLength(100); + + b1.Property("Country") + .IsRequired() + .HasColumnType("TEXT") + .HasMaxLength(90); + + b1.Property("RecipientName") + .IsRequired() + .HasColumnType("TEXT") + .HasMaxLength(255); + + b1.Property("State") + .HasColumnType("TEXT") + .HasMaxLength(60); + + b1.Property("Street") + .IsRequired() + .HasColumnType("TEXT") + .HasMaxLength(180); + + b1.Property("ZipCode") + .IsRequired() + .HasColumnType("TEXT") + .HasMaxLength(18); + + b1.HasKey("BasketId"); + + b1.ToTable("Baskets"); + + b1.WithOwner() + .HasForeignKey("BasketId"); + }); + + b.OwnsOne("Nethereum.eShop.ApplicationCore.Entities.PostalAddress", "ShipTo", b1 => + { + b1.Property("BasketId") + .HasColumnType("INTEGER"); + + b1.Property("City") + .IsRequired() + .HasColumnType("TEXT") + .HasMaxLength(100); + + b1.Property("Country") + .IsRequired() + .HasColumnType("TEXT") + .HasMaxLength(90); + + b1.Property("RecipientName") + .IsRequired() + .HasColumnType("TEXT") + .HasMaxLength(255); + + b1.Property("State") + .HasColumnType("TEXT") + .HasMaxLength(60); + + b1.Property("Street") + .IsRequired() + .HasColumnType("TEXT") + .HasMaxLength(180); + + b1.Property("ZipCode") + .IsRequired() + .HasColumnType("TEXT") + .HasMaxLength(18); + + b1.HasKey("BasketId"); + + b1.ToTable("Baskets"); + + b1.WithOwner() + .HasForeignKey("BasketId"); + }); + }); + + modelBuilder.Entity("Nethereum.eShop.ApplicationCore.Entities.BasketAggregate.BasketItem", b => + { + b.HasOne("Nethereum.eShop.ApplicationCore.Entities.BasketAggregate.Basket", null) + .WithMany("Items") + .HasForeignKey("BasketId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + }); + + modelBuilder.Entity("Nethereum.eShop.ApplicationCore.Entities.BuyerAggregate.BuyerPostalAddress", b => + { + b.HasOne("Nethereum.eShop.ApplicationCore.Entities.BuyerAggregate.Buyer", null) + .WithMany("PostalAddresses") + .HasForeignKey("BuyerId"); + + b.OwnsOne("Nethereum.eShop.ApplicationCore.Entities.PostalAddress", "PostalAddress", b1 => + { + b1.Property("BuyerPostalAddressId") + .HasColumnType("INTEGER"); + + b1.Property("City") + .IsRequired() + .HasColumnType("TEXT") + .HasMaxLength(100); + + b1.Property("Country") + .IsRequired() + .HasColumnType("TEXT") + .HasMaxLength(90); + + b1.Property("RecipientName") + .IsRequired() + .HasColumnType("TEXT") + .HasMaxLength(255); + + b1.Property("State") + .HasColumnType("TEXT") + .HasMaxLength(60); + + b1.Property("Street") + .IsRequired() + .HasColumnType("TEXT") + .HasMaxLength(180); + + b1.Property("ZipCode") + .IsRequired() + .HasColumnType("TEXT") + .HasMaxLength(18); + + b1.HasKey("BuyerPostalAddressId"); + + b1.ToTable("BuyerPostalAddress"); + + b1.WithOwner() + .HasForeignKey("BuyerPostalAddressId"); + }); + }); + + modelBuilder.Entity("Nethereum.eShop.ApplicationCore.Entities.CatalogItem", b => + { + b.HasOne("Nethereum.eShop.ApplicationCore.Entities.CatalogBrand", "CatalogBrand") + .WithMany() + .HasForeignKey("CatalogBrandId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.HasOne("Nethereum.eShop.ApplicationCore.Entities.CatalogType", "CatalogType") + .WithMany() + .HasForeignKey("CatalogTypeId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + }); + + modelBuilder.Entity("Nethereum.eShop.ApplicationCore.Entities.OrderAggregate.Order", b => + { + b.OwnsOne("Nethereum.eShop.ApplicationCore.Entities.PostalAddress", "BillTo", b1 => + { + b1.Property("OrderId") + .HasColumnType("INTEGER"); + + b1.Property("City") + .IsRequired() + .HasColumnType("TEXT") + .HasMaxLength(100); + + b1.Property("Country") + .IsRequired() + .HasColumnType("TEXT") + .HasMaxLength(90); + + b1.Property("RecipientName") + .IsRequired() + .HasColumnType("TEXT") + .HasMaxLength(255); + + b1.Property("State") + .HasColumnType("TEXT") + .HasMaxLength(60); + + b1.Property("Street") + .IsRequired() + .HasColumnType("TEXT") + .HasMaxLength(180); + + b1.Property("ZipCode") + .IsRequired() + .HasColumnType("TEXT") + .HasMaxLength(18); + + b1.HasKey("OrderId"); + + b1.ToTable("Orders"); + + b1.WithOwner() + .HasForeignKey("OrderId"); + }); + + b.OwnsOne("Nethereum.eShop.ApplicationCore.Entities.PostalAddress", "ShipTo", b1 => + { + b1.Property("OrderId") + .HasColumnType("INTEGER"); + + b1.Property("City") + .IsRequired() + .HasColumnType("TEXT") + .HasMaxLength(100); + + b1.Property("Country") + .IsRequired() + .HasColumnType("TEXT") + .HasMaxLength(90); + + b1.Property("RecipientName") + .IsRequired() + .HasColumnType("TEXT") + .HasMaxLength(255); + + b1.Property("State") + .HasColumnType("TEXT") + .HasMaxLength(60); + + b1.Property("Street") + .IsRequired() + .HasColumnType("TEXT") + .HasMaxLength(180); + + b1.Property("ZipCode") + .IsRequired() + .HasColumnType("TEXT") + .HasMaxLength(18); + + b1.HasKey("OrderId"); + + b1.ToTable("Orders"); + + b1.WithOwner() + .HasForeignKey("OrderId"); + }); + }); + + modelBuilder.Entity("Nethereum.eShop.ApplicationCore.Entities.OrderAggregate.OrderItem", b => + { + b.HasOne("Nethereum.eShop.ApplicationCore.Entities.OrderAggregate.Order", null) + .WithMany("OrderItems") + .HasForeignKey("OrderId"); + + b.OwnsOne("Nethereum.eShop.ApplicationCore.Entities.CatalogItemExcerpt", "ItemOrdered", b1 => + { + b1.Property("OrderItemId") + .HasColumnType("INTEGER"); + + b1.Property("CatalogItemId") + .HasColumnType("INTEGER"); + + b1.Property("Gtin") + .HasColumnType("TEXT") + .HasMaxLength(14); + + b1.Property("GtinRegistryId") + .HasColumnType("INTEGER"); + + b1.Property("PictureUri") + .HasColumnType("TEXT") + .HasMaxLength(512); + + b1.Property("ProductName") + .IsRequired() + .HasColumnType("TEXT") + .HasMaxLength(50); + + b1.HasKey("OrderItemId"); + + b1.ToTable("OrderItems"); + + b1.WithOwner() + .HasForeignKey("OrderItemId"); + }); + }); + + modelBuilder.Entity("Nethereum.eShop.ApplicationCore.Entities.QuoteAggregate.Quote", b => + { + b.OwnsOne("Nethereum.eShop.ApplicationCore.Entities.PostalAddress", "BillTo", b1 => + { + b1.Property("QuoteId") + .HasColumnType("INTEGER"); + + b1.Property("City") + .IsRequired() + .HasColumnType("TEXT") + .HasMaxLength(100); + + b1.Property("Country") + .IsRequired() + .HasColumnType("TEXT") + .HasMaxLength(90); + + b1.Property("RecipientName") + .IsRequired() + .HasColumnType("TEXT") + .HasMaxLength(255); + + b1.Property("State") + .HasColumnType("TEXT") + .HasMaxLength(60); + + b1.Property("Street") + .IsRequired() + .HasColumnType("TEXT") + .HasMaxLength(180); + + b1.Property("ZipCode") + .IsRequired() + .HasColumnType("TEXT") + .HasMaxLength(18); + + b1.HasKey("QuoteId"); + + b1.ToTable("Quotes"); + + b1.WithOwner() + .HasForeignKey("QuoteId"); + }); + + b.OwnsOne("Nethereum.eShop.ApplicationCore.Entities.PostalAddress", "ShipTo", b1 => + { + b1.Property("QuoteId") + .HasColumnType("INTEGER"); + + b1.Property("City") + .IsRequired() + .HasColumnType("TEXT") + .HasMaxLength(100); + + b1.Property("Country") + .IsRequired() + .HasColumnType("TEXT") + .HasMaxLength(90); + + b1.Property("RecipientName") + .IsRequired() + .HasColumnType("TEXT") + .HasMaxLength(255); + + b1.Property("State") + .HasColumnType("TEXT") + .HasMaxLength(60); + + b1.Property("Street") + .IsRequired() + .HasColumnType("TEXT") + .HasMaxLength(180); + + b1.Property("ZipCode") + .IsRequired() + .HasColumnType("TEXT") + .HasMaxLength(18); + + b1.HasKey("QuoteId"); + + b1.ToTable("Quotes"); + + b1.WithOwner() + .HasForeignKey("QuoteId"); + }); + }); + + modelBuilder.Entity("Nethereum.eShop.ApplicationCore.Entities.QuoteAggregate.QuoteItem", b => + { + b.HasOne("Nethereum.eShop.ApplicationCore.Entities.QuoteAggregate.Quote", null) + .WithMany("QuoteItems") + .HasForeignKey("QuoteId"); + + b.OwnsOne("Nethereum.eShop.ApplicationCore.Entities.CatalogItemExcerpt", "ItemOrdered", b1 => + { + b1.Property("QuoteItemId") + .HasColumnType("INTEGER"); + + b1.Property("CatalogItemId") + .HasColumnType("INTEGER"); + + b1.Property("Gtin") + .HasColumnType("TEXT") + .HasMaxLength(14); + + b1.Property("GtinRegistryId") + .HasColumnType("INTEGER"); + + b1.Property("PictureUri") + .HasColumnType("TEXT") + .HasMaxLength(512); + + b1.Property("ProductName") + .IsRequired() + .HasColumnType("TEXT") + .HasMaxLength(50); + + b1.HasKey("QuoteItemId"); + + b1.ToTable("QuoteItems"); + + b1.WithOwner() + .HasForeignKey("QuoteItemId"); + }); + }); + + modelBuilder.Entity("Nethereum.eShop.ApplicationCore.Entities.StockItem", b => + { + b.HasOne("Nethereum.eShop.ApplicationCore.Entities.CatalogItem", "CatalogItem") + .WithMany() + .HasForeignKey("CatalogItemId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + }); +#pragma warning restore 612, 618 + } + } +} diff --git a/src/Nethereum.eShop.Sqlite/Catalog/Migrations/20200311172413_BuyerWalletAddress.cs b/src/Nethereum.eShop.Sqlite/Catalog/Migrations/20200311172413_BuyerWalletAddress.cs new file mode 100644 index 0000000..93dccf2 --- /dev/null +++ b/src/Nethereum.eShop.Sqlite/Catalog/Migrations/20200311172413_BuyerWalletAddress.cs @@ -0,0 +1,33 @@ +using Microsoft.EntityFrameworkCore.Migrations; + +namespace Nethereum.eShop.Sqlite.Catalog.Migrations +{ + public partial class BuyerWalletAddress : Migration + { + protected override void Up(MigrationBuilder migrationBuilder) + { + migrationBuilder.AddColumn( + name: "BuyerWalletAddress", + table: "Buyers", + maxLength: 43, + nullable: true); + + migrationBuilder.CreateIndex( + name: "IX_Buyers_BuyerWalletAddress", + table: "Buyers", + column: "BuyerWalletAddress", + unique: true); + } + + protected override void Down(MigrationBuilder migrationBuilder) + { + migrationBuilder.DropIndex( + name: "IX_Buyers_BuyerWalletAddress", + table: "Buyers"); + + migrationBuilder.DropColumn( + name: "BuyerWalletAddress", + table: "Buyers"); + } + } +} diff --git a/src/Nethereum.eShop.Sqlite/Catalog/Migrations/Scripts/CreateCatalogDb.sql b/src/Nethereum.eShop.Sqlite/Catalog/Migrations/Scripts/CreateCatalogDb.sql index 9b5e163..b9296fa 100644 --- a/src/Nethereum.eShop.Sqlite/Catalog/Migrations/Scripts/CreateCatalogDb.sql +++ b/src/Nethereum.eShop.Sqlite/Catalog/Migrations/Scripts/CreateCatalogDb.sql @@ -228,3 +228,10 @@ CREATE INDEX "IX_Stock_CatalogItemId" ON "Stock" ("CatalogItemId"); INSERT INTO "__EFMigrationsHistory" ("MigrationId", "ProductVersion") VALUES ('20200311151703_InitialCreate', '3.1.2'); +ALTER TABLE "Buyers" ADD "BuyerWalletAddress" TEXT NULL; + +CREATE UNIQUE INDEX "IX_Buyers_BuyerWalletAddress" ON "Buyers" ("BuyerWalletAddress"); + +INSERT INTO "__EFMigrationsHistory" ("MigrationId", "ProductVersion") +VALUES ('20200311172413_BuyerWalletAddress', '3.1.2'); + diff --git a/src/Nethereum.eShop.Sqlite/Catalog/Migrations/SqliteCatalogContextModelSnapshot.cs b/src/Nethereum.eShop.Sqlite/Catalog/Migrations/SqliteCatalogContextModelSnapshot.cs index 4b248ed..666095d 100644 --- a/src/Nethereum.eShop.Sqlite/Catalog/Migrations/SqliteCatalogContextModelSnapshot.cs +++ b/src/Nethereum.eShop.Sqlite/Catalog/Migrations/SqliteCatalogContextModelSnapshot.cs @@ -85,6 +85,10 @@ protected override void BuildModel(ModelBuilder modelBuilder) .HasColumnType("TEXT") .HasMaxLength(256); + b.Property("BuyerWalletAddress") + .HasColumnType("TEXT") + .HasMaxLength(43); + b.HasKey("Id"); b.HasIndex("BuyerAddress") @@ -93,6 +97,9 @@ protected override void BuildModel(ModelBuilder modelBuilder) b.HasIndex("BuyerId") .IsUnique(); + b.HasIndex("BuyerWalletAddress") + .IsUnique(); + b.ToTable("Buyers"); }); diff --git a/src/Nethereum.eShop.Sqlite/Identity/Migrations/20200311172419_BuyerWalletAddress.Designer.cs b/src/Nethereum.eShop.Sqlite/Identity/Migrations/20200311172419_BuyerWalletAddress.Designer.cs new file mode 100644 index 0000000..5d5ba8e --- /dev/null +++ b/src/Nethereum.eShop.Sqlite/Identity/Migrations/20200311172419_BuyerWalletAddress.Designer.cs @@ -0,0 +1,266 @@ +// +using System; +using Microsoft.EntityFrameworkCore; +using Microsoft.EntityFrameworkCore.Infrastructure; +using Microsoft.EntityFrameworkCore.Migrations; +using Microsoft.EntityFrameworkCore.Storage.ValueConversion; +using Nethereum.eShop.Sqlite.Identity; + +namespace Nethereum.eShop.Sqlite.Identity.Migrations +{ + [DbContext(typeof(SqliteAppIdentityDbContext))] + [Migration("20200311172419_BuyerWalletAddress")] + partial class BuyerWalletAddress + { + protected override void BuildTargetModel(ModelBuilder modelBuilder) + { +#pragma warning disable 612, 618 + modelBuilder + .HasAnnotation("ProductVersion", "3.1.2"); + + modelBuilder.Entity("Microsoft.AspNetCore.Identity.IdentityRole", b => + { + b.Property("Id") + .HasColumnType("TEXT"); + + b.Property("ConcurrencyStamp") + .IsConcurrencyToken() + .HasColumnType("TEXT"); + + b.Property("Name") + .HasColumnType("TEXT") + .HasMaxLength(256); + + b.Property("NormalizedName") + .HasColumnType("TEXT") + .HasMaxLength(256); + + b.HasKey("Id"); + + b.HasIndex("NormalizedName") + .IsUnique() + .HasName("RoleNameIndex"); + + b.ToTable("AspNetRoles"); + }); + + modelBuilder.Entity("Microsoft.AspNetCore.Identity.IdentityRoleClaim", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("INTEGER"); + + b.Property("ClaimType") + .HasColumnType("TEXT"); + + b.Property("ClaimValue") + .HasColumnType("TEXT"); + + b.Property("RoleId") + .IsRequired() + .HasColumnType("TEXT"); + + b.HasKey("Id"); + + b.HasIndex("RoleId"); + + b.ToTable("AspNetRoleClaims"); + }); + + modelBuilder.Entity("Microsoft.AspNetCore.Identity.IdentityUserClaim", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("INTEGER"); + + b.Property("ClaimType") + .HasColumnType("TEXT"); + + b.Property("ClaimValue") + .HasColumnType("TEXT"); + + b.Property("UserId") + .IsRequired() + .HasColumnType("TEXT"); + + b.HasKey("Id"); + + b.HasIndex("UserId"); + + b.ToTable("AspNetUserClaims"); + }); + + modelBuilder.Entity("Microsoft.AspNetCore.Identity.IdentityUserLogin", b => + { + b.Property("LoginProvider") + .HasColumnType("TEXT"); + + b.Property("ProviderKey") + .HasColumnType("TEXT"); + + b.Property("ProviderDisplayName") + .HasColumnType("TEXT"); + + b.Property("UserId") + .IsRequired() + .HasColumnType("TEXT"); + + b.HasKey("LoginProvider", "ProviderKey"); + + b.HasIndex("UserId"); + + b.ToTable("AspNetUserLogins"); + }); + + modelBuilder.Entity("Microsoft.AspNetCore.Identity.IdentityUserRole", b => + { + b.Property("UserId") + .HasColumnType("TEXT"); + + b.Property("RoleId") + .HasColumnType("TEXT"); + + b.HasKey("UserId", "RoleId"); + + b.HasIndex("RoleId"); + + b.ToTable("AspNetUserRoles"); + }); + + modelBuilder.Entity("Microsoft.AspNetCore.Identity.IdentityUserToken", b => + { + b.Property("UserId") + .HasColumnType("TEXT"); + + b.Property("LoginProvider") + .HasColumnType("TEXT"); + + b.Property("Name") + .HasColumnType("TEXT"); + + b.Property("Value") + .HasColumnType("TEXT"); + + b.HasKey("UserId", "LoginProvider", "Name"); + + b.ToTable("AspNetUserTokens"); + }); + + modelBuilder.Entity("Nethereum.eShop.Infrastructure.Identity.ApplicationUser", b => + { + b.Property("Id") + .HasColumnType("TEXT"); + + b.Property("AccessFailedCount") + .HasColumnType("INTEGER"); + + b.Property("ConcurrencyStamp") + .IsConcurrencyToken() + .HasColumnType("TEXT"); + + b.Property("Email") + .HasColumnType("TEXT") + .HasMaxLength(256); + + b.Property("EmailConfirmed") + .HasColumnType("INTEGER"); + + b.Property("LockoutEnabled") + .HasColumnType("INTEGER"); + + b.Property("LockoutEnd") + .HasColumnType("TEXT"); + + b.Property("NormalizedEmail") + .HasColumnType("TEXT") + .HasMaxLength(256); + + b.Property("NormalizedUserName") + .HasColumnType("TEXT") + .HasMaxLength(256); + + b.Property("PasswordHash") + .HasColumnType("TEXT"); + + b.Property("PhoneNumber") + .HasColumnType("TEXT"); + + b.Property("PhoneNumberConfirmed") + .HasColumnType("INTEGER"); + + b.Property("SecurityStamp") + .HasColumnType("TEXT"); + + b.Property("TwoFactorEnabled") + .HasColumnType("INTEGER"); + + b.Property("UserName") + .HasColumnType("TEXT") + .HasMaxLength(256); + + b.HasKey("Id"); + + b.HasIndex("NormalizedEmail") + .HasName("EmailIndex"); + + b.HasIndex("NormalizedUserName") + .IsUnique() + .HasName("UserNameIndex"); + + b.ToTable("AspNetUsers"); + }); + + modelBuilder.Entity("Microsoft.AspNetCore.Identity.IdentityRoleClaim", b => + { + b.HasOne("Microsoft.AspNetCore.Identity.IdentityRole", null) + .WithMany() + .HasForeignKey("RoleId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + }); + + modelBuilder.Entity("Microsoft.AspNetCore.Identity.IdentityUserClaim", b => + { + b.HasOne("Nethereum.eShop.Infrastructure.Identity.ApplicationUser", null) + .WithMany() + .HasForeignKey("UserId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + }); + + modelBuilder.Entity("Microsoft.AspNetCore.Identity.IdentityUserLogin", b => + { + b.HasOne("Nethereum.eShop.Infrastructure.Identity.ApplicationUser", null) + .WithMany() + .HasForeignKey("UserId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + }); + + modelBuilder.Entity("Microsoft.AspNetCore.Identity.IdentityUserRole", b => + { + b.HasOne("Microsoft.AspNetCore.Identity.IdentityRole", null) + .WithMany() + .HasForeignKey("RoleId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.HasOne("Nethereum.eShop.Infrastructure.Identity.ApplicationUser", null) + .WithMany() + .HasForeignKey("UserId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + }); + + modelBuilder.Entity("Microsoft.AspNetCore.Identity.IdentityUserToken", b => + { + b.HasOne("Nethereum.eShop.Infrastructure.Identity.ApplicationUser", null) + .WithMany() + .HasForeignKey("UserId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + }); +#pragma warning restore 612, 618 + } + } +} diff --git a/src/Nethereum.eShop.Sqlite/Identity/Migrations/20200311172419_BuyerWalletAddress.cs b/src/Nethereum.eShop.Sqlite/Identity/Migrations/20200311172419_BuyerWalletAddress.cs new file mode 100644 index 0000000..a71e2f0 --- /dev/null +++ b/src/Nethereum.eShop.Sqlite/Identity/Migrations/20200311172419_BuyerWalletAddress.cs @@ -0,0 +1,17 @@ +using Microsoft.EntityFrameworkCore.Migrations; + +namespace Nethereum.eShop.Sqlite.Identity.Migrations +{ + public partial class BuyerWalletAddress : Migration + { + protected override void Up(MigrationBuilder migrationBuilder) + { + + } + + protected override void Down(MigrationBuilder migrationBuilder) + { + + } + } +} diff --git a/src/Nethereum.eShop.Sqlite/Identity/Migrations/Scripts/CreateIdentityDb.sql b/src/Nethereum.eShop.Sqlite/Identity/Migrations/Scripts/CreateIdentityDb.sql index 8d5bd1d..6352fc0 100644 --- a/src/Nethereum.eShop.Sqlite/Identity/Migrations/Scripts/CreateIdentityDb.sql +++ b/src/Nethereum.eShop.Sqlite/Identity/Migrations/Scripts/CreateIdentityDb.sql @@ -87,3 +87,6 @@ CREATE UNIQUE INDEX "UserNameIndex" ON "AspNetUsers" ("NormalizedUserName"); INSERT INTO "__EFMigrationsHistory" ("MigrationId", "ProductVersion") VALUES ('20200311151709_InitialCreate', '3.1.2'); +INSERT INTO "__EFMigrationsHistory" ("MigrationId", "ProductVersion") +VALUES ('20200311172419_BuyerWalletAddress', '3.1.2'); + diff --git a/src/Nethereum.eShop/ApplicationCore/Entities/BuyerAggregate/Buyer.cs b/src/Nethereum.eShop/ApplicationCore/Entities/BuyerAggregate/Buyer.cs index 6ddd89b..0c97f42 100644 --- a/src/Nethereum.eShop/ApplicationCore/Entities/BuyerAggregate/Buyer.cs +++ b/src/Nethereum.eShop/ApplicationCore/Entities/BuyerAggregate/Buyer.cs @@ -15,6 +15,8 @@ public class Buyer : BaseEntity, IAggregateRoot // Expected To Be Ethereum Address public string BuyerAddress { get; private set; } + public string BuyerWalletAddress { get; private set; } + private Buyer() { // required by EF @@ -26,5 +28,10 @@ public Buyer(string identity) : this() BuyerId = identity; } + + public void SetWalletAddress(string walletAddress) + { + BuyerWalletAddress = walletAddress; + } } } From fcfd97b8cb1baa10328b74b751d41160a4297a02 Mon Sep 17 00:00:00 2001 From: Dave Whiffin Date: Thu, 12 Mar 2020 12:11:51 +0000 Subject: [PATCH 18/27] Removing unecessary dependencies and updating migration doc. --- docs/eShop-Db-Setup.md | 11 ++++++++--- .../EShopAppIdentityDbBootstrapperBase.cs | 9 ++++++++- .../Nethereum.eShop.EntityFramework.csproj | 2 +- .../AddCatalogMigration.bat | 2 ++ ...AddMigration.bat => AddIdentityMigration.bat} | 2 -- .../ScriptCatalogDb.bat | 2 ++ .../{ScriptDbs.bat => ScriptIdentityDb.bat} | 2 -- .../Entities/RulesEngine/RulesDomainSeed.cs | 6 +++--- .../Interfaces/IEShopIdentityDbBootstrapper.cs | 5 ++++- src/Nethereum.eShop/Nethereum.eShop.csproj | 5 +---- src/Web/Startup.cs | 16 ++++++++-------- src/Web/Web.csproj | 10 +--------- src/WebJobs/Program.cs | 16 ++-------------- src/WebJobs/WebJobs.csproj | 1 - 14 files changed, 40 insertions(+), 49 deletions(-) create mode 100644 src/Nethereum.eShop.Migrations/AddCatalogMigration.bat rename src/Nethereum.eShop.Migrations/{AddMigration.bat => AddIdentityMigration.bat} (50%) create mode 100644 src/Nethereum.eShop.Migrations/ScriptCatalogDb.bat rename src/Nethereum.eShop.Migrations/{ScriptDbs.bat => ScriptIdentityDb.bat} (50%) diff --git a/docs/eShop-Db-Setup.md b/docs/eShop-Db-Setup.md index 3bced88..545002e 100644 --- a/docs/eShop-Db-Setup.md +++ b/docs/eShop-Db-Setup.md @@ -86,16 +86,21 @@ dotnet tool install --global dotnet-ef --version 3.1.2 #### Adding a migration +Batch files which create a named migration for Catalog and Identity for all supported Db Providers. + ``` -AddMigration.bat +AddCatalogMigration.bat +AddIdentityMigration.bat ``` Creates a new migration in each DB provider project. #### Creating Db Scripts +Generates a complete DB creation script for each supported Db Provider for both the Catalog connection and Identity connection. This script can be run manually against the chosen database. + ``` -ScriptDbs.bat +ScriptCatalogDb.bat +ScriptIdentityDb.bat ``` -Generates a complete DB creation script for each supported Db Provider for both the Catalog connection and Identity connection. This script can be run manually against the chosen database. \ No newline at end of file diff --git a/src/Nethereum.eShop.EntityFramework/Identity/EShopAppIdentityDbBootstrapperBase.cs b/src/Nethereum.eShop.EntityFramework/Identity/EShopAppIdentityDbBootstrapperBase.cs index 8f9e300..f56e95a 100644 --- a/src/Nethereum.eShop.EntityFramework/Identity/EShopAppIdentityDbBootstrapperBase.cs +++ b/src/Nethereum.eShop.EntityFramework/Identity/EShopAppIdentityDbBootstrapperBase.cs @@ -1,6 +1,8 @@ -using Microsoft.EntityFrameworkCore; +using Microsoft.AspNetCore.Identity; +using Microsoft.EntityFrameworkCore; using Microsoft.Extensions.Configuration; using Microsoft.Extensions.DependencyInjection; +using Nethereum.eShop.Infrastructure.Identity; using System; using System.Collections.Generic; using System.Text; @@ -25,5 +27,10 @@ protected virtual bool ApplyMigrationsOnStartup(IConfiguration configuration) { return configuration.GetValue("IdentityApplyMigrationsOnStartup", false); } + + public virtual void AddIdentityStores(IdentityBuilder identityBuilder, IServiceCollection services) + { + identityBuilder.AddEntityFrameworkStores(); + } } } diff --git a/src/Nethereum.eShop.EntityFramework/Nethereum.eShop.EntityFramework.csproj b/src/Nethereum.eShop.EntityFramework/Nethereum.eShop.EntityFramework.csproj index b0d940b..63e48af 100644 --- a/src/Nethereum.eShop.EntityFramework/Nethereum.eShop.EntityFramework.csproj +++ b/src/Nethereum.eShop.EntityFramework/Nethereum.eShop.EntityFramework.csproj @@ -9,12 +9,12 @@ + - diff --git a/src/Nethereum.eShop.Migrations/AddCatalogMigration.bat b/src/Nethereum.eShop.Migrations/AddCatalogMigration.bat new file mode 100644 index 0000000..10e6197 --- /dev/null +++ b/src/Nethereum.eShop.Migrations/AddCatalogMigration.bat @@ -0,0 +1,2 @@ +dotnet ef migrations add %1 --project ..\Nethereum.eShop.SqlServer --context Nethereum.eShop.SqlServer.Catalog.SqlServerCatalogContext --output-dir ..\Nethereum.eShop.SqlServer\Catalog\Migrations +dotnet ef migrations add %1 --project ..\Nethereum.eShop.Sqlite --context Nethereum.eShop.Sqlite.Catalog.SqliteCatalogContext --output-dir ..\Nethereum.eShop.Sqlite\Catalog\Migrations \ No newline at end of file diff --git a/src/Nethereum.eShop.Migrations/AddMigration.bat b/src/Nethereum.eShop.Migrations/AddIdentityMigration.bat similarity index 50% rename from src/Nethereum.eShop.Migrations/AddMigration.bat rename to src/Nethereum.eShop.Migrations/AddIdentityMigration.bat index 3097371..6e27901 100644 --- a/src/Nethereum.eShop.Migrations/AddMigration.bat +++ b/src/Nethereum.eShop.Migrations/AddIdentityMigration.bat @@ -1,4 +1,2 @@ -dotnet ef migrations add %1 --project ..\Nethereum.eShop.SqlServer --context Nethereum.eShop.SqlServer.Catalog.SqlServerCatalogContext --output-dir ..\Nethereum.eShop.SqlServer\Catalog\Migrations dotnet ef migrations add %1 --project ..\Nethereum.eShop.SqlServer --context Nethereum.eShop.SqlServer.Identity.SqlServerAppIdentityDbContext --output-dir ..\Nethereum.eShop.SqlServer\Identity\Migrations -dotnet ef migrations add %1 --project ..\Nethereum.eShop.Sqlite --context Nethereum.eShop.Sqlite.Catalog.SqliteCatalogContext --output-dir ..\Nethereum.eShop.Sqlite\Catalog\Migrations dotnet ef migrations add %1 --project ..\Nethereum.eShop.Sqlite --context Nethereum.eShop.Sqlite.Identity.SqliteAppIdentityDbContext --output-dir ..\Nethereum.eShop.Sqlite\Identity\Migrations \ No newline at end of file diff --git a/src/Nethereum.eShop.Migrations/ScriptCatalogDb.bat b/src/Nethereum.eShop.Migrations/ScriptCatalogDb.bat new file mode 100644 index 0000000..dacc0e5 --- /dev/null +++ b/src/Nethereum.eShop.Migrations/ScriptCatalogDb.bat @@ -0,0 +1,2 @@ +dotnet ef migrations script --idempotent --project ..\Nethereum.eShop.SqlServer --context Nethereum.eShop.SqlServer.Catalog.SqlServerCatalogContext --output ..\Nethereum.eShop.SqlServer\Catalog\Migrations\Scripts\CreateCatalogDb.sql +dotnet ef migrations script --project ..\Nethereum.eShop.Sqlite --context Nethereum.eShop.Sqlite.Catalog.SqliteCatalogContext --output ..\Nethereum.eShop.Sqlite\Catalog\Migrations\Scripts\CreateCatalogDb.sql \ No newline at end of file diff --git a/src/Nethereum.eShop.Migrations/ScriptDbs.bat b/src/Nethereum.eShop.Migrations/ScriptIdentityDb.bat similarity index 50% rename from src/Nethereum.eShop.Migrations/ScriptDbs.bat rename to src/Nethereum.eShop.Migrations/ScriptIdentityDb.bat index 10b7b96..7034f4d 100644 --- a/src/Nethereum.eShop.Migrations/ScriptDbs.bat +++ b/src/Nethereum.eShop.Migrations/ScriptIdentityDb.bat @@ -1,4 +1,2 @@ -dotnet ef migrations script --idempotent --project ..\Nethereum.eShop.SqlServer --context Nethereum.eShop.SqlServer.Catalog.SqlServerCatalogContext --output ..\Nethereum.eShop.SqlServer\Catalog\Migrations\Scripts\CreateCatalogDb.sql dotnet ef migrations script --idempotent --project ..\Nethereum.eShop.SqlServer --context Nethereum.eShop.SqlServer.Identity.SqlServerAppIdentityDbContext --output ..\Nethereum.eShop.SqlServer\Identity\Migrations\Scripts\CreateIdentityDb.sql -dotnet ef migrations script --project ..\Nethereum.eShop.Sqlite --context Nethereum.eShop.Sqlite.Catalog.SqliteCatalogContext --output ..\Nethereum.eShop.Sqlite\Catalog\Migrations\Scripts\CreateCatalogDb.sql dotnet ef migrations script --project ..\Nethereum.eShop.Sqlite --context Nethereum.eShop.Sqlite.Identity.SqliteAppIdentityDbContext --output ..\Nethereum.eShop.Sqlite\Identity\Migrations\Scripts\CreateIdentityDb.sql \ No newline at end of file diff --git a/src/Nethereum.eShop/ApplicationCore/Entities/RulesEngine/RulesDomainSeed.cs b/src/Nethereum.eShop/ApplicationCore/Entities/RulesEngine/RulesDomainSeed.cs index 1c88add..d43a549 100644 --- a/src/Nethereum.eShop/ApplicationCore/Entities/RulesEngine/RulesDomainSeed.cs +++ b/src/Nethereum.eShop/ApplicationCore/Entities/RulesEngine/RulesDomainSeed.cs @@ -1,6 +1,6 @@ using System; using System.Collections.Generic; -using System.Data.SqlClient; +using System.Data; namespace Nethereum.eShop.ApplicationCore.Entities.RulesEngine { @@ -11,7 +11,7 @@ public RulesDomainSeed() Init(); } - public RulesDomainSeed(SqlConnection conn, string table, HashSet cols) + public RulesDomainSeed(IDbConnection conn, string table, HashSet cols) { Init(); @@ -29,7 +29,7 @@ public RulesDomainSeed(HashSet types) #region Properties - public SqlConnection Connection { get; protected set; } + public IDbConnection Connection { get; protected set; } public string TargetTable { get; protected set; } diff --git a/src/Nethereum.eShop/ApplicationCore/Interfaces/IEShopIdentityDbBootstrapper.cs b/src/Nethereum.eShop/ApplicationCore/Interfaces/IEShopIdentityDbBootstrapper.cs index 4618d7a..fccda4f 100644 --- a/src/Nethereum.eShop/ApplicationCore/Interfaces/IEShopIdentityDbBootstrapper.cs +++ b/src/Nethereum.eShop/ApplicationCore/Interfaces/IEShopIdentityDbBootstrapper.cs @@ -1,4 +1,5 @@ -using Microsoft.Extensions.Configuration; +using Microsoft.AspNetCore.Identity; +using Microsoft.Extensions.Configuration; using Microsoft.Extensions.DependencyInjection; using System; using System.Threading; @@ -10,6 +11,8 @@ public interface IEShopIdentityDbBootstrapper { void AddDbContext(IServiceCollection services, IConfiguration configuration); + void AddIdentityStores(IdentityBuilder identityBuilder, IServiceCollection services); + Task EnsureCreatedAsync(IServiceProvider serviceProvider, IConfiguration configuration, CancellationToken cancellationToken = default); } } diff --git a/src/Nethereum.eShop/Nethereum.eShop.csproj b/src/Nethereum.eShop/Nethereum.eShop.csproj index f0370e0..7877732 100644 --- a/src/Nethereum.eShop/Nethereum.eShop.csproj +++ b/src/Nethereum.eShop/Nethereum.eShop.csproj @@ -9,14 +9,11 @@ - - - + - diff --git a/src/Web/Startup.cs b/src/Web/Startup.cs index b8ee550..ee9f9d4 100644 --- a/src/Web/Startup.cs +++ b/src/Web/Startup.cs @@ -26,6 +26,7 @@ using System.Collections.Generic; using System.Linq; using System.Net.Mime; +using System.Threading.Tasks; namespace Nethereum.eShop.Web { @@ -54,7 +55,7 @@ public void ConfigureProductionServices(IServiceCollection services) services.AddSingleton(identityDbBootstrapper); identityDbBootstrapper.AddDbContext(services, Configuration); - ConfigureServices(services, dbBootstrapper); + ConfigureServices(services, dbBootstrapper, identityDbBootstrapper); } public void ConfigureTestingServices(IServiceCollection services) @@ -67,11 +68,11 @@ public void ConfigureTestingServices(IServiceCollection services) // This method gets called by the runtime. Use this method to add services to the container. public void ConfigureServices( - IServiceCollection services, IEShopDbBootstrapper dbBootstrapper) + IServiceCollection services, IEShopDbBootstrapper dbBootstrapper, IEShopIdentityDbBootstrapper eShopIdentityDbBootstrapper) { ConfigureCookieSettings(services); - CreateIdentityIfNotCreated(services); + CreateIdentityIfNotCreated(services, eShopIdentityDbBootstrapper); services.AddMediatR(typeof(BasketViewModelService).Assembly); @@ -143,7 +144,7 @@ public void ConfigureServices( _services = services; // used to debug registered services } - private static void CreateIdentityIfNotCreated(IServiceCollection services) + private static void CreateIdentityIfNotCreated(IServiceCollection services, IEShopIdentityDbBootstrapper eShopIdentityDbBootstrapper) { var sp = services.BuildServiceProvider(); using (var scope = sp.CreateScope()) @@ -152,10 +153,9 @@ private static void CreateIdentityIfNotCreated(IServiceCollection services) .GetService>(); if(existingUserManager == null) { - services.AddIdentity() - .AddDefaultUI() - .AddEntityFrameworkStores() - .AddDefaultTokenProviders(); + var builder = services.AddIdentity().AddDefaultUI(); + eShopIdentityDbBootstrapper.AddIdentityStores(builder, services); + builder.AddDefaultTokenProviders(); } } } diff --git a/src/Web/Web.csproj b/src/Web/Web.csproj index ca3c1a3..d71cdbc 100644 --- a/src/Web/Web.csproj +++ b/src/Web/Web.csproj @@ -19,20 +19,12 @@ - - - - - - - all - runtime; build; native; contentfiles; analyzers; buildtransitive - + diff --git a/src/WebJobs/Program.cs b/src/WebJobs/Program.cs index 91fb687..5433077 100644 --- a/src/WebJobs/Program.cs +++ b/src/WebJobs/Program.cs @@ -6,9 +6,7 @@ using Nethereum.BlockchainProcessing.ProgressRepositories; using Nethereum.eShop.ApplicationCore.Interfaces; using Nethereum.eShop.ApplicationCore.Services; -using Nethereum.eShop.InMemory.Infrastructure.Data.Config; -using Nethereum.eShop.Sqlite.Infrastructure.Data.Config; -using Nethereum.eShop.SqlServer.Infrastructure.Data.Config; +using Nethereum.eShop.DbFactory; using Nethereum.eShop.WebJobs.Configuration; using Nethereum.eShop.WebJobs.Jobs; @@ -31,7 +29,7 @@ static void Main(string[] args) services.AddSingleton(eShopConfig); // db - var dbBootstrapper = CreateDbBootstrapper(config); + var dbBootstrapper = EShopDbBootstrapper.CreateDbBootstrapper(config); dbBootstrapper.AddDbContext(services, config); //repositories @@ -94,15 +92,5 @@ static void Main(string[] args) } } - private static IEShopDbBootstrapper CreateDbBootstrapper(IConfiguration configuration) - { - var name = configuration["CatalogDbProvider"]; - return name switch - { - "SqlServer" => new SqlServerEShopDbBootstrapper(), - "Sqlite" => new SqliteEShopDbBootstrapper(), - _ => new InMemoryEShopDbBootrapper() - }; - } } } diff --git a/src/WebJobs/WebJobs.csproj b/src/WebJobs/WebJobs.csproj index 763f33a..9111e34 100644 --- a/src/WebJobs/WebJobs.csproj +++ b/src/WebJobs/WebJobs.csproj @@ -20,7 +20,6 @@ - From 58a78cb3c87dc994d4373ec11643c9cfc9f12a57 Mon Sep 17 00:00:00 2001 From: Dave Whiffin Date: Thu, 12 Mar 2020 12:18:42 +0000 Subject: [PATCH 19/27] Adding ToDo for extra PaginatedResult properties --- src/Nethereum.eShop/ApplicationCore/Queries/PaginatedResult.cs | 1 + 1 file changed, 1 insertion(+) diff --git a/src/Nethereum.eShop/ApplicationCore/Queries/PaginatedResult.cs b/src/Nethereum.eShop/ApplicationCore/Queries/PaginatedResult.cs index cf08532..8560b9f 100644 --- a/src/Nethereum.eShop/ApplicationCore/Queries/PaginatedResult.cs +++ b/src/Nethereum.eShop/ApplicationCore/Queries/PaginatedResult.cs @@ -2,6 +2,7 @@ namespace Nethereum.eShop.ApplicationCore.Queries { + // TODO: Consider adding properties for Item Count, Page Number, Next Index etc public class PaginatedResult where TModel : class { public int Offset { get; private set; } From 268d85ee7b9104b5e8a32f67f98dd095a278028c Mon Sep 17 00:00:00 2001 From: Dave Whiffin Date: Thu, 12 Mar 2020 17:34:57 +0000 Subject: [PATCH 20/27] MySql implementation Plus Fix for CatalogImport caused by BaseEntity Id becoming read only and therefore breaking deserializing from json. --- .../EShopDbBootstrapper.cs | 4 + .../Nethereum.eShop.DbFactory.csproj | 1 + .../Catalog/Seed/CatalogImportDto.cs | 33 +- .../Catalog/Seed/JsonCatalogContextSeeder.cs | 2 + .../AddCatalogMigration _MySql.bat | 1 + .../AddIdentityMigration_MySql.bat | 1 + .../ScriptCatalogDb_MySql.bat | 1 + .../ScriptIdentityDb_MySql.bat | 1 + .../20200312152404_InitialCreate.Designer.cs | 916 ++++++++++++++++++ .../20200312152404_InitialCreate.cs | 458 +++++++++ .../MySqlCatalogContextModelSnapshot.cs | 914 +++++++++++++++++ .../Migrations/Scripts/CreateCatalogDb.sql | 623 ++++++++++++ .../Catalog/MySqlCatalogContext.cs | 31 + .../Catalog/MySqlEShopDbBootstrapper.cs | 32 + .../Catalog/Queries/CatalogQueries.cs | 65 ++ .../Catalog/Queries/OrderQueries.cs | 73 ++ .../Catalog/Queries/QuoteQueries.cs | 73 ++ .../20200312152429_InitialCreate.Designer.cs | 267 +++++ .../20200312152429_InitialCreate.cs | 218 +++++ .../MySqlAppIdentityDbContextModelSnapshot.cs | 265 +++++ .../Migrations/Scripts/CreateIdentityDb.sql | 289 ++++++ .../Identity/MySqlAppIdentityDbContext.cs | 25 + .../MySqlEShopAppIdentityDbBootstrapper.cs | 17 + .../Nethereum.eShop.MySql.csproj | 20 + src/Nethereum.eShop.sln | 7 + src/Web/appsettings.json | 4 +- .../Books.ImportUtil/Books.ImportUtil.csproj | 1 + .../Books.ImportUtil/TopRankBookImportUtil.cs | 17 +- 28 files changed, 4346 insertions(+), 13 deletions(-) create mode 100644 src/Nethereum.eShop.Migrations/AddCatalogMigration _MySql.bat create mode 100644 src/Nethereum.eShop.Migrations/AddIdentityMigration_MySql.bat create mode 100644 src/Nethereum.eShop.Migrations/ScriptCatalogDb_MySql.bat create mode 100644 src/Nethereum.eShop.Migrations/ScriptIdentityDb_MySql.bat create mode 100644 src/Nethereum.eShop.MySql/Catalog/Migrations/20200312152404_InitialCreate.Designer.cs create mode 100644 src/Nethereum.eShop.MySql/Catalog/Migrations/20200312152404_InitialCreate.cs create mode 100644 src/Nethereum.eShop.MySql/Catalog/Migrations/MySqlCatalogContextModelSnapshot.cs create mode 100644 src/Nethereum.eShop.MySql/Catalog/Migrations/Scripts/CreateCatalogDb.sql create mode 100644 src/Nethereum.eShop.MySql/Catalog/MySqlCatalogContext.cs create mode 100644 src/Nethereum.eShop.MySql/Catalog/MySqlEShopDbBootstrapper.cs create mode 100644 src/Nethereum.eShop.MySql/Catalog/Queries/CatalogQueries.cs create mode 100644 src/Nethereum.eShop.MySql/Catalog/Queries/OrderQueries.cs create mode 100644 src/Nethereum.eShop.MySql/Catalog/Queries/QuoteQueries.cs create mode 100644 src/Nethereum.eShop.MySql/Identity/Migrations/20200312152429_InitialCreate.Designer.cs create mode 100644 src/Nethereum.eShop.MySql/Identity/Migrations/20200312152429_InitialCreate.cs create mode 100644 src/Nethereum.eShop.MySql/Identity/Migrations/MySqlAppIdentityDbContextModelSnapshot.cs create mode 100644 src/Nethereum.eShop.MySql/Identity/Migrations/Scripts/CreateIdentityDb.sql create mode 100644 src/Nethereum.eShop.MySql/Identity/MySqlAppIdentityDbContext.cs create mode 100644 src/Nethereum.eShop.MySql/Identity/MySqlEShopAppIdentityDbBootstrapper.cs create mode 100644 src/Nethereum.eShop.MySql/Nethereum.eShop.MySql.csproj diff --git a/src/Nethereum.eShop.DbFactory/EShopDbBootstrapper.cs b/src/Nethereum.eShop.DbFactory/EShopDbBootstrapper.cs index 874d755..35c2d96 100644 --- a/src/Nethereum.eShop.DbFactory/EShopDbBootstrapper.cs +++ b/src/Nethereum.eShop.DbFactory/EShopDbBootstrapper.cs @@ -2,6 +2,8 @@ using Nethereum.eShop.ApplicationCore.Interfaces; using Nethereum.eShop.InMemory.Catalog; using Nethereum.eShop.InMemory.Infrastructure.Identity; +using Nethereum.eShop.MySql.Catalog; +using Nethereum.eShop.MySql.Identity; using Nethereum.eShop.Sqlite.Catalog; using Nethereum.eShop.Sqlite.Identity; using Nethereum.eShop.SqlServer.Catalog; @@ -21,6 +23,7 @@ public static IEShopDbBootstrapper CreateDbBootstrapper(IConfiguration configura { "sqlserver" => new SqlServerEShopDbBootstrapper(), "sqlite" => new SqliteEShopDbBootstrapper(), + "mysql" => new MySqlEShopDbBootstrapper(), _ => new InMemoryEShopDbBootrapper() }; } @@ -32,6 +35,7 @@ public static IEShopIdentityDbBootstrapper CreateAppIdentityDbBootstrapper(IConf { "sqlserver" => new SqlServerEShopAppIdentityDbBootstrapper(), "sqlite" => new SqliteEShopAppIdentityDbBootstrapper(), + "mysql" => new MySqlEShopAppIdentityDbBootstrapper(), _ => new InMemoryEShopAppIdentityDbBootrapper() }; } diff --git a/src/Nethereum.eShop.DbFactory/Nethereum.eShop.DbFactory.csproj b/src/Nethereum.eShop.DbFactory/Nethereum.eShop.DbFactory.csproj index 68760ee..afd993f 100644 --- a/src/Nethereum.eShop.DbFactory/Nethereum.eShop.DbFactory.csproj +++ b/src/Nethereum.eShop.DbFactory/Nethereum.eShop.DbFactory.csproj @@ -6,6 +6,7 @@ + diff --git a/src/Nethereum.eShop.EntityFramework/Catalog/Seed/CatalogImportDto.cs b/src/Nethereum.eShop.EntityFramework/Catalog/Seed/CatalogImportDto.cs index a01ea9b..f14f457 100644 --- a/src/Nethereum.eShop.EntityFramework/Catalog/Seed/CatalogImportDto.cs +++ b/src/Nethereum.eShop.EntityFramework/Catalog/Seed/CatalogImportDto.cs @@ -5,8 +5,35 @@ namespace Nethereum.eShop.EntityFramework.Catalog.Seed { public class CatalogImportDto { - public List CatalogBrands { get; set; } = new List(); - public List CatalogTypes { get; set; } = new List(); - public List CatalogItems { get; set; } = new List(); + public List CatalogBrands { get; set; } = new List(); + public List CatalogTypes { get; set; } = new List(); + public List CatalogItems { get; set; } = new List(); + } + + public class CatalogBrandForImport : CatalogBrand + { + public new int Id + { + get => base.Id; + set => base.Id = value; + } + } + + public class CatalogTypeForImport : CatalogType + { + public new int Id + { + get => base.Id; + set => base.Id = value; + } + } + + public class CatalogItemForImport : CatalogItem + { + public new int Id + { + get => base.Id; + set => base.Id = value; + } } } diff --git a/src/Nethereum.eShop.EntityFramework/Catalog/Seed/JsonCatalogContextSeeder.cs b/src/Nethereum.eShop.EntityFramework/Catalog/Seed/JsonCatalogContextSeeder.cs index 2a35e82..30f2ea4 100644 --- a/src/Nethereum.eShop.EntityFramework/Catalog/Seed/JsonCatalogContextSeeder.cs +++ b/src/Nethereum.eShop.EntityFramework/Catalog/Seed/JsonCatalogContextSeeder.cs @@ -49,6 +49,8 @@ public async Task SeedAsync(ILoggerFactory loggerFactory, int? retry = 0) // if we are not running an in memory db - we may need allow id's to be inserted intead of auto generated // context.Database.ExecuteSqlCommand("SET IDENTITY_INSERT dbo.Students ON"); + var dictionary = importData.CatalogBrands.ToDictionary(b => b.Brand, b => b.Id); + if (!catalogContext.CatalogBrands.Any()) { catalogContext.CatalogBrands.AddRange( diff --git a/src/Nethereum.eShop.Migrations/AddCatalogMigration _MySql.bat b/src/Nethereum.eShop.Migrations/AddCatalogMigration _MySql.bat new file mode 100644 index 0000000..109e774 --- /dev/null +++ b/src/Nethereum.eShop.Migrations/AddCatalogMigration _MySql.bat @@ -0,0 +1 @@ +dotnet ef migrations add %1 --project ..\Nethereum.eShop.MySql --context Nethereum.eShop.MySql.Catalog.MySqlCatalogContext --output-dir ..\Nethereum.eShop.MySql\Catalog\Migrations \ No newline at end of file diff --git a/src/Nethereum.eShop.Migrations/AddIdentityMigration_MySql.bat b/src/Nethereum.eShop.Migrations/AddIdentityMigration_MySql.bat new file mode 100644 index 0000000..1015452 --- /dev/null +++ b/src/Nethereum.eShop.Migrations/AddIdentityMigration_MySql.bat @@ -0,0 +1 @@ +dotnet ef migrations add %1 --project ..\Nethereum.eShop.MySql --context Nethereum.eShop.MySql.Identity.MySqlAppIdentityDbContext --output-dir ..\Nethereum.eShop.MySql\Identity\Migrations \ No newline at end of file diff --git a/src/Nethereum.eShop.Migrations/ScriptCatalogDb_MySql.bat b/src/Nethereum.eShop.Migrations/ScriptCatalogDb_MySql.bat new file mode 100644 index 0000000..b3a23b4 --- /dev/null +++ b/src/Nethereum.eShop.Migrations/ScriptCatalogDb_MySql.bat @@ -0,0 +1 @@ +dotnet ef migrations script --idempotent --project ..\Nethereum.eShop.MySql --context Nethereum.eShop.MySql.Catalog.MySqlCatalogContext --output ..\Nethereum.eShop.MySql\Catalog\Migrations\Scripts\CreateCatalogDb.sql \ No newline at end of file diff --git a/src/Nethereum.eShop.Migrations/ScriptIdentityDb_MySql.bat b/src/Nethereum.eShop.Migrations/ScriptIdentityDb_MySql.bat new file mode 100644 index 0000000..15e01cd --- /dev/null +++ b/src/Nethereum.eShop.Migrations/ScriptIdentityDb_MySql.bat @@ -0,0 +1 @@ +dotnet ef migrations script --idempotent --project ..\Nethereum.eShop.MySql --context Nethereum.eShop.MySql.Identity.MySqlAppIdentityDbContext --output ..\Nethereum.eShop.MySql\Identity\Migrations\Scripts\CreateIdentityDb.sql \ No newline at end of file diff --git a/src/Nethereum.eShop.MySql/Catalog/Migrations/20200312152404_InitialCreate.Designer.cs b/src/Nethereum.eShop.MySql/Catalog/Migrations/20200312152404_InitialCreate.Designer.cs new file mode 100644 index 0000000..3314808 --- /dev/null +++ b/src/Nethereum.eShop.MySql/Catalog/Migrations/20200312152404_InitialCreate.Designer.cs @@ -0,0 +1,916 @@ +// +using System; +using Microsoft.EntityFrameworkCore; +using Microsoft.EntityFrameworkCore.Infrastructure; +using Microsoft.EntityFrameworkCore.Migrations; +using Microsoft.EntityFrameworkCore.Storage.ValueConversion; +using Nethereum.eShop.MySql.Catalog; + +namespace Nethereum.eShop.MySql.Catalog.Migrations +{ + [DbContext(typeof(MySqlCatalogContext))] + [Migration("20200312152404_InitialCreate")] + partial class InitialCreate + { + protected override void BuildTargetModel(ModelBuilder modelBuilder) + { +#pragma warning disable 612, 618 + modelBuilder + .HasAnnotation("ProductVersion", "3.1.2") + .HasAnnotation("Relational:MaxIdentifierLength", 64); + + modelBuilder.Entity("Nethereum.eShop.ApplicationCore.Entities.BasketAggregate.Basket", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("int"); + + b.Property("BuyerAddress") + .IsRequired() + .HasColumnType("varchar(43) CHARACTER SET utf8mb4") + .HasMaxLength(43); + + b.Property("BuyerId") + .IsRequired() + .HasColumnType("varchar(256) CHARACTER SET utf8mb4") + .HasMaxLength(256); + + b.Property("TransactionHash") + .HasColumnType("varchar(67) CHARACTER SET utf8mb4") + .HasMaxLength(67); + + b.HasKey("Id"); + + b.HasIndex("BuyerAddress"); + + b.HasIndex("BuyerId"); + + b.ToTable("Baskets"); + }); + + modelBuilder.Entity("Nethereum.eShop.ApplicationCore.Entities.BasketAggregate.BasketItem", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("int"); + + b.Property("BasketId") + .HasColumnType("int"); + + b.Property("CatalogItemId") + .HasColumnType("int"); + + b.Property("Quantity") + .HasColumnType("int"); + + b.Property("UnitPrice") + .HasColumnType("decimal(18,2)"); + + b.HasKey("Id"); + + b.HasIndex("BasketId"); + + b.ToTable("BasketItems"); + }); + + modelBuilder.Entity("Nethereum.eShop.ApplicationCore.Entities.BuyerAggregate.Buyer", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("int"); + + b.Property("BuyerAddress") + .HasColumnType("varchar(43) CHARACTER SET utf8mb4") + .HasMaxLength(43); + + b.Property("BuyerId") + .IsRequired() + .HasColumnType("varchar(256) CHARACTER SET utf8mb4") + .HasMaxLength(256); + + b.Property("BuyerWalletAddress") + .HasColumnType("varchar(43) CHARACTER SET utf8mb4") + .HasMaxLength(43); + + b.HasKey("Id"); + + b.HasIndex("BuyerAddress") + .IsUnique(); + + b.HasIndex("BuyerId") + .IsUnique(); + + b.HasIndex("BuyerWalletAddress") + .IsUnique(); + + b.ToTable("Buyers"); + }); + + modelBuilder.Entity("Nethereum.eShop.ApplicationCore.Entities.BuyerAggregate.BuyerPostalAddress", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("int"); + + b.Property("BuyerId") + .HasColumnType("int"); + + b.Property("Name") + .HasColumnType("longtext CHARACTER SET utf8mb4"); + + b.HasKey("Id"); + + b.HasIndex("BuyerId"); + + b.ToTable("BuyerPostalAddress"); + }); + + modelBuilder.Entity("Nethereum.eShop.ApplicationCore.Entities.CatalogBrand", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("int"); + + b.Property("Brand") + .IsRequired() + .HasColumnType("varchar(100) CHARACTER SET utf8mb4") + .HasMaxLength(100); + + b.HasKey("Id"); + + b.ToTable("CatalogBrands"); + }); + + modelBuilder.Entity("Nethereum.eShop.ApplicationCore.Entities.CatalogItem", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("int"); + + b.Property("AttributeJson") + .HasColumnType("longtext CHARACTER SET utf8mb4"); + + b.Property("CatalogBrandId") + .HasColumnType("int"); + + b.Property("CatalogTypeId") + .HasColumnType("int"); + + b.Property("Depth") + .HasColumnType("int"); + + b.Property("Description") + .HasColumnType("longtext CHARACTER SET utf8mb4"); + + b.Property("Gtin") + .IsRequired() + .HasColumnType("varchar(14) CHARACTER SET utf8mb4") + .HasMaxLength(14); + + b.Property("GtinRegistryId") + .HasColumnType("int"); + + b.Property("Height") + .HasColumnType("int"); + + b.Property("Name") + .IsRequired() + .HasColumnType("varchar(50) CHARACTER SET utf8mb4") + .HasMaxLength(50); + + b.Property("PictureLargeUri") + .HasColumnType("varchar(512) CHARACTER SET utf8mb4") + .HasMaxLength(512); + + b.Property("PictureMediumUri") + .HasColumnType("varchar(512) CHARACTER SET utf8mb4") + .HasMaxLength(512); + + b.Property("PictureSmallUri") + .HasColumnType("varchar(512) CHARACTER SET utf8mb4") + .HasMaxLength(512); + + b.Property("PictureUri") + .HasColumnType("varchar(512) CHARACTER SET utf8mb4") + .HasMaxLength(512); + + b.Property("Price") + .HasColumnType("decimal(18,2)"); + + b.Property("Rank") + .HasColumnType("int"); + + b.Property("Status") + .HasColumnType("int"); + + b.Property("Unit") + .HasColumnType("varchar(8) CHARACTER SET utf8mb4") + .HasMaxLength(8); + + b.Property("Weight") + .HasColumnType("int"); + + b.Property("Width") + .HasColumnType("int"); + + b.HasKey("Id"); + + b.HasIndex("CatalogBrandId"); + + b.HasIndex("CatalogTypeId"); + + b.ToTable("Catalog"); + }); + + modelBuilder.Entity("Nethereum.eShop.ApplicationCore.Entities.CatalogType", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("int"); + + b.Property("Type") + .IsRequired() + .HasColumnType("varchar(100) CHARACTER SET utf8mb4") + .HasMaxLength(100); + + b.HasKey("Id"); + + b.ToTable("CatalogTypes"); + }); + + modelBuilder.Entity("Nethereum.eShop.ApplicationCore.Entities.OrderAggregate.Order", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("int"); + + b.Property("ApproverAddress") + .HasColumnType("varchar(43) CHARACTER SET utf8mb4") + .HasMaxLength(43); + + b.Property("BuyerAddress") + .HasColumnType("varchar(43) CHARACTER SET utf8mb4") + .HasMaxLength(43); + + b.Property("BuyerId") + .IsRequired() + .HasColumnType("varchar(256) CHARACTER SET utf8mb4") + .HasMaxLength(256); + + b.Property("BuyerWalletAddress") + .HasColumnType("varchar(43) CHARACTER SET utf8mb4") + .HasMaxLength(43); + + b.Property("CurrencyAddress") + .HasColumnType("varchar(43) CHARACTER SET utf8mb4") + .HasMaxLength(43); + + b.Property("CurrencySymbol") + .HasColumnType("varchar(32) CHARACTER SET utf8mb4") + .HasMaxLength(32); + + b.Property("OrderDate") + .HasColumnType("datetime(6)"); + + b.Property("PoDate") + .HasColumnType("datetime(6)"); + + b.Property("PoNumber") + .HasColumnType("bigint"); + + b.Property("PoType") + .HasColumnType("int"); + + b.Property("QuoteId") + .HasColumnType("int"); + + b.Property("SellerId") + .HasColumnType("varchar(32) CHARACTER SET utf8mb4") + .HasMaxLength(32); + + b.Property("Status") + .HasColumnType("int"); + + b.Property("TransactionHash") + .HasColumnType("varchar(67) CHARACTER SET utf8mb4") + .HasMaxLength(67); + + b.HasKey("Id"); + + b.HasIndex("BuyerAddress"); + + b.HasIndex("BuyerId"); + + b.ToTable("Orders"); + }); + + modelBuilder.Entity("Nethereum.eShop.ApplicationCore.Entities.OrderAggregate.OrderItem", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("int"); + + b.Property("ActualEscrowReleaseDate") + .HasColumnType("datetime(6)"); + + b.Property("CurrencyValue") + .HasColumnType("varchar(100) CHARACTER SET utf8mb4") + .HasMaxLength(100); + + b.Property("GoodsIssueDate") + .HasColumnType("datetime(6)"); + + b.Property("IsEscrowReleased") + .HasColumnType("tinyint(1)"); + + b.Property("OrderId") + .HasColumnType("int"); + + b.Property("PlannedEscrowReleaseDate") + .HasColumnType("datetime(6)"); + + b.Property("PoItemNumber") + .HasColumnType("int"); + + b.Property("PoItemStatus") + .HasColumnType("int"); + + b.Property("Quantity") + .HasColumnType("int"); + + b.Property("QuantityAddress") + .HasColumnType("varchar(43) CHARACTER SET utf8mb4") + .HasMaxLength(43); + + b.Property("QuantitySymbol") + .HasColumnType("varchar(32) CHARACTER SET utf8mb4") + .HasMaxLength(32); + + b.Property("Status") + .HasColumnType("int"); + + b.Property("Unit") + .HasColumnType("varchar(50) CHARACTER SET utf8mb4") + .HasMaxLength(50); + + b.Property("UnitPrice") + .HasColumnType("decimal(18,2)"); + + b.HasKey("Id"); + + b.HasIndex("OrderId"); + + b.ToTable("OrderItems"); + }); + + modelBuilder.Entity("Nethereum.eShop.ApplicationCore.Entities.QuoteAggregate.Quote", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("int"); + + b.Property("ApproverAddress") + .HasColumnType("varchar(43) CHARACTER SET utf8mb4") + .HasMaxLength(43); + + b.Property("BuyerAddress") + .HasColumnType("varchar(43) CHARACTER SET utf8mb4") + .HasMaxLength(43); + + b.Property("BuyerId") + .IsRequired() + .HasColumnType("varchar(256) CHARACTER SET utf8mb4") + .HasMaxLength(256); + + b.Property("BuyerWalletAddress") + .HasColumnType("varchar(43) CHARACTER SET utf8mb4") + .HasMaxLength(43); + + b.Property("CurrencyAddress") + .HasColumnType("varchar(43) CHARACTER SET utf8mb4") + .HasMaxLength(43); + + b.Property("CurrencySymbol") + .HasColumnType("varchar(32) CHARACTER SET utf8mb4") + .HasMaxLength(32); + + b.Property("Date") + .HasColumnType("datetime(6)"); + + b.Property("Expiry") + .HasColumnType("datetime(6)"); + + b.Property("PoNumber") + .HasColumnType("bigint"); + + b.Property("PoType") + .HasColumnType("int"); + + b.Property("SellerId") + .HasColumnType("varchar(32) CHARACTER SET utf8mb4") + .HasMaxLength(32); + + b.Property("Status") + .HasColumnType("int"); + + b.Property("TransactionHash") + .HasColumnType("varchar(67) CHARACTER SET utf8mb4") + .HasMaxLength(67); + + b.HasKey("Id"); + + b.HasIndex("BuyerAddress"); + + b.HasIndex("BuyerId"); + + b.ToTable("Quotes"); + }); + + modelBuilder.Entity("Nethereum.eShop.ApplicationCore.Entities.QuoteAggregate.QuoteItem", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("int"); + + b.Property("CurrencyValue") + .HasColumnType("longtext CHARACTER SET utf8mb4"); + + b.Property("EscrowReleaseDate") + .HasColumnType("datetime(6)"); + + b.Property("PoItemNumber") + .HasColumnType("int"); + + b.Property("Quantity") + .HasColumnType("int"); + + b.Property("QuantityAddress") + .HasColumnType("longtext CHARACTER SET utf8mb4"); + + b.Property("QuantitySymbol") + .HasColumnType("longtext CHARACTER SET utf8mb4"); + + b.Property("QuoteId") + .HasColumnType("int"); + + b.Property("Unit") + .HasColumnType("longtext CHARACTER SET utf8mb4"); + + b.Property("UnitPrice") + .HasColumnType("decimal(18,2)"); + + b.HasKey("Id"); + + b.HasIndex("QuoteId"); + + b.ToTable("QuoteItems"); + }); + + modelBuilder.Entity("Nethereum.eShop.ApplicationCore.Entities.StockItem", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("int"); + + b.Property("CatalogItemId") + .HasColumnType("int"); + + b.Property("Location") + .IsRequired() + .HasColumnType("varchar(50) CHARACTER SET utf8mb4") + .HasMaxLength(50); + + b.Property("Quantity") + .HasColumnType("int"); + + b.HasKey("Id"); + + b.HasIndex("CatalogItemId"); + + b.ToTable("Stock"); + }); + + modelBuilder.Entity("Nethereum.eShop.ApplicationCore.Entities.BasketAggregate.Basket", b => + { + b.OwnsOne("Nethereum.eShop.ApplicationCore.Entities.PostalAddress", "BillTo", b1 => + { + b1.Property("BasketId") + .HasColumnType("int"); + + b1.Property("City") + .IsRequired() + .HasColumnType("varchar(100) CHARACTER SET utf8mb4") + .HasMaxLength(100); + + b1.Property("Country") + .IsRequired() + .HasColumnType("varchar(90) CHARACTER SET utf8mb4") + .HasMaxLength(90); + + b1.Property("RecipientName") + .IsRequired() + .HasColumnType("varchar(255) CHARACTER SET utf8mb4") + .HasMaxLength(255); + + b1.Property("State") + .HasColumnType("varchar(60) CHARACTER SET utf8mb4") + .HasMaxLength(60); + + b1.Property("Street") + .IsRequired() + .HasColumnType("varchar(180) CHARACTER SET utf8mb4") + .HasMaxLength(180); + + b1.Property("ZipCode") + .IsRequired() + .HasColumnType("varchar(18) CHARACTER SET utf8mb4") + .HasMaxLength(18); + + b1.HasKey("BasketId"); + + b1.ToTable("Baskets"); + + b1.WithOwner() + .HasForeignKey("BasketId"); + }); + + b.OwnsOne("Nethereum.eShop.ApplicationCore.Entities.PostalAddress", "ShipTo", b1 => + { + b1.Property("BasketId") + .HasColumnType("int"); + + b1.Property("City") + .IsRequired() + .HasColumnType("varchar(100) CHARACTER SET utf8mb4") + .HasMaxLength(100); + + b1.Property("Country") + .IsRequired() + .HasColumnType("varchar(90) CHARACTER SET utf8mb4") + .HasMaxLength(90); + + b1.Property("RecipientName") + .IsRequired() + .HasColumnType("varchar(255) CHARACTER SET utf8mb4") + .HasMaxLength(255); + + b1.Property("State") + .HasColumnType("varchar(60) CHARACTER SET utf8mb4") + .HasMaxLength(60); + + b1.Property("Street") + .IsRequired() + .HasColumnType("varchar(180) CHARACTER SET utf8mb4") + .HasMaxLength(180); + + b1.Property("ZipCode") + .IsRequired() + .HasColumnType("varchar(18) CHARACTER SET utf8mb4") + .HasMaxLength(18); + + b1.HasKey("BasketId"); + + b1.ToTable("Baskets"); + + b1.WithOwner() + .HasForeignKey("BasketId"); + }); + }); + + modelBuilder.Entity("Nethereum.eShop.ApplicationCore.Entities.BasketAggregate.BasketItem", b => + { + b.HasOne("Nethereum.eShop.ApplicationCore.Entities.BasketAggregate.Basket", null) + .WithMany("Items") + .HasForeignKey("BasketId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + }); + + modelBuilder.Entity("Nethereum.eShop.ApplicationCore.Entities.BuyerAggregate.BuyerPostalAddress", b => + { + b.HasOne("Nethereum.eShop.ApplicationCore.Entities.BuyerAggregate.Buyer", null) + .WithMany("PostalAddresses") + .HasForeignKey("BuyerId"); + + b.OwnsOne("Nethereum.eShop.ApplicationCore.Entities.PostalAddress", "PostalAddress", b1 => + { + b1.Property("BuyerPostalAddressId") + .HasColumnType("int"); + + b1.Property("City") + .IsRequired() + .HasColumnType("varchar(100) CHARACTER SET utf8mb4") + .HasMaxLength(100); + + b1.Property("Country") + .IsRequired() + .HasColumnType("varchar(90) CHARACTER SET utf8mb4") + .HasMaxLength(90); + + b1.Property("RecipientName") + .IsRequired() + .HasColumnType("varchar(255) CHARACTER SET utf8mb4") + .HasMaxLength(255); + + b1.Property("State") + .HasColumnType("varchar(60) CHARACTER SET utf8mb4") + .HasMaxLength(60); + + b1.Property("Street") + .IsRequired() + .HasColumnType("varchar(180) CHARACTER SET utf8mb4") + .HasMaxLength(180); + + b1.Property("ZipCode") + .IsRequired() + .HasColumnType("varchar(18) CHARACTER SET utf8mb4") + .HasMaxLength(18); + + b1.HasKey("BuyerPostalAddressId"); + + b1.ToTable("BuyerPostalAddress"); + + b1.WithOwner() + .HasForeignKey("BuyerPostalAddressId"); + }); + }); + + modelBuilder.Entity("Nethereum.eShop.ApplicationCore.Entities.CatalogItem", b => + { + b.HasOne("Nethereum.eShop.ApplicationCore.Entities.CatalogBrand", "CatalogBrand") + .WithMany() + .HasForeignKey("CatalogBrandId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.HasOne("Nethereum.eShop.ApplicationCore.Entities.CatalogType", "CatalogType") + .WithMany() + .HasForeignKey("CatalogTypeId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + }); + + modelBuilder.Entity("Nethereum.eShop.ApplicationCore.Entities.OrderAggregate.Order", b => + { + b.OwnsOne("Nethereum.eShop.ApplicationCore.Entities.PostalAddress", "BillTo", b1 => + { + b1.Property("OrderId") + .HasColumnType("int"); + + b1.Property("City") + .IsRequired() + .HasColumnType("varchar(100) CHARACTER SET utf8mb4") + .HasMaxLength(100); + + b1.Property("Country") + .IsRequired() + .HasColumnType("varchar(90) CHARACTER SET utf8mb4") + .HasMaxLength(90); + + b1.Property("RecipientName") + .IsRequired() + .HasColumnType("varchar(255) CHARACTER SET utf8mb4") + .HasMaxLength(255); + + b1.Property("State") + .HasColumnType("varchar(60) CHARACTER SET utf8mb4") + .HasMaxLength(60); + + b1.Property("Street") + .IsRequired() + .HasColumnType("varchar(180) CHARACTER SET utf8mb4") + .HasMaxLength(180); + + b1.Property("ZipCode") + .IsRequired() + .HasColumnType("varchar(18) CHARACTER SET utf8mb4") + .HasMaxLength(18); + + b1.HasKey("OrderId"); + + b1.ToTable("Orders"); + + b1.WithOwner() + .HasForeignKey("OrderId"); + }); + + b.OwnsOne("Nethereum.eShop.ApplicationCore.Entities.PostalAddress", "ShipTo", b1 => + { + b1.Property("OrderId") + .HasColumnType("int"); + + b1.Property("City") + .IsRequired() + .HasColumnType("varchar(100) CHARACTER SET utf8mb4") + .HasMaxLength(100); + + b1.Property("Country") + .IsRequired() + .HasColumnType("varchar(90) CHARACTER SET utf8mb4") + .HasMaxLength(90); + + b1.Property("RecipientName") + .IsRequired() + .HasColumnType("varchar(255) CHARACTER SET utf8mb4") + .HasMaxLength(255); + + b1.Property("State") + .HasColumnType("varchar(60) CHARACTER SET utf8mb4") + .HasMaxLength(60); + + b1.Property("Street") + .IsRequired() + .HasColumnType("varchar(180) CHARACTER SET utf8mb4") + .HasMaxLength(180); + + b1.Property("ZipCode") + .IsRequired() + .HasColumnType("varchar(18) CHARACTER SET utf8mb4") + .HasMaxLength(18); + + b1.HasKey("OrderId"); + + b1.ToTable("Orders"); + + b1.WithOwner() + .HasForeignKey("OrderId"); + }); + }); + + modelBuilder.Entity("Nethereum.eShop.ApplicationCore.Entities.OrderAggregate.OrderItem", b => + { + b.HasOne("Nethereum.eShop.ApplicationCore.Entities.OrderAggregate.Order", null) + .WithMany("OrderItems") + .HasForeignKey("OrderId"); + + b.OwnsOne("Nethereum.eShop.ApplicationCore.Entities.CatalogItemExcerpt", "ItemOrdered", b1 => + { + b1.Property("OrderItemId") + .HasColumnType("int"); + + b1.Property("CatalogItemId") + .HasColumnType("int"); + + b1.Property("Gtin") + .HasColumnType("varchar(14) CHARACTER SET utf8mb4") + .HasMaxLength(14); + + b1.Property("GtinRegistryId") + .HasColumnType("int"); + + b1.Property("PictureUri") + .HasColumnType("varchar(512) CHARACTER SET utf8mb4") + .HasMaxLength(512); + + b1.Property("ProductName") + .IsRequired() + .HasColumnType("varchar(50) CHARACTER SET utf8mb4") + .HasMaxLength(50); + + b1.HasKey("OrderItemId"); + + b1.ToTable("OrderItems"); + + b1.WithOwner() + .HasForeignKey("OrderItemId"); + }); + }); + + modelBuilder.Entity("Nethereum.eShop.ApplicationCore.Entities.QuoteAggregate.Quote", b => + { + b.OwnsOne("Nethereum.eShop.ApplicationCore.Entities.PostalAddress", "BillTo", b1 => + { + b1.Property("QuoteId") + .HasColumnType("int"); + + b1.Property("City") + .IsRequired() + .HasColumnType("varchar(100) CHARACTER SET utf8mb4") + .HasMaxLength(100); + + b1.Property("Country") + .IsRequired() + .HasColumnType("varchar(90) CHARACTER SET utf8mb4") + .HasMaxLength(90); + + b1.Property("RecipientName") + .IsRequired() + .HasColumnType("varchar(255) CHARACTER SET utf8mb4") + .HasMaxLength(255); + + b1.Property("State") + .HasColumnType("varchar(60) CHARACTER SET utf8mb4") + .HasMaxLength(60); + + b1.Property("Street") + .IsRequired() + .HasColumnType("varchar(180) CHARACTER SET utf8mb4") + .HasMaxLength(180); + + b1.Property("ZipCode") + .IsRequired() + .HasColumnType("varchar(18) CHARACTER SET utf8mb4") + .HasMaxLength(18); + + b1.HasKey("QuoteId"); + + b1.ToTable("Quotes"); + + b1.WithOwner() + .HasForeignKey("QuoteId"); + }); + + b.OwnsOne("Nethereum.eShop.ApplicationCore.Entities.PostalAddress", "ShipTo", b1 => + { + b1.Property("QuoteId") + .HasColumnType("int"); + + b1.Property("City") + .IsRequired() + .HasColumnType("varchar(100) CHARACTER SET utf8mb4") + .HasMaxLength(100); + + b1.Property("Country") + .IsRequired() + .HasColumnType("varchar(90) CHARACTER SET utf8mb4") + .HasMaxLength(90); + + b1.Property("RecipientName") + .IsRequired() + .HasColumnType("varchar(255) CHARACTER SET utf8mb4") + .HasMaxLength(255); + + b1.Property("State") + .HasColumnType("varchar(60) CHARACTER SET utf8mb4") + .HasMaxLength(60); + + b1.Property("Street") + .IsRequired() + .HasColumnType("varchar(180) CHARACTER SET utf8mb4") + .HasMaxLength(180); + + b1.Property("ZipCode") + .IsRequired() + .HasColumnType("varchar(18) CHARACTER SET utf8mb4") + .HasMaxLength(18); + + b1.HasKey("QuoteId"); + + b1.ToTable("Quotes"); + + b1.WithOwner() + .HasForeignKey("QuoteId"); + }); + }); + + modelBuilder.Entity("Nethereum.eShop.ApplicationCore.Entities.QuoteAggregate.QuoteItem", b => + { + b.HasOne("Nethereum.eShop.ApplicationCore.Entities.QuoteAggregate.Quote", null) + .WithMany("QuoteItems") + .HasForeignKey("QuoteId"); + + b.OwnsOne("Nethereum.eShop.ApplicationCore.Entities.CatalogItemExcerpt", "ItemOrdered", b1 => + { + b1.Property("QuoteItemId") + .HasColumnType("int"); + + b1.Property("CatalogItemId") + .HasColumnType("int"); + + b1.Property("Gtin") + .HasColumnType("varchar(14) CHARACTER SET utf8mb4") + .HasMaxLength(14); + + b1.Property("GtinRegistryId") + .HasColumnType("int"); + + b1.Property("PictureUri") + .HasColumnType("varchar(512) CHARACTER SET utf8mb4") + .HasMaxLength(512); + + b1.Property("ProductName") + .IsRequired() + .HasColumnType("varchar(50) CHARACTER SET utf8mb4") + .HasMaxLength(50); + + b1.HasKey("QuoteItemId"); + + b1.ToTable("QuoteItems"); + + b1.WithOwner() + .HasForeignKey("QuoteItemId"); + }); + }); + + modelBuilder.Entity("Nethereum.eShop.ApplicationCore.Entities.StockItem", b => + { + b.HasOne("Nethereum.eShop.ApplicationCore.Entities.CatalogItem", "CatalogItem") + .WithMany() + .HasForeignKey("CatalogItemId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + }); +#pragma warning restore 612, 618 + } + } +} diff --git a/src/Nethereum.eShop.MySql/Catalog/Migrations/20200312152404_InitialCreate.cs b/src/Nethereum.eShop.MySql/Catalog/Migrations/20200312152404_InitialCreate.cs new file mode 100644 index 0000000..d6cab2d --- /dev/null +++ b/src/Nethereum.eShop.MySql/Catalog/Migrations/20200312152404_InitialCreate.cs @@ -0,0 +1,458 @@ +using System; +using Microsoft.EntityFrameworkCore.Metadata; +using Microsoft.EntityFrameworkCore.Migrations; + +namespace Nethereum.eShop.MySql.Catalog.Migrations +{ + public partial class InitialCreate : Migration + { + protected override void Up(MigrationBuilder migrationBuilder) + { + migrationBuilder.CreateTable( + name: "Baskets", + columns: table => new + { + Id = table.Column(nullable: false) + .Annotation("MySql:ValueGenerationStrategy", MySqlValueGenerationStrategy.IdentityColumn), + BuyerId = table.Column(maxLength: 256, nullable: false), + BuyerAddress = table.Column(maxLength: 43, nullable: false), + BillTo_RecipientName = table.Column(maxLength: 255, nullable: true), + BillTo_Street = table.Column(maxLength: 180, nullable: true), + BillTo_City = table.Column(maxLength: 100, nullable: true), + BillTo_State = table.Column(maxLength: 60, nullable: true), + BillTo_Country = table.Column(maxLength: 90, nullable: true), + BillTo_ZipCode = table.Column(maxLength: 18, nullable: true), + ShipTo_RecipientName = table.Column(maxLength: 255, nullable: true), + ShipTo_Street = table.Column(maxLength: 180, nullable: true), + ShipTo_City = table.Column(maxLength: 100, nullable: true), + ShipTo_State = table.Column(maxLength: 60, nullable: true), + ShipTo_Country = table.Column(maxLength: 90, nullable: true), + ShipTo_ZipCode = table.Column(maxLength: 18, nullable: true), + TransactionHash = table.Column(maxLength: 67, nullable: true) + }, + constraints: table => + { + table.PrimaryKey("PK_Baskets", x => x.Id); + }); + + migrationBuilder.CreateTable( + name: "Buyers", + columns: table => new + { + Id = table.Column(nullable: false) + .Annotation("MySql:ValueGenerationStrategy", MySqlValueGenerationStrategy.IdentityColumn), + BuyerId = table.Column(maxLength: 256, nullable: false), + BuyerAddress = table.Column(maxLength: 43, nullable: true), + BuyerWalletAddress = table.Column(maxLength: 43, nullable: true) + }, + constraints: table => + { + table.PrimaryKey("PK_Buyers", x => x.Id); + }); + + migrationBuilder.CreateTable( + name: "CatalogBrands", + columns: table => new + { + Id = table.Column(nullable: false) + .Annotation("MySql:ValueGenerationStrategy", MySqlValueGenerationStrategy.IdentityColumn), + Brand = table.Column(maxLength: 100, nullable: false) + }, + constraints: table => + { + table.PrimaryKey("PK_CatalogBrands", x => x.Id); + }); + + migrationBuilder.CreateTable( + name: "CatalogTypes", + columns: table => new + { + Id = table.Column(nullable: false) + .Annotation("MySql:ValueGenerationStrategy", MySqlValueGenerationStrategy.IdentityColumn), + Type = table.Column(maxLength: 100, nullable: false) + }, + constraints: table => + { + table.PrimaryKey("PK_CatalogTypes", x => x.Id); + }); + + migrationBuilder.CreateTable( + name: "Orders", + columns: table => new + { + Id = table.Column(nullable: false) + .Annotation("MySql:ValueGenerationStrategy", MySqlValueGenerationStrategy.IdentityColumn), + QuoteId = table.Column(nullable: true), + Status = table.Column(nullable: false), + TransactionHash = table.Column(maxLength: 67, nullable: true), + BuyerId = table.Column(maxLength: 256, nullable: false), + BuyerAddress = table.Column(maxLength: 43, nullable: true), + CurrencyAddress = table.Column(maxLength: 43, nullable: true), + CurrencySymbol = table.Column(maxLength: 32, nullable: true), + ApproverAddress = table.Column(maxLength: 43, nullable: true), + PoNumber = table.Column(nullable: true), + PoType = table.Column(nullable: false), + BuyerWalletAddress = table.Column(maxLength: 43, nullable: true), + SellerId = table.Column(maxLength: 32, nullable: true), + PoDate = table.Column(nullable: true), + OrderDate = table.Column(nullable: false), + BillTo_RecipientName = table.Column(maxLength: 255, nullable: true), + BillTo_Street = table.Column(maxLength: 180, nullable: true), + BillTo_City = table.Column(maxLength: 100, nullable: true), + BillTo_State = table.Column(maxLength: 60, nullable: true), + BillTo_Country = table.Column(maxLength: 90, nullable: true), + BillTo_ZipCode = table.Column(maxLength: 18, nullable: true), + ShipTo_RecipientName = table.Column(maxLength: 255, nullable: true), + ShipTo_Street = table.Column(maxLength: 180, nullable: true), + ShipTo_City = table.Column(maxLength: 100, nullable: true), + ShipTo_State = table.Column(maxLength: 60, nullable: true), + ShipTo_Country = table.Column(maxLength: 90, nullable: true), + ShipTo_ZipCode = table.Column(maxLength: 18, nullable: true) + }, + constraints: table => + { + table.PrimaryKey("PK_Orders", x => x.Id); + }); + + migrationBuilder.CreateTable( + name: "Quotes", + columns: table => new + { + Id = table.Column(nullable: false) + .Annotation("MySql:ValueGenerationStrategy", MySqlValueGenerationStrategy.IdentityColumn), + Status = table.Column(nullable: false), + Date = table.Column(nullable: false), + Expiry = table.Column(nullable: false), + TransactionHash = table.Column(maxLength: 67, nullable: true), + BuyerAddress = table.Column(maxLength: 43, nullable: true), + CurrencySymbol = table.Column(maxLength: 32, nullable: true), + CurrencyAddress = table.Column(maxLength: 43, nullable: true), + ApproverAddress = table.Column(maxLength: 43, nullable: true), + PoNumber = table.Column(nullable: true), + PoType = table.Column(nullable: false), + BuyerWalletAddress = table.Column(maxLength: 43, nullable: true), + SellerId = table.Column(maxLength: 32, nullable: true), + BuyerId = table.Column(maxLength: 256, nullable: false), + BillTo_RecipientName = table.Column(maxLength: 255, nullable: true), + BillTo_Street = table.Column(maxLength: 180, nullable: true), + BillTo_City = table.Column(maxLength: 100, nullable: true), + BillTo_State = table.Column(maxLength: 60, nullable: true), + BillTo_Country = table.Column(maxLength: 90, nullable: true), + BillTo_ZipCode = table.Column(maxLength: 18, nullable: true), + ShipTo_RecipientName = table.Column(maxLength: 255, nullable: true), + ShipTo_Street = table.Column(maxLength: 180, nullable: true), + ShipTo_City = table.Column(maxLength: 100, nullable: true), + ShipTo_State = table.Column(maxLength: 60, nullable: true), + ShipTo_Country = table.Column(maxLength: 90, nullable: true), + ShipTo_ZipCode = table.Column(maxLength: 18, nullable: true) + }, + constraints: table => + { + table.PrimaryKey("PK_Quotes", x => x.Id); + }); + + migrationBuilder.CreateTable( + name: "BasketItems", + columns: table => new + { + Id = table.Column(nullable: false) + .Annotation("MySql:ValueGenerationStrategy", MySqlValueGenerationStrategy.IdentityColumn), + UnitPrice = table.Column(type: "decimal(18,2)", nullable: false), + Quantity = table.Column(nullable: false), + CatalogItemId = table.Column(nullable: false), + BasketId = table.Column(nullable: false) + }, + constraints: table => + { + table.PrimaryKey("PK_BasketItems", x => x.Id); + table.ForeignKey( + name: "FK_BasketItems_Baskets_BasketId", + column: x => x.BasketId, + principalTable: "Baskets", + principalColumn: "Id", + onDelete: ReferentialAction.Cascade); + }); + + migrationBuilder.CreateTable( + name: "BuyerPostalAddress", + columns: table => new + { + Id = table.Column(nullable: false) + .Annotation("MySql:ValueGenerationStrategy", MySqlValueGenerationStrategy.IdentityColumn), + Name = table.Column(nullable: true), + PostalAddress_RecipientName = table.Column(maxLength: 255, nullable: true), + PostalAddress_Street = table.Column(maxLength: 180, nullable: true), + PostalAddress_City = table.Column(maxLength: 100, nullable: true), + PostalAddress_State = table.Column(maxLength: 60, nullable: true), + PostalAddress_Country = table.Column(maxLength: 90, nullable: true), + PostalAddress_ZipCode = table.Column(maxLength: 18, nullable: true), + BuyerId = table.Column(nullable: true) + }, + constraints: table => + { + table.PrimaryKey("PK_BuyerPostalAddress", x => x.Id); + table.ForeignKey( + name: "FK_BuyerPostalAddress_Buyers_BuyerId", + column: x => x.BuyerId, + principalTable: "Buyers", + principalColumn: "Id", + onDelete: ReferentialAction.Restrict); + }); + + migrationBuilder.CreateTable( + name: "Catalog", + columns: table => new + { + Id = table.Column(nullable: false) + .Annotation("MySql:ValueGenerationStrategy", MySqlValueGenerationStrategy.IdentityColumn), + Status = table.Column(nullable: false), + Gtin = table.Column(maxLength: 14, nullable: false), + GtinRegistryId = table.Column(nullable: true), + Name = table.Column(maxLength: 50, nullable: false), + Description = table.Column(nullable: true), + Price = table.Column(type: "decimal(18,2)", nullable: false), + Unit = table.Column(maxLength: 8, nullable: true), + CatalogTypeId = table.Column(nullable: false), + CatalogBrandId = table.Column(nullable: false), + PictureUri = table.Column(maxLength: 512, nullable: true), + PictureSmallUri = table.Column(maxLength: 512, nullable: true), + PictureMediumUri = table.Column(maxLength: 512, nullable: true), + PictureLargeUri = table.Column(maxLength: 512, nullable: true), + AttributeJson = table.Column(nullable: true), + Rank = table.Column(nullable: false), + Height = table.Column(nullable: false), + Width = table.Column(nullable: false), + Depth = table.Column(nullable: false), + Weight = table.Column(nullable: false) + }, + constraints: table => + { + table.PrimaryKey("PK_Catalog", x => x.Id); + table.ForeignKey( + name: "FK_Catalog_CatalogBrands_CatalogBrandId", + column: x => x.CatalogBrandId, + principalTable: "CatalogBrands", + principalColumn: "Id", + onDelete: ReferentialAction.Cascade); + table.ForeignKey( + name: "FK_Catalog_CatalogTypes_CatalogTypeId", + column: x => x.CatalogTypeId, + principalTable: "CatalogTypes", + principalColumn: "Id", + onDelete: ReferentialAction.Cascade); + }); + + migrationBuilder.CreateTable( + name: "OrderItems", + columns: table => new + { + Id = table.Column(nullable: false) + .Annotation("MySql:ValueGenerationStrategy", MySqlValueGenerationStrategy.IdentityColumn), + Status = table.Column(nullable: false), + ItemOrdered_CatalogItemId = table.Column(nullable: true), + ItemOrdered_Gtin = table.Column(maxLength: 14, nullable: true), + ItemOrdered_GtinRegistryId = table.Column(nullable: true), + ItemOrdered_ProductName = table.Column(maxLength: 50, nullable: true), + ItemOrdered_PictureUri = table.Column(maxLength: 512, nullable: true), + UnitPrice = table.Column(type: "decimal(18,2)", nullable: false), + Quantity = table.Column(nullable: false), + Unit = table.Column(maxLength: 50, nullable: true), + PoItemStatus = table.Column(nullable: true), + PoItemNumber = table.Column(nullable: true), + GoodsIssueDate = table.Column(nullable: true), + ActualEscrowReleaseDate = table.Column(nullable: true), + PlannedEscrowReleaseDate = table.Column(nullable: true), + IsEscrowReleased = table.Column(nullable: true), + QuantitySymbol = table.Column(maxLength: 32, nullable: true), + QuantityAddress = table.Column(maxLength: 43, nullable: true), + CurrencyValue = table.Column(maxLength: 100, nullable: true), + OrderId = table.Column(nullable: true) + }, + constraints: table => + { + table.PrimaryKey("PK_OrderItems", x => x.Id); + table.ForeignKey( + name: "FK_OrderItems_Orders_OrderId", + column: x => x.OrderId, + principalTable: "Orders", + principalColumn: "Id", + onDelete: ReferentialAction.Restrict); + }); + + migrationBuilder.CreateTable( + name: "QuoteItems", + columns: table => new + { + Id = table.Column(nullable: false) + .Annotation("MySql:ValueGenerationStrategy", MySqlValueGenerationStrategy.IdentityColumn), + ItemOrdered_CatalogItemId = table.Column(nullable: true), + ItemOrdered_Gtin = table.Column(maxLength: 14, nullable: true), + ItemOrdered_GtinRegistryId = table.Column(nullable: true), + ItemOrdered_ProductName = table.Column(maxLength: 50, nullable: true), + ItemOrdered_PictureUri = table.Column(maxLength: 512, nullable: true), + UnitPrice = table.Column(type: "decimal(18,2)", nullable: false), + Quantity = table.Column(nullable: false), + Unit = table.Column(nullable: true), + PoItemNumber = table.Column(nullable: true), + EscrowReleaseDate = table.Column(nullable: true), + QuantitySymbol = table.Column(nullable: true), + QuantityAddress = table.Column(nullable: true), + CurrencyValue = table.Column(nullable: true), + QuoteId = table.Column(nullable: true) + }, + constraints: table => + { + table.PrimaryKey("PK_QuoteItems", x => x.Id); + table.ForeignKey( + name: "FK_QuoteItems_Quotes_QuoteId", + column: x => x.QuoteId, + principalTable: "Quotes", + principalColumn: "Id", + onDelete: ReferentialAction.Restrict); + }); + + migrationBuilder.CreateTable( + name: "Stock", + columns: table => new + { + Id = table.Column(nullable: false) + .Annotation("MySql:ValueGenerationStrategy", MySqlValueGenerationStrategy.IdentityColumn), + CatalogItemId = table.Column(nullable: false), + Location = table.Column(maxLength: 50, nullable: false), + Quantity = table.Column(nullable: false) + }, + constraints: table => + { + table.PrimaryKey("PK_Stock", x => x.Id); + table.ForeignKey( + name: "FK_Stock_Catalog_CatalogItemId", + column: x => x.CatalogItemId, + principalTable: "Catalog", + principalColumn: "Id", + onDelete: ReferentialAction.Cascade); + }); + + migrationBuilder.CreateIndex( + name: "IX_BasketItems_BasketId", + table: "BasketItems", + column: "BasketId"); + + migrationBuilder.CreateIndex( + name: "IX_Baskets_BuyerAddress", + table: "Baskets", + column: "BuyerAddress"); + + migrationBuilder.CreateIndex( + name: "IX_Baskets_BuyerId", + table: "Baskets", + column: "BuyerId"); + + migrationBuilder.CreateIndex( + name: "IX_BuyerPostalAddress_BuyerId", + table: "BuyerPostalAddress", + column: "BuyerId"); + + migrationBuilder.CreateIndex( + name: "IX_Buyers_BuyerAddress", + table: "Buyers", + column: "BuyerAddress", + unique: true); + + migrationBuilder.CreateIndex( + name: "IX_Buyers_BuyerId", + table: "Buyers", + column: "BuyerId", + unique: true); + + migrationBuilder.CreateIndex( + name: "IX_Buyers_BuyerWalletAddress", + table: "Buyers", + column: "BuyerWalletAddress", + unique: true); + + migrationBuilder.CreateIndex( + name: "IX_Catalog_CatalogBrandId", + table: "Catalog", + column: "CatalogBrandId"); + + migrationBuilder.CreateIndex( + name: "IX_Catalog_CatalogTypeId", + table: "Catalog", + column: "CatalogTypeId"); + + migrationBuilder.CreateIndex( + name: "IX_OrderItems_OrderId", + table: "OrderItems", + column: "OrderId"); + + migrationBuilder.CreateIndex( + name: "IX_Orders_BuyerAddress", + table: "Orders", + column: "BuyerAddress"); + + migrationBuilder.CreateIndex( + name: "IX_Orders_BuyerId", + table: "Orders", + column: "BuyerId"); + + migrationBuilder.CreateIndex( + name: "IX_QuoteItems_QuoteId", + table: "QuoteItems", + column: "QuoteId"); + + migrationBuilder.CreateIndex( + name: "IX_Quotes_BuyerAddress", + table: "Quotes", + column: "BuyerAddress"); + + migrationBuilder.CreateIndex( + name: "IX_Quotes_BuyerId", + table: "Quotes", + column: "BuyerId"); + + migrationBuilder.CreateIndex( + name: "IX_Stock_CatalogItemId", + table: "Stock", + column: "CatalogItemId"); + } + + protected override void Down(MigrationBuilder migrationBuilder) + { + migrationBuilder.DropTable( + name: "BasketItems"); + + migrationBuilder.DropTable( + name: "BuyerPostalAddress"); + + migrationBuilder.DropTable( + name: "OrderItems"); + + migrationBuilder.DropTable( + name: "QuoteItems"); + + migrationBuilder.DropTable( + name: "Stock"); + + migrationBuilder.DropTable( + name: "Baskets"); + + migrationBuilder.DropTable( + name: "Buyers"); + + migrationBuilder.DropTable( + name: "Orders"); + + migrationBuilder.DropTable( + name: "Quotes"); + + migrationBuilder.DropTable( + name: "Catalog"); + + migrationBuilder.DropTable( + name: "CatalogBrands"); + + migrationBuilder.DropTable( + name: "CatalogTypes"); + } + } +} diff --git a/src/Nethereum.eShop.MySql/Catalog/Migrations/MySqlCatalogContextModelSnapshot.cs b/src/Nethereum.eShop.MySql/Catalog/Migrations/MySqlCatalogContextModelSnapshot.cs new file mode 100644 index 0000000..cf20653 --- /dev/null +++ b/src/Nethereum.eShop.MySql/Catalog/Migrations/MySqlCatalogContextModelSnapshot.cs @@ -0,0 +1,914 @@ +// +using System; +using Microsoft.EntityFrameworkCore; +using Microsoft.EntityFrameworkCore.Infrastructure; +using Microsoft.EntityFrameworkCore.Storage.ValueConversion; +using Nethereum.eShop.MySql.Catalog; + +namespace Nethereum.eShop.MySql.Catalog.Migrations +{ + [DbContext(typeof(MySqlCatalogContext))] + partial class MySqlCatalogContextModelSnapshot : ModelSnapshot + { + protected override void BuildModel(ModelBuilder modelBuilder) + { +#pragma warning disable 612, 618 + modelBuilder + .HasAnnotation("ProductVersion", "3.1.2") + .HasAnnotation("Relational:MaxIdentifierLength", 64); + + modelBuilder.Entity("Nethereum.eShop.ApplicationCore.Entities.BasketAggregate.Basket", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("int"); + + b.Property("BuyerAddress") + .IsRequired() + .HasColumnType("varchar(43) CHARACTER SET utf8mb4") + .HasMaxLength(43); + + b.Property("BuyerId") + .IsRequired() + .HasColumnType("varchar(256) CHARACTER SET utf8mb4") + .HasMaxLength(256); + + b.Property("TransactionHash") + .HasColumnType("varchar(67) CHARACTER SET utf8mb4") + .HasMaxLength(67); + + b.HasKey("Id"); + + b.HasIndex("BuyerAddress"); + + b.HasIndex("BuyerId"); + + b.ToTable("Baskets"); + }); + + modelBuilder.Entity("Nethereum.eShop.ApplicationCore.Entities.BasketAggregate.BasketItem", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("int"); + + b.Property("BasketId") + .HasColumnType("int"); + + b.Property("CatalogItemId") + .HasColumnType("int"); + + b.Property("Quantity") + .HasColumnType("int"); + + b.Property("UnitPrice") + .HasColumnType("decimal(18,2)"); + + b.HasKey("Id"); + + b.HasIndex("BasketId"); + + b.ToTable("BasketItems"); + }); + + modelBuilder.Entity("Nethereum.eShop.ApplicationCore.Entities.BuyerAggregate.Buyer", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("int"); + + b.Property("BuyerAddress") + .HasColumnType("varchar(43) CHARACTER SET utf8mb4") + .HasMaxLength(43); + + b.Property("BuyerId") + .IsRequired() + .HasColumnType("varchar(256) CHARACTER SET utf8mb4") + .HasMaxLength(256); + + b.Property("BuyerWalletAddress") + .HasColumnType("varchar(43) CHARACTER SET utf8mb4") + .HasMaxLength(43); + + b.HasKey("Id"); + + b.HasIndex("BuyerAddress") + .IsUnique(); + + b.HasIndex("BuyerId") + .IsUnique(); + + b.HasIndex("BuyerWalletAddress") + .IsUnique(); + + b.ToTable("Buyers"); + }); + + modelBuilder.Entity("Nethereum.eShop.ApplicationCore.Entities.BuyerAggregate.BuyerPostalAddress", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("int"); + + b.Property("BuyerId") + .HasColumnType("int"); + + b.Property("Name") + .HasColumnType("longtext CHARACTER SET utf8mb4"); + + b.HasKey("Id"); + + b.HasIndex("BuyerId"); + + b.ToTable("BuyerPostalAddress"); + }); + + modelBuilder.Entity("Nethereum.eShop.ApplicationCore.Entities.CatalogBrand", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("int"); + + b.Property("Brand") + .IsRequired() + .HasColumnType("varchar(100) CHARACTER SET utf8mb4") + .HasMaxLength(100); + + b.HasKey("Id"); + + b.ToTable("CatalogBrands"); + }); + + modelBuilder.Entity("Nethereum.eShop.ApplicationCore.Entities.CatalogItem", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("int"); + + b.Property("AttributeJson") + .HasColumnType("longtext CHARACTER SET utf8mb4"); + + b.Property("CatalogBrandId") + .HasColumnType("int"); + + b.Property("CatalogTypeId") + .HasColumnType("int"); + + b.Property("Depth") + .HasColumnType("int"); + + b.Property("Description") + .HasColumnType("longtext CHARACTER SET utf8mb4"); + + b.Property("Gtin") + .IsRequired() + .HasColumnType("varchar(14) CHARACTER SET utf8mb4") + .HasMaxLength(14); + + b.Property("GtinRegistryId") + .HasColumnType("int"); + + b.Property("Height") + .HasColumnType("int"); + + b.Property("Name") + .IsRequired() + .HasColumnType("varchar(50) CHARACTER SET utf8mb4") + .HasMaxLength(50); + + b.Property("PictureLargeUri") + .HasColumnType("varchar(512) CHARACTER SET utf8mb4") + .HasMaxLength(512); + + b.Property("PictureMediumUri") + .HasColumnType("varchar(512) CHARACTER SET utf8mb4") + .HasMaxLength(512); + + b.Property("PictureSmallUri") + .HasColumnType("varchar(512) CHARACTER SET utf8mb4") + .HasMaxLength(512); + + b.Property("PictureUri") + .HasColumnType("varchar(512) CHARACTER SET utf8mb4") + .HasMaxLength(512); + + b.Property("Price") + .HasColumnType("decimal(18,2)"); + + b.Property("Rank") + .HasColumnType("int"); + + b.Property("Status") + .HasColumnType("int"); + + b.Property("Unit") + .HasColumnType("varchar(8) CHARACTER SET utf8mb4") + .HasMaxLength(8); + + b.Property("Weight") + .HasColumnType("int"); + + b.Property("Width") + .HasColumnType("int"); + + b.HasKey("Id"); + + b.HasIndex("CatalogBrandId"); + + b.HasIndex("CatalogTypeId"); + + b.ToTable("Catalog"); + }); + + modelBuilder.Entity("Nethereum.eShop.ApplicationCore.Entities.CatalogType", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("int"); + + b.Property("Type") + .IsRequired() + .HasColumnType("varchar(100) CHARACTER SET utf8mb4") + .HasMaxLength(100); + + b.HasKey("Id"); + + b.ToTable("CatalogTypes"); + }); + + modelBuilder.Entity("Nethereum.eShop.ApplicationCore.Entities.OrderAggregate.Order", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("int"); + + b.Property("ApproverAddress") + .HasColumnType("varchar(43) CHARACTER SET utf8mb4") + .HasMaxLength(43); + + b.Property("BuyerAddress") + .HasColumnType("varchar(43) CHARACTER SET utf8mb4") + .HasMaxLength(43); + + b.Property("BuyerId") + .IsRequired() + .HasColumnType("varchar(256) CHARACTER SET utf8mb4") + .HasMaxLength(256); + + b.Property("BuyerWalletAddress") + .HasColumnType("varchar(43) CHARACTER SET utf8mb4") + .HasMaxLength(43); + + b.Property("CurrencyAddress") + .HasColumnType("varchar(43) CHARACTER SET utf8mb4") + .HasMaxLength(43); + + b.Property("CurrencySymbol") + .HasColumnType("varchar(32) CHARACTER SET utf8mb4") + .HasMaxLength(32); + + b.Property("OrderDate") + .HasColumnType("datetime(6)"); + + b.Property("PoDate") + .HasColumnType("datetime(6)"); + + b.Property("PoNumber") + .HasColumnType("bigint"); + + b.Property("PoType") + .HasColumnType("int"); + + b.Property("QuoteId") + .HasColumnType("int"); + + b.Property("SellerId") + .HasColumnType("varchar(32) CHARACTER SET utf8mb4") + .HasMaxLength(32); + + b.Property("Status") + .HasColumnType("int"); + + b.Property("TransactionHash") + .HasColumnType("varchar(67) CHARACTER SET utf8mb4") + .HasMaxLength(67); + + b.HasKey("Id"); + + b.HasIndex("BuyerAddress"); + + b.HasIndex("BuyerId"); + + b.ToTable("Orders"); + }); + + modelBuilder.Entity("Nethereum.eShop.ApplicationCore.Entities.OrderAggregate.OrderItem", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("int"); + + b.Property("ActualEscrowReleaseDate") + .HasColumnType("datetime(6)"); + + b.Property("CurrencyValue") + .HasColumnType("varchar(100) CHARACTER SET utf8mb4") + .HasMaxLength(100); + + b.Property("GoodsIssueDate") + .HasColumnType("datetime(6)"); + + b.Property("IsEscrowReleased") + .HasColumnType("tinyint(1)"); + + b.Property("OrderId") + .HasColumnType("int"); + + b.Property("PlannedEscrowReleaseDate") + .HasColumnType("datetime(6)"); + + b.Property("PoItemNumber") + .HasColumnType("int"); + + b.Property("PoItemStatus") + .HasColumnType("int"); + + b.Property("Quantity") + .HasColumnType("int"); + + b.Property("QuantityAddress") + .HasColumnType("varchar(43) CHARACTER SET utf8mb4") + .HasMaxLength(43); + + b.Property("QuantitySymbol") + .HasColumnType("varchar(32) CHARACTER SET utf8mb4") + .HasMaxLength(32); + + b.Property("Status") + .HasColumnType("int"); + + b.Property("Unit") + .HasColumnType("varchar(50) CHARACTER SET utf8mb4") + .HasMaxLength(50); + + b.Property("UnitPrice") + .HasColumnType("decimal(18,2)"); + + b.HasKey("Id"); + + b.HasIndex("OrderId"); + + b.ToTable("OrderItems"); + }); + + modelBuilder.Entity("Nethereum.eShop.ApplicationCore.Entities.QuoteAggregate.Quote", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("int"); + + b.Property("ApproverAddress") + .HasColumnType("varchar(43) CHARACTER SET utf8mb4") + .HasMaxLength(43); + + b.Property("BuyerAddress") + .HasColumnType("varchar(43) CHARACTER SET utf8mb4") + .HasMaxLength(43); + + b.Property("BuyerId") + .IsRequired() + .HasColumnType("varchar(256) CHARACTER SET utf8mb4") + .HasMaxLength(256); + + b.Property("BuyerWalletAddress") + .HasColumnType("varchar(43) CHARACTER SET utf8mb4") + .HasMaxLength(43); + + b.Property("CurrencyAddress") + .HasColumnType("varchar(43) CHARACTER SET utf8mb4") + .HasMaxLength(43); + + b.Property("CurrencySymbol") + .HasColumnType("varchar(32) CHARACTER SET utf8mb4") + .HasMaxLength(32); + + b.Property("Date") + .HasColumnType("datetime(6)"); + + b.Property("Expiry") + .HasColumnType("datetime(6)"); + + b.Property("PoNumber") + .HasColumnType("bigint"); + + b.Property("PoType") + .HasColumnType("int"); + + b.Property("SellerId") + .HasColumnType("varchar(32) CHARACTER SET utf8mb4") + .HasMaxLength(32); + + b.Property("Status") + .HasColumnType("int"); + + b.Property("TransactionHash") + .HasColumnType("varchar(67) CHARACTER SET utf8mb4") + .HasMaxLength(67); + + b.HasKey("Id"); + + b.HasIndex("BuyerAddress"); + + b.HasIndex("BuyerId"); + + b.ToTable("Quotes"); + }); + + modelBuilder.Entity("Nethereum.eShop.ApplicationCore.Entities.QuoteAggregate.QuoteItem", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("int"); + + b.Property("CurrencyValue") + .HasColumnType("longtext CHARACTER SET utf8mb4"); + + b.Property("EscrowReleaseDate") + .HasColumnType("datetime(6)"); + + b.Property("PoItemNumber") + .HasColumnType("int"); + + b.Property("Quantity") + .HasColumnType("int"); + + b.Property("QuantityAddress") + .HasColumnType("longtext CHARACTER SET utf8mb4"); + + b.Property("QuantitySymbol") + .HasColumnType("longtext CHARACTER SET utf8mb4"); + + b.Property("QuoteId") + .HasColumnType("int"); + + b.Property("Unit") + .HasColumnType("longtext CHARACTER SET utf8mb4"); + + b.Property("UnitPrice") + .HasColumnType("decimal(18,2)"); + + b.HasKey("Id"); + + b.HasIndex("QuoteId"); + + b.ToTable("QuoteItems"); + }); + + modelBuilder.Entity("Nethereum.eShop.ApplicationCore.Entities.StockItem", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("int"); + + b.Property("CatalogItemId") + .HasColumnType("int"); + + b.Property("Location") + .IsRequired() + .HasColumnType("varchar(50) CHARACTER SET utf8mb4") + .HasMaxLength(50); + + b.Property("Quantity") + .HasColumnType("int"); + + b.HasKey("Id"); + + b.HasIndex("CatalogItemId"); + + b.ToTable("Stock"); + }); + + modelBuilder.Entity("Nethereum.eShop.ApplicationCore.Entities.BasketAggregate.Basket", b => + { + b.OwnsOne("Nethereum.eShop.ApplicationCore.Entities.PostalAddress", "BillTo", b1 => + { + b1.Property("BasketId") + .HasColumnType("int"); + + b1.Property("City") + .IsRequired() + .HasColumnType("varchar(100) CHARACTER SET utf8mb4") + .HasMaxLength(100); + + b1.Property("Country") + .IsRequired() + .HasColumnType("varchar(90) CHARACTER SET utf8mb4") + .HasMaxLength(90); + + b1.Property("RecipientName") + .IsRequired() + .HasColumnType("varchar(255) CHARACTER SET utf8mb4") + .HasMaxLength(255); + + b1.Property("State") + .HasColumnType("varchar(60) CHARACTER SET utf8mb4") + .HasMaxLength(60); + + b1.Property("Street") + .IsRequired() + .HasColumnType("varchar(180) CHARACTER SET utf8mb4") + .HasMaxLength(180); + + b1.Property("ZipCode") + .IsRequired() + .HasColumnType("varchar(18) CHARACTER SET utf8mb4") + .HasMaxLength(18); + + b1.HasKey("BasketId"); + + b1.ToTable("Baskets"); + + b1.WithOwner() + .HasForeignKey("BasketId"); + }); + + b.OwnsOne("Nethereum.eShop.ApplicationCore.Entities.PostalAddress", "ShipTo", b1 => + { + b1.Property("BasketId") + .HasColumnType("int"); + + b1.Property("City") + .IsRequired() + .HasColumnType("varchar(100) CHARACTER SET utf8mb4") + .HasMaxLength(100); + + b1.Property("Country") + .IsRequired() + .HasColumnType("varchar(90) CHARACTER SET utf8mb4") + .HasMaxLength(90); + + b1.Property("RecipientName") + .IsRequired() + .HasColumnType("varchar(255) CHARACTER SET utf8mb4") + .HasMaxLength(255); + + b1.Property("State") + .HasColumnType("varchar(60) CHARACTER SET utf8mb4") + .HasMaxLength(60); + + b1.Property("Street") + .IsRequired() + .HasColumnType("varchar(180) CHARACTER SET utf8mb4") + .HasMaxLength(180); + + b1.Property("ZipCode") + .IsRequired() + .HasColumnType("varchar(18) CHARACTER SET utf8mb4") + .HasMaxLength(18); + + b1.HasKey("BasketId"); + + b1.ToTable("Baskets"); + + b1.WithOwner() + .HasForeignKey("BasketId"); + }); + }); + + modelBuilder.Entity("Nethereum.eShop.ApplicationCore.Entities.BasketAggregate.BasketItem", b => + { + b.HasOne("Nethereum.eShop.ApplicationCore.Entities.BasketAggregate.Basket", null) + .WithMany("Items") + .HasForeignKey("BasketId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + }); + + modelBuilder.Entity("Nethereum.eShop.ApplicationCore.Entities.BuyerAggregate.BuyerPostalAddress", b => + { + b.HasOne("Nethereum.eShop.ApplicationCore.Entities.BuyerAggregate.Buyer", null) + .WithMany("PostalAddresses") + .HasForeignKey("BuyerId"); + + b.OwnsOne("Nethereum.eShop.ApplicationCore.Entities.PostalAddress", "PostalAddress", b1 => + { + b1.Property("BuyerPostalAddressId") + .HasColumnType("int"); + + b1.Property("City") + .IsRequired() + .HasColumnType("varchar(100) CHARACTER SET utf8mb4") + .HasMaxLength(100); + + b1.Property("Country") + .IsRequired() + .HasColumnType("varchar(90) CHARACTER SET utf8mb4") + .HasMaxLength(90); + + b1.Property("RecipientName") + .IsRequired() + .HasColumnType("varchar(255) CHARACTER SET utf8mb4") + .HasMaxLength(255); + + b1.Property("State") + .HasColumnType("varchar(60) CHARACTER SET utf8mb4") + .HasMaxLength(60); + + b1.Property("Street") + .IsRequired() + .HasColumnType("varchar(180) CHARACTER SET utf8mb4") + .HasMaxLength(180); + + b1.Property("ZipCode") + .IsRequired() + .HasColumnType("varchar(18) CHARACTER SET utf8mb4") + .HasMaxLength(18); + + b1.HasKey("BuyerPostalAddressId"); + + b1.ToTable("BuyerPostalAddress"); + + b1.WithOwner() + .HasForeignKey("BuyerPostalAddressId"); + }); + }); + + modelBuilder.Entity("Nethereum.eShop.ApplicationCore.Entities.CatalogItem", b => + { + b.HasOne("Nethereum.eShop.ApplicationCore.Entities.CatalogBrand", "CatalogBrand") + .WithMany() + .HasForeignKey("CatalogBrandId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.HasOne("Nethereum.eShop.ApplicationCore.Entities.CatalogType", "CatalogType") + .WithMany() + .HasForeignKey("CatalogTypeId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + }); + + modelBuilder.Entity("Nethereum.eShop.ApplicationCore.Entities.OrderAggregate.Order", b => + { + b.OwnsOne("Nethereum.eShop.ApplicationCore.Entities.PostalAddress", "BillTo", b1 => + { + b1.Property("OrderId") + .HasColumnType("int"); + + b1.Property("City") + .IsRequired() + .HasColumnType("varchar(100) CHARACTER SET utf8mb4") + .HasMaxLength(100); + + b1.Property("Country") + .IsRequired() + .HasColumnType("varchar(90) CHARACTER SET utf8mb4") + .HasMaxLength(90); + + b1.Property("RecipientName") + .IsRequired() + .HasColumnType("varchar(255) CHARACTER SET utf8mb4") + .HasMaxLength(255); + + b1.Property("State") + .HasColumnType("varchar(60) CHARACTER SET utf8mb4") + .HasMaxLength(60); + + b1.Property("Street") + .IsRequired() + .HasColumnType("varchar(180) CHARACTER SET utf8mb4") + .HasMaxLength(180); + + b1.Property("ZipCode") + .IsRequired() + .HasColumnType("varchar(18) CHARACTER SET utf8mb4") + .HasMaxLength(18); + + b1.HasKey("OrderId"); + + b1.ToTable("Orders"); + + b1.WithOwner() + .HasForeignKey("OrderId"); + }); + + b.OwnsOne("Nethereum.eShop.ApplicationCore.Entities.PostalAddress", "ShipTo", b1 => + { + b1.Property("OrderId") + .HasColumnType("int"); + + b1.Property("City") + .IsRequired() + .HasColumnType("varchar(100) CHARACTER SET utf8mb4") + .HasMaxLength(100); + + b1.Property("Country") + .IsRequired() + .HasColumnType("varchar(90) CHARACTER SET utf8mb4") + .HasMaxLength(90); + + b1.Property("RecipientName") + .IsRequired() + .HasColumnType("varchar(255) CHARACTER SET utf8mb4") + .HasMaxLength(255); + + b1.Property("State") + .HasColumnType("varchar(60) CHARACTER SET utf8mb4") + .HasMaxLength(60); + + b1.Property("Street") + .IsRequired() + .HasColumnType("varchar(180) CHARACTER SET utf8mb4") + .HasMaxLength(180); + + b1.Property("ZipCode") + .IsRequired() + .HasColumnType("varchar(18) CHARACTER SET utf8mb4") + .HasMaxLength(18); + + b1.HasKey("OrderId"); + + b1.ToTable("Orders"); + + b1.WithOwner() + .HasForeignKey("OrderId"); + }); + }); + + modelBuilder.Entity("Nethereum.eShop.ApplicationCore.Entities.OrderAggregate.OrderItem", b => + { + b.HasOne("Nethereum.eShop.ApplicationCore.Entities.OrderAggregate.Order", null) + .WithMany("OrderItems") + .HasForeignKey("OrderId"); + + b.OwnsOne("Nethereum.eShop.ApplicationCore.Entities.CatalogItemExcerpt", "ItemOrdered", b1 => + { + b1.Property("OrderItemId") + .HasColumnType("int"); + + b1.Property("CatalogItemId") + .HasColumnType("int"); + + b1.Property("Gtin") + .HasColumnType("varchar(14) CHARACTER SET utf8mb4") + .HasMaxLength(14); + + b1.Property("GtinRegistryId") + .HasColumnType("int"); + + b1.Property("PictureUri") + .HasColumnType("varchar(512) CHARACTER SET utf8mb4") + .HasMaxLength(512); + + b1.Property("ProductName") + .IsRequired() + .HasColumnType("varchar(50) CHARACTER SET utf8mb4") + .HasMaxLength(50); + + b1.HasKey("OrderItemId"); + + b1.ToTable("OrderItems"); + + b1.WithOwner() + .HasForeignKey("OrderItemId"); + }); + }); + + modelBuilder.Entity("Nethereum.eShop.ApplicationCore.Entities.QuoteAggregate.Quote", b => + { + b.OwnsOne("Nethereum.eShop.ApplicationCore.Entities.PostalAddress", "BillTo", b1 => + { + b1.Property("QuoteId") + .HasColumnType("int"); + + b1.Property("City") + .IsRequired() + .HasColumnType("varchar(100) CHARACTER SET utf8mb4") + .HasMaxLength(100); + + b1.Property("Country") + .IsRequired() + .HasColumnType("varchar(90) CHARACTER SET utf8mb4") + .HasMaxLength(90); + + b1.Property("RecipientName") + .IsRequired() + .HasColumnType("varchar(255) CHARACTER SET utf8mb4") + .HasMaxLength(255); + + b1.Property("State") + .HasColumnType("varchar(60) CHARACTER SET utf8mb4") + .HasMaxLength(60); + + b1.Property("Street") + .IsRequired() + .HasColumnType("varchar(180) CHARACTER SET utf8mb4") + .HasMaxLength(180); + + b1.Property("ZipCode") + .IsRequired() + .HasColumnType("varchar(18) CHARACTER SET utf8mb4") + .HasMaxLength(18); + + b1.HasKey("QuoteId"); + + b1.ToTable("Quotes"); + + b1.WithOwner() + .HasForeignKey("QuoteId"); + }); + + b.OwnsOne("Nethereum.eShop.ApplicationCore.Entities.PostalAddress", "ShipTo", b1 => + { + b1.Property("QuoteId") + .HasColumnType("int"); + + b1.Property("City") + .IsRequired() + .HasColumnType("varchar(100) CHARACTER SET utf8mb4") + .HasMaxLength(100); + + b1.Property("Country") + .IsRequired() + .HasColumnType("varchar(90) CHARACTER SET utf8mb4") + .HasMaxLength(90); + + b1.Property("RecipientName") + .IsRequired() + .HasColumnType("varchar(255) CHARACTER SET utf8mb4") + .HasMaxLength(255); + + b1.Property("State") + .HasColumnType("varchar(60) CHARACTER SET utf8mb4") + .HasMaxLength(60); + + b1.Property("Street") + .IsRequired() + .HasColumnType("varchar(180) CHARACTER SET utf8mb4") + .HasMaxLength(180); + + b1.Property("ZipCode") + .IsRequired() + .HasColumnType("varchar(18) CHARACTER SET utf8mb4") + .HasMaxLength(18); + + b1.HasKey("QuoteId"); + + b1.ToTable("Quotes"); + + b1.WithOwner() + .HasForeignKey("QuoteId"); + }); + }); + + modelBuilder.Entity("Nethereum.eShop.ApplicationCore.Entities.QuoteAggregate.QuoteItem", b => + { + b.HasOne("Nethereum.eShop.ApplicationCore.Entities.QuoteAggregate.Quote", null) + .WithMany("QuoteItems") + .HasForeignKey("QuoteId"); + + b.OwnsOne("Nethereum.eShop.ApplicationCore.Entities.CatalogItemExcerpt", "ItemOrdered", b1 => + { + b1.Property("QuoteItemId") + .HasColumnType("int"); + + b1.Property("CatalogItemId") + .HasColumnType("int"); + + b1.Property("Gtin") + .HasColumnType("varchar(14) CHARACTER SET utf8mb4") + .HasMaxLength(14); + + b1.Property("GtinRegistryId") + .HasColumnType("int"); + + b1.Property("PictureUri") + .HasColumnType("varchar(512) CHARACTER SET utf8mb4") + .HasMaxLength(512); + + b1.Property("ProductName") + .IsRequired() + .HasColumnType("varchar(50) CHARACTER SET utf8mb4") + .HasMaxLength(50); + + b1.HasKey("QuoteItemId"); + + b1.ToTable("QuoteItems"); + + b1.WithOwner() + .HasForeignKey("QuoteItemId"); + }); + }); + + modelBuilder.Entity("Nethereum.eShop.ApplicationCore.Entities.StockItem", b => + { + b.HasOne("Nethereum.eShop.ApplicationCore.Entities.CatalogItem", "CatalogItem") + .WithMany() + .HasForeignKey("CatalogItemId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + }); +#pragma warning restore 612, 618 + } + } +} diff --git a/src/Nethereum.eShop.MySql/Catalog/Migrations/Scripts/CreateCatalogDb.sql b/src/Nethereum.eShop.MySql/Catalog/Migrations/Scripts/CreateCatalogDb.sql new file mode 100644 index 0000000..5b755fd --- /dev/null +++ b/src/Nethereum.eShop.MySql/Catalog/Migrations/Scripts/CreateCatalogDb.sql @@ -0,0 +1,623 @@ +CREATE TABLE IF NOT EXISTS `__EFMigrationsHistory` ( + `MigrationId` varchar(95) NOT NULL, + `ProductVersion` varchar(32) NOT NULL, + CONSTRAINT `PK___EFMigrationsHistory` PRIMARY KEY (`MigrationId`) +); + + +DROP PROCEDURE IF EXISTS MigrationsScript; +DELIMITER // +CREATE PROCEDURE MigrationsScript() +BEGIN + IF NOT EXISTS(SELECT 1 FROM `__EFMigrationsHistory` WHERE `MigrationId` = '20200312152404_InitialCreate') THEN + + CREATE TABLE `Baskets` ( + `Id` int NOT NULL AUTO_INCREMENT, + `BuyerId` varchar(256) CHARACTER SET utf8mb4 NOT NULL, + `BuyerAddress` varchar(43) CHARACTER SET utf8mb4 NOT NULL, + `BillTo_RecipientName` varchar(255) CHARACTER SET utf8mb4 NULL, + `BillTo_Street` varchar(180) CHARACTER SET utf8mb4 NULL, + `BillTo_City` varchar(100) CHARACTER SET utf8mb4 NULL, + `BillTo_State` varchar(60) CHARACTER SET utf8mb4 NULL, + `BillTo_Country` varchar(90) CHARACTER SET utf8mb4 NULL, + `BillTo_ZipCode` varchar(18) CHARACTER SET utf8mb4 NULL, + `ShipTo_RecipientName` varchar(255) CHARACTER SET utf8mb4 NULL, + `ShipTo_Street` varchar(180) CHARACTER SET utf8mb4 NULL, + `ShipTo_City` varchar(100) CHARACTER SET utf8mb4 NULL, + `ShipTo_State` varchar(60) CHARACTER SET utf8mb4 NULL, + `ShipTo_Country` varchar(90) CHARACTER SET utf8mb4 NULL, + `ShipTo_ZipCode` varchar(18) CHARACTER SET utf8mb4 NULL, + `TransactionHash` varchar(67) CHARACTER SET utf8mb4 NULL, + CONSTRAINT `PK_Baskets` PRIMARY KEY (`Id`) + ); + + END IF; +END // +DELIMITER ; +CALL MigrationsScript(); +DROP PROCEDURE MigrationsScript; + + +DROP PROCEDURE IF EXISTS MigrationsScript; +DELIMITER // +CREATE PROCEDURE MigrationsScript() +BEGIN + IF NOT EXISTS(SELECT 1 FROM `__EFMigrationsHistory` WHERE `MigrationId` = '20200312152404_InitialCreate') THEN + + CREATE TABLE `Buyers` ( + `Id` int NOT NULL AUTO_INCREMENT, + `BuyerId` varchar(256) CHARACTER SET utf8mb4 NOT NULL, + `BuyerAddress` varchar(43) CHARACTER SET utf8mb4 NULL, + `BuyerWalletAddress` varchar(43) CHARACTER SET utf8mb4 NULL, + CONSTRAINT `PK_Buyers` PRIMARY KEY (`Id`) + ); + + END IF; +END // +DELIMITER ; +CALL MigrationsScript(); +DROP PROCEDURE MigrationsScript; + + +DROP PROCEDURE IF EXISTS MigrationsScript; +DELIMITER // +CREATE PROCEDURE MigrationsScript() +BEGIN + IF NOT EXISTS(SELECT 1 FROM `__EFMigrationsHistory` WHERE `MigrationId` = '20200312152404_InitialCreate') THEN + + CREATE TABLE `CatalogBrands` ( + `Id` int NOT NULL AUTO_INCREMENT, + `Brand` varchar(100) CHARACTER SET utf8mb4 NOT NULL, + CONSTRAINT `PK_CatalogBrands` PRIMARY KEY (`Id`) + ); + + END IF; +END // +DELIMITER ; +CALL MigrationsScript(); +DROP PROCEDURE MigrationsScript; + + +DROP PROCEDURE IF EXISTS MigrationsScript; +DELIMITER // +CREATE PROCEDURE MigrationsScript() +BEGIN + IF NOT EXISTS(SELECT 1 FROM `__EFMigrationsHistory` WHERE `MigrationId` = '20200312152404_InitialCreate') THEN + + CREATE TABLE `CatalogTypes` ( + `Id` int NOT NULL AUTO_INCREMENT, + `Type` varchar(100) CHARACTER SET utf8mb4 NOT NULL, + CONSTRAINT `PK_CatalogTypes` PRIMARY KEY (`Id`) + ); + + END IF; +END // +DELIMITER ; +CALL MigrationsScript(); +DROP PROCEDURE MigrationsScript; + + +DROP PROCEDURE IF EXISTS MigrationsScript; +DELIMITER // +CREATE PROCEDURE MigrationsScript() +BEGIN + IF NOT EXISTS(SELECT 1 FROM `__EFMigrationsHistory` WHERE `MigrationId` = '20200312152404_InitialCreate') THEN + + CREATE TABLE `Orders` ( + `Id` int NOT NULL AUTO_INCREMENT, + `QuoteId` int NULL, + `Status` int NOT NULL, + `TransactionHash` varchar(67) CHARACTER SET utf8mb4 NULL, + `BuyerId` varchar(256) CHARACTER SET utf8mb4 NOT NULL, + `BuyerAddress` varchar(43) CHARACTER SET utf8mb4 NULL, + `CurrencyAddress` varchar(43) CHARACTER SET utf8mb4 NULL, + `CurrencySymbol` varchar(32) CHARACTER SET utf8mb4 NULL, + `ApproverAddress` varchar(43) CHARACTER SET utf8mb4 NULL, + `PoNumber` bigint NULL, + `PoType` int NOT NULL, + `BuyerWalletAddress` varchar(43) CHARACTER SET utf8mb4 NULL, + `SellerId` varchar(32) CHARACTER SET utf8mb4 NULL, + `PoDate` datetime(6) NULL, + `OrderDate` datetime(6) NOT NULL, + `BillTo_RecipientName` varchar(255) CHARACTER SET utf8mb4 NULL, + `BillTo_Street` varchar(180) CHARACTER SET utf8mb4 NULL, + `BillTo_City` varchar(100) CHARACTER SET utf8mb4 NULL, + `BillTo_State` varchar(60) CHARACTER SET utf8mb4 NULL, + `BillTo_Country` varchar(90) CHARACTER SET utf8mb4 NULL, + `BillTo_ZipCode` varchar(18) CHARACTER SET utf8mb4 NULL, + `ShipTo_RecipientName` varchar(255) CHARACTER SET utf8mb4 NULL, + `ShipTo_Street` varchar(180) CHARACTER SET utf8mb4 NULL, + `ShipTo_City` varchar(100) CHARACTER SET utf8mb4 NULL, + `ShipTo_State` varchar(60) CHARACTER SET utf8mb4 NULL, + `ShipTo_Country` varchar(90) CHARACTER SET utf8mb4 NULL, + `ShipTo_ZipCode` varchar(18) CHARACTER SET utf8mb4 NULL, + CONSTRAINT `PK_Orders` PRIMARY KEY (`Id`) + ); + + END IF; +END // +DELIMITER ; +CALL MigrationsScript(); +DROP PROCEDURE MigrationsScript; + + +DROP PROCEDURE IF EXISTS MigrationsScript; +DELIMITER // +CREATE PROCEDURE MigrationsScript() +BEGIN + IF NOT EXISTS(SELECT 1 FROM `__EFMigrationsHistory` WHERE `MigrationId` = '20200312152404_InitialCreate') THEN + + CREATE TABLE `Quotes` ( + `Id` int NOT NULL AUTO_INCREMENT, + `Status` int NOT NULL, + `Date` datetime(6) NOT NULL, + `Expiry` datetime(6) NOT NULL, + `TransactionHash` varchar(67) CHARACTER SET utf8mb4 NULL, + `BuyerAddress` varchar(43) CHARACTER SET utf8mb4 NULL, + `CurrencySymbol` varchar(32) CHARACTER SET utf8mb4 NULL, + `CurrencyAddress` varchar(43) CHARACTER SET utf8mb4 NULL, + `ApproverAddress` varchar(43) CHARACTER SET utf8mb4 NULL, + `PoNumber` bigint NULL, + `PoType` int NOT NULL, + `BuyerWalletAddress` varchar(43) CHARACTER SET utf8mb4 NULL, + `SellerId` varchar(32) CHARACTER SET utf8mb4 NULL, + `BuyerId` varchar(256) CHARACTER SET utf8mb4 NOT NULL, + `BillTo_RecipientName` varchar(255) CHARACTER SET utf8mb4 NULL, + `BillTo_Street` varchar(180) CHARACTER SET utf8mb4 NULL, + `BillTo_City` varchar(100) CHARACTER SET utf8mb4 NULL, + `BillTo_State` varchar(60) CHARACTER SET utf8mb4 NULL, + `BillTo_Country` varchar(90) CHARACTER SET utf8mb4 NULL, + `BillTo_ZipCode` varchar(18) CHARACTER SET utf8mb4 NULL, + `ShipTo_RecipientName` varchar(255) CHARACTER SET utf8mb4 NULL, + `ShipTo_Street` varchar(180) CHARACTER SET utf8mb4 NULL, + `ShipTo_City` varchar(100) CHARACTER SET utf8mb4 NULL, + `ShipTo_State` varchar(60) CHARACTER SET utf8mb4 NULL, + `ShipTo_Country` varchar(90) CHARACTER SET utf8mb4 NULL, + `ShipTo_ZipCode` varchar(18) CHARACTER SET utf8mb4 NULL, + CONSTRAINT `PK_Quotes` PRIMARY KEY (`Id`) + ); + + END IF; +END // +DELIMITER ; +CALL MigrationsScript(); +DROP PROCEDURE MigrationsScript; + + +DROP PROCEDURE IF EXISTS MigrationsScript; +DELIMITER // +CREATE PROCEDURE MigrationsScript() +BEGIN + IF NOT EXISTS(SELECT 1 FROM `__EFMigrationsHistory` WHERE `MigrationId` = '20200312152404_InitialCreate') THEN + + CREATE TABLE `BasketItems` ( + `Id` int NOT NULL AUTO_INCREMENT, + `UnitPrice` decimal(18,2) NOT NULL, + `Quantity` int NOT NULL, + `CatalogItemId` int NOT NULL, + `BasketId` int NOT NULL, + CONSTRAINT `PK_BasketItems` PRIMARY KEY (`Id`), + CONSTRAINT `FK_BasketItems_Baskets_BasketId` FOREIGN KEY (`BasketId`) REFERENCES `Baskets` (`Id`) ON DELETE CASCADE + ); + + END IF; +END // +DELIMITER ; +CALL MigrationsScript(); +DROP PROCEDURE MigrationsScript; + + +DROP PROCEDURE IF EXISTS MigrationsScript; +DELIMITER // +CREATE PROCEDURE MigrationsScript() +BEGIN + IF NOT EXISTS(SELECT 1 FROM `__EFMigrationsHistory` WHERE `MigrationId` = '20200312152404_InitialCreate') THEN + + CREATE TABLE `BuyerPostalAddress` ( + `Id` int NOT NULL AUTO_INCREMENT, + `Name` longtext CHARACTER SET utf8mb4 NULL, + `PostalAddress_RecipientName` varchar(255) CHARACTER SET utf8mb4 NULL, + `PostalAddress_Street` varchar(180) CHARACTER SET utf8mb4 NULL, + `PostalAddress_City` varchar(100) CHARACTER SET utf8mb4 NULL, + `PostalAddress_State` varchar(60) CHARACTER SET utf8mb4 NULL, + `PostalAddress_Country` varchar(90) CHARACTER SET utf8mb4 NULL, + `PostalAddress_ZipCode` varchar(18) CHARACTER SET utf8mb4 NULL, + `BuyerId` int NULL, + CONSTRAINT `PK_BuyerPostalAddress` PRIMARY KEY (`Id`), + CONSTRAINT `FK_BuyerPostalAddress_Buyers_BuyerId` FOREIGN KEY (`BuyerId`) REFERENCES `Buyers` (`Id`) ON DELETE RESTRICT + ); + + END IF; +END // +DELIMITER ; +CALL MigrationsScript(); +DROP PROCEDURE MigrationsScript; + + +DROP PROCEDURE IF EXISTS MigrationsScript; +DELIMITER // +CREATE PROCEDURE MigrationsScript() +BEGIN + IF NOT EXISTS(SELECT 1 FROM `__EFMigrationsHistory` WHERE `MigrationId` = '20200312152404_InitialCreate') THEN + + CREATE TABLE `Catalog` ( + `Id` int NOT NULL AUTO_INCREMENT, + `Status` int NOT NULL, + `Gtin` varchar(14) CHARACTER SET utf8mb4 NOT NULL, + `GtinRegistryId` int NULL, + `Name` varchar(50) CHARACTER SET utf8mb4 NOT NULL, + `Description` longtext CHARACTER SET utf8mb4 NULL, + `Price` decimal(18,2) NOT NULL, + `Unit` varchar(8) CHARACTER SET utf8mb4 NULL, + `CatalogTypeId` int NOT NULL, + `CatalogBrandId` int NOT NULL, + `PictureUri` varchar(512) CHARACTER SET utf8mb4 NULL, + `PictureSmallUri` varchar(512) CHARACTER SET utf8mb4 NULL, + `PictureMediumUri` varchar(512) CHARACTER SET utf8mb4 NULL, + `PictureLargeUri` varchar(512) CHARACTER SET utf8mb4 NULL, + `AttributeJson` longtext CHARACTER SET utf8mb4 NULL, + `Rank` int NOT NULL, + `Height` int NOT NULL, + `Width` int NOT NULL, + `Depth` int NOT NULL, + `Weight` int NOT NULL, + CONSTRAINT `PK_Catalog` PRIMARY KEY (`Id`), + CONSTRAINT `FK_Catalog_CatalogBrands_CatalogBrandId` FOREIGN KEY (`CatalogBrandId`) REFERENCES `CatalogBrands` (`Id`) ON DELETE CASCADE, + CONSTRAINT `FK_Catalog_CatalogTypes_CatalogTypeId` FOREIGN KEY (`CatalogTypeId`) REFERENCES `CatalogTypes` (`Id`) ON DELETE CASCADE + ); + + END IF; +END // +DELIMITER ; +CALL MigrationsScript(); +DROP PROCEDURE MigrationsScript; + + +DROP PROCEDURE IF EXISTS MigrationsScript; +DELIMITER // +CREATE PROCEDURE MigrationsScript() +BEGIN + IF NOT EXISTS(SELECT 1 FROM `__EFMigrationsHistory` WHERE `MigrationId` = '20200312152404_InitialCreate') THEN + + CREATE TABLE `OrderItems` ( + `Id` int NOT NULL AUTO_INCREMENT, + `Status` int NOT NULL, + `ItemOrdered_CatalogItemId` int NULL, + `ItemOrdered_Gtin` varchar(14) CHARACTER SET utf8mb4 NULL, + `ItemOrdered_GtinRegistryId` int NULL, + `ItemOrdered_ProductName` varchar(50) CHARACTER SET utf8mb4 NULL, + `ItemOrdered_PictureUri` varchar(512) CHARACTER SET utf8mb4 NULL, + `UnitPrice` decimal(18,2) NOT NULL, + `Quantity` int NOT NULL, + `Unit` varchar(50) CHARACTER SET utf8mb4 NULL, + `PoItemStatus` int NULL, + `PoItemNumber` int NULL, + `GoodsIssueDate` datetime(6) NULL, + `ActualEscrowReleaseDate` datetime(6) NULL, + `PlannedEscrowReleaseDate` datetime(6) NULL, + `IsEscrowReleased` tinyint(1) NULL, + `QuantitySymbol` varchar(32) CHARACTER SET utf8mb4 NULL, + `QuantityAddress` varchar(43) CHARACTER SET utf8mb4 NULL, + `CurrencyValue` varchar(100) CHARACTER SET utf8mb4 NULL, + `OrderId` int NULL, + CONSTRAINT `PK_OrderItems` PRIMARY KEY (`Id`), + CONSTRAINT `FK_OrderItems_Orders_OrderId` FOREIGN KEY (`OrderId`) REFERENCES `Orders` (`Id`) ON DELETE RESTRICT + ); + + END IF; +END // +DELIMITER ; +CALL MigrationsScript(); +DROP PROCEDURE MigrationsScript; + + +DROP PROCEDURE IF EXISTS MigrationsScript; +DELIMITER // +CREATE PROCEDURE MigrationsScript() +BEGIN + IF NOT EXISTS(SELECT 1 FROM `__EFMigrationsHistory` WHERE `MigrationId` = '20200312152404_InitialCreate') THEN + + CREATE TABLE `QuoteItems` ( + `Id` int NOT NULL AUTO_INCREMENT, + `ItemOrdered_CatalogItemId` int NULL, + `ItemOrdered_Gtin` varchar(14) CHARACTER SET utf8mb4 NULL, + `ItemOrdered_GtinRegistryId` int NULL, + `ItemOrdered_ProductName` varchar(50) CHARACTER SET utf8mb4 NULL, + `ItemOrdered_PictureUri` varchar(512) CHARACTER SET utf8mb4 NULL, + `UnitPrice` decimal(18,2) NOT NULL, + `Quantity` int NOT NULL, + `Unit` longtext CHARACTER SET utf8mb4 NULL, + `PoItemNumber` int NULL, + `EscrowReleaseDate` datetime(6) NULL, + `QuantitySymbol` longtext CHARACTER SET utf8mb4 NULL, + `QuantityAddress` longtext CHARACTER SET utf8mb4 NULL, + `CurrencyValue` longtext CHARACTER SET utf8mb4 NULL, + `QuoteId` int NULL, + CONSTRAINT `PK_QuoteItems` PRIMARY KEY (`Id`), + CONSTRAINT `FK_QuoteItems_Quotes_QuoteId` FOREIGN KEY (`QuoteId`) REFERENCES `Quotes` (`Id`) ON DELETE RESTRICT + ); + + END IF; +END // +DELIMITER ; +CALL MigrationsScript(); +DROP PROCEDURE MigrationsScript; + + +DROP PROCEDURE IF EXISTS MigrationsScript; +DELIMITER // +CREATE PROCEDURE MigrationsScript() +BEGIN + IF NOT EXISTS(SELECT 1 FROM `__EFMigrationsHistory` WHERE `MigrationId` = '20200312152404_InitialCreate') THEN + + CREATE TABLE `Stock` ( + `Id` int NOT NULL AUTO_INCREMENT, + `CatalogItemId` int NOT NULL, + `Location` varchar(50) CHARACTER SET utf8mb4 NOT NULL, + `Quantity` int NOT NULL, + CONSTRAINT `PK_Stock` PRIMARY KEY (`Id`), + CONSTRAINT `FK_Stock_Catalog_CatalogItemId` FOREIGN KEY (`CatalogItemId`) REFERENCES `Catalog` (`Id`) ON DELETE CASCADE + ); + + END IF; +END // +DELIMITER ; +CALL MigrationsScript(); +DROP PROCEDURE MigrationsScript; + + +DROP PROCEDURE IF EXISTS MigrationsScript; +DELIMITER // +CREATE PROCEDURE MigrationsScript() +BEGIN + IF NOT EXISTS(SELECT 1 FROM `__EFMigrationsHistory` WHERE `MigrationId` = '20200312152404_InitialCreate') THEN + + CREATE INDEX `IX_BasketItems_BasketId` ON `BasketItems` (`BasketId`); + + END IF; +END // +DELIMITER ; +CALL MigrationsScript(); +DROP PROCEDURE MigrationsScript; + + +DROP PROCEDURE IF EXISTS MigrationsScript; +DELIMITER // +CREATE PROCEDURE MigrationsScript() +BEGIN + IF NOT EXISTS(SELECT 1 FROM `__EFMigrationsHistory` WHERE `MigrationId` = '20200312152404_InitialCreate') THEN + + CREATE INDEX `IX_Baskets_BuyerAddress` ON `Baskets` (`BuyerAddress`); + + END IF; +END // +DELIMITER ; +CALL MigrationsScript(); +DROP PROCEDURE MigrationsScript; + + +DROP PROCEDURE IF EXISTS MigrationsScript; +DELIMITER // +CREATE PROCEDURE MigrationsScript() +BEGIN + IF NOT EXISTS(SELECT 1 FROM `__EFMigrationsHistory` WHERE `MigrationId` = '20200312152404_InitialCreate') THEN + + CREATE INDEX `IX_Baskets_BuyerId` ON `Baskets` (`BuyerId`); + + END IF; +END // +DELIMITER ; +CALL MigrationsScript(); +DROP PROCEDURE MigrationsScript; + + +DROP PROCEDURE IF EXISTS MigrationsScript; +DELIMITER // +CREATE PROCEDURE MigrationsScript() +BEGIN + IF NOT EXISTS(SELECT 1 FROM `__EFMigrationsHistory` WHERE `MigrationId` = '20200312152404_InitialCreate') THEN + + CREATE INDEX `IX_BuyerPostalAddress_BuyerId` ON `BuyerPostalAddress` (`BuyerId`); + + END IF; +END // +DELIMITER ; +CALL MigrationsScript(); +DROP PROCEDURE MigrationsScript; + + +DROP PROCEDURE IF EXISTS MigrationsScript; +DELIMITER // +CREATE PROCEDURE MigrationsScript() +BEGIN + IF NOT EXISTS(SELECT 1 FROM `__EFMigrationsHistory` WHERE `MigrationId` = '20200312152404_InitialCreate') THEN + + CREATE UNIQUE INDEX `IX_Buyers_BuyerAddress` ON `Buyers` (`BuyerAddress`); + + END IF; +END // +DELIMITER ; +CALL MigrationsScript(); +DROP PROCEDURE MigrationsScript; + + +DROP PROCEDURE IF EXISTS MigrationsScript; +DELIMITER // +CREATE PROCEDURE MigrationsScript() +BEGIN + IF NOT EXISTS(SELECT 1 FROM `__EFMigrationsHistory` WHERE `MigrationId` = '20200312152404_InitialCreate') THEN + + CREATE UNIQUE INDEX `IX_Buyers_BuyerId` ON `Buyers` (`BuyerId`); + + END IF; +END // +DELIMITER ; +CALL MigrationsScript(); +DROP PROCEDURE MigrationsScript; + + +DROP PROCEDURE IF EXISTS MigrationsScript; +DELIMITER // +CREATE PROCEDURE MigrationsScript() +BEGIN + IF NOT EXISTS(SELECT 1 FROM `__EFMigrationsHistory` WHERE `MigrationId` = '20200312152404_InitialCreate') THEN + + CREATE UNIQUE INDEX `IX_Buyers_BuyerWalletAddress` ON `Buyers` (`BuyerWalletAddress`); + + END IF; +END // +DELIMITER ; +CALL MigrationsScript(); +DROP PROCEDURE MigrationsScript; + + +DROP PROCEDURE IF EXISTS MigrationsScript; +DELIMITER // +CREATE PROCEDURE MigrationsScript() +BEGIN + IF NOT EXISTS(SELECT 1 FROM `__EFMigrationsHistory` WHERE `MigrationId` = '20200312152404_InitialCreate') THEN + + CREATE INDEX `IX_Catalog_CatalogBrandId` ON `Catalog` (`CatalogBrandId`); + + END IF; +END // +DELIMITER ; +CALL MigrationsScript(); +DROP PROCEDURE MigrationsScript; + + +DROP PROCEDURE IF EXISTS MigrationsScript; +DELIMITER // +CREATE PROCEDURE MigrationsScript() +BEGIN + IF NOT EXISTS(SELECT 1 FROM `__EFMigrationsHistory` WHERE `MigrationId` = '20200312152404_InitialCreate') THEN + + CREATE INDEX `IX_Catalog_CatalogTypeId` ON `Catalog` (`CatalogTypeId`); + + END IF; +END // +DELIMITER ; +CALL MigrationsScript(); +DROP PROCEDURE MigrationsScript; + + +DROP PROCEDURE IF EXISTS MigrationsScript; +DELIMITER // +CREATE PROCEDURE MigrationsScript() +BEGIN + IF NOT EXISTS(SELECT 1 FROM `__EFMigrationsHistory` WHERE `MigrationId` = '20200312152404_InitialCreate') THEN + + CREATE INDEX `IX_OrderItems_OrderId` ON `OrderItems` (`OrderId`); + + END IF; +END // +DELIMITER ; +CALL MigrationsScript(); +DROP PROCEDURE MigrationsScript; + + +DROP PROCEDURE IF EXISTS MigrationsScript; +DELIMITER // +CREATE PROCEDURE MigrationsScript() +BEGIN + IF NOT EXISTS(SELECT 1 FROM `__EFMigrationsHistory` WHERE `MigrationId` = '20200312152404_InitialCreate') THEN + + CREATE INDEX `IX_Orders_BuyerAddress` ON `Orders` (`BuyerAddress`); + + END IF; +END // +DELIMITER ; +CALL MigrationsScript(); +DROP PROCEDURE MigrationsScript; + + +DROP PROCEDURE IF EXISTS MigrationsScript; +DELIMITER // +CREATE PROCEDURE MigrationsScript() +BEGIN + IF NOT EXISTS(SELECT 1 FROM `__EFMigrationsHistory` WHERE `MigrationId` = '20200312152404_InitialCreate') THEN + + CREATE INDEX `IX_Orders_BuyerId` ON `Orders` (`BuyerId`); + + END IF; +END // +DELIMITER ; +CALL MigrationsScript(); +DROP PROCEDURE MigrationsScript; + + +DROP PROCEDURE IF EXISTS MigrationsScript; +DELIMITER // +CREATE PROCEDURE MigrationsScript() +BEGIN + IF NOT EXISTS(SELECT 1 FROM `__EFMigrationsHistory` WHERE `MigrationId` = '20200312152404_InitialCreate') THEN + + CREATE INDEX `IX_QuoteItems_QuoteId` ON `QuoteItems` (`QuoteId`); + + END IF; +END // +DELIMITER ; +CALL MigrationsScript(); +DROP PROCEDURE MigrationsScript; + + +DROP PROCEDURE IF EXISTS MigrationsScript; +DELIMITER // +CREATE PROCEDURE MigrationsScript() +BEGIN + IF NOT EXISTS(SELECT 1 FROM `__EFMigrationsHistory` WHERE `MigrationId` = '20200312152404_InitialCreate') THEN + + CREATE INDEX `IX_Quotes_BuyerAddress` ON `Quotes` (`BuyerAddress`); + + END IF; +END // +DELIMITER ; +CALL MigrationsScript(); +DROP PROCEDURE MigrationsScript; + + +DROP PROCEDURE IF EXISTS MigrationsScript; +DELIMITER // +CREATE PROCEDURE MigrationsScript() +BEGIN + IF NOT EXISTS(SELECT 1 FROM `__EFMigrationsHistory` WHERE `MigrationId` = '20200312152404_InitialCreate') THEN + + CREATE INDEX `IX_Quotes_BuyerId` ON `Quotes` (`BuyerId`); + + END IF; +END // +DELIMITER ; +CALL MigrationsScript(); +DROP PROCEDURE MigrationsScript; + + +DROP PROCEDURE IF EXISTS MigrationsScript; +DELIMITER // +CREATE PROCEDURE MigrationsScript() +BEGIN + IF NOT EXISTS(SELECT 1 FROM `__EFMigrationsHistory` WHERE `MigrationId` = '20200312152404_InitialCreate') THEN + + CREATE INDEX `IX_Stock_CatalogItemId` ON `Stock` (`CatalogItemId`); + + END IF; +END // +DELIMITER ; +CALL MigrationsScript(); +DROP PROCEDURE MigrationsScript; + + +DROP PROCEDURE IF EXISTS MigrationsScript; +DELIMITER // +CREATE PROCEDURE MigrationsScript() +BEGIN + IF NOT EXISTS(SELECT 1 FROM `__EFMigrationsHistory` WHERE `MigrationId` = '20200312152404_InitialCreate') THEN + + INSERT INTO `__EFMigrationsHistory` (`MigrationId`, `ProductVersion`) + VALUES ('20200312152404_InitialCreate', '3.1.2'); + + END IF; +END // +DELIMITER ; +CALL MigrationsScript(); +DROP PROCEDURE MigrationsScript; + diff --git a/src/Nethereum.eShop.MySql/Catalog/MySqlCatalogContext.cs b/src/Nethereum.eShop.MySql/Catalog/MySqlCatalogContext.cs new file mode 100644 index 0000000..040a82a --- /dev/null +++ b/src/Nethereum.eShop.MySql/Catalog/MySqlCatalogContext.cs @@ -0,0 +1,31 @@ +using MediatR; +using Microsoft.EntityFrameworkCore; +using Microsoft.EntityFrameworkCore.Design; +using Nethereum.eShop.EntityFramework.Catalog; + +namespace Nethereum.eShop.MySql.Catalog +{ + public class MySqlCatalogContext : CatalogContext + { + public MySqlCatalogContext(DbContextOptions options, IMediator mediator) : base(options, mediator) + { + } + + protected override void OnModelCreating(ModelBuilder builder) + { + base.OnModelCreating(builder); + //config is in EntityFramework project + builder.ApplyConfigurationsFromAssembly(typeof(CatalogContext).Assembly); + } + } + + public class MySqlCatalogContextContextDesignTimeFactory : IDesignTimeDbContextFactory + { + public MySqlCatalogContext CreateDbContext(string[] args) + { + var optionsBuilder = new DbContextOptionsBuilder(); + optionsBuilder.UseMySql("server=localhost;database=library;user=user;password=password"); + return new MySqlCatalogContext(optionsBuilder.Options, null); + } + } +} diff --git a/src/Nethereum.eShop.MySql/Catalog/MySqlEShopDbBootstrapper.cs b/src/Nethereum.eShop.MySql/Catalog/MySqlEShopDbBootstrapper.cs new file mode 100644 index 0000000..c83cac2 --- /dev/null +++ b/src/Nethereum.eShop.MySql/Catalog/MySqlEShopDbBootstrapper.cs @@ -0,0 +1,32 @@ +using Microsoft.EntityFrameworkCore; +using Microsoft.Extensions.Configuration; +using Microsoft.Extensions.DependencyInjection; +using Nethereum.eShop.ApplicationCore.Interfaces; +using Nethereum.eShop.ApplicationCore.Queries.Catalog; +using Nethereum.eShop.ApplicationCore.Queries.Orders; +using Nethereum.eShop.ApplicationCore.Queries.Quotes; +using Nethereum.eShop.EntityFramework.Catalog; +using Nethereum.eShop.MySql.Catalog.Queries; + +namespace Nethereum.eShop.MySql.Catalog +{ + public class MySqlEShopDbBootstrapper : EShopDbBootstrapperBase, IEShopDbBootstrapper + { + private const string ConnectionName = "CatalogConnection_MySql"; + + public void AddDbContext(IServiceCollection services, IConfiguration configuration) + { + services.AddDbContext((serviceProvider, options) => + options.UseMySql(configuration.GetConnectionString(ConnectionName))); + } + + public void AddQueries(IServiceCollection services, IConfiguration configuration) + { + string queryConnectionString = configuration.GetConnectionString(ConnectionName); + services.AddSingleton(new QuoteQueries(queryConnectionString)); + services.AddSingleton(new OrderQueries(queryConnectionString)); + services.AddSingleton(new CatalogQueries(queryConnectionString)); + } + } + +} diff --git a/src/Nethereum.eShop.MySql/Catalog/Queries/CatalogQueries.cs b/src/Nethereum.eShop.MySql/Catalog/Queries/CatalogQueries.cs new file mode 100644 index 0000000..767c8cc --- /dev/null +++ b/src/Nethereum.eShop.MySql/Catalog/Queries/CatalogQueries.cs @@ -0,0 +1,65 @@ +using Dapper; +using MySql.Data.MySqlClient; +using Nethereum.eShop.ApplicationCore.Queries; +using Nethereum.eShop.ApplicationCore.Queries.Catalog; +using System; +using System.Linq; +using System.Threading.Tasks; + +namespace Nethereum.eShop.MySql.Catalog.Queries +{ + public class CatalogQueries : ICatalogQueries + { + private readonly string _connectionString; + + public CatalogQueries(string connectionString) + { + _connectionString = connectionString ?? throw new ArgumentNullException(nameof(connectionString)); + } + + private static string[] SortByColumns = new[] { "Rank" }; + public async Task> GetCatalogItemsAsync(GetCatalogItemsSpecification catalogQuerySpecification) + { + string sortOrder = catalogQuerySpecification.SortDescending ? "desc" : "asc"; + catalogQuerySpecification.SortBy = catalogQuerySpecification.SortBy ?? "Rank"; + + if (!SortByColumns.Contains(catalogQuerySpecification.SortBy)) throw new ArgumentException(nameof(catalogQuerySpecification.SortBy)); + + using (var connection = new MySqlConnection(_connectionString)) + { + connection.Open(); + + var parameters = new DynamicParameters(); + parameters.Add("@searchText", catalogQuerySpecification.SearchText); + parameters.Add("@brandId", catalogQuerySpecification.BrandId); + parameters.Add("@typeId", catalogQuerySpecification.TypeId); + + var dbResults = await connection.QueryMultipleAsync( +@$"SELECT Count(1) FROM Catalog c +INNER JOIN CatalogBrands b ON c.CatalogBrandId = b.Id +INNER JOIN CatalogTypes t ON c.CatalogTypeId = t.Id +WHERE + (@brandId IS NULL OR (b.Id = @brandId)) AND + (@typeId IS NULL OR (t.Id = @typeId)) AND + (@searchText IS NULL OR ((c.Name LIKE CONCAT('%', @searchText,'%'))) OR (b.Brand LIKE CONCAT('%', @searchText, '%'))); +SELECT c.Id, c.Name, c.CatalogBrandId, b.Brand, c.CatalogTypeId, t.Type, c.PictureUri, c.Price, c.Rank +FROM Catalog c +INNER JOIN CatalogBrands b ON c.CatalogBrandId = b.Id +INNER JOIN CatalogTypes t ON c.CatalogTypeId = t.Id +WHERE + (@brandId IS NULL OR (b.Id = @brandId)) AND + (@typeId IS NULL OR (t.Id = @typeId)) AND + (@searchText IS NULL OR ((c.Name LIKE CONCAT('%', @searchText,'%'))) OR (b.Brand LIKE CONCAT('%', @searchText, '%'))) +ORDER BY c.{catalogQuerySpecification.SortBy} {sortOrder} +LIMIT {catalogQuerySpecification.Offset},{catalogQuerySpecification.Fetch};" + , parameters + ); + + var totalCount = dbResults.Read().Single(); + var rows = dbResults.Read(); + + return new PaginatedResult(totalCount, rows, catalogQuerySpecification); + } + } + } +} diff --git a/src/Nethereum.eShop.MySql/Catalog/Queries/OrderQueries.cs b/src/Nethereum.eShop.MySql/Catalog/Queries/OrderQueries.cs new file mode 100644 index 0000000..abba7af --- /dev/null +++ b/src/Nethereum.eShop.MySql/Catalog/Queries/OrderQueries.cs @@ -0,0 +1,73 @@ +using Dapper; +using MySql.Data.MySqlClient; +using Nethereum.eShop.ApplicationCore.Queries; +using Nethereum.eShop.ApplicationCore.Queries.Orders; +using System; +using System.Linq; +using System.Threading.Tasks; + +namespace Nethereum.eShop.MySql.Catalog.Queries +{ + public class OrderQueries: IOrderQueries + { + private readonly string _connectionString; + + public OrderQueries(string connectionString) + { + _connectionString = connectionString ?? throw new ArgumentNullException(nameof(connectionString)); + } + + private static string[] SortByColumns = new[] { "Id", "Status" }; + + public async Task> GetByBuyerIdAsync(string buyerId, PaginationArgs paginationArgs) + { + paginationArgs.SortBy = paginationArgs.SortBy ?? "Id"; + + if (!SortByColumns.Contains(paginationArgs.SortBy)) throw new ArgumentException(nameof(paginationArgs.SortBy)); + + using (var connection = new MySqlConnection(_connectionString)) + { + connection.Open(); + + var parameters = new DynamicParameters(); + parameters.Add("@buyerId", buyerId); + + string sortOrder = paginationArgs.SortDescending ? "desc" : "asc"; + + var dbResults = await connection.QueryMultipleAsync( +@$" +SELECT COUNT(1) FROM Orders as o WHERE o.BuyerId = @buyerId; +SELECT + o.Id as OrderId, + o.QuoteId as QuoteId, + o.BuyerAddress, + o.BuyerId, + o.TransactionHash, + o.OrderDate, + o.Status, + o.PoNumber, + o.PoType, + o.CurrencySymbol, + o.BillTo_RecipientName, + o.BillTo_ZipCode, + o.ShipTo_RecipientName, + o.ShipTo_ZipCode, + (select sum(oi.Quantity * oi.UnitPrice) from OrderItems oi where oi.OrderId = o.Id) as Total, + (select count(1) from OrderItems oi where oi.OrderId = o.Id) as ItemCount +FROM Orders as o +WHERE o.BuyerId = @buyerId +ORDER BY o.{paginationArgs.SortBy} {sortOrder} +LIMIT {paginationArgs.Offset},{paginationArgs.Fetch}; +" + , parameters + ); + + var totalCount = dbResults.Read().First(); + var rows = dbResults.Read(); + + return new PaginatedResult(totalCount, rows, paginationArgs); + } + } + + } +} diff --git a/src/Nethereum.eShop.MySql/Catalog/Queries/QuoteQueries.cs b/src/Nethereum.eShop.MySql/Catalog/Queries/QuoteQueries.cs new file mode 100644 index 0000000..1001a2e --- /dev/null +++ b/src/Nethereum.eShop.MySql/Catalog/Queries/QuoteQueries.cs @@ -0,0 +1,73 @@ +using Dapper; +using MySql.Data.MySqlClient; +using Nethereum.eShop.ApplicationCore.Queries; +using Nethereum.eShop.ApplicationCore.Queries.Quotes; +using System; +using System.Linq; +using System.Threading.Tasks; + +namespace Nethereum.eShop.MySql.Catalog.Queries +{ + public class QuoteQueries: IQuoteQueries + { + private readonly string _connectionString; + + public QuoteQueries(string connectionString) + { + _connectionString = connectionString ?? throw new ArgumentNullException(nameof(connectionString)); + } + + private static string[] SortByColumns = new[] { "Id", "Status" }; + + public async Task> GetByBuyerIdAsync(string buyerId, PaginationArgs paginationArgs) + { + paginationArgs.SortBy = paginationArgs.SortBy ?? "Id"; + + if (!SortByColumns.Contains(paginationArgs.SortBy)) throw new ArgumentException(nameof(paginationArgs.SortBy)); + + using (var connection = new MySqlConnection(_connectionString)) + { + connection.Open(); + + var parameters = new DynamicParameters(); + parameters.Add("@buyerId", buyerId); + + string sortOrder = paginationArgs.SortDescending ? "desc" : "asc"; + + var dbResults = await connection.QueryMultipleAsync( +@$" +SELECT COUNT(1) FROM Quotes as q WHERE q.BuyerId = @buyerId; +SELECT + q.Id as QuoteId, + q.BuyerAddress, + q.BuyerId, + q.TransactionHash, + q.Date as QuoteDate, + q.Status, + q.PoNumber, + q.PoType, + q.CurrencySymbol, + q.Expiry, + q.BillTo_RecipientName, + q.BillTo_ZipCode, + q.ShipTo_RecipientName, + q.ShipTo_ZipCode, + (select sum(qi.Quantity * qi.UnitPrice) from QuoteItems qi where qi.QuoteId = q.Id) as Total, + (select count(1) from QuoteItems qi where qi.QuoteId = q.Id) as ItemCount +FROM Quotes as q +WHERE q.BuyerId = @buyerId +ORDER BY q.{paginationArgs.SortBy} {sortOrder} +LIMIT {paginationArgs.Offset},{paginationArgs.Fetch}; +" + , parameters + ); + + var totalCount = dbResults.Read().First(); + var rows = dbResults.Read(); + + return new PaginatedResult(totalCount, rows, paginationArgs); + } + } + + } +} diff --git a/src/Nethereum.eShop.MySql/Identity/Migrations/20200312152429_InitialCreate.Designer.cs b/src/Nethereum.eShop.MySql/Identity/Migrations/20200312152429_InitialCreate.Designer.cs new file mode 100644 index 0000000..1f31e3f --- /dev/null +++ b/src/Nethereum.eShop.MySql/Identity/Migrations/20200312152429_InitialCreate.Designer.cs @@ -0,0 +1,267 @@ +// +using System; +using Microsoft.EntityFrameworkCore; +using Microsoft.EntityFrameworkCore.Infrastructure; +using Microsoft.EntityFrameworkCore.Migrations; +using Microsoft.EntityFrameworkCore.Storage.ValueConversion; +using Nethereum.eShop.MySql.Identity; + +namespace Nethereum.eShop.MySql.Identity.Migrations +{ + [DbContext(typeof(MySqlAppIdentityDbContext))] + [Migration("20200312152429_InitialCreate")] + partial class InitialCreate + { + protected override void BuildTargetModel(ModelBuilder modelBuilder) + { +#pragma warning disable 612, 618 + modelBuilder + .HasAnnotation("ProductVersion", "3.1.2") + .HasAnnotation("Relational:MaxIdentifierLength", 64); + + modelBuilder.Entity("Microsoft.AspNetCore.Identity.IdentityRole", b => + { + b.Property("Id") + .HasColumnType("varchar(255) CHARACTER SET utf8mb4"); + + b.Property("ConcurrencyStamp") + .IsConcurrencyToken() + .HasColumnType("longtext CHARACTER SET utf8mb4"); + + b.Property("Name") + .HasColumnType("varchar(256) CHARACTER SET utf8mb4") + .HasMaxLength(256); + + b.Property("NormalizedName") + .HasColumnType("varchar(256) CHARACTER SET utf8mb4") + .HasMaxLength(256); + + b.HasKey("Id"); + + b.HasIndex("NormalizedName") + .IsUnique() + .HasName("RoleNameIndex"); + + b.ToTable("AspNetRoles"); + }); + + modelBuilder.Entity("Microsoft.AspNetCore.Identity.IdentityRoleClaim", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("int"); + + b.Property("ClaimType") + .HasColumnType("longtext CHARACTER SET utf8mb4"); + + b.Property("ClaimValue") + .HasColumnType("longtext CHARACTER SET utf8mb4"); + + b.Property("RoleId") + .IsRequired() + .HasColumnType("varchar(255) CHARACTER SET utf8mb4"); + + b.HasKey("Id"); + + b.HasIndex("RoleId"); + + b.ToTable("AspNetRoleClaims"); + }); + + modelBuilder.Entity("Microsoft.AspNetCore.Identity.IdentityUserClaim", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("int"); + + b.Property("ClaimType") + .HasColumnType("longtext CHARACTER SET utf8mb4"); + + b.Property("ClaimValue") + .HasColumnType("longtext CHARACTER SET utf8mb4"); + + b.Property("UserId") + .IsRequired() + .HasColumnType("varchar(255) CHARACTER SET utf8mb4"); + + b.HasKey("Id"); + + b.HasIndex("UserId"); + + b.ToTable("AspNetUserClaims"); + }); + + modelBuilder.Entity("Microsoft.AspNetCore.Identity.IdentityUserLogin", b => + { + b.Property("LoginProvider") + .HasColumnType("varchar(255) CHARACTER SET utf8mb4"); + + b.Property("ProviderKey") + .HasColumnType("varchar(255) CHARACTER SET utf8mb4"); + + b.Property("ProviderDisplayName") + .HasColumnType("longtext CHARACTER SET utf8mb4"); + + b.Property("UserId") + .IsRequired() + .HasColumnType("varchar(255) CHARACTER SET utf8mb4"); + + b.HasKey("LoginProvider", "ProviderKey"); + + b.HasIndex("UserId"); + + b.ToTable("AspNetUserLogins"); + }); + + modelBuilder.Entity("Microsoft.AspNetCore.Identity.IdentityUserRole", b => + { + b.Property("UserId") + .HasColumnType("varchar(255) CHARACTER SET utf8mb4"); + + b.Property("RoleId") + .HasColumnType("varchar(255) CHARACTER SET utf8mb4"); + + b.HasKey("UserId", "RoleId"); + + b.HasIndex("RoleId"); + + b.ToTable("AspNetUserRoles"); + }); + + modelBuilder.Entity("Microsoft.AspNetCore.Identity.IdentityUserToken", b => + { + b.Property("UserId") + .HasColumnType("varchar(255) CHARACTER SET utf8mb4"); + + b.Property("LoginProvider") + .HasColumnType("varchar(255) CHARACTER SET utf8mb4"); + + b.Property("Name") + .HasColumnType("varchar(255) CHARACTER SET utf8mb4"); + + b.Property("Value") + .HasColumnType("longtext CHARACTER SET utf8mb4"); + + b.HasKey("UserId", "LoginProvider", "Name"); + + b.ToTable("AspNetUserTokens"); + }); + + modelBuilder.Entity("Nethereum.eShop.Infrastructure.Identity.ApplicationUser", b => + { + b.Property("Id") + .HasColumnType("varchar(255) CHARACTER SET utf8mb4"); + + b.Property("AccessFailedCount") + .HasColumnType("int"); + + b.Property("ConcurrencyStamp") + .IsConcurrencyToken() + .HasColumnType("longtext CHARACTER SET utf8mb4"); + + b.Property("Email") + .HasColumnType("varchar(256) CHARACTER SET utf8mb4") + .HasMaxLength(256); + + b.Property("EmailConfirmed") + .HasColumnType("tinyint(1)"); + + b.Property("LockoutEnabled") + .HasColumnType("tinyint(1)"); + + b.Property("LockoutEnd") + .HasColumnType("datetime(6)"); + + b.Property("NormalizedEmail") + .HasColumnType("varchar(256) CHARACTER SET utf8mb4") + .HasMaxLength(256); + + b.Property("NormalizedUserName") + .HasColumnType("varchar(256) CHARACTER SET utf8mb4") + .HasMaxLength(256); + + b.Property("PasswordHash") + .HasColumnType("longtext CHARACTER SET utf8mb4"); + + b.Property("PhoneNumber") + .HasColumnType("longtext CHARACTER SET utf8mb4"); + + b.Property("PhoneNumberConfirmed") + .HasColumnType("tinyint(1)"); + + b.Property("SecurityStamp") + .HasColumnType("longtext CHARACTER SET utf8mb4"); + + b.Property("TwoFactorEnabled") + .HasColumnType("tinyint(1)"); + + b.Property("UserName") + .HasColumnType("varchar(256) CHARACTER SET utf8mb4") + .HasMaxLength(256); + + b.HasKey("Id"); + + b.HasIndex("NormalizedEmail") + .HasName("EmailIndex"); + + b.HasIndex("NormalizedUserName") + .IsUnique() + .HasName("UserNameIndex"); + + b.ToTable("AspNetUsers"); + }); + + modelBuilder.Entity("Microsoft.AspNetCore.Identity.IdentityRoleClaim", b => + { + b.HasOne("Microsoft.AspNetCore.Identity.IdentityRole", null) + .WithMany() + .HasForeignKey("RoleId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + }); + + modelBuilder.Entity("Microsoft.AspNetCore.Identity.IdentityUserClaim", b => + { + b.HasOne("Nethereum.eShop.Infrastructure.Identity.ApplicationUser", null) + .WithMany() + .HasForeignKey("UserId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + }); + + modelBuilder.Entity("Microsoft.AspNetCore.Identity.IdentityUserLogin", b => + { + b.HasOne("Nethereum.eShop.Infrastructure.Identity.ApplicationUser", null) + .WithMany() + .HasForeignKey("UserId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + }); + + modelBuilder.Entity("Microsoft.AspNetCore.Identity.IdentityUserRole", b => + { + b.HasOne("Microsoft.AspNetCore.Identity.IdentityRole", null) + .WithMany() + .HasForeignKey("RoleId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.HasOne("Nethereum.eShop.Infrastructure.Identity.ApplicationUser", null) + .WithMany() + .HasForeignKey("UserId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + }); + + modelBuilder.Entity("Microsoft.AspNetCore.Identity.IdentityUserToken", b => + { + b.HasOne("Nethereum.eShop.Infrastructure.Identity.ApplicationUser", null) + .WithMany() + .HasForeignKey("UserId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + }); +#pragma warning restore 612, 618 + } + } +} diff --git a/src/Nethereum.eShop.MySql/Identity/Migrations/20200312152429_InitialCreate.cs b/src/Nethereum.eShop.MySql/Identity/Migrations/20200312152429_InitialCreate.cs new file mode 100644 index 0000000..732ac1c --- /dev/null +++ b/src/Nethereum.eShop.MySql/Identity/Migrations/20200312152429_InitialCreate.cs @@ -0,0 +1,218 @@ +using System; +using Microsoft.EntityFrameworkCore.Metadata; +using Microsoft.EntityFrameworkCore.Migrations; + +namespace Nethereum.eShop.MySql.Identity.Migrations +{ + public partial class InitialCreate : Migration + { + protected override void Up(MigrationBuilder migrationBuilder) + { + migrationBuilder.CreateTable( + name: "AspNetRoles", + columns: table => new + { + Id = table.Column(nullable: false), + Name = table.Column(maxLength: 256, nullable: true), + NormalizedName = table.Column(maxLength: 256, nullable: true), + ConcurrencyStamp = table.Column(nullable: true) + }, + constraints: table => + { + table.PrimaryKey("PK_AspNetRoles", x => x.Id); + }); + + migrationBuilder.CreateTable( + name: "AspNetUsers", + columns: table => new + { + Id = table.Column(nullable: false), + UserName = table.Column(maxLength: 256, nullable: true), + NormalizedUserName = table.Column(maxLength: 256, nullable: true), + Email = table.Column(maxLength: 256, nullable: true), + NormalizedEmail = table.Column(maxLength: 256, nullable: true), + EmailConfirmed = table.Column(nullable: false), + PasswordHash = table.Column(nullable: true), + SecurityStamp = table.Column(nullable: true), + ConcurrencyStamp = table.Column(nullable: true), + PhoneNumber = table.Column(nullable: true), + PhoneNumberConfirmed = table.Column(nullable: false), + TwoFactorEnabled = table.Column(nullable: false), + LockoutEnd = table.Column(nullable: true), + LockoutEnabled = table.Column(nullable: false), + AccessFailedCount = table.Column(nullable: false) + }, + constraints: table => + { + table.PrimaryKey("PK_AspNetUsers", x => x.Id); + }); + + migrationBuilder.CreateTable( + name: "AspNetRoleClaims", + columns: table => new + { + Id = table.Column(nullable: false) + .Annotation("MySql:ValueGenerationStrategy", MySqlValueGenerationStrategy.IdentityColumn), + RoleId = table.Column(nullable: false), + ClaimType = table.Column(nullable: true), + ClaimValue = table.Column(nullable: true) + }, + constraints: table => + { + table.PrimaryKey("PK_AspNetRoleClaims", x => x.Id); + table.ForeignKey( + name: "FK_AspNetRoleClaims_AspNetRoles_RoleId", + column: x => x.RoleId, + principalTable: "AspNetRoles", + principalColumn: "Id", + onDelete: ReferentialAction.Cascade); + }); + + migrationBuilder.CreateTable( + name: "AspNetUserClaims", + columns: table => new + { + Id = table.Column(nullable: false) + .Annotation("MySql:ValueGenerationStrategy", MySqlValueGenerationStrategy.IdentityColumn), + UserId = table.Column(nullable: false), + ClaimType = table.Column(nullable: true), + ClaimValue = table.Column(nullable: true) + }, + constraints: table => + { + table.PrimaryKey("PK_AspNetUserClaims", x => x.Id); + table.ForeignKey( + name: "FK_AspNetUserClaims_AspNetUsers_UserId", + column: x => x.UserId, + principalTable: "AspNetUsers", + principalColumn: "Id", + onDelete: ReferentialAction.Cascade); + }); + + migrationBuilder.CreateTable( + name: "AspNetUserLogins", + columns: table => new + { + LoginProvider = table.Column(nullable: false), + ProviderKey = table.Column(nullable: false), + ProviderDisplayName = table.Column(nullable: true), + UserId = table.Column(nullable: false) + }, + constraints: table => + { + table.PrimaryKey("PK_AspNetUserLogins", x => new { x.LoginProvider, x.ProviderKey }); + table.ForeignKey( + name: "FK_AspNetUserLogins_AspNetUsers_UserId", + column: x => x.UserId, + principalTable: "AspNetUsers", + principalColumn: "Id", + onDelete: ReferentialAction.Cascade); + }); + + migrationBuilder.CreateTable( + name: "AspNetUserRoles", + columns: table => new + { + UserId = table.Column(nullable: false), + RoleId = table.Column(nullable: false) + }, + constraints: table => + { + table.PrimaryKey("PK_AspNetUserRoles", x => new { x.UserId, x.RoleId }); + table.ForeignKey( + name: "FK_AspNetUserRoles_AspNetRoles_RoleId", + column: x => x.RoleId, + principalTable: "AspNetRoles", + principalColumn: "Id", + onDelete: ReferentialAction.Cascade); + table.ForeignKey( + name: "FK_AspNetUserRoles_AspNetUsers_UserId", + column: x => x.UserId, + principalTable: "AspNetUsers", + principalColumn: "Id", + onDelete: ReferentialAction.Cascade); + }); + + migrationBuilder.CreateTable( + name: "AspNetUserTokens", + columns: table => new + { + UserId = table.Column(nullable: false), + LoginProvider = table.Column(nullable: false), + Name = table.Column(nullable: false), + Value = table.Column(nullable: true) + }, + constraints: table => + { + table.PrimaryKey("PK_AspNetUserTokens", x => new { x.UserId, x.LoginProvider, x.Name }); + table.ForeignKey( + name: "FK_AspNetUserTokens_AspNetUsers_UserId", + column: x => x.UserId, + principalTable: "AspNetUsers", + principalColumn: "Id", + onDelete: ReferentialAction.Cascade); + }); + + migrationBuilder.CreateIndex( + name: "IX_AspNetRoleClaims_RoleId", + table: "AspNetRoleClaims", + column: "RoleId"); + + migrationBuilder.CreateIndex( + name: "RoleNameIndex", + table: "AspNetRoles", + column: "NormalizedName", + unique: true); + + migrationBuilder.CreateIndex( + name: "IX_AspNetUserClaims_UserId", + table: "AspNetUserClaims", + column: "UserId"); + + migrationBuilder.CreateIndex( + name: "IX_AspNetUserLogins_UserId", + table: "AspNetUserLogins", + column: "UserId"); + + migrationBuilder.CreateIndex( + name: "IX_AspNetUserRoles_RoleId", + table: "AspNetUserRoles", + column: "RoleId"); + + migrationBuilder.CreateIndex( + name: "EmailIndex", + table: "AspNetUsers", + column: "NormalizedEmail"); + + migrationBuilder.CreateIndex( + name: "UserNameIndex", + table: "AspNetUsers", + column: "NormalizedUserName", + unique: true); + } + + protected override void Down(MigrationBuilder migrationBuilder) + { + migrationBuilder.DropTable( + name: "AspNetRoleClaims"); + + migrationBuilder.DropTable( + name: "AspNetUserClaims"); + + migrationBuilder.DropTable( + name: "AspNetUserLogins"); + + migrationBuilder.DropTable( + name: "AspNetUserRoles"); + + migrationBuilder.DropTable( + name: "AspNetUserTokens"); + + migrationBuilder.DropTable( + name: "AspNetRoles"); + + migrationBuilder.DropTable( + name: "AspNetUsers"); + } + } +} diff --git a/src/Nethereum.eShop.MySql/Identity/Migrations/MySqlAppIdentityDbContextModelSnapshot.cs b/src/Nethereum.eShop.MySql/Identity/Migrations/MySqlAppIdentityDbContextModelSnapshot.cs new file mode 100644 index 0000000..992bc24 --- /dev/null +++ b/src/Nethereum.eShop.MySql/Identity/Migrations/MySqlAppIdentityDbContextModelSnapshot.cs @@ -0,0 +1,265 @@ +// +using System; +using Microsoft.EntityFrameworkCore; +using Microsoft.EntityFrameworkCore.Infrastructure; +using Microsoft.EntityFrameworkCore.Storage.ValueConversion; +using Nethereum.eShop.MySql.Identity; + +namespace Nethereum.eShop.MySql.Identity.Migrations +{ + [DbContext(typeof(MySqlAppIdentityDbContext))] + partial class MySqlAppIdentityDbContextModelSnapshot : ModelSnapshot + { + protected override void BuildModel(ModelBuilder modelBuilder) + { +#pragma warning disable 612, 618 + modelBuilder + .HasAnnotation("ProductVersion", "3.1.2") + .HasAnnotation("Relational:MaxIdentifierLength", 64); + + modelBuilder.Entity("Microsoft.AspNetCore.Identity.IdentityRole", b => + { + b.Property("Id") + .HasColumnType("varchar(255) CHARACTER SET utf8mb4"); + + b.Property("ConcurrencyStamp") + .IsConcurrencyToken() + .HasColumnType("longtext CHARACTER SET utf8mb4"); + + b.Property("Name") + .HasColumnType("varchar(256) CHARACTER SET utf8mb4") + .HasMaxLength(256); + + b.Property("NormalizedName") + .HasColumnType("varchar(256) CHARACTER SET utf8mb4") + .HasMaxLength(256); + + b.HasKey("Id"); + + b.HasIndex("NormalizedName") + .IsUnique() + .HasName("RoleNameIndex"); + + b.ToTable("AspNetRoles"); + }); + + modelBuilder.Entity("Microsoft.AspNetCore.Identity.IdentityRoleClaim", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("int"); + + b.Property("ClaimType") + .HasColumnType("longtext CHARACTER SET utf8mb4"); + + b.Property("ClaimValue") + .HasColumnType("longtext CHARACTER SET utf8mb4"); + + b.Property("RoleId") + .IsRequired() + .HasColumnType("varchar(255) CHARACTER SET utf8mb4"); + + b.HasKey("Id"); + + b.HasIndex("RoleId"); + + b.ToTable("AspNetRoleClaims"); + }); + + modelBuilder.Entity("Microsoft.AspNetCore.Identity.IdentityUserClaim", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("int"); + + b.Property("ClaimType") + .HasColumnType("longtext CHARACTER SET utf8mb4"); + + b.Property("ClaimValue") + .HasColumnType("longtext CHARACTER SET utf8mb4"); + + b.Property("UserId") + .IsRequired() + .HasColumnType("varchar(255) CHARACTER SET utf8mb4"); + + b.HasKey("Id"); + + b.HasIndex("UserId"); + + b.ToTable("AspNetUserClaims"); + }); + + modelBuilder.Entity("Microsoft.AspNetCore.Identity.IdentityUserLogin", b => + { + b.Property("LoginProvider") + .HasColumnType("varchar(255) CHARACTER SET utf8mb4"); + + b.Property("ProviderKey") + .HasColumnType("varchar(255) CHARACTER SET utf8mb4"); + + b.Property("ProviderDisplayName") + .HasColumnType("longtext CHARACTER SET utf8mb4"); + + b.Property("UserId") + .IsRequired() + .HasColumnType("varchar(255) CHARACTER SET utf8mb4"); + + b.HasKey("LoginProvider", "ProviderKey"); + + b.HasIndex("UserId"); + + b.ToTable("AspNetUserLogins"); + }); + + modelBuilder.Entity("Microsoft.AspNetCore.Identity.IdentityUserRole", b => + { + b.Property("UserId") + .HasColumnType("varchar(255) CHARACTER SET utf8mb4"); + + b.Property("RoleId") + .HasColumnType("varchar(255) CHARACTER SET utf8mb4"); + + b.HasKey("UserId", "RoleId"); + + b.HasIndex("RoleId"); + + b.ToTable("AspNetUserRoles"); + }); + + modelBuilder.Entity("Microsoft.AspNetCore.Identity.IdentityUserToken", b => + { + b.Property("UserId") + .HasColumnType("varchar(255) CHARACTER SET utf8mb4"); + + b.Property("LoginProvider") + .HasColumnType("varchar(255) CHARACTER SET utf8mb4"); + + b.Property("Name") + .HasColumnType("varchar(255) CHARACTER SET utf8mb4"); + + b.Property("Value") + .HasColumnType("longtext CHARACTER SET utf8mb4"); + + b.HasKey("UserId", "LoginProvider", "Name"); + + b.ToTable("AspNetUserTokens"); + }); + + modelBuilder.Entity("Nethereum.eShop.Infrastructure.Identity.ApplicationUser", b => + { + b.Property("Id") + .HasColumnType("varchar(255) CHARACTER SET utf8mb4"); + + b.Property("AccessFailedCount") + .HasColumnType("int"); + + b.Property("ConcurrencyStamp") + .IsConcurrencyToken() + .HasColumnType("longtext CHARACTER SET utf8mb4"); + + b.Property("Email") + .HasColumnType("varchar(256) CHARACTER SET utf8mb4") + .HasMaxLength(256); + + b.Property("EmailConfirmed") + .HasColumnType("tinyint(1)"); + + b.Property("LockoutEnabled") + .HasColumnType("tinyint(1)"); + + b.Property("LockoutEnd") + .HasColumnType("datetime(6)"); + + b.Property("NormalizedEmail") + .HasColumnType("varchar(256) CHARACTER SET utf8mb4") + .HasMaxLength(256); + + b.Property("NormalizedUserName") + .HasColumnType("varchar(256) CHARACTER SET utf8mb4") + .HasMaxLength(256); + + b.Property("PasswordHash") + .HasColumnType("longtext CHARACTER SET utf8mb4"); + + b.Property("PhoneNumber") + .HasColumnType("longtext CHARACTER SET utf8mb4"); + + b.Property("PhoneNumberConfirmed") + .HasColumnType("tinyint(1)"); + + b.Property("SecurityStamp") + .HasColumnType("longtext CHARACTER SET utf8mb4"); + + b.Property("TwoFactorEnabled") + .HasColumnType("tinyint(1)"); + + b.Property("UserName") + .HasColumnType("varchar(256) CHARACTER SET utf8mb4") + .HasMaxLength(256); + + b.HasKey("Id"); + + b.HasIndex("NormalizedEmail") + .HasName("EmailIndex"); + + b.HasIndex("NormalizedUserName") + .IsUnique() + .HasName("UserNameIndex"); + + b.ToTable("AspNetUsers"); + }); + + modelBuilder.Entity("Microsoft.AspNetCore.Identity.IdentityRoleClaim", b => + { + b.HasOne("Microsoft.AspNetCore.Identity.IdentityRole", null) + .WithMany() + .HasForeignKey("RoleId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + }); + + modelBuilder.Entity("Microsoft.AspNetCore.Identity.IdentityUserClaim", b => + { + b.HasOne("Nethereum.eShop.Infrastructure.Identity.ApplicationUser", null) + .WithMany() + .HasForeignKey("UserId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + }); + + modelBuilder.Entity("Microsoft.AspNetCore.Identity.IdentityUserLogin", b => + { + b.HasOne("Nethereum.eShop.Infrastructure.Identity.ApplicationUser", null) + .WithMany() + .HasForeignKey("UserId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + }); + + modelBuilder.Entity("Microsoft.AspNetCore.Identity.IdentityUserRole", b => + { + b.HasOne("Microsoft.AspNetCore.Identity.IdentityRole", null) + .WithMany() + .HasForeignKey("RoleId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.HasOne("Nethereum.eShop.Infrastructure.Identity.ApplicationUser", null) + .WithMany() + .HasForeignKey("UserId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + }); + + modelBuilder.Entity("Microsoft.AspNetCore.Identity.IdentityUserToken", b => + { + b.HasOne("Nethereum.eShop.Infrastructure.Identity.ApplicationUser", null) + .WithMany() + .HasForeignKey("UserId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + }); +#pragma warning restore 612, 618 + } + } +} diff --git a/src/Nethereum.eShop.MySql/Identity/Migrations/Scripts/CreateIdentityDb.sql b/src/Nethereum.eShop.MySql/Identity/Migrations/Scripts/CreateIdentityDb.sql new file mode 100644 index 0000000..5a408b3 --- /dev/null +++ b/src/Nethereum.eShop.MySql/Identity/Migrations/Scripts/CreateIdentityDb.sql @@ -0,0 +1,289 @@ +CREATE TABLE IF NOT EXISTS `__EFMigrationsHistory` ( + `MigrationId` varchar(95) NOT NULL, + `ProductVersion` varchar(32) NOT NULL, + CONSTRAINT `PK___EFMigrationsHistory` PRIMARY KEY (`MigrationId`) +); + + +DROP PROCEDURE IF EXISTS MigrationsScript; +DELIMITER // +CREATE PROCEDURE MigrationsScript() +BEGIN + IF NOT EXISTS(SELECT 1 FROM `__EFMigrationsHistory` WHERE `MigrationId` = '20200312152429_InitialCreate') THEN + + CREATE TABLE `AspNetRoles` ( + `Id` varchar(255) CHARACTER SET utf8mb4 NOT NULL, + `Name` varchar(256) CHARACTER SET utf8mb4 NULL, + `NormalizedName` varchar(256) CHARACTER SET utf8mb4 NULL, + `ConcurrencyStamp` longtext CHARACTER SET utf8mb4 NULL, + CONSTRAINT `PK_AspNetRoles` PRIMARY KEY (`Id`) + ); + + END IF; +END // +DELIMITER ; +CALL MigrationsScript(); +DROP PROCEDURE MigrationsScript; + + +DROP PROCEDURE IF EXISTS MigrationsScript; +DELIMITER // +CREATE PROCEDURE MigrationsScript() +BEGIN + IF NOT EXISTS(SELECT 1 FROM `__EFMigrationsHistory` WHERE `MigrationId` = '20200312152429_InitialCreate') THEN + + CREATE TABLE `AspNetUsers` ( + `Id` varchar(255) CHARACTER SET utf8mb4 NOT NULL, + `UserName` varchar(256) CHARACTER SET utf8mb4 NULL, + `NormalizedUserName` varchar(256) CHARACTER SET utf8mb4 NULL, + `Email` varchar(256) CHARACTER SET utf8mb4 NULL, + `NormalizedEmail` varchar(256) CHARACTER SET utf8mb4 NULL, + `EmailConfirmed` tinyint(1) NOT NULL, + `PasswordHash` longtext CHARACTER SET utf8mb4 NULL, + `SecurityStamp` longtext CHARACTER SET utf8mb4 NULL, + `ConcurrencyStamp` longtext CHARACTER SET utf8mb4 NULL, + `PhoneNumber` longtext CHARACTER SET utf8mb4 NULL, + `PhoneNumberConfirmed` tinyint(1) NOT NULL, + `TwoFactorEnabled` tinyint(1) NOT NULL, + `LockoutEnd` datetime(6) NULL, + `LockoutEnabled` tinyint(1) NOT NULL, + `AccessFailedCount` int NOT NULL, + CONSTRAINT `PK_AspNetUsers` PRIMARY KEY (`Id`) + ); + + END IF; +END // +DELIMITER ; +CALL MigrationsScript(); +DROP PROCEDURE MigrationsScript; + + +DROP PROCEDURE IF EXISTS MigrationsScript; +DELIMITER // +CREATE PROCEDURE MigrationsScript() +BEGIN + IF NOT EXISTS(SELECT 1 FROM `__EFMigrationsHistory` WHERE `MigrationId` = '20200312152429_InitialCreate') THEN + + CREATE TABLE `AspNetRoleClaims` ( + `Id` int NOT NULL AUTO_INCREMENT, + `RoleId` varchar(255) CHARACTER SET utf8mb4 NOT NULL, + `ClaimType` longtext CHARACTER SET utf8mb4 NULL, + `ClaimValue` longtext CHARACTER SET utf8mb4 NULL, + CONSTRAINT `PK_AspNetRoleClaims` PRIMARY KEY (`Id`), + CONSTRAINT `FK_AspNetRoleClaims_AspNetRoles_RoleId` FOREIGN KEY (`RoleId`) REFERENCES `AspNetRoles` (`Id`) ON DELETE CASCADE + ); + + END IF; +END // +DELIMITER ; +CALL MigrationsScript(); +DROP PROCEDURE MigrationsScript; + + +DROP PROCEDURE IF EXISTS MigrationsScript; +DELIMITER // +CREATE PROCEDURE MigrationsScript() +BEGIN + IF NOT EXISTS(SELECT 1 FROM `__EFMigrationsHistory` WHERE `MigrationId` = '20200312152429_InitialCreate') THEN + + CREATE TABLE `AspNetUserClaims` ( + `Id` int NOT NULL AUTO_INCREMENT, + `UserId` varchar(255) CHARACTER SET utf8mb4 NOT NULL, + `ClaimType` longtext CHARACTER SET utf8mb4 NULL, + `ClaimValue` longtext CHARACTER SET utf8mb4 NULL, + CONSTRAINT `PK_AspNetUserClaims` PRIMARY KEY (`Id`), + CONSTRAINT `FK_AspNetUserClaims_AspNetUsers_UserId` FOREIGN KEY (`UserId`) REFERENCES `AspNetUsers` (`Id`) ON DELETE CASCADE + ); + + END IF; +END // +DELIMITER ; +CALL MigrationsScript(); +DROP PROCEDURE MigrationsScript; + + +DROP PROCEDURE IF EXISTS MigrationsScript; +DELIMITER // +CREATE PROCEDURE MigrationsScript() +BEGIN + IF NOT EXISTS(SELECT 1 FROM `__EFMigrationsHistory` WHERE `MigrationId` = '20200312152429_InitialCreate') THEN + + CREATE TABLE `AspNetUserLogins` ( + `LoginProvider` varchar(255) CHARACTER SET utf8mb4 NOT NULL, + `ProviderKey` varchar(255) CHARACTER SET utf8mb4 NOT NULL, + `ProviderDisplayName` longtext CHARACTER SET utf8mb4 NULL, + `UserId` varchar(255) CHARACTER SET utf8mb4 NOT NULL, + CONSTRAINT `PK_AspNetUserLogins` PRIMARY KEY (`LoginProvider`, `ProviderKey`), + CONSTRAINT `FK_AspNetUserLogins_AspNetUsers_UserId` FOREIGN KEY (`UserId`) REFERENCES `AspNetUsers` (`Id`) ON DELETE CASCADE + ); + + END IF; +END // +DELIMITER ; +CALL MigrationsScript(); +DROP PROCEDURE MigrationsScript; + + +DROP PROCEDURE IF EXISTS MigrationsScript; +DELIMITER // +CREATE PROCEDURE MigrationsScript() +BEGIN + IF NOT EXISTS(SELECT 1 FROM `__EFMigrationsHistory` WHERE `MigrationId` = '20200312152429_InitialCreate') THEN + + CREATE TABLE `AspNetUserRoles` ( + `UserId` varchar(255) CHARACTER SET utf8mb4 NOT NULL, + `RoleId` varchar(255) CHARACTER SET utf8mb4 NOT NULL, + CONSTRAINT `PK_AspNetUserRoles` PRIMARY KEY (`UserId`, `RoleId`), + CONSTRAINT `FK_AspNetUserRoles_AspNetRoles_RoleId` FOREIGN KEY (`RoleId`) REFERENCES `AspNetRoles` (`Id`) ON DELETE CASCADE, + CONSTRAINT `FK_AspNetUserRoles_AspNetUsers_UserId` FOREIGN KEY (`UserId`) REFERENCES `AspNetUsers` (`Id`) ON DELETE CASCADE + ); + + END IF; +END // +DELIMITER ; +CALL MigrationsScript(); +DROP PROCEDURE MigrationsScript; + + +DROP PROCEDURE IF EXISTS MigrationsScript; +DELIMITER // +CREATE PROCEDURE MigrationsScript() +BEGIN + IF NOT EXISTS(SELECT 1 FROM `__EFMigrationsHistory` WHERE `MigrationId` = '20200312152429_InitialCreate') THEN + + CREATE TABLE `AspNetUserTokens` ( + `UserId` varchar(255) CHARACTER SET utf8mb4 NOT NULL, + `LoginProvider` varchar(255) CHARACTER SET utf8mb4 NOT NULL, + `Name` varchar(255) CHARACTER SET utf8mb4 NOT NULL, + `Value` longtext CHARACTER SET utf8mb4 NULL, + CONSTRAINT `PK_AspNetUserTokens` PRIMARY KEY (`UserId`, `LoginProvider`, `Name`), + CONSTRAINT `FK_AspNetUserTokens_AspNetUsers_UserId` FOREIGN KEY (`UserId`) REFERENCES `AspNetUsers` (`Id`) ON DELETE CASCADE + ); + + END IF; +END // +DELIMITER ; +CALL MigrationsScript(); +DROP PROCEDURE MigrationsScript; + + +DROP PROCEDURE IF EXISTS MigrationsScript; +DELIMITER // +CREATE PROCEDURE MigrationsScript() +BEGIN + IF NOT EXISTS(SELECT 1 FROM `__EFMigrationsHistory` WHERE `MigrationId` = '20200312152429_InitialCreate') THEN + + CREATE INDEX `IX_AspNetRoleClaims_RoleId` ON `AspNetRoleClaims` (`RoleId`); + + END IF; +END // +DELIMITER ; +CALL MigrationsScript(); +DROP PROCEDURE MigrationsScript; + + +DROP PROCEDURE IF EXISTS MigrationsScript; +DELIMITER // +CREATE PROCEDURE MigrationsScript() +BEGIN + IF NOT EXISTS(SELECT 1 FROM `__EFMigrationsHistory` WHERE `MigrationId` = '20200312152429_InitialCreate') THEN + + CREATE UNIQUE INDEX `RoleNameIndex` ON `AspNetRoles` (`NormalizedName`); + + END IF; +END // +DELIMITER ; +CALL MigrationsScript(); +DROP PROCEDURE MigrationsScript; + + +DROP PROCEDURE IF EXISTS MigrationsScript; +DELIMITER // +CREATE PROCEDURE MigrationsScript() +BEGIN + IF NOT EXISTS(SELECT 1 FROM `__EFMigrationsHistory` WHERE `MigrationId` = '20200312152429_InitialCreate') THEN + + CREATE INDEX `IX_AspNetUserClaims_UserId` ON `AspNetUserClaims` (`UserId`); + + END IF; +END // +DELIMITER ; +CALL MigrationsScript(); +DROP PROCEDURE MigrationsScript; + + +DROP PROCEDURE IF EXISTS MigrationsScript; +DELIMITER // +CREATE PROCEDURE MigrationsScript() +BEGIN + IF NOT EXISTS(SELECT 1 FROM `__EFMigrationsHistory` WHERE `MigrationId` = '20200312152429_InitialCreate') THEN + + CREATE INDEX `IX_AspNetUserLogins_UserId` ON `AspNetUserLogins` (`UserId`); + + END IF; +END // +DELIMITER ; +CALL MigrationsScript(); +DROP PROCEDURE MigrationsScript; + + +DROP PROCEDURE IF EXISTS MigrationsScript; +DELIMITER // +CREATE PROCEDURE MigrationsScript() +BEGIN + IF NOT EXISTS(SELECT 1 FROM `__EFMigrationsHistory` WHERE `MigrationId` = '20200312152429_InitialCreate') THEN + + CREATE INDEX `IX_AspNetUserRoles_RoleId` ON `AspNetUserRoles` (`RoleId`); + + END IF; +END // +DELIMITER ; +CALL MigrationsScript(); +DROP PROCEDURE MigrationsScript; + + +DROP PROCEDURE IF EXISTS MigrationsScript; +DELIMITER // +CREATE PROCEDURE MigrationsScript() +BEGIN + IF NOT EXISTS(SELECT 1 FROM `__EFMigrationsHistory` WHERE `MigrationId` = '20200312152429_InitialCreate') THEN + + CREATE INDEX `EmailIndex` ON `AspNetUsers` (`NormalizedEmail`); + + END IF; +END // +DELIMITER ; +CALL MigrationsScript(); +DROP PROCEDURE MigrationsScript; + + +DROP PROCEDURE IF EXISTS MigrationsScript; +DELIMITER // +CREATE PROCEDURE MigrationsScript() +BEGIN + IF NOT EXISTS(SELECT 1 FROM `__EFMigrationsHistory` WHERE `MigrationId` = '20200312152429_InitialCreate') THEN + + CREATE UNIQUE INDEX `UserNameIndex` ON `AspNetUsers` (`NormalizedUserName`); + + END IF; +END // +DELIMITER ; +CALL MigrationsScript(); +DROP PROCEDURE MigrationsScript; + + +DROP PROCEDURE IF EXISTS MigrationsScript; +DELIMITER // +CREATE PROCEDURE MigrationsScript() +BEGIN + IF NOT EXISTS(SELECT 1 FROM `__EFMigrationsHistory` WHERE `MigrationId` = '20200312152429_InitialCreate') THEN + + INSERT INTO `__EFMigrationsHistory` (`MigrationId`, `ProductVersion`) + VALUES ('20200312152429_InitialCreate', '3.1.2'); + + END IF; +END // +DELIMITER ; +CALL MigrationsScript(); +DROP PROCEDURE MigrationsScript; + diff --git a/src/Nethereum.eShop.MySql/Identity/MySqlAppIdentityDbContext.cs b/src/Nethereum.eShop.MySql/Identity/MySqlAppIdentityDbContext.cs new file mode 100644 index 0000000..b58ebd2 --- /dev/null +++ b/src/Nethereum.eShop.MySql/Identity/MySqlAppIdentityDbContext.cs @@ -0,0 +1,25 @@ +using Microsoft.EntityFrameworkCore; +using Microsoft.EntityFrameworkCore.Design; +using Nethereum.eShop.EntityFramework.Identity; + +namespace Nethereum.eShop.MySql.Identity +{ + public class MySqlAppIdentityDbContext : AppIdentityDbContext + { + public MySqlAppIdentityDbContext(DbContextOptions options) : base(options) + { + } + } + + public class MySqlAppIdentityDbContextDesignTimeFactory : IDesignTimeDbContextFactory + { + public MySqlAppIdentityDbContext CreateDbContext(string[] args) + { + var optionsBuilder = new DbContextOptionsBuilder(); + optionsBuilder.UseMySql("server=localhost;database=library;user=user;password=password"); + + return new MySqlAppIdentityDbContext( + optionsBuilder.Options); + } + } +} diff --git a/src/Nethereum.eShop.MySql/Identity/MySqlEShopAppIdentityDbBootstrapper.cs b/src/Nethereum.eShop.MySql/Identity/MySqlEShopAppIdentityDbBootstrapper.cs new file mode 100644 index 0000000..671f915 --- /dev/null +++ b/src/Nethereum.eShop.MySql/Identity/MySqlEShopAppIdentityDbBootstrapper.cs @@ -0,0 +1,17 @@ +using Microsoft.EntityFrameworkCore; +using Microsoft.Extensions.Configuration; +using Microsoft.Extensions.DependencyInjection; +using Nethereum.eShop.ApplicationCore.Interfaces; +using Nethereum.eShop.EntityFramework.Identity; + +namespace Nethereum.eShop.MySql.Identity +{ + public class MySqlEShopAppIdentityDbBootstrapper : EShopAppIdentityDbBootstrapperBase, IEShopIdentityDbBootstrapper + { + public void AddDbContext(IServiceCollection services, IConfiguration configuration) + { + services.AddDbContext(options => + options.UseMySql(configuration.GetConnectionString("IdentityConnection_MySql"))); + } + } +} diff --git a/src/Nethereum.eShop.MySql/Nethereum.eShop.MySql.csproj b/src/Nethereum.eShop.MySql/Nethereum.eShop.MySql.csproj new file mode 100644 index 0000000..d41681d --- /dev/null +++ b/src/Nethereum.eShop.MySql/Nethereum.eShop.MySql.csproj @@ -0,0 +1,20 @@ + + + + netstandard2.1 + + + + + + + + + + + + + + + + diff --git a/src/Nethereum.eShop.sln b/src/Nethereum.eShop.sln index 854e448..bc7e62c 100644 --- a/src/Nethereum.eShop.sln +++ b/src/Nethereum.eShop.sln @@ -41,6 +41,8 @@ Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Nethereum.eShop.Migrations" EndProject Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "migration", "migration", "{487D2931-4813-4280-9FE1-E1AA7EA6ED34}" EndProject +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Nethereum.eShop.MySql", "Nethereum.eShop.MySql\Nethereum.eShop.MySql.csproj", "{D607FEC2-2145-4660-A391-AE0737D5BE8B}" +EndProject Global GlobalSection(SolutionConfigurationPlatforms) = preSolution Debug|Any CPU = Debug|Any CPU @@ -95,6 +97,10 @@ Global {0E47F900-DBE4-4AFB-86A1-376303CECDFB}.Debug|Any CPU.Build.0 = Debug|Any CPU {0E47F900-DBE4-4AFB-86A1-376303CECDFB}.Release|Any CPU.ActiveCfg = Release|Any CPU {0E47F900-DBE4-4AFB-86A1-376303CECDFB}.Release|Any CPU.Build.0 = Release|Any CPU + {D607FEC2-2145-4660-A391-AE0737D5BE8B}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {D607FEC2-2145-4660-A391-AE0737D5BE8B}.Debug|Any CPU.Build.0 = Debug|Any CPU + {D607FEC2-2145-4660-A391-AE0737D5BE8B}.Release|Any CPU.ActiveCfg = Release|Any CPU + {D607FEC2-2145-4660-A391-AE0737D5BE8B}.Release|Any CPU.Build.0 = Release|Any CPU EndGlobalSection GlobalSection(SolutionProperties) = preSolution HideSolutionNode = FALSE @@ -113,6 +119,7 @@ Global {173B3ACF-DB6E-497C-B778-4BBEB53EFA3A} = {8ABF2EF8-3DBE-4F90-A681-9CBAF211EA6D} {0E47F900-DBE4-4AFB-86A1-376303CECDFB} = {487D2931-4813-4280-9FE1-E1AA7EA6ED34} {487D2931-4813-4280-9FE1-E1AA7EA6ED34} = {8ABF2EF8-3DBE-4F90-A681-9CBAF211EA6D} + {D607FEC2-2145-4660-A391-AE0737D5BE8B} = {8ABF2EF8-3DBE-4F90-A681-9CBAF211EA6D} EndGlobalSection GlobalSection(ExtensibilityGlobals) = postSolution SolutionGuid = {8BEA2189-D111-472E-BA29-993E206C6CE3} diff --git a/src/Web/appsettings.json b/src/Web/appsettings.json index 16c13d4..477be89 100644 --- a/src/Web/appsettings.json +++ b/src/Web/appsettings.json @@ -5,7 +5,9 @@ "CatalogConnection_SqlServer": "Server=localhost;Integrated Security=true;Initial Catalog=eShop;", "IdentityConnection_SqlServer": "Server=localhost;Integrated Security=true;Initial Catalog=eShop;", "CatalogConnection_Sqlite": "Data Source=C:/temp/eshop_catalog.db", - "IdentityConnection_Sqlite": "Data Source=C:/temp/eshop_app_identity.db" + "IdentityConnection_Sqlite": "Data Source=C:/temp/eshop_app_identity.db", + "CatalogConnection_MySql": "server=localhost;database=eShop;user=user;password=password", + "IdentityConnection_MySql": "server=localhost;database=eShop;user=user;password=password" }, // SqlServer, Sqlite, InMemory (default) "CatalogDbProvider": "InMemory", diff --git a/src/utils/Books.ImportUtil/Books.ImportUtil.csproj b/src/utils/Books.ImportUtil/Books.ImportUtil.csproj index 89d39c8..0a0d91f 100644 --- a/src/utils/Books.ImportUtil/Books.ImportUtil.csproj +++ b/src/utils/Books.ImportUtil/Books.ImportUtil.csproj @@ -18,6 +18,7 @@ + diff --git a/src/utils/Books.ImportUtil/TopRankBookImportUtil.cs b/src/utils/Books.ImportUtil/TopRankBookImportUtil.cs index ebcedf4..9f293e1 100644 --- a/src/utils/Books.ImportUtil/TopRankBookImportUtil.cs +++ b/src/utils/Books.ImportUtil/TopRankBookImportUtil.cs @@ -1,6 +1,5 @@ -using CsvHelper.Configuration; -using Nethereum.eShop.ApplicationCore.Entities; -using Nethereum.eShop.Infrastructure.Data; +using Nethereum.eShop.ApplicationCore.Entities; +using Nethereum.eShop.EntityFramework.Catalog.Seed; using Newtonsoft.Json; using System; using System.Collections.Generic; @@ -104,10 +103,10 @@ private static CatalogImportDto GenerateCatalogImport( Dictionary> bookCoverDictionary) { var excerpt = new CatalogImportDto(); - var bookCatalogType = new CatalogType { Id = 1, Type = "Book" }; + var bookCatalogType = new CatalogTypeForImport { Id = 1, Type = "Book" }; excerpt.CatalogTypes.Add(bookCatalogType); - var authorDictionary = new Dictionary(StringComparer.OrdinalIgnoreCase); + var authorDictionary = new Dictionary(StringComparer.OrdinalIgnoreCase); int id = 0; int authorIdCounter = 0; @@ -125,19 +124,19 @@ private static CatalogImportDto GenerateCatalogImport( return excerpt; } - private static CatalogItem Convert( + private static CatalogItemForImport Convert( int catalogTypeIdForBooks, BookWithDescription book, Dictionary> bookCoverDictionary, int id, - Dictionary authorDictionary, + Dictionary authorDictionary, ref int authorIdCounter) { if (!authorDictionary.ContainsKey(book.Book.AUTHOR)) { authorIdCounter++; - authorDictionary[book.Book.AUTHOR] = new CatalogBrand + authorDictionary[book.Book.AUTHOR] = new CatalogBrandForImport { Id = authorIdCounter, Brand = book.Book.AUTHOR @@ -164,7 +163,7 @@ private static CatalogItem Convert( return Decimal.TryParse(i, out var d) ? (int)(d * 25.4m) : 0; }); - var catalogItem = new CatalogItem { + var catalogItem = new CatalogItemForImport { Id = id, Rank = id, Gtin = book.Book.EAN, From 6459924dc8adead74ac8a0a9df7f9022ee02d52d Mon Sep 17 00:00:00 2001 From: Dave Whiffin Date: Tue, 31 Mar 2020 13:00:35 +0100 Subject: [PATCH 21/27] Merged Kevin's contract changes. Removed old columns and created migrations. --- docs/eShop-Db-Design.md | 11 + .../EntityBuilders/OrderConfiguration.cs | 3 - .../Catalog/Queries/OrderQueries.cs | 1 - .../AddCatalogMigration _MySql.bat | 1 - .../AddCatalogMigration.bat | 3 +- .../AddIdentityMigration.bat | 3 +- .../AddIdentityMigration_MySql.bat | 1 - src/Nethereum.eShop.Migrations/Program.cs | 10 +- .../ScriptCatalogDb.bat | 3 +- .../ScriptCatalogDb_MySql.bat | 1 - .../ScriptIdentityDb.bat | 3 +- .../ScriptIdentityDb_MySql.bat | 1 - ...34_RemoveBuyerAndWalletAddress.Designer.cs | 906 +++++++++++++++++ ...00331114834_RemoveBuyerAndWalletAddress.cs | 44 + .../MySqlCatalogContextModelSnapshot.cs | 10 - .../Migrations/Scripts/CreateCatalogDb.sql | 61 ++ ...18_RemoveBuyerAndWalletAddress.Designer.cs | 948 ++++++++++++++++++ ...00331114818_RemoveBuyerAndWalletAddress.cs | 44 + .../Migrations/Scripts/CreateCatalogDb.sql | 41 + .../SqlServerCatalogContextModelSnapshot.cs | 10 - ...26_RemoveBuyerAndWalletAddress.Designer.cs | 905 +++++++++++++++++ ...00331114826_RemoveBuyerAndWalletAddress.cs | 50 + .../Migrations/Scripts/CreateCatalogDb.sql | 5 + .../SqliteCatalogContextModelSnapshot.cs | 10 - .../Entities/OrderAggregate/Order.cs | 13 +- .../ApplicationCore/Services/OrderService.cs | 4 +- src/WebJobs/Config/EshopConfiguration.cs | 4 +- src/WebJobs/Jobs/CreateFakePurchaseOrders.cs | 26 +- .../Jobs/ProcessPurchaseOrderEventLogs.cs | 10 +- src/WebJobs/appsettings.json | 2 +- 30 files changed, 3054 insertions(+), 80 deletions(-) create mode 100644 docs/eShop-Db-Design.md delete mode 100644 src/Nethereum.eShop.Migrations/AddCatalogMigration _MySql.bat delete mode 100644 src/Nethereum.eShop.Migrations/AddIdentityMigration_MySql.bat delete mode 100644 src/Nethereum.eShop.Migrations/ScriptCatalogDb_MySql.bat delete mode 100644 src/Nethereum.eShop.Migrations/ScriptIdentityDb_MySql.bat create mode 100644 src/Nethereum.eShop.MySql/Catalog/Migrations/20200331114834_RemoveBuyerAndWalletAddress.Designer.cs create mode 100644 src/Nethereum.eShop.MySql/Catalog/Migrations/20200331114834_RemoveBuyerAndWalletAddress.cs create mode 100644 src/Nethereum.eShop.SqlServer/Catalog/Migrations/20200331114818_RemoveBuyerAndWalletAddress.Designer.cs create mode 100644 src/Nethereum.eShop.SqlServer/Catalog/Migrations/20200331114818_RemoveBuyerAndWalletAddress.cs create mode 100644 src/Nethereum.eShop.Sqlite/Catalog/Migrations/20200331114826_RemoveBuyerAndWalletAddress.Designer.cs create mode 100644 src/Nethereum.eShop.Sqlite/Catalog/Migrations/20200331114826_RemoveBuyerAndWalletAddress.cs diff --git a/docs/eShop-Db-Design.md b/docs/eShop-Db-Design.md new file mode 100644 index 0000000..26450d1 --- /dev/null +++ b/docs/eShop-Db-Design.md @@ -0,0 +1,11 @@ +# Nethereum eShop Db Design + +The eShop takes a hybrid approach to decentralisation. It attempts to balance Blockchain benefits with some requirements for off-chain processing and storage. For instance, data which is subject to privacy rules may not belong on chain (e.g. personal postal addresses) whilst some documents (e.g. proof of purchase) may suit on chain storage perfectly. + +## Data Layer + +The core business services in the Nethereum.eShop are agnostic of the actual data persistence provider. A mixture of the repository and CQRS patterns are present. The repositories are typically involved in business unit transactions whilst queries are for highly optimised, performance intensive requirements which may require a provider specific implementation or additional resources such as data warehouses, external API's, search services etc. As a basic example, Entity Framework Core can provide a repository layer implementation whilst Dapper can help provide optimised queries which in some organisations remain under DBA control. + +One of the primary reasons for this was that some entities would be likely to move from one storage solution to another over time. Some entities which can't be stored on chain at present may be able to go on chain in the future once specific privacy concerns have been addressed in core Blockchain technology. + +Both the repository or query interfaces are agnostic of provider. diff --git a/src/Nethereum.eShop.EntityFramework/Catalog/EntityBuilders/OrderConfiguration.cs b/src/Nethereum.eShop.EntityFramework/Catalog/EntityBuilders/OrderConfiguration.cs index 11b40f7..06d4657 100644 --- a/src/Nethereum.eShop.EntityFramework/Catalog/EntityBuilders/OrderConfiguration.cs +++ b/src/Nethereum.eShop.EntityFramework/Catalog/EntityBuilders/OrderConfiguration.cs @@ -15,8 +15,6 @@ public virtual void Configure(EntityTypeBuilder builder) builder.OwnsOne(o => o.ShipTo, a => a.ConfigureAddress()); builder.OwnsOne(o => o.BillTo, a => a.ConfigureAddress()); builder.Property(o => o.BuyerId).HasMaxLength(256).IsRequired(); - builder.Property(o => o.BuyerAddress).IsAddress(); - builder.Property(o => o.ApproverAddress).IsAddress(); builder.Property(o => o.BuyerWalletAddress).IsAddress(); builder.Property(o => o.TransactionHash).IsHash(); builder.Property(o => o.CurrencyAddress).IsAddress(); @@ -24,7 +22,6 @@ public virtual void Configure(EntityTypeBuilder builder) builder.Property(o => o.SellerId).IsBytes32(); builder.HasIndex(b => b.BuyerId); - builder.HasIndex(b => b.BuyerAddress); } } } diff --git a/src/Nethereum.eShop.InMemory/Catalog/Queries/OrderQueries.cs b/src/Nethereum.eShop.InMemory/Catalog/Queries/OrderQueries.cs index 5318ff4..affb0cc 100644 --- a/src/Nethereum.eShop.InMemory/Catalog/Queries/OrderQueries.cs +++ b/src/Nethereum.eShop.InMemory/Catalog/Queries/OrderQueries.cs @@ -29,7 +29,6 @@ public async Task> GetByBuyerIdAsync(string buyerI { BillTo_RecipientName = o.BillTo.RecipientName, BillTo_ZipCode = o.BillTo.ZipCode, - BuyerAddress = o.BuyerAddress, BuyerId = o.BuyerId, CurrencySymbol = o.CurrencySymbol, ItemCount = o.ItemCount(), diff --git a/src/Nethereum.eShop.Migrations/AddCatalogMigration _MySql.bat b/src/Nethereum.eShop.Migrations/AddCatalogMigration _MySql.bat deleted file mode 100644 index 109e774..0000000 --- a/src/Nethereum.eShop.Migrations/AddCatalogMigration _MySql.bat +++ /dev/null @@ -1 +0,0 @@ -dotnet ef migrations add %1 --project ..\Nethereum.eShop.MySql --context Nethereum.eShop.MySql.Catalog.MySqlCatalogContext --output-dir ..\Nethereum.eShop.MySql\Catalog\Migrations \ No newline at end of file diff --git a/src/Nethereum.eShop.Migrations/AddCatalogMigration.bat b/src/Nethereum.eShop.Migrations/AddCatalogMigration.bat index 10e6197..38a859b 100644 --- a/src/Nethereum.eShop.Migrations/AddCatalogMigration.bat +++ b/src/Nethereum.eShop.Migrations/AddCatalogMigration.bat @@ -1,2 +1,3 @@ dotnet ef migrations add %1 --project ..\Nethereum.eShop.SqlServer --context Nethereum.eShop.SqlServer.Catalog.SqlServerCatalogContext --output-dir ..\Nethereum.eShop.SqlServer\Catalog\Migrations -dotnet ef migrations add %1 --project ..\Nethereum.eShop.Sqlite --context Nethereum.eShop.Sqlite.Catalog.SqliteCatalogContext --output-dir ..\Nethereum.eShop.Sqlite\Catalog\Migrations \ No newline at end of file +dotnet ef migrations add %1 --project ..\Nethereum.eShop.Sqlite --context Nethereum.eShop.Sqlite.Catalog.SqliteCatalogContext --output-dir ..\Nethereum.eShop.Sqlite\Catalog\Migrations +dotnet ef migrations add %1 --project ..\Nethereum.eShop.MySql --context Nethereum.eShop.MySql.Catalog.MySqlCatalogContext --output-dir ..\Nethereum.eShop.MySql\Catalog\Migrations \ No newline at end of file diff --git a/src/Nethereum.eShop.Migrations/AddIdentityMigration.bat b/src/Nethereum.eShop.Migrations/AddIdentityMigration.bat index 6e27901..2ce8910 100644 --- a/src/Nethereum.eShop.Migrations/AddIdentityMigration.bat +++ b/src/Nethereum.eShop.Migrations/AddIdentityMigration.bat @@ -1,2 +1,3 @@ dotnet ef migrations add %1 --project ..\Nethereum.eShop.SqlServer --context Nethereum.eShop.SqlServer.Identity.SqlServerAppIdentityDbContext --output-dir ..\Nethereum.eShop.SqlServer\Identity\Migrations -dotnet ef migrations add %1 --project ..\Nethereum.eShop.Sqlite --context Nethereum.eShop.Sqlite.Identity.SqliteAppIdentityDbContext --output-dir ..\Nethereum.eShop.Sqlite\Identity\Migrations \ No newline at end of file +dotnet ef migrations add %1 --project ..\Nethereum.eShop.Sqlite --context Nethereum.eShop.Sqlite.Identity.SqliteAppIdentityDbContext --output-dir ..\Nethereum.eShop.Sqlite\Identity\Migrations +dotnet ef migrations add %1 --project ..\Nethereum.eShop.MySql --context Nethereum.eShop.MySql.Identity.MySqlAppIdentityDbContext --output-dir ..\Nethereum.eShop.MySql\Identity\Migrations \ No newline at end of file diff --git a/src/Nethereum.eShop.Migrations/AddIdentityMigration_MySql.bat b/src/Nethereum.eShop.Migrations/AddIdentityMigration_MySql.bat deleted file mode 100644 index 1015452..0000000 --- a/src/Nethereum.eShop.Migrations/AddIdentityMigration_MySql.bat +++ /dev/null @@ -1 +0,0 @@ -dotnet ef migrations add %1 --project ..\Nethereum.eShop.MySql --context Nethereum.eShop.MySql.Identity.MySqlAppIdentityDbContext --output-dir ..\Nethereum.eShop.MySql\Identity\Migrations \ No newline at end of file diff --git a/src/Nethereum.eShop.Migrations/Program.cs b/src/Nethereum.eShop.Migrations/Program.cs index 8dbfa3f..5f9c882 100644 --- a/src/Nethereum.eShop.Migrations/Program.cs +++ b/src/Nethereum.eShop.Migrations/Program.cs @@ -10,12 +10,12 @@ static void Main(string[] args) Console.WriteLine("This 'Nethereum.eShop.Migrations' console is only for generating Entity Framework Migrations"); Console.WriteLine("It is ONLY intended to be run as the startup project for the dotnet-ef tool to add a migration or create a script"); Console.WriteLine(); - Console.WriteLine("To add a name migration - go to command line and run AddMigration.bat {name}"); - Console.WriteLine("This will create migrations for each DB provider (e.g. SqlServer, Sqlite)"); - Console.WriteLine(" e.g. AddMigration.bat InitialCreate"); + Console.WriteLine("To add a named migration - go to the command line and run either AddCatalogMigration.bat or AddIdentityMigratoin.bat and supply the name of the migration"); + Console.WriteLine("This will create migrations for each DB provider (e.g. SqlServer, Sqlite, MySql etc)"); + Console.WriteLine(" e.g. AddCatalogMigration.bat InitialCreate"); Console.ReadLine(); - Console.WriteLine("To create a SQL Script for DB Creation (e.g. SqlServer, Sqlite)"); - Console.WriteLine(" e.g. ScriptDbs.bat"); + Console.WriteLine("To create SQL Scripts for DB Creation or Update"); + Console.WriteLine(" e.g. ScriptCatalogDbs.bat or ScriptIdentityDb.bat"); Console.ReadLine(); } } diff --git a/src/Nethereum.eShop.Migrations/ScriptCatalogDb.bat b/src/Nethereum.eShop.Migrations/ScriptCatalogDb.bat index dacc0e5..e7317f9 100644 --- a/src/Nethereum.eShop.Migrations/ScriptCatalogDb.bat +++ b/src/Nethereum.eShop.Migrations/ScriptCatalogDb.bat @@ -1,2 +1,3 @@ dotnet ef migrations script --idempotent --project ..\Nethereum.eShop.SqlServer --context Nethereum.eShop.SqlServer.Catalog.SqlServerCatalogContext --output ..\Nethereum.eShop.SqlServer\Catalog\Migrations\Scripts\CreateCatalogDb.sql -dotnet ef migrations script --project ..\Nethereum.eShop.Sqlite --context Nethereum.eShop.Sqlite.Catalog.SqliteCatalogContext --output ..\Nethereum.eShop.Sqlite\Catalog\Migrations\Scripts\CreateCatalogDb.sql \ No newline at end of file +dotnet ef migrations script --project ..\Nethereum.eShop.Sqlite --context Nethereum.eShop.Sqlite.Catalog.SqliteCatalogContext --output ..\Nethereum.eShop.Sqlite\Catalog\Migrations\Scripts\CreateCatalogDb.sql +dotnet ef migrations script --idempotent --project ..\Nethereum.eShop.MySql --context Nethereum.eShop.MySql.Catalog.MySqlCatalogContext --output ..\Nethereum.eShop.MySql\Catalog\Migrations\Scripts\CreateCatalogDb.sql \ No newline at end of file diff --git a/src/Nethereum.eShop.Migrations/ScriptCatalogDb_MySql.bat b/src/Nethereum.eShop.Migrations/ScriptCatalogDb_MySql.bat deleted file mode 100644 index b3a23b4..0000000 --- a/src/Nethereum.eShop.Migrations/ScriptCatalogDb_MySql.bat +++ /dev/null @@ -1 +0,0 @@ -dotnet ef migrations script --idempotent --project ..\Nethereum.eShop.MySql --context Nethereum.eShop.MySql.Catalog.MySqlCatalogContext --output ..\Nethereum.eShop.MySql\Catalog\Migrations\Scripts\CreateCatalogDb.sql \ No newline at end of file diff --git a/src/Nethereum.eShop.Migrations/ScriptIdentityDb.bat b/src/Nethereum.eShop.Migrations/ScriptIdentityDb.bat index 7034f4d..46fa552 100644 --- a/src/Nethereum.eShop.Migrations/ScriptIdentityDb.bat +++ b/src/Nethereum.eShop.Migrations/ScriptIdentityDb.bat @@ -1,2 +1,3 @@ dotnet ef migrations script --idempotent --project ..\Nethereum.eShop.SqlServer --context Nethereum.eShop.SqlServer.Identity.SqlServerAppIdentityDbContext --output ..\Nethereum.eShop.SqlServer\Identity\Migrations\Scripts\CreateIdentityDb.sql -dotnet ef migrations script --project ..\Nethereum.eShop.Sqlite --context Nethereum.eShop.Sqlite.Identity.SqliteAppIdentityDbContext --output ..\Nethereum.eShop.Sqlite\Identity\Migrations\Scripts\CreateIdentityDb.sql \ No newline at end of file +dotnet ef migrations script --project ..\Nethereum.eShop.Sqlite --context Nethereum.eShop.Sqlite.Identity.SqliteAppIdentityDbContext --output ..\Nethereum.eShop.Sqlite\Identity\Migrations\Scripts\CreateIdentityDb.sql +dotnet ef migrations script --idempotent --project ..\Nethereum.eShop.MySql --context Nethereum.eShop.MySql.Identity.MySqlAppIdentityDbContext --output ..\Nethereum.eShop.MySql\Identity\Migrations\Scripts\CreateIdentityDb.sql \ No newline at end of file diff --git a/src/Nethereum.eShop.Migrations/ScriptIdentityDb_MySql.bat b/src/Nethereum.eShop.Migrations/ScriptIdentityDb_MySql.bat deleted file mode 100644 index 15e01cd..0000000 --- a/src/Nethereum.eShop.Migrations/ScriptIdentityDb_MySql.bat +++ /dev/null @@ -1 +0,0 @@ -dotnet ef migrations script --idempotent --project ..\Nethereum.eShop.MySql --context Nethereum.eShop.MySql.Identity.MySqlAppIdentityDbContext --output ..\Nethereum.eShop.MySql\Identity\Migrations\Scripts\CreateIdentityDb.sql \ No newline at end of file diff --git a/src/Nethereum.eShop.MySql/Catalog/Migrations/20200331114834_RemoveBuyerAndWalletAddress.Designer.cs b/src/Nethereum.eShop.MySql/Catalog/Migrations/20200331114834_RemoveBuyerAndWalletAddress.Designer.cs new file mode 100644 index 0000000..68fb5f1 --- /dev/null +++ b/src/Nethereum.eShop.MySql/Catalog/Migrations/20200331114834_RemoveBuyerAndWalletAddress.Designer.cs @@ -0,0 +1,906 @@ +// +using System; +using Microsoft.EntityFrameworkCore; +using Microsoft.EntityFrameworkCore.Infrastructure; +using Microsoft.EntityFrameworkCore.Migrations; +using Microsoft.EntityFrameworkCore.Storage.ValueConversion; +using Nethereum.eShop.MySql.Catalog; + +namespace Nethereum.eShop.MySql.Catalog.Migrations +{ + [DbContext(typeof(MySqlCatalogContext))] + [Migration("20200331114834_RemoveBuyerAndWalletAddress")] + partial class RemoveBuyerAndWalletAddress + { + protected override void BuildTargetModel(ModelBuilder modelBuilder) + { +#pragma warning disable 612, 618 + modelBuilder + .HasAnnotation("ProductVersion", "3.1.2") + .HasAnnotation("Relational:MaxIdentifierLength", 64); + + modelBuilder.Entity("Nethereum.eShop.ApplicationCore.Entities.BasketAggregate.Basket", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("int"); + + b.Property("BuyerAddress") + .IsRequired() + .HasColumnType("varchar(43) CHARACTER SET utf8mb4") + .HasMaxLength(43); + + b.Property("BuyerId") + .IsRequired() + .HasColumnType("varchar(256) CHARACTER SET utf8mb4") + .HasMaxLength(256); + + b.Property("TransactionHash") + .HasColumnType("varchar(67) CHARACTER SET utf8mb4") + .HasMaxLength(67); + + b.HasKey("Id"); + + b.HasIndex("BuyerAddress"); + + b.HasIndex("BuyerId"); + + b.ToTable("Baskets"); + }); + + modelBuilder.Entity("Nethereum.eShop.ApplicationCore.Entities.BasketAggregate.BasketItem", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("int"); + + b.Property("BasketId") + .HasColumnType("int"); + + b.Property("CatalogItemId") + .HasColumnType("int"); + + b.Property("Quantity") + .HasColumnType("int"); + + b.Property("UnitPrice") + .HasColumnType("decimal(18,2)"); + + b.HasKey("Id"); + + b.HasIndex("BasketId"); + + b.ToTable("BasketItems"); + }); + + modelBuilder.Entity("Nethereum.eShop.ApplicationCore.Entities.BuyerAggregate.Buyer", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("int"); + + b.Property("BuyerAddress") + .HasColumnType("varchar(43) CHARACTER SET utf8mb4") + .HasMaxLength(43); + + b.Property("BuyerId") + .IsRequired() + .HasColumnType("varchar(256) CHARACTER SET utf8mb4") + .HasMaxLength(256); + + b.Property("BuyerWalletAddress") + .HasColumnType("varchar(43) CHARACTER SET utf8mb4") + .HasMaxLength(43); + + b.HasKey("Id"); + + b.HasIndex("BuyerAddress") + .IsUnique(); + + b.HasIndex("BuyerId") + .IsUnique(); + + b.HasIndex("BuyerWalletAddress") + .IsUnique(); + + b.ToTable("Buyers"); + }); + + modelBuilder.Entity("Nethereum.eShop.ApplicationCore.Entities.BuyerAggregate.BuyerPostalAddress", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("int"); + + b.Property("BuyerId") + .HasColumnType("int"); + + b.Property("Name") + .HasColumnType("longtext CHARACTER SET utf8mb4"); + + b.HasKey("Id"); + + b.HasIndex("BuyerId"); + + b.ToTable("BuyerPostalAddress"); + }); + + modelBuilder.Entity("Nethereum.eShop.ApplicationCore.Entities.CatalogBrand", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("int"); + + b.Property("Brand") + .IsRequired() + .HasColumnType("varchar(100) CHARACTER SET utf8mb4") + .HasMaxLength(100); + + b.HasKey("Id"); + + b.ToTable("CatalogBrands"); + }); + + modelBuilder.Entity("Nethereum.eShop.ApplicationCore.Entities.CatalogItem", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("int"); + + b.Property("AttributeJson") + .HasColumnType("longtext CHARACTER SET utf8mb4"); + + b.Property("CatalogBrandId") + .HasColumnType("int"); + + b.Property("CatalogTypeId") + .HasColumnType("int"); + + b.Property("Depth") + .HasColumnType("int"); + + b.Property("Description") + .HasColumnType("longtext CHARACTER SET utf8mb4"); + + b.Property("Gtin") + .IsRequired() + .HasColumnType("varchar(14) CHARACTER SET utf8mb4") + .HasMaxLength(14); + + b.Property("GtinRegistryId") + .HasColumnType("int"); + + b.Property("Height") + .HasColumnType("int"); + + b.Property("Name") + .IsRequired() + .HasColumnType("varchar(50) CHARACTER SET utf8mb4") + .HasMaxLength(50); + + b.Property("PictureLargeUri") + .HasColumnType("varchar(512) CHARACTER SET utf8mb4") + .HasMaxLength(512); + + b.Property("PictureMediumUri") + .HasColumnType("varchar(512) CHARACTER SET utf8mb4") + .HasMaxLength(512); + + b.Property("PictureSmallUri") + .HasColumnType("varchar(512) CHARACTER SET utf8mb4") + .HasMaxLength(512); + + b.Property("PictureUri") + .HasColumnType("varchar(512) CHARACTER SET utf8mb4") + .HasMaxLength(512); + + b.Property("Price") + .HasColumnType("decimal(18,2)"); + + b.Property("Rank") + .HasColumnType("int"); + + b.Property("Status") + .HasColumnType("int"); + + b.Property("Unit") + .HasColumnType("varchar(8) CHARACTER SET utf8mb4") + .HasMaxLength(8); + + b.Property("Weight") + .HasColumnType("int"); + + b.Property("Width") + .HasColumnType("int"); + + b.HasKey("Id"); + + b.HasIndex("CatalogBrandId"); + + b.HasIndex("CatalogTypeId"); + + b.ToTable("Catalog"); + }); + + modelBuilder.Entity("Nethereum.eShop.ApplicationCore.Entities.CatalogType", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("int"); + + b.Property("Type") + .IsRequired() + .HasColumnType("varchar(100) CHARACTER SET utf8mb4") + .HasMaxLength(100); + + b.HasKey("Id"); + + b.ToTable("CatalogTypes"); + }); + + modelBuilder.Entity("Nethereum.eShop.ApplicationCore.Entities.OrderAggregate.Order", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("int"); + + b.Property("BuyerId") + .IsRequired() + .HasColumnType("varchar(256) CHARACTER SET utf8mb4") + .HasMaxLength(256); + + b.Property("BuyerWalletAddress") + .HasColumnType("varchar(43) CHARACTER SET utf8mb4") + .HasMaxLength(43); + + b.Property("CurrencyAddress") + .HasColumnType("varchar(43) CHARACTER SET utf8mb4") + .HasMaxLength(43); + + b.Property("CurrencySymbol") + .HasColumnType("varchar(32) CHARACTER SET utf8mb4") + .HasMaxLength(32); + + b.Property("OrderDate") + .HasColumnType("datetime(6)"); + + b.Property("PoDate") + .HasColumnType("datetime(6)"); + + b.Property("PoNumber") + .HasColumnType("bigint"); + + b.Property("PoType") + .HasColumnType("int"); + + b.Property("QuoteId") + .HasColumnType("int"); + + b.Property("SellerId") + .HasColumnType("varchar(32) CHARACTER SET utf8mb4") + .HasMaxLength(32); + + b.Property("Status") + .HasColumnType("int"); + + b.Property("TransactionHash") + .HasColumnType("varchar(67) CHARACTER SET utf8mb4") + .HasMaxLength(67); + + b.HasKey("Id"); + + b.HasIndex("BuyerId"); + + b.ToTable("Orders"); + }); + + modelBuilder.Entity("Nethereum.eShop.ApplicationCore.Entities.OrderAggregate.OrderItem", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("int"); + + b.Property("ActualEscrowReleaseDate") + .HasColumnType("datetime(6)"); + + b.Property("CurrencyValue") + .HasColumnType("varchar(100) CHARACTER SET utf8mb4") + .HasMaxLength(100); + + b.Property("GoodsIssueDate") + .HasColumnType("datetime(6)"); + + b.Property("IsEscrowReleased") + .HasColumnType("tinyint(1)"); + + b.Property("OrderId") + .HasColumnType("int"); + + b.Property("PlannedEscrowReleaseDate") + .HasColumnType("datetime(6)"); + + b.Property("PoItemNumber") + .HasColumnType("int"); + + b.Property("PoItemStatus") + .HasColumnType("int"); + + b.Property("Quantity") + .HasColumnType("int"); + + b.Property("QuantityAddress") + .HasColumnType("varchar(43) CHARACTER SET utf8mb4") + .HasMaxLength(43); + + b.Property("QuantitySymbol") + .HasColumnType("varchar(32) CHARACTER SET utf8mb4") + .HasMaxLength(32); + + b.Property("Status") + .HasColumnType("int"); + + b.Property("Unit") + .HasColumnType("varchar(50) CHARACTER SET utf8mb4") + .HasMaxLength(50); + + b.Property("UnitPrice") + .HasColumnType("decimal(18,2)"); + + b.HasKey("Id"); + + b.HasIndex("OrderId"); + + b.ToTable("OrderItems"); + }); + + modelBuilder.Entity("Nethereum.eShop.ApplicationCore.Entities.QuoteAggregate.Quote", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("int"); + + b.Property("ApproverAddress") + .HasColumnType("varchar(43) CHARACTER SET utf8mb4") + .HasMaxLength(43); + + b.Property("BuyerAddress") + .HasColumnType("varchar(43) CHARACTER SET utf8mb4") + .HasMaxLength(43); + + b.Property("BuyerId") + .IsRequired() + .HasColumnType("varchar(256) CHARACTER SET utf8mb4") + .HasMaxLength(256); + + b.Property("BuyerWalletAddress") + .HasColumnType("varchar(43) CHARACTER SET utf8mb4") + .HasMaxLength(43); + + b.Property("CurrencyAddress") + .HasColumnType("varchar(43) CHARACTER SET utf8mb4") + .HasMaxLength(43); + + b.Property("CurrencySymbol") + .HasColumnType("varchar(32) CHARACTER SET utf8mb4") + .HasMaxLength(32); + + b.Property("Date") + .HasColumnType("datetime(6)"); + + b.Property("Expiry") + .HasColumnType("datetime(6)"); + + b.Property("PoNumber") + .HasColumnType("bigint"); + + b.Property("PoType") + .HasColumnType("int"); + + b.Property("SellerId") + .HasColumnType("varchar(32) CHARACTER SET utf8mb4") + .HasMaxLength(32); + + b.Property("Status") + .HasColumnType("int"); + + b.Property("TransactionHash") + .HasColumnType("varchar(67) CHARACTER SET utf8mb4") + .HasMaxLength(67); + + b.HasKey("Id"); + + b.HasIndex("BuyerAddress"); + + b.HasIndex("BuyerId"); + + b.ToTable("Quotes"); + }); + + modelBuilder.Entity("Nethereum.eShop.ApplicationCore.Entities.QuoteAggregate.QuoteItem", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("int"); + + b.Property("CurrencyValue") + .HasColumnType("longtext CHARACTER SET utf8mb4"); + + b.Property("EscrowReleaseDate") + .HasColumnType("datetime(6)"); + + b.Property("PoItemNumber") + .HasColumnType("int"); + + b.Property("Quantity") + .HasColumnType("int"); + + b.Property("QuantityAddress") + .HasColumnType("longtext CHARACTER SET utf8mb4"); + + b.Property("QuantitySymbol") + .HasColumnType("longtext CHARACTER SET utf8mb4"); + + b.Property("QuoteId") + .HasColumnType("int"); + + b.Property("Unit") + .HasColumnType("longtext CHARACTER SET utf8mb4"); + + b.Property("UnitPrice") + .HasColumnType("decimal(18,2)"); + + b.HasKey("Id"); + + b.HasIndex("QuoteId"); + + b.ToTable("QuoteItems"); + }); + + modelBuilder.Entity("Nethereum.eShop.ApplicationCore.Entities.StockItem", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("int"); + + b.Property("CatalogItemId") + .HasColumnType("int"); + + b.Property("Location") + .IsRequired() + .HasColumnType("varchar(50) CHARACTER SET utf8mb4") + .HasMaxLength(50); + + b.Property("Quantity") + .HasColumnType("int"); + + b.HasKey("Id"); + + b.HasIndex("CatalogItemId"); + + b.ToTable("Stock"); + }); + + modelBuilder.Entity("Nethereum.eShop.ApplicationCore.Entities.BasketAggregate.Basket", b => + { + b.OwnsOne("Nethereum.eShop.ApplicationCore.Entities.PostalAddress", "BillTo", b1 => + { + b1.Property("BasketId") + .HasColumnType("int"); + + b1.Property("City") + .IsRequired() + .HasColumnType("varchar(100) CHARACTER SET utf8mb4") + .HasMaxLength(100); + + b1.Property("Country") + .IsRequired() + .HasColumnType("varchar(90) CHARACTER SET utf8mb4") + .HasMaxLength(90); + + b1.Property("RecipientName") + .IsRequired() + .HasColumnType("varchar(255) CHARACTER SET utf8mb4") + .HasMaxLength(255); + + b1.Property("State") + .HasColumnType("varchar(60) CHARACTER SET utf8mb4") + .HasMaxLength(60); + + b1.Property("Street") + .IsRequired() + .HasColumnType("varchar(180) CHARACTER SET utf8mb4") + .HasMaxLength(180); + + b1.Property("ZipCode") + .IsRequired() + .HasColumnType("varchar(18) CHARACTER SET utf8mb4") + .HasMaxLength(18); + + b1.HasKey("BasketId"); + + b1.ToTable("Baskets"); + + b1.WithOwner() + .HasForeignKey("BasketId"); + }); + + b.OwnsOne("Nethereum.eShop.ApplicationCore.Entities.PostalAddress", "ShipTo", b1 => + { + b1.Property("BasketId") + .HasColumnType("int"); + + b1.Property("City") + .IsRequired() + .HasColumnType("varchar(100) CHARACTER SET utf8mb4") + .HasMaxLength(100); + + b1.Property("Country") + .IsRequired() + .HasColumnType("varchar(90) CHARACTER SET utf8mb4") + .HasMaxLength(90); + + b1.Property("RecipientName") + .IsRequired() + .HasColumnType("varchar(255) CHARACTER SET utf8mb4") + .HasMaxLength(255); + + b1.Property("State") + .HasColumnType("varchar(60) CHARACTER SET utf8mb4") + .HasMaxLength(60); + + b1.Property("Street") + .IsRequired() + .HasColumnType("varchar(180) CHARACTER SET utf8mb4") + .HasMaxLength(180); + + b1.Property("ZipCode") + .IsRequired() + .HasColumnType("varchar(18) CHARACTER SET utf8mb4") + .HasMaxLength(18); + + b1.HasKey("BasketId"); + + b1.ToTable("Baskets"); + + b1.WithOwner() + .HasForeignKey("BasketId"); + }); + }); + + modelBuilder.Entity("Nethereum.eShop.ApplicationCore.Entities.BasketAggregate.BasketItem", b => + { + b.HasOne("Nethereum.eShop.ApplicationCore.Entities.BasketAggregate.Basket", null) + .WithMany("Items") + .HasForeignKey("BasketId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + }); + + modelBuilder.Entity("Nethereum.eShop.ApplicationCore.Entities.BuyerAggregate.BuyerPostalAddress", b => + { + b.HasOne("Nethereum.eShop.ApplicationCore.Entities.BuyerAggregate.Buyer", null) + .WithMany("PostalAddresses") + .HasForeignKey("BuyerId"); + + b.OwnsOne("Nethereum.eShop.ApplicationCore.Entities.PostalAddress", "PostalAddress", b1 => + { + b1.Property("BuyerPostalAddressId") + .HasColumnType("int"); + + b1.Property("City") + .IsRequired() + .HasColumnType("varchar(100) CHARACTER SET utf8mb4") + .HasMaxLength(100); + + b1.Property("Country") + .IsRequired() + .HasColumnType("varchar(90) CHARACTER SET utf8mb4") + .HasMaxLength(90); + + b1.Property("RecipientName") + .IsRequired() + .HasColumnType("varchar(255) CHARACTER SET utf8mb4") + .HasMaxLength(255); + + b1.Property("State") + .HasColumnType("varchar(60) CHARACTER SET utf8mb4") + .HasMaxLength(60); + + b1.Property("Street") + .IsRequired() + .HasColumnType("varchar(180) CHARACTER SET utf8mb4") + .HasMaxLength(180); + + b1.Property("ZipCode") + .IsRequired() + .HasColumnType("varchar(18) CHARACTER SET utf8mb4") + .HasMaxLength(18); + + b1.HasKey("BuyerPostalAddressId"); + + b1.ToTable("BuyerPostalAddress"); + + b1.WithOwner() + .HasForeignKey("BuyerPostalAddressId"); + }); + }); + + modelBuilder.Entity("Nethereum.eShop.ApplicationCore.Entities.CatalogItem", b => + { + b.HasOne("Nethereum.eShop.ApplicationCore.Entities.CatalogBrand", "CatalogBrand") + .WithMany() + .HasForeignKey("CatalogBrandId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.HasOne("Nethereum.eShop.ApplicationCore.Entities.CatalogType", "CatalogType") + .WithMany() + .HasForeignKey("CatalogTypeId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + }); + + modelBuilder.Entity("Nethereum.eShop.ApplicationCore.Entities.OrderAggregate.Order", b => + { + b.OwnsOne("Nethereum.eShop.ApplicationCore.Entities.PostalAddress", "BillTo", b1 => + { + b1.Property("OrderId") + .HasColumnType("int"); + + b1.Property("City") + .IsRequired() + .HasColumnType("varchar(100) CHARACTER SET utf8mb4") + .HasMaxLength(100); + + b1.Property("Country") + .IsRequired() + .HasColumnType("varchar(90) CHARACTER SET utf8mb4") + .HasMaxLength(90); + + b1.Property("RecipientName") + .IsRequired() + .HasColumnType("varchar(255) CHARACTER SET utf8mb4") + .HasMaxLength(255); + + b1.Property("State") + .HasColumnType("varchar(60) CHARACTER SET utf8mb4") + .HasMaxLength(60); + + b1.Property("Street") + .IsRequired() + .HasColumnType("varchar(180) CHARACTER SET utf8mb4") + .HasMaxLength(180); + + b1.Property("ZipCode") + .IsRequired() + .HasColumnType("varchar(18) CHARACTER SET utf8mb4") + .HasMaxLength(18); + + b1.HasKey("OrderId"); + + b1.ToTable("Orders"); + + b1.WithOwner() + .HasForeignKey("OrderId"); + }); + + b.OwnsOne("Nethereum.eShop.ApplicationCore.Entities.PostalAddress", "ShipTo", b1 => + { + b1.Property("OrderId") + .HasColumnType("int"); + + b1.Property("City") + .IsRequired() + .HasColumnType("varchar(100) CHARACTER SET utf8mb4") + .HasMaxLength(100); + + b1.Property("Country") + .IsRequired() + .HasColumnType("varchar(90) CHARACTER SET utf8mb4") + .HasMaxLength(90); + + b1.Property("RecipientName") + .IsRequired() + .HasColumnType("varchar(255) CHARACTER SET utf8mb4") + .HasMaxLength(255); + + b1.Property("State") + .HasColumnType("varchar(60) CHARACTER SET utf8mb4") + .HasMaxLength(60); + + b1.Property("Street") + .IsRequired() + .HasColumnType("varchar(180) CHARACTER SET utf8mb4") + .HasMaxLength(180); + + b1.Property("ZipCode") + .IsRequired() + .HasColumnType("varchar(18) CHARACTER SET utf8mb4") + .HasMaxLength(18); + + b1.HasKey("OrderId"); + + b1.ToTable("Orders"); + + b1.WithOwner() + .HasForeignKey("OrderId"); + }); + }); + + modelBuilder.Entity("Nethereum.eShop.ApplicationCore.Entities.OrderAggregate.OrderItem", b => + { + b.HasOne("Nethereum.eShop.ApplicationCore.Entities.OrderAggregate.Order", null) + .WithMany("OrderItems") + .HasForeignKey("OrderId"); + + b.OwnsOne("Nethereum.eShop.ApplicationCore.Entities.CatalogItemExcerpt", "ItemOrdered", b1 => + { + b1.Property("OrderItemId") + .HasColumnType("int"); + + b1.Property("CatalogItemId") + .HasColumnType("int"); + + b1.Property("Gtin") + .HasColumnType("varchar(14) CHARACTER SET utf8mb4") + .HasMaxLength(14); + + b1.Property("GtinRegistryId") + .HasColumnType("int"); + + b1.Property("PictureUri") + .HasColumnType("varchar(512) CHARACTER SET utf8mb4") + .HasMaxLength(512); + + b1.Property("ProductName") + .IsRequired() + .HasColumnType("varchar(50) CHARACTER SET utf8mb4") + .HasMaxLength(50); + + b1.HasKey("OrderItemId"); + + b1.ToTable("OrderItems"); + + b1.WithOwner() + .HasForeignKey("OrderItemId"); + }); + }); + + modelBuilder.Entity("Nethereum.eShop.ApplicationCore.Entities.QuoteAggregate.Quote", b => + { + b.OwnsOne("Nethereum.eShop.ApplicationCore.Entities.PostalAddress", "BillTo", b1 => + { + b1.Property("QuoteId") + .HasColumnType("int"); + + b1.Property("City") + .IsRequired() + .HasColumnType("varchar(100) CHARACTER SET utf8mb4") + .HasMaxLength(100); + + b1.Property("Country") + .IsRequired() + .HasColumnType("varchar(90) CHARACTER SET utf8mb4") + .HasMaxLength(90); + + b1.Property("RecipientName") + .IsRequired() + .HasColumnType("varchar(255) CHARACTER SET utf8mb4") + .HasMaxLength(255); + + b1.Property("State") + .HasColumnType("varchar(60) CHARACTER SET utf8mb4") + .HasMaxLength(60); + + b1.Property("Street") + .IsRequired() + .HasColumnType("varchar(180) CHARACTER SET utf8mb4") + .HasMaxLength(180); + + b1.Property("ZipCode") + .IsRequired() + .HasColumnType("varchar(18) CHARACTER SET utf8mb4") + .HasMaxLength(18); + + b1.HasKey("QuoteId"); + + b1.ToTable("Quotes"); + + b1.WithOwner() + .HasForeignKey("QuoteId"); + }); + + b.OwnsOne("Nethereum.eShop.ApplicationCore.Entities.PostalAddress", "ShipTo", b1 => + { + b1.Property("QuoteId") + .HasColumnType("int"); + + b1.Property("City") + .IsRequired() + .HasColumnType("varchar(100) CHARACTER SET utf8mb4") + .HasMaxLength(100); + + b1.Property("Country") + .IsRequired() + .HasColumnType("varchar(90) CHARACTER SET utf8mb4") + .HasMaxLength(90); + + b1.Property("RecipientName") + .IsRequired() + .HasColumnType("varchar(255) CHARACTER SET utf8mb4") + .HasMaxLength(255); + + b1.Property("State") + .HasColumnType("varchar(60) CHARACTER SET utf8mb4") + .HasMaxLength(60); + + b1.Property("Street") + .IsRequired() + .HasColumnType("varchar(180) CHARACTER SET utf8mb4") + .HasMaxLength(180); + + b1.Property("ZipCode") + .IsRequired() + .HasColumnType("varchar(18) CHARACTER SET utf8mb4") + .HasMaxLength(18); + + b1.HasKey("QuoteId"); + + b1.ToTable("Quotes"); + + b1.WithOwner() + .HasForeignKey("QuoteId"); + }); + }); + + modelBuilder.Entity("Nethereum.eShop.ApplicationCore.Entities.QuoteAggregate.QuoteItem", b => + { + b.HasOne("Nethereum.eShop.ApplicationCore.Entities.QuoteAggregate.Quote", null) + .WithMany("QuoteItems") + .HasForeignKey("QuoteId"); + + b.OwnsOne("Nethereum.eShop.ApplicationCore.Entities.CatalogItemExcerpt", "ItemOrdered", b1 => + { + b1.Property("QuoteItemId") + .HasColumnType("int"); + + b1.Property("CatalogItemId") + .HasColumnType("int"); + + b1.Property("Gtin") + .HasColumnType("varchar(14) CHARACTER SET utf8mb4") + .HasMaxLength(14); + + b1.Property("GtinRegistryId") + .HasColumnType("int"); + + b1.Property("PictureUri") + .HasColumnType("varchar(512) CHARACTER SET utf8mb4") + .HasMaxLength(512); + + b1.Property("ProductName") + .IsRequired() + .HasColumnType("varchar(50) CHARACTER SET utf8mb4") + .HasMaxLength(50); + + b1.HasKey("QuoteItemId"); + + b1.ToTable("QuoteItems"); + + b1.WithOwner() + .HasForeignKey("QuoteItemId"); + }); + }); + + modelBuilder.Entity("Nethereum.eShop.ApplicationCore.Entities.StockItem", b => + { + b.HasOne("Nethereum.eShop.ApplicationCore.Entities.CatalogItem", "CatalogItem") + .WithMany() + .HasForeignKey("CatalogItemId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + }); +#pragma warning restore 612, 618 + } + } +} diff --git a/src/Nethereum.eShop.MySql/Catalog/Migrations/20200331114834_RemoveBuyerAndWalletAddress.cs b/src/Nethereum.eShop.MySql/Catalog/Migrations/20200331114834_RemoveBuyerAndWalletAddress.cs new file mode 100644 index 0000000..ac2a56b --- /dev/null +++ b/src/Nethereum.eShop.MySql/Catalog/Migrations/20200331114834_RemoveBuyerAndWalletAddress.cs @@ -0,0 +1,44 @@ +using Microsoft.EntityFrameworkCore.Migrations; + +namespace Nethereum.eShop.MySql.Catalog.Migrations +{ + public partial class RemoveBuyerAndWalletAddress : Migration + { + protected override void Up(MigrationBuilder migrationBuilder) + { + migrationBuilder.DropIndex( + name: "IX_Orders_BuyerAddress", + table: "Orders"); + + migrationBuilder.DropColumn( + name: "ApproverAddress", + table: "Orders"); + + migrationBuilder.DropColumn( + name: "BuyerAddress", + table: "Orders"); + } + + protected override void Down(MigrationBuilder migrationBuilder) + { + migrationBuilder.AddColumn( + name: "ApproverAddress", + table: "Orders", + type: "varchar(43) CHARACTER SET utf8mb4", + maxLength: 43, + nullable: true); + + migrationBuilder.AddColumn( + name: "BuyerAddress", + table: "Orders", + type: "varchar(43) CHARACTER SET utf8mb4", + maxLength: 43, + nullable: true); + + migrationBuilder.CreateIndex( + name: "IX_Orders_BuyerAddress", + table: "Orders", + column: "BuyerAddress"); + } + } +} diff --git a/src/Nethereum.eShop.MySql/Catalog/Migrations/MySqlCatalogContextModelSnapshot.cs b/src/Nethereum.eShop.MySql/Catalog/Migrations/MySqlCatalogContextModelSnapshot.cs index cf20653..eaf5ffa 100644 --- a/src/Nethereum.eShop.MySql/Catalog/Migrations/MySqlCatalogContextModelSnapshot.cs +++ b/src/Nethereum.eShop.MySql/Catalog/Migrations/MySqlCatalogContextModelSnapshot.cs @@ -242,14 +242,6 @@ protected override void BuildModel(ModelBuilder modelBuilder) .ValueGeneratedOnAdd() .HasColumnType("int"); - b.Property("ApproverAddress") - .HasColumnType("varchar(43) CHARACTER SET utf8mb4") - .HasMaxLength(43); - - b.Property("BuyerAddress") - .HasColumnType("varchar(43) CHARACTER SET utf8mb4") - .HasMaxLength(43); - b.Property("BuyerId") .IsRequired() .HasColumnType("varchar(256) CHARACTER SET utf8mb4") @@ -295,8 +287,6 @@ protected override void BuildModel(ModelBuilder modelBuilder) b.HasKey("Id"); - b.HasIndex("BuyerAddress"); - b.HasIndex("BuyerId"); b.ToTable("Orders"); diff --git a/src/Nethereum.eShop.MySql/Catalog/Migrations/Scripts/CreateCatalogDb.sql b/src/Nethereum.eShop.MySql/Catalog/Migrations/Scripts/CreateCatalogDb.sql index 5b755fd..e1d6b95 100644 --- a/src/Nethereum.eShop.MySql/Catalog/Migrations/Scripts/CreateCatalogDb.sql +++ b/src/Nethereum.eShop.MySql/Catalog/Migrations/Scripts/CreateCatalogDb.sql @@ -621,3 +621,64 @@ DELIMITER ; CALL MigrationsScript(); DROP PROCEDURE MigrationsScript; + +DROP PROCEDURE IF EXISTS MigrationsScript; +DELIMITER // +CREATE PROCEDURE MigrationsScript() +BEGIN + IF NOT EXISTS(SELECT 1 FROM `__EFMigrationsHistory` WHERE `MigrationId` = '20200331114834_RemoveBuyerAndWalletAddress') THEN + + ALTER TABLE `Orders` DROP INDEX `IX_Orders_BuyerAddress`; + + END IF; +END // +DELIMITER ; +CALL MigrationsScript(); +DROP PROCEDURE MigrationsScript; + + +DROP PROCEDURE IF EXISTS MigrationsScript; +DELIMITER // +CREATE PROCEDURE MigrationsScript() +BEGIN + IF NOT EXISTS(SELECT 1 FROM `__EFMigrationsHistory` WHERE `MigrationId` = '20200331114834_RemoveBuyerAndWalletAddress') THEN + + ALTER TABLE `Orders` DROP COLUMN `ApproverAddress`; + + END IF; +END // +DELIMITER ; +CALL MigrationsScript(); +DROP PROCEDURE MigrationsScript; + + +DROP PROCEDURE IF EXISTS MigrationsScript; +DELIMITER // +CREATE PROCEDURE MigrationsScript() +BEGIN + IF NOT EXISTS(SELECT 1 FROM `__EFMigrationsHistory` WHERE `MigrationId` = '20200331114834_RemoveBuyerAndWalletAddress') THEN + + ALTER TABLE `Orders` DROP COLUMN `BuyerAddress`; + + END IF; +END // +DELIMITER ; +CALL MigrationsScript(); +DROP PROCEDURE MigrationsScript; + + +DROP PROCEDURE IF EXISTS MigrationsScript; +DELIMITER // +CREATE PROCEDURE MigrationsScript() +BEGIN + IF NOT EXISTS(SELECT 1 FROM `__EFMigrationsHistory` WHERE `MigrationId` = '20200331114834_RemoveBuyerAndWalletAddress') THEN + + INSERT INTO `__EFMigrationsHistory` (`MigrationId`, `ProductVersion`) + VALUES ('20200331114834_RemoveBuyerAndWalletAddress', '3.1.2'); + + END IF; +END // +DELIMITER ; +CALL MigrationsScript(); +DROP PROCEDURE MigrationsScript; + diff --git a/src/Nethereum.eShop.SqlServer/Catalog/Migrations/20200331114818_RemoveBuyerAndWalletAddress.Designer.cs b/src/Nethereum.eShop.SqlServer/Catalog/Migrations/20200331114818_RemoveBuyerAndWalletAddress.Designer.cs new file mode 100644 index 0000000..b48c11d --- /dev/null +++ b/src/Nethereum.eShop.SqlServer/Catalog/Migrations/20200331114818_RemoveBuyerAndWalletAddress.Designer.cs @@ -0,0 +1,948 @@ +// +using System; +using Microsoft.EntityFrameworkCore; +using Microsoft.EntityFrameworkCore.Infrastructure; +using Microsoft.EntityFrameworkCore.Metadata; +using Microsoft.EntityFrameworkCore.Migrations; +using Microsoft.EntityFrameworkCore.Storage.ValueConversion; +using Nethereum.eShop.SqlServer.Catalog; + +namespace Nethereum.eShop.SqlServer.Catalog.Migrations +{ + [DbContext(typeof(SqlServerCatalogContext))] + [Migration("20200331114818_RemoveBuyerAndWalletAddress")] + partial class RemoveBuyerAndWalletAddress + { + protected override void BuildTargetModel(ModelBuilder modelBuilder) + { +#pragma warning disable 612, 618 + modelBuilder + .HasAnnotation("ProductVersion", "3.1.2") + .HasAnnotation("Relational:MaxIdentifierLength", 128) + .HasAnnotation("Relational:Sequence:.catalog_brand_hilo", "'catalog_brand_hilo', '', '1', '10', '', '', 'Int64', 'False'") + .HasAnnotation("Relational:Sequence:.catalog_hilo", "'catalog_hilo', '', '1', '10', '', '', 'Int64', 'False'") + .HasAnnotation("Relational:Sequence:.catalog_type_hilo", "'catalog_type_hilo', '', '1', '10', '', '', 'Int64', 'False'") + .HasAnnotation("Relational:Sequence:.stock_hilo", "'stock_hilo', '', '1', '10', '', '', 'Int64', 'False'") + .HasAnnotation("SqlServer:ValueGenerationStrategy", SqlServerValueGenerationStrategy.IdentityColumn); + + modelBuilder.Entity("Nethereum.eShop.ApplicationCore.Entities.BasketAggregate.Basket", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("int") + .HasAnnotation("SqlServer:ValueGenerationStrategy", SqlServerValueGenerationStrategy.IdentityColumn); + + b.Property("BuyerAddress") + .IsRequired() + .HasColumnType("nvarchar(43)") + .HasMaxLength(43); + + b.Property("BuyerId") + .IsRequired() + .HasColumnType("nvarchar(256)") + .HasMaxLength(256); + + b.Property("TransactionHash") + .HasColumnType("nvarchar(67)") + .HasMaxLength(67); + + b.HasKey("Id"); + + b.HasIndex("BuyerAddress"); + + b.HasIndex("BuyerId"); + + b.ToTable("Baskets"); + }); + + modelBuilder.Entity("Nethereum.eShop.ApplicationCore.Entities.BasketAggregate.BasketItem", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("int") + .HasAnnotation("SqlServer:ValueGenerationStrategy", SqlServerValueGenerationStrategy.IdentityColumn); + + b.Property("BasketId") + .HasColumnType("int"); + + b.Property("CatalogItemId") + .HasColumnType("int"); + + b.Property("Quantity") + .HasColumnType("int"); + + b.Property("UnitPrice") + .HasColumnType("decimal(18,2)"); + + b.HasKey("Id"); + + b.HasIndex("BasketId"); + + b.ToTable("BasketItems"); + }); + + modelBuilder.Entity("Nethereum.eShop.ApplicationCore.Entities.BuyerAggregate.Buyer", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("int") + .HasAnnotation("SqlServer:ValueGenerationStrategy", SqlServerValueGenerationStrategy.IdentityColumn); + + b.Property("BuyerAddress") + .HasColumnType("nvarchar(43)") + .HasMaxLength(43); + + b.Property("BuyerId") + .IsRequired() + .HasColumnType("nvarchar(256)") + .HasMaxLength(256); + + b.Property("BuyerWalletAddress") + .HasColumnType("nvarchar(43)") + .HasMaxLength(43); + + b.HasKey("Id"); + + b.HasIndex("BuyerAddress") + .IsUnique() + .HasFilter("[BuyerAddress] IS NOT NULL"); + + b.HasIndex("BuyerId") + .IsUnique(); + + b.HasIndex("BuyerWalletAddress") + .IsUnique() + .HasFilter("[BuyerWalletAddress] IS NOT NULL"); + + b.ToTable("Buyers"); + }); + + modelBuilder.Entity("Nethereum.eShop.ApplicationCore.Entities.BuyerAggregate.BuyerPostalAddress", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("int") + .HasAnnotation("SqlServer:ValueGenerationStrategy", SqlServerValueGenerationStrategy.IdentityColumn); + + b.Property("BuyerId") + .HasColumnType("int"); + + b.Property("Name") + .HasColumnType("nvarchar(max)"); + + b.HasKey("Id"); + + b.HasIndex("BuyerId"); + + b.ToTable("BuyerPostalAddress"); + }); + + modelBuilder.Entity("Nethereum.eShop.ApplicationCore.Entities.CatalogBrand", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("int") + .HasAnnotation("SqlServer:HiLoSequenceName", "catalog_brand_hilo") + .HasAnnotation("SqlServer:ValueGenerationStrategy", SqlServerValueGenerationStrategy.SequenceHiLo); + + b.Property("Brand") + .IsRequired() + .HasColumnType("nvarchar(100)") + .HasMaxLength(100); + + b.HasKey("Id"); + + b.ToTable("CatalogBrands"); + }); + + modelBuilder.Entity("Nethereum.eShop.ApplicationCore.Entities.CatalogItem", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("int") + .HasAnnotation("SqlServer:HiLoSequenceName", "catalog_hilo") + .HasAnnotation("SqlServer:ValueGenerationStrategy", SqlServerValueGenerationStrategy.SequenceHiLo); + + b.Property("AttributeJson") + .HasColumnType("nvarchar(max)"); + + b.Property("CatalogBrandId") + .HasColumnType("int"); + + b.Property("CatalogTypeId") + .HasColumnType("int"); + + b.Property("Depth") + .HasColumnType("int"); + + b.Property("Description") + .HasColumnType("nvarchar(max)"); + + b.Property("Gtin") + .IsRequired() + .HasColumnType("nvarchar(14)") + .HasMaxLength(14); + + b.Property("GtinRegistryId") + .HasColumnType("int"); + + b.Property("Height") + .HasColumnType("int"); + + b.Property("Name") + .IsRequired() + .HasColumnType("nvarchar(50)") + .HasMaxLength(50); + + b.Property("PictureLargeUri") + .HasColumnType("nvarchar(512)") + .HasMaxLength(512); + + b.Property("PictureMediumUri") + .HasColumnType("nvarchar(512)") + .HasMaxLength(512); + + b.Property("PictureSmallUri") + .HasColumnType("nvarchar(512)") + .HasMaxLength(512); + + b.Property("PictureUri") + .HasColumnType("nvarchar(512)") + .HasMaxLength(512); + + b.Property("Price") + .HasColumnType("decimal(18,2)"); + + b.Property("Rank") + .HasColumnType("int"); + + b.Property("Status") + .HasColumnType("int"); + + b.Property("Unit") + .HasColumnType("nvarchar(8)") + .HasMaxLength(8); + + b.Property("Weight") + .HasColumnType("int"); + + b.Property("Width") + .HasColumnType("int"); + + b.HasKey("Id"); + + b.HasIndex("CatalogBrandId"); + + b.HasIndex("CatalogTypeId"); + + b.ToTable("Catalog"); + }); + + modelBuilder.Entity("Nethereum.eShop.ApplicationCore.Entities.CatalogType", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("int") + .HasAnnotation("SqlServer:HiLoSequenceName", "catalog_type_hilo") + .HasAnnotation("SqlServer:ValueGenerationStrategy", SqlServerValueGenerationStrategy.SequenceHiLo); + + b.Property("Type") + .IsRequired() + .HasColumnType("nvarchar(100)") + .HasMaxLength(100); + + b.HasKey("Id"); + + b.ToTable("CatalogTypes"); + }); + + modelBuilder.Entity("Nethereum.eShop.ApplicationCore.Entities.OrderAggregate.Order", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("int") + .HasAnnotation("SqlServer:ValueGenerationStrategy", SqlServerValueGenerationStrategy.IdentityColumn); + + b.Property("BuyerId") + .IsRequired() + .HasColumnType("nvarchar(256)") + .HasMaxLength(256); + + b.Property("BuyerWalletAddress") + .HasColumnType("nvarchar(43)") + .HasMaxLength(43); + + b.Property("CurrencyAddress") + .HasColumnType("nvarchar(43)") + .HasMaxLength(43); + + b.Property("CurrencySymbol") + .HasColumnType("nvarchar(32)") + .HasMaxLength(32); + + b.Property("OrderDate") + .HasColumnType("datetimeoffset"); + + b.Property("PoDate") + .HasColumnType("datetimeoffset"); + + b.Property("PoNumber") + .HasColumnType("bigint"); + + b.Property("PoType") + .HasColumnType("int"); + + b.Property("QuoteId") + .HasColumnType("int"); + + b.Property("SellerId") + .HasColumnType("nvarchar(32)") + .HasMaxLength(32); + + b.Property("Status") + .HasColumnType("int"); + + b.Property("TransactionHash") + .HasColumnType("nvarchar(67)") + .HasMaxLength(67); + + b.HasKey("Id"); + + b.HasIndex("BuyerId"); + + b.ToTable("Orders"); + }); + + modelBuilder.Entity("Nethereum.eShop.ApplicationCore.Entities.OrderAggregate.OrderItem", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("int") + .HasAnnotation("SqlServer:ValueGenerationStrategy", SqlServerValueGenerationStrategy.IdentityColumn); + + b.Property("ActualEscrowReleaseDate") + .HasColumnType("datetimeoffset"); + + b.Property("CurrencyValue") + .HasColumnType("nvarchar(100)") + .HasMaxLength(100); + + b.Property("GoodsIssueDate") + .HasColumnType("datetimeoffset"); + + b.Property("IsEscrowReleased") + .HasColumnType("bit"); + + b.Property("OrderId") + .HasColumnType("int"); + + b.Property("PlannedEscrowReleaseDate") + .HasColumnType("datetimeoffset"); + + b.Property("PoItemNumber") + .HasColumnType("int"); + + b.Property("PoItemStatus") + .HasColumnType("int"); + + b.Property("Quantity") + .HasColumnType("int"); + + b.Property("QuantityAddress") + .HasColumnType("nvarchar(43)") + .HasMaxLength(43); + + b.Property("QuantitySymbol") + .HasColumnType("nvarchar(32)") + .HasMaxLength(32); + + b.Property("Status") + .HasColumnType("int"); + + b.Property("Unit") + .HasColumnType("nvarchar(50)") + .HasMaxLength(50); + + b.Property("UnitPrice") + .HasColumnType("decimal(18,2)"); + + b.HasKey("Id"); + + b.HasIndex("OrderId"); + + b.ToTable("OrderItems"); + }); + + modelBuilder.Entity("Nethereum.eShop.ApplicationCore.Entities.QuoteAggregate.Quote", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("int") + .HasAnnotation("SqlServer:ValueGenerationStrategy", SqlServerValueGenerationStrategy.IdentityColumn); + + b.Property("ApproverAddress") + .HasColumnType("nvarchar(43)") + .HasMaxLength(43); + + b.Property("BuyerAddress") + .HasColumnType("nvarchar(43)") + .HasMaxLength(43); + + b.Property("BuyerId") + .IsRequired() + .HasColumnType("nvarchar(256)") + .HasMaxLength(256); + + b.Property("BuyerWalletAddress") + .HasColumnType("nvarchar(43)") + .HasMaxLength(43); + + b.Property("CurrencyAddress") + .HasColumnType("nvarchar(43)") + .HasMaxLength(43); + + b.Property("CurrencySymbol") + .HasColumnType("nvarchar(32)") + .HasMaxLength(32); + + b.Property("Date") + .HasColumnType("datetimeoffset"); + + b.Property("Expiry") + .HasColumnType("datetimeoffset"); + + b.Property("PoNumber") + .HasColumnType("bigint"); + + b.Property("PoType") + .HasColumnType("int"); + + b.Property("SellerId") + .HasColumnType("nvarchar(32)") + .HasMaxLength(32); + + b.Property("Status") + .HasColumnType("int"); + + b.Property("TransactionHash") + .HasColumnType("nvarchar(67)") + .HasMaxLength(67); + + b.HasKey("Id"); + + b.HasIndex("BuyerAddress"); + + b.HasIndex("BuyerId"); + + b.ToTable("Quotes"); + }); + + modelBuilder.Entity("Nethereum.eShop.ApplicationCore.Entities.QuoteAggregate.QuoteItem", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("int") + .HasAnnotation("SqlServer:ValueGenerationStrategy", SqlServerValueGenerationStrategy.IdentityColumn); + + b.Property("CurrencyValue") + .HasColumnType("nvarchar(max)"); + + b.Property("EscrowReleaseDate") + .HasColumnType("datetimeoffset"); + + b.Property("PoItemNumber") + .HasColumnType("int"); + + b.Property("Quantity") + .HasColumnType("int"); + + b.Property("QuantityAddress") + .HasColumnType("nvarchar(max)"); + + b.Property("QuantitySymbol") + .HasColumnType("nvarchar(max)"); + + b.Property("QuoteId") + .HasColumnType("int"); + + b.Property("Unit") + .HasColumnType("nvarchar(max)"); + + b.Property("UnitPrice") + .HasColumnType("decimal(18,2)"); + + b.HasKey("Id"); + + b.HasIndex("QuoteId"); + + b.ToTable("QuoteItems"); + }); + + modelBuilder.Entity("Nethereum.eShop.ApplicationCore.Entities.StockItem", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("int") + .HasAnnotation("SqlServer:HiLoSequenceName", "stock_hilo") + .HasAnnotation("SqlServer:ValueGenerationStrategy", SqlServerValueGenerationStrategy.SequenceHiLo); + + b.Property("CatalogItemId") + .HasColumnType("int"); + + b.Property("Location") + .IsRequired() + .HasColumnType("nvarchar(50)") + .HasMaxLength(50); + + b.Property("Quantity") + .HasColumnType("int"); + + b.HasKey("Id"); + + b.HasIndex("CatalogItemId"); + + b.ToTable("Stock"); + }); + + modelBuilder.Entity("Nethereum.eShop.ApplicationCore.Entities.BasketAggregate.Basket", b => + { + b.OwnsOne("Nethereum.eShop.ApplicationCore.Entities.PostalAddress", "BillTo", b1 => + { + b1.Property("BasketId") + .ValueGeneratedOnAdd() + .HasColumnType("int") + .HasAnnotation("SqlServer:ValueGenerationStrategy", SqlServerValueGenerationStrategy.IdentityColumn); + + b1.Property("City") + .IsRequired() + .HasColumnType("nvarchar(100)") + .HasMaxLength(100); + + b1.Property("Country") + .IsRequired() + .HasColumnType("nvarchar(90)") + .HasMaxLength(90); + + b1.Property("RecipientName") + .IsRequired() + .HasColumnType("nvarchar(255)") + .HasMaxLength(255); + + b1.Property("State") + .HasColumnType("nvarchar(60)") + .HasMaxLength(60); + + b1.Property("Street") + .IsRequired() + .HasColumnType("nvarchar(180)") + .HasMaxLength(180); + + b1.Property("ZipCode") + .IsRequired() + .HasColumnType("nvarchar(18)") + .HasMaxLength(18); + + b1.HasKey("BasketId"); + + b1.ToTable("Baskets"); + + b1.WithOwner() + .HasForeignKey("BasketId"); + }); + + b.OwnsOne("Nethereum.eShop.ApplicationCore.Entities.PostalAddress", "ShipTo", b1 => + { + b1.Property("BasketId") + .ValueGeneratedOnAdd() + .HasColumnType("int") + .HasAnnotation("SqlServer:ValueGenerationStrategy", SqlServerValueGenerationStrategy.IdentityColumn); + + b1.Property("City") + .IsRequired() + .HasColumnType("nvarchar(100)") + .HasMaxLength(100); + + b1.Property("Country") + .IsRequired() + .HasColumnType("nvarchar(90)") + .HasMaxLength(90); + + b1.Property("RecipientName") + .IsRequired() + .HasColumnType("nvarchar(255)") + .HasMaxLength(255); + + b1.Property("State") + .HasColumnType("nvarchar(60)") + .HasMaxLength(60); + + b1.Property("Street") + .IsRequired() + .HasColumnType("nvarchar(180)") + .HasMaxLength(180); + + b1.Property("ZipCode") + .IsRequired() + .HasColumnType("nvarchar(18)") + .HasMaxLength(18); + + b1.HasKey("BasketId"); + + b1.ToTable("Baskets"); + + b1.WithOwner() + .HasForeignKey("BasketId"); + }); + }); + + modelBuilder.Entity("Nethereum.eShop.ApplicationCore.Entities.BasketAggregate.BasketItem", b => + { + b.HasOne("Nethereum.eShop.ApplicationCore.Entities.BasketAggregate.Basket", null) + .WithMany("Items") + .HasForeignKey("BasketId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + }); + + modelBuilder.Entity("Nethereum.eShop.ApplicationCore.Entities.BuyerAggregate.BuyerPostalAddress", b => + { + b.HasOne("Nethereum.eShop.ApplicationCore.Entities.BuyerAggregate.Buyer", null) + .WithMany("PostalAddresses") + .HasForeignKey("BuyerId"); + + b.OwnsOne("Nethereum.eShop.ApplicationCore.Entities.PostalAddress", "PostalAddress", b1 => + { + b1.Property("BuyerPostalAddressId") + .ValueGeneratedOnAdd() + .HasColumnType("int") + .HasAnnotation("SqlServer:ValueGenerationStrategy", SqlServerValueGenerationStrategy.IdentityColumn); + + b1.Property("City") + .IsRequired() + .HasColumnType("nvarchar(100)") + .HasMaxLength(100); + + b1.Property("Country") + .IsRequired() + .HasColumnType("nvarchar(90)") + .HasMaxLength(90); + + b1.Property("RecipientName") + .IsRequired() + .HasColumnType("nvarchar(255)") + .HasMaxLength(255); + + b1.Property("State") + .HasColumnType("nvarchar(60)") + .HasMaxLength(60); + + b1.Property("Street") + .IsRequired() + .HasColumnType("nvarchar(180)") + .HasMaxLength(180); + + b1.Property("ZipCode") + .IsRequired() + .HasColumnType("nvarchar(18)") + .HasMaxLength(18); + + b1.HasKey("BuyerPostalAddressId"); + + b1.ToTable("BuyerPostalAddress"); + + b1.WithOwner() + .HasForeignKey("BuyerPostalAddressId"); + }); + }); + + modelBuilder.Entity("Nethereum.eShop.ApplicationCore.Entities.CatalogItem", b => + { + b.HasOne("Nethereum.eShop.ApplicationCore.Entities.CatalogBrand", "CatalogBrand") + .WithMany() + .HasForeignKey("CatalogBrandId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.HasOne("Nethereum.eShop.ApplicationCore.Entities.CatalogType", "CatalogType") + .WithMany() + .HasForeignKey("CatalogTypeId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + }); + + modelBuilder.Entity("Nethereum.eShop.ApplicationCore.Entities.OrderAggregate.Order", b => + { + b.OwnsOne("Nethereum.eShop.ApplicationCore.Entities.PostalAddress", "BillTo", b1 => + { + b1.Property("OrderId") + .ValueGeneratedOnAdd() + .HasColumnType("int") + .HasAnnotation("SqlServer:ValueGenerationStrategy", SqlServerValueGenerationStrategy.IdentityColumn); + + b1.Property("City") + .IsRequired() + .HasColumnType("nvarchar(100)") + .HasMaxLength(100); + + b1.Property("Country") + .IsRequired() + .HasColumnType("nvarchar(90)") + .HasMaxLength(90); + + b1.Property("RecipientName") + .IsRequired() + .HasColumnType("nvarchar(255)") + .HasMaxLength(255); + + b1.Property("State") + .HasColumnType("nvarchar(60)") + .HasMaxLength(60); + + b1.Property("Street") + .IsRequired() + .HasColumnType("nvarchar(180)") + .HasMaxLength(180); + + b1.Property("ZipCode") + .IsRequired() + .HasColumnType("nvarchar(18)") + .HasMaxLength(18); + + b1.HasKey("OrderId"); + + b1.ToTable("Orders"); + + b1.WithOwner() + .HasForeignKey("OrderId"); + }); + + b.OwnsOne("Nethereum.eShop.ApplicationCore.Entities.PostalAddress", "ShipTo", b1 => + { + b1.Property("OrderId") + .ValueGeneratedOnAdd() + .HasColumnType("int") + .HasAnnotation("SqlServer:ValueGenerationStrategy", SqlServerValueGenerationStrategy.IdentityColumn); + + b1.Property("City") + .IsRequired() + .HasColumnType("nvarchar(100)") + .HasMaxLength(100); + + b1.Property("Country") + .IsRequired() + .HasColumnType("nvarchar(90)") + .HasMaxLength(90); + + b1.Property("RecipientName") + .IsRequired() + .HasColumnType("nvarchar(255)") + .HasMaxLength(255); + + b1.Property("State") + .HasColumnType("nvarchar(60)") + .HasMaxLength(60); + + b1.Property("Street") + .IsRequired() + .HasColumnType("nvarchar(180)") + .HasMaxLength(180); + + b1.Property("ZipCode") + .IsRequired() + .HasColumnType("nvarchar(18)") + .HasMaxLength(18); + + b1.HasKey("OrderId"); + + b1.ToTable("Orders"); + + b1.WithOwner() + .HasForeignKey("OrderId"); + }); + }); + + modelBuilder.Entity("Nethereum.eShop.ApplicationCore.Entities.OrderAggregate.OrderItem", b => + { + b.HasOne("Nethereum.eShop.ApplicationCore.Entities.OrderAggregate.Order", null) + .WithMany("OrderItems") + .HasForeignKey("OrderId"); + + b.OwnsOne("Nethereum.eShop.ApplicationCore.Entities.CatalogItemExcerpt", "ItemOrdered", b1 => + { + b1.Property("OrderItemId") + .ValueGeneratedOnAdd() + .HasColumnType("int") + .HasAnnotation("SqlServer:ValueGenerationStrategy", SqlServerValueGenerationStrategy.IdentityColumn); + + b1.Property("CatalogItemId") + .HasColumnType("int"); + + b1.Property("Gtin") + .HasColumnType("nvarchar(14)") + .HasMaxLength(14); + + b1.Property("GtinRegistryId") + .HasColumnType("int"); + + b1.Property("PictureUri") + .HasColumnType("nvarchar(512)") + .HasMaxLength(512); + + b1.Property("ProductName") + .IsRequired() + .HasColumnType("nvarchar(50)") + .HasMaxLength(50); + + b1.HasKey("OrderItemId"); + + b1.ToTable("OrderItems"); + + b1.WithOwner() + .HasForeignKey("OrderItemId"); + }); + }); + + modelBuilder.Entity("Nethereum.eShop.ApplicationCore.Entities.QuoteAggregate.Quote", b => + { + b.OwnsOne("Nethereum.eShop.ApplicationCore.Entities.PostalAddress", "BillTo", b1 => + { + b1.Property("QuoteId") + .ValueGeneratedOnAdd() + .HasColumnType("int") + .HasAnnotation("SqlServer:ValueGenerationStrategy", SqlServerValueGenerationStrategy.IdentityColumn); + + b1.Property("City") + .IsRequired() + .HasColumnType("nvarchar(100)") + .HasMaxLength(100); + + b1.Property("Country") + .IsRequired() + .HasColumnType("nvarchar(90)") + .HasMaxLength(90); + + b1.Property("RecipientName") + .IsRequired() + .HasColumnType("nvarchar(255)") + .HasMaxLength(255); + + b1.Property("State") + .HasColumnType("nvarchar(60)") + .HasMaxLength(60); + + b1.Property("Street") + .IsRequired() + .HasColumnType("nvarchar(180)") + .HasMaxLength(180); + + b1.Property("ZipCode") + .IsRequired() + .HasColumnType("nvarchar(18)") + .HasMaxLength(18); + + b1.HasKey("QuoteId"); + + b1.ToTable("Quotes"); + + b1.WithOwner() + .HasForeignKey("QuoteId"); + }); + + b.OwnsOne("Nethereum.eShop.ApplicationCore.Entities.PostalAddress", "ShipTo", b1 => + { + b1.Property("QuoteId") + .ValueGeneratedOnAdd() + .HasColumnType("int") + .HasAnnotation("SqlServer:ValueGenerationStrategy", SqlServerValueGenerationStrategy.IdentityColumn); + + b1.Property("City") + .IsRequired() + .HasColumnType("nvarchar(100)") + .HasMaxLength(100); + + b1.Property("Country") + .IsRequired() + .HasColumnType("nvarchar(90)") + .HasMaxLength(90); + + b1.Property("RecipientName") + .IsRequired() + .HasColumnType("nvarchar(255)") + .HasMaxLength(255); + + b1.Property("State") + .HasColumnType("nvarchar(60)") + .HasMaxLength(60); + + b1.Property("Street") + .IsRequired() + .HasColumnType("nvarchar(180)") + .HasMaxLength(180); + + b1.Property("ZipCode") + .IsRequired() + .HasColumnType("nvarchar(18)") + .HasMaxLength(18); + + b1.HasKey("QuoteId"); + + b1.ToTable("Quotes"); + + b1.WithOwner() + .HasForeignKey("QuoteId"); + }); + }); + + modelBuilder.Entity("Nethereum.eShop.ApplicationCore.Entities.QuoteAggregate.QuoteItem", b => + { + b.HasOne("Nethereum.eShop.ApplicationCore.Entities.QuoteAggregate.Quote", null) + .WithMany("QuoteItems") + .HasForeignKey("QuoteId"); + + b.OwnsOne("Nethereum.eShop.ApplicationCore.Entities.CatalogItemExcerpt", "ItemOrdered", b1 => + { + b1.Property("QuoteItemId") + .ValueGeneratedOnAdd() + .HasColumnType("int") + .HasAnnotation("SqlServer:ValueGenerationStrategy", SqlServerValueGenerationStrategy.IdentityColumn); + + b1.Property("CatalogItemId") + .HasColumnType("int"); + + b1.Property("Gtin") + .HasColumnType("nvarchar(14)") + .HasMaxLength(14); + + b1.Property("GtinRegistryId") + .HasColumnType("int"); + + b1.Property("PictureUri") + .HasColumnType("nvarchar(512)") + .HasMaxLength(512); + + b1.Property("ProductName") + .IsRequired() + .HasColumnType("nvarchar(50)") + .HasMaxLength(50); + + b1.HasKey("QuoteItemId"); + + b1.ToTable("QuoteItems"); + + b1.WithOwner() + .HasForeignKey("QuoteItemId"); + }); + }); + + modelBuilder.Entity("Nethereum.eShop.ApplicationCore.Entities.StockItem", b => + { + b.HasOne("Nethereum.eShop.ApplicationCore.Entities.CatalogItem", "CatalogItem") + .WithMany() + .HasForeignKey("CatalogItemId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + }); +#pragma warning restore 612, 618 + } + } +} diff --git a/src/Nethereum.eShop.SqlServer/Catalog/Migrations/20200331114818_RemoveBuyerAndWalletAddress.cs b/src/Nethereum.eShop.SqlServer/Catalog/Migrations/20200331114818_RemoveBuyerAndWalletAddress.cs new file mode 100644 index 0000000..ec806a0 --- /dev/null +++ b/src/Nethereum.eShop.SqlServer/Catalog/Migrations/20200331114818_RemoveBuyerAndWalletAddress.cs @@ -0,0 +1,44 @@ +using Microsoft.EntityFrameworkCore.Migrations; + +namespace Nethereum.eShop.SqlServer.Catalog.Migrations +{ + public partial class RemoveBuyerAndWalletAddress : Migration + { + protected override void Up(MigrationBuilder migrationBuilder) + { + migrationBuilder.DropIndex( + name: "IX_Orders_BuyerAddress", + table: "Orders"); + + migrationBuilder.DropColumn( + name: "ApproverAddress", + table: "Orders"); + + migrationBuilder.DropColumn( + name: "BuyerAddress", + table: "Orders"); + } + + protected override void Down(MigrationBuilder migrationBuilder) + { + migrationBuilder.AddColumn( + name: "ApproverAddress", + table: "Orders", + type: "nvarchar(43)", + maxLength: 43, + nullable: true); + + migrationBuilder.AddColumn( + name: "BuyerAddress", + table: "Orders", + type: "nvarchar(43)", + maxLength: 43, + nullable: true); + + migrationBuilder.CreateIndex( + name: "IX_Orders_BuyerAddress", + table: "Orders", + column: "BuyerAddress"); + } + } +} diff --git a/src/Nethereum.eShop.SqlServer/Catalog/Migrations/Scripts/CreateCatalogDb.sql b/src/Nethereum.eShop.SqlServer/Catalog/Migrations/Scripts/CreateCatalogDb.sql index 2a769d5..a3c6559 100644 --- a/src/Nethereum.eShop.SqlServer/Catalog/Migrations/Scripts/CreateCatalogDb.sql +++ b/src/Nethereum.eShop.SqlServer/Catalog/Migrations/Scripts/CreateCatalogDb.sql @@ -436,3 +436,44 @@ END; GO +IF NOT EXISTS(SELECT * FROM [__EFMigrationsHistory] WHERE [MigrationId] = N'20200331114818_RemoveBuyerAndWalletAddress') +BEGIN + DROP INDEX [IX_Orders_BuyerAddress] ON [Orders]; +END; + +GO + +IF NOT EXISTS(SELECT * FROM [__EFMigrationsHistory] WHERE [MigrationId] = N'20200331114818_RemoveBuyerAndWalletAddress') +BEGIN + DECLARE @var0 sysname; + SELECT @var0 = [d].[name] + FROM [sys].[default_constraints] [d] + INNER JOIN [sys].[columns] [c] ON [d].[parent_column_id] = [c].[column_id] AND [d].[parent_object_id] = [c].[object_id] + WHERE ([d].[parent_object_id] = OBJECT_ID(N'[Orders]') AND [c].[name] = N'ApproverAddress'); + IF @var0 IS NOT NULL EXEC(N'ALTER TABLE [Orders] DROP CONSTRAINT [' + @var0 + '];'); + ALTER TABLE [Orders] DROP COLUMN [ApproverAddress]; +END; + +GO + +IF NOT EXISTS(SELECT * FROM [__EFMigrationsHistory] WHERE [MigrationId] = N'20200331114818_RemoveBuyerAndWalletAddress') +BEGIN + DECLARE @var1 sysname; + SELECT @var1 = [d].[name] + FROM [sys].[default_constraints] [d] + INNER JOIN [sys].[columns] [c] ON [d].[parent_column_id] = [c].[column_id] AND [d].[parent_object_id] = [c].[object_id] + WHERE ([d].[parent_object_id] = OBJECT_ID(N'[Orders]') AND [c].[name] = N'BuyerAddress'); + IF @var1 IS NOT NULL EXEC(N'ALTER TABLE [Orders] DROP CONSTRAINT [' + @var1 + '];'); + ALTER TABLE [Orders] DROP COLUMN [BuyerAddress]; +END; + +GO + +IF NOT EXISTS(SELECT * FROM [__EFMigrationsHistory] WHERE [MigrationId] = N'20200331114818_RemoveBuyerAndWalletAddress') +BEGIN + INSERT INTO [__EFMigrationsHistory] ([MigrationId], [ProductVersion]) + VALUES (N'20200331114818_RemoveBuyerAndWalletAddress', N'3.1.2'); +END; + +GO + diff --git a/src/Nethereum.eShop.SqlServer/Catalog/Migrations/SqlServerCatalogContextModelSnapshot.cs b/src/Nethereum.eShop.SqlServer/Catalog/Migrations/SqlServerCatalogContextModelSnapshot.cs index caed0dc..200696b 100644 --- a/src/Nethereum.eShop.SqlServer/Catalog/Migrations/SqlServerCatalogContextModelSnapshot.cs +++ b/src/Nethereum.eShop.SqlServer/Catalog/Migrations/SqlServerCatalogContextModelSnapshot.cs @@ -261,14 +261,6 @@ protected override void BuildModel(ModelBuilder modelBuilder) .HasColumnType("int") .HasAnnotation("SqlServer:ValueGenerationStrategy", SqlServerValueGenerationStrategy.IdentityColumn); - b.Property("ApproverAddress") - .HasColumnType("nvarchar(43)") - .HasMaxLength(43); - - b.Property("BuyerAddress") - .HasColumnType("nvarchar(43)") - .HasMaxLength(43); - b.Property("BuyerId") .IsRequired() .HasColumnType("nvarchar(256)") @@ -314,8 +306,6 @@ protected override void BuildModel(ModelBuilder modelBuilder) b.HasKey("Id"); - b.HasIndex("BuyerAddress"); - b.HasIndex("BuyerId"); b.ToTable("Orders"); diff --git a/src/Nethereum.eShop.Sqlite/Catalog/Migrations/20200331114826_RemoveBuyerAndWalletAddress.Designer.cs b/src/Nethereum.eShop.Sqlite/Catalog/Migrations/20200331114826_RemoveBuyerAndWalletAddress.Designer.cs new file mode 100644 index 0000000..13625ed --- /dev/null +++ b/src/Nethereum.eShop.Sqlite/Catalog/Migrations/20200331114826_RemoveBuyerAndWalletAddress.Designer.cs @@ -0,0 +1,905 @@ +// +using System; +using Microsoft.EntityFrameworkCore; +using Microsoft.EntityFrameworkCore.Infrastructure; +using Microsoft.EntityFrameworkCore.Migrations; +using Microsoft.EntityFrameworkCore.Storage.ValueConversion; +using Nethereum.eShop.Sqlite.Catalog; + +namespace Nethereum.eShop.Sqlite.Catalog.Migrations +{ + [DbContext(typeof(SqliteCatalogContext))] + [Migration("20200331114826_RemoveBuyerAndWalletAddress")] + partial class RemoveBuyerAndWalletAddress + { + protected override void BuildTargetModel(ModelBuilder modelBuilder) + { +#pragma warning disable 612, 618 + modelBuilder + .HasAnnotation("ProductVersion", "3.1.2"); + + modelBuilder.Entity("Nethereum.eShop.ApplicationCore.Entities.BasketAggregate.Basket", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("INTEGER"); + + b.Property("BuyerAddress") + .IsRequired() + .HasColumnType("TEXT") + .HasMaxLength(43); + + b.Property("BuyerId") + .IsRequired() + .HasColumnType("TEXT") + .HasMaxLength(256); + + b.Property("TransactionHash") + .HasColumnType("TEXT") + .HasMaxLength(67); + + b.HasKey("Id"); + + b.HasIndex("BuyerAddress"); + + b.HasIndex("BuyerId"); + + b.ToTable("Baskets"); + }); + + modelBuilder.Entity("Nethereum.eShop.ApplicationCore.Entities.BasketAggregate.BasketItem", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("INTEGER"); + + b.Property("BasketId") + .HasColumnType("INTEGER"); + + b.Property("CatalogItemId") + .HasColumnType("INTEGER"); + + b.Property("Quantity") + .HasColumnType("INTEGER"); + + b.Property("UnitPrice") + .HasColumnType("decimal(18,2)"); + + b.HasKey("Id"); + + b.HasIndex("BasketId"); + + b.ToTable("BasketItems"); + }); + + modelBuilder.Entity("Nethereum.eShop.ApplicationCore.Entities.BuyerAggregate.Buyer", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("INTEGER"); + + b.Property("BuyerAddress") + .HasColumnType("TEXT") + .HasMaxLength(43); + + b.Property("BuyerId") + .IsRequired() + .HasColumnType("TEXT") + .HasMaxLength(256); + + b.Property("BuyerWalletAddress") + .HasColumnType("TEXT") + .HasMaxLength(43); + + b.HasKey("Id"); + + b.HasIndex("BuyerAddress") + .IsUnique(); + + b.HasIndex("BuyerId") + .IsUnique(); + + b.HasIndex("BuyerWalletAddress") + .IsUnique(); + + b.ToTable("Buyers"); + }); + + modelBuilder.Entity("Nethereum.eShop.ApplicationCore.Entities.BuyerAggregate.BuyerPostalAddress", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("INTEGER"); + + b.Property("BuyerId") + .HasColumnType("INTEGER"); + + b.Property("Name") + .HasColumnType("TEXT"); + + b.HasKey("Id"); + + b.HasIndex("BuyerId"); + + b.ToTable("BuyerPostalAddress"); + }); + + modelBuilder.Entity("Nethereum.eShop.ApplicationCore.Entities.CatalogBrand", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("INTEGER"); + + b.Property("Brand") + .IsRequired() + .HasColumnType("TEXT") + .HasMaxLength(100); + + b.HasKey("Id"); + + b.ToTable("CatalogBrands"); + }); + + modelBuilder.Entity("Nethereum.eShop.ApplicationCore.Entities.CatalogItem", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("INTEGER"); + + b.Property("AttributeJson") + .HasColumnType("TEXT"); + + b.Property("CatalogBrandId") + .HasColumnType("INTEGER"); + + b.Property("CatalogTypeId") + .HasColumnType("INTEGER"); + + b.Property("Depth") + .HasColumnType("INTEGER"); + + b.Property("Description") + .HasColumnType("TEXT"); + + b.Property("Gtin") + .IsRequired() + .HasColumnType("TEXT") + .HasMaxLength(14); + + b.Property("GtinRegistryId") + .HasColumnType("INTEGER"); + + b.Property("Height") + .HasColumnType("INTEGER"); + + b.Property("Name") + .IsRequired() + .HasColumnType("TEXT") + .HasMaxLength(50); + + b.Property("PictureLargeUri") + .HasColumnType("TEXT") + .HasMaxLength(512); + + b.Property("PictureMediumUri") + .HasColumnType("TEXT") + .HasMaxLength(512); + + b.Property("PictureSmallUri") + .HasColumnType("TEXT") + .HasMaxLength(512); + + b.Property("PictureUri") + .HasColumnType("TEXT") + .HasMaxLength(512); + + b.Property("Price") + .HasColumnType("decimal(18,2)"); + + b.Property("Rank") + .HasColumnType("INTEGER"); + + b.Property("Status") + .HasColumnType("INTEGER"); + + b.Property("Unit") + .HasColumnType("TEXT") + .HasMaxLength(8); + + b.Property("Weight") + .HasColumnType("INTEGER"); + + b.Property("Width") + .HasColumnType("INTEGER"); + + b.HasKey("Id"); + + b.HasIndex("CatalogBrandId"); + + b.HasIndex("CatalogTypeId"); + + b.ToTable("Catalog"); + }); + + modelBuilder.Entity("Nethereum.eShop.ApplicationCore.Entities.CatalogType", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("INTEGER"); + + b.Property("Type") + .IsRequired() + .HasColumnType("TEXT") + .HasMaxLength(100); + + b.HasKey("Id"); + + b.ToTable("CatalogTypes"); + }); + + modelBuilder.Entity("Nethereum.eShop.ApplicationCore.Entities.OrderAggregate.Order", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("INTEGER"); + + b.Property("BuyerId") + .IsRequired() + .HasColumnType("TEXT") + .HasMaxLength(256); + + b.Property("BuyerWalletAddress") + .HasColumnType("TEXT") + .HasMaxLength(43); + + b.Property("CurrencyAddress") + .HasColumnType("TEXT") + .HasMaxLength(43); + + b.Property("CurrencySymbol") + .HasColumnType("TEXT") + .HasMaxLength(32); + + b.Property("OrderDate") + .HasColumnType("TEXT"); + + b.Property("PoDate") + .HasColumnType("TEXT"); + + b.Property("PoNumber") + .HasColumnType("INTEGER"); + + b.Property("PoType") + .HasColumnType("INTEGER"); + + b.Property("QuoteId") + .HasColumnType("INTEGER"); + + b.Property("SellerId") + .HasColumnType("TEXT") + .HasMaxLength(32); + + b.Property("Status") + .HasColumnType("INTEGER"); + + b.Property("TransactionHash") + .HasColumnType("TEXT") + .HasMaxLength(67); + + b.HasKey("Id"); + + b.HasIndex("BuyerId"); + + b.ToTable("Orders"); + }); + + modelBuilder.Entity("Nethereum.eShop.ApplicationCore.Entities.OrderAggregate.OrderItem", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("INTEGER"); + + b.Property("ActualEscrowReleaseDate") + .HasColumnType("TEXT"); + + b.Property("CurrencyValue") + .HasColumnType("TEXT") + .HasMaxLength(100); + + b.Property("GoodsIssueDate") + .HasColumnType("TEXT"); + + b.Property("IsEscrowReleased") + .HasColumnType("INTEGER"); + + b.Property("OrderId") + .HasColumnType("INTEGER"); + + b.Property("PlannedEscrowReleaseDate") + .HasColumnType("TEXT"); + + b.Property("PoItemNumber") + .HasColumnType("INTEGER"); + + b.Property("PoItemStatus") + .HasColumnType("INTEGER"); + + b.Property("Quantity") + .HasColumnType("INTEGER"); + + b.Property("QuantityAddress") + .HasColumnType("TEXT") + .HasMaxLength(43); + + b.Property("QuantitySymbol") + .HasColumnType("TEXT") + .HasMaxLength(32); + + b.Property("Status") + .HasColumnType("INTEGER"); + + b.Property("Unit") + .HasColumnType("TEXT") + .HasMaxLength(50); + + b.Property("UnitPrice") + .HasColumnType("decimal(18,2)"); + + b.HasKey("Id"); + + b.HasIndex("OrderId"); + + b.ToTable("OrderItems"); + }); + + modelBuilder.Entity("Nethereum.eShop.ApplicationCore.Entities.QuoteAggregate.Quote", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("INTEGER"); + + b.Property("ApproverAddress") + .HasColumnType("TEXT") + .HasMaxLength(43); + + b.Property("BuyerAddress") + .HasColumnType("TEXT") + .HasMaxLength(43); + + b.Property("BuyerId") + .IsRequired() + .HasColumnType("TEXT") + .HasMaxLength(256); + + b.Property("BuyerWalletAddress") + .HasColumnType("TEXT") + .HasMaxLength(43); + + b.Property("CurrencyAddress") + .HasColumnType("TEXT") + .HasMaxLength(43); + + b.Property("CurrencySymbol") + .HasColumnType("TEXT") + .HasMaxLength(32); + + b.Property("Date") + .HasColumnType("TEXT"); + + b.Property("Expiry") + .HasColumnType("TEXT"); + + b.Property("PoNumber") + .HasColumnType("INTEGER"); + + b.Property("PoType") + .HasColumnType("INTEGER"); + + b.Property("SellerId") + .HasColumnType("TEXT") + .HasMaxLength(32); + + b.Property("Status") + .HasColumnType("INTEGER"); + + b.Property("TransactionHash") + .HasColumnType("TEXT") + .HasMaxLength(67); + + b.HasKey("Id"); + + b.HasIndex("BuyerAddress"); + + b.HasIndex("BuyerId"); + + b.ToTable("Quotes"); + }); + + modelBuilder.Entity("Nethereum.eShop.ApplicationCore.Entities.QuoteAggregate.QuoteItem", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("INTEGER"); + + b.Property("CurrencyValue") + .HasColumnType("TEXT"); + + b.Property("EscrowReleaseDate") + .HasColumnType("TEXT"); + + b.Property("PoItemNumber") + .HasColumnType("INTEGER"); + + b.Property("Quantity") + .HasColumnType("INTEGER"); + + b.Property("QuantityAddress") + .HasColumnType("TEXT"); + + b.Property("QuantitySymbol") + .HasColumnType("TEXT"); + + b.Property("QuoteId") + .HasColumnType("INTEGER"); + + b.Property("Unit") + .HasColumnType("TEXT"); + + b.Property("UnitPrice") + .HasColumnType("decimal(18,2)"); + + b.HasKey("Id"); + + b.HasIndex("QuoteId"); + + b.ToTable("QuoteItems"); + }); + + modelBuilder.Entity("Nethereum.eShop.ApplicationCore.Entities.StockItem", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("INTEGER"); + + b.Property("CatalogItemId") + .HasColumnType("INTEGER"); + + b.Property("Location") + .IsRequired() + .HasColumnType("TEXT") + .HasMaxLength(50); + + b.Property("Quantity") + .HasColumnType("INTEGER"); + + b.HasKey("Id"); + + b.HasIndex("CatalogItemId"); + + b.ToTable("Stock"); + }); + + modelBuilder.Entity("Nethereum.eShop.ApplicationCore.Entities.BasketAggregate.Basket", b => + { + b.OwnsOne("Nethereum.eShop.ApplicationCore.Entities.PostalAddress", "BillTo", b1 => + { + b1.Property("BasketId") + .HasColumnType("INTEGER"); + + b1.Property("City") + .IsRequired() + .HasColumnType("TEXT") + .HasMaxLength(100); + + b1.Property("Country") + .IsRequired() + .HasColumnType("TEXT") + .HasMaxLength(90); + + b1.Property("RecipientName") + .IsRequired() + .HasColumnType("TEXT") + .HasMaxLength(255); + + b1.Property("State") + .HasColumnType("TEXT") + .HasMaxLength(60); + + b1.Property("Street") + .IsRequired() + .HasColumnType("TEXT") + .HasMaxLength(180); + + b1.Property("ZipCode") + .IsRequired() + .HasColumnType("TEXT") + .HasMaxLength(18); + + b1.HasKey("BasketId"); + + b1.ToTable("Baskets"); + + b1.WithOwner() + .HasForeignKey("BasketId"); + }); + + b.OwnsOne("Nethereum.eShop.ApplicationCore.Entities.PostalAddress", "ShipTo", b1 => + { + b1.Property("BasketId") + .HasColumnType("INTEGER"); + + b1.Property("City") + .IsRequired() + .HasColumnType("TEXT") + .HasMaxLength(100); + + b1.Property("Country") + .IsRequired() + .HasColumnType("TEXT") + .HasMaxLength(90); + + b1.Property("RecipientName") + .IsRequired() + .HasColumnType("TEXT") + .HasMaxLength(255); + + b1.Property("State") + .HasColumnType("TEXT") + .HasMaxLength(60); + + b1.Property("Street") + .IsRequired() + .HasColumnType("TEXT") + .HasMaxLength(180); + + b1.Property("ZipCode") + .IsRequired() + .HasColumnType("TEXT") + .HasMaxLength(18); + + b1.HasKey("BasketId"); + + b1.ToTable("Baskets"); + + b1.WithOwner() + .HasForeignKey("BasketId"); + }); + }); + + modelBuilder.Entity("Nethereum.eShop.ApplicationCore.Entities.BasketAggregate.BasketItem", b => + { + b.HasOne("Nethereum.eShop.ApplicationCore.Entities.BasketAggregate.Basket", null) + .WithMany("Items") + .HasForeignKey("BasketId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + }); + + modelBuilder.Entity("Nethereum.eShop.ApplicationCore.Entities.BuyerAggregate.BuyerPostalAddress", b => + { + b.HasOne("Nethereum.eShop.ApplicationCore.Entities.BuyerAggregate.Buyer", null) + .WithMany("PostalAddresses") + .HasForeignKey("BuyerId"); + + b.OwnsOne("Nethereum.eShop.ApplicationCore.Entities.PostalAddress", "PostalAddress", b1 => + { + b1.Property("BuyerPostalAddressId") + .HasColumnType("INTEGER"); + + b1.Property("City") + .IsRequired() + .HasColumnType("TEXT") + .HasMaxLength(100); + + b1.Property("Country") + .IsRequired() + .HasColumnType("TEXT") + .HasMaxLength(90); + + b1.Property("RecipientName") + .IsRequired() + .HasColumnType("TEXT") + .HasMaxLength(255); + + b1.Property("State") + .HasColumnType("TEXT") + .HasMaxLength(60); + + b1.Property("Street") + .IsRequired() + .HasColumnType("TEXT") + .HasMaxLength(180); + + b1.Property("ZipCode") + .IsRequired() + .HasColumnType("TEXT") + .HasMaxLength(18); + + b1.HasKey("BuyerPostalAddressId"); + + b1.ToTable("BuyerPostalAddress"); + + b1.WithOwner() + .HasForeignKey("BuyerPostalAddressId"); + }); + }); + + modelBuilder.Entity("Nethereum.eShop.ApplicationCore.Entities.CatalogItem", b => + { + b.HasOne("Nethereum.eShop.ApplicationCore.Entities.CatalogBrand", "CatalogBrand") + .WithMany() + .HasForeignKey("CatalogBrandId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.HasOne("Nethereum.eShop.ApplicationCore.Entities.CatalogType", "CatalogType") + .WithMany() + .HasForeignKey("CatalogTypeId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + }); + + modelBuilder.Entity("Nethereum.eShop.ApplicationCore.Entities.OrderAggregate.Order", b => + { + b.OwnsOne("Nethereum.eShop.ApplicationCore.Entities.PostalAddress", "BillTo", b1 => + { + b1.Property("OrderId") + .HasColumnType("INTEGER"); + + b1.Property("City") + .IsRequired() + .HasColumnType("TEXT") + .HasMaxLength(100); + + b1.Property("Country") + .IsRequired() + .HasColumnType("TEXT") + .HasMaxLength(90); + + b1.Property("RecipientName") + .IsRequired() + .HasColumnType("TEXT") + .HasMaxLength(255); + + b1.Property("State") + .HasColumnType("TEXT") + .HasMaxLength(60); + + b1.Property("Street") + .IsRequired() + .HasColumnType("TEXT") + .HasMaxLength(180); + + b1.Property("ZipCode") + .IsRequired() + .HasColumnType("TEXT") + .HasMaxLength(18); + + b1.HasKey("OrderId"); + + b1.ToTable("Orders"); + + b1.WithOwner() + .HasForeignKey("OrderId"); + }); + + b.OwnsOne("Nethereum.eShop.ApplicationCore.Entities.PostalAddress", "ShipTo", b1 => + { + b1.Property("OrderId") + .HasColumnType("INTEGER"); + + b1.Property("City") + .IsRequired() + .HasColumnType("TEXT") + .HasMaxLength(100); + + b1.Property("Country") + .IsRequired() + .HasColumnType("TEXT") + .HasMaxLength(90); + + b1.Property("RecipientName") + .IsRequired() + .HasColumnType("TEXT") + .HasMaxLength(255); + + b1.Property("State") + .HasColumnType("TEXT") + .HasMaxLength(60); + + b1.Property("Street") + .IsRequired() + .HasColumnType("TEXT") + .HasMaxLength(180); + + b1.Property("ZipCode") + .IsRequired() + .HasColumnType("TEXT") + .HasMaxLength(18); + + b1.HasKey("OrderId"); + + b1.ToTable("Orders"); + + b1.WithOwner() + .HasForeignKey("OrderId"); + }); + }); + + modelBuilder.Entity("Nethereum.eShop.ApplicationCore.Entities.OrderAggregate.OrderItem", b => + { + b.HasOne("Nethereum.eShop.ApplicationCore.Entities.OrderAggregate.Order", null) + .WithMany("OrderItems") + .HasForeignKey("OrderId"); + + b.OwnsOne("Nethereum.eShop.ApplicationCore.Entities.CatalogItemExcerpt", "ItemOrdered", b1 => + { + b1.Property("OrderItemId") + .HasColumnType("INTEGER"); + + b1.Property("CatalogItemId") + .HasColumnType("INTEGER"); + + b1.Property("Gtin") + .HasColumnType("TEXT") + .HasMaxLength(14); + + b1.Property("GtinRegistryId") + .HasColumnType("INTEGER"); + + b1.Property("PictureUri") + .HasColumnType("TEXT") + .HasMaxLength(512); + + b1.Property("ProductName") + .IsRequired() + .HasColumnType("TEXT") + .HasMaxLength(50); + + b1.HasKey("OrderItemId"); + + b1.ToTable("OrderItems"); + + b1.WithOwner() + .HasForeignKey("OrderItemId"); + }); + }); + + modelBuilder.Entity("Nethereum.eShop.ApplicationCore.Entities.QuoteAggregate.Quote", b => + { + b.OwnsOne("Nethereum.eShop.ApplicationCore.Entities.PostalAddress", "BillTo", b1 => + { + b1.Property("QuoteId") + .HasColumnType("INTEGER"); + + b1.Property("City") + .IsRequired() + .HasColumnType("TEXT") + .HasMaxLength(100); + + b1.Property("Country") + .IsRequired() + .HasColumnType("TEXT") + .HasMaxLength(90); + + b1.Property("RecipientName") + .IsRequired() + .HasColumnType("TEXT") + .HasMaxLength(255); + + b1.Property("State") + .HasColumnType("TEXT") + .HasMaxLength(60); + + b1.Property("Street") + .IsRequired() + .HasColumnType("TEXT") + .HasMaxLength(180); + + b1.Property("ZipCode") + .IsRequired() + .HasColumnType("TEXT") + .HasMaxLength(18); + + b1.HasKey("QuoteId"); + + b1.ToTable("Quotes"); + + b1.WithOwner() + .HasForeignKey("QuoteId"); + }); + + b.OwnsOne("Nethereum.eShop.ApplicationCore.Entities.PostalAddress", "ShipTo", b1 => + { + b1.Property("QuoteId") + .HasColumnType("INTEGER"); + + b1.Property("City") + .IsRequired() + .HasColumnType("TEXT") + .HasMaxLength(100); + + b1.Property("Country") + .IsRequired() + .HasColumnType("TEXT") + .HasMaxLength(90); + + b1.Property("RecipientName") + .IsRequired() + .HasColumnType("TEXT") + .HasMaxLength(255); + + b1.Property("State") + .HasColumnType("TEXT") + .HasMaxLength(60); + + b1.Property("Street") + .IsRequired() + .HasColumnType("TEXT") + .HasMaxLength(180); + + b1.Property("ZipCode") + .IsRequired() + .HasColumnType("TEXT") + .HasMaxLength(18); + + b1.HasKey("QuoteId"); + + b1.ToTable("Quotes"); + + b1.WithOwner() + .HasForeignKey("QuoteId"); + }); + }); + + modelBuilder.Entity("Nethereum.eShop.ApplicationCore.Entities.QuoteAggregate.QuoteItem", b => + { + b.HasOne("Nethereum.eShop.ApplicationCore.Entities.QuoteAggregate.Quote", null) + .WithMany("QuoteItems") + .HasForeignKey("QuoteId"); + + b.OwnsOne("Nethereum.eShop.ApplicationCore.Entities.CatalogItemExcerpt", "ItemOrdered", b1 => + { + b1.Property("QuoteItemId") + .HasColumnType("INTEGER"); + + b1.Property("CatalogItemId") + .HasColumnType("INTEGER"); + + b1.Property("Gtin") + .HasColumnType("TEXT") + .HasMaxLength(14); + + b1.Property("GtinRegistryId") + .HasColumnType("INTEGER"); + + b1.Property("PictureUri") + .HasColumnType("TEXT") + .HasMaxLength(512); + + b1.Property("ProductName") + .IsRequired() + .HasColumnType("TEXT") + .HasMaxLength(50); + + b1.HasKey("QuoteItemId"); + + b1.ToTable("QuoteItems"); + + b1.WithOwner() + .HasForeignKey("QuoteItemId"); + }); + }); + + modelBuilder.Entity("Nethereum.eShop.ApplicationCore.Entities.StockItem", b => + { + b.HasOne("Nethereum.eShop.ApplicationCore.Entities.CatalogItem", "CatalogItem") + .WithMany() + .HasForeignKey("CatalogItemId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + }); +#pragma warning restore 612, 618 + } + } +} diff --git a/src/Nethereum.eShop.Sqlite/Catalog/Migrations/20200331114826_RemoveBuyerAndWalletAddress.cs b/src/Nethereum.eShop.Sqlite/Catalog/Migrations/20200331114826_RemoveBuyerAndWalletAddress.cs new file mode 100644 index 0000000..45a4da5 --- /dev/null +++ b/src/Nethereum.eShop.Sqlite/Catalog/Migrations/20200331114826_RemoveBuyerAndWalletAddress.cs @@ -0,0 +1,50 @@ +using Microsoft.EntityFrameworkCore.Migrations; + +namespace Nethereum.eShop.Sqlite.Catalog.Migrations +{ + public partial class RemoveBuyerAndWalletAddress : Migration + { + protected override void Up(MigrationBuilder migrationBuilder) + { + migrationBuilder.DropIndex( + name: "IX_Orders_BuyerAddress", + table: "Orders"); + + //SQLite does not support drop column + // TODO: implement a workaround - create new table with only required columns, copy data to new table, rename + // https://t-heiten.net/ef-core/fix-sqlite-migration/ + + //migrationBuilder.DropColumn( + // name: "ApproverAddress", + // table: "Orders"); + + //migrationBuilder.DropColumn( + // name: "BuyerAddress", + // table: "Orders"); + } + + protected override void Down(MigrationBuilder migrationBuilder) + { + //SQLite does not support drop column + + //migrationBuilder.AddColumn( + // name: "ApproverAddress", + // table: "Orders", + // type: "TEXT", + // maxLength: 43, + // nullable: true); + + //migrationBuilder.AddColumn( + // name: "BuyerAddress", + // table: "Orders", + // type: "TEXT", + // maxLength: 43, + // nullable: true); + + migrationBuilder.CreateIndex( + name: "IX_Orders_BuyerAddress", + table: "Orders", + column: "BuyerAddress"); + } + } +} diff --git a/src/Nethereum.eShop.Sqlite/Catalog/Migrations/Scripts/CreateCatalogDb.sql b/src/Nethereum.eShop.Sqlite/Catalog/Migrations/Scripts/CreateCatalogDb.sql index b9296fa..552c299 100644 --- a/src/Nethereum.eShop.Sqlite/Catalog/Migrations/Scripts/CreateCatalogDb.sql +++ b/src/Nethereum.eShop.Sqlite/Catalog/Migrations/Scripts/CreateCatalogDb.sql @@ -235,3 +235,8 @@ CREATE UNIQUE INDEX "IX_Buyers_BuyerWalletAddress" ON "Buyers" ("BuyerWalletAddr INSERT INTO "__EFMigrationsHistory" ("MigrationId", "ProductVersion") VALUES ('20200311172413_BuyerWalletAddress', '3.1.2'); +DROP INDEX "IX_Orders_BuyerAddress"; + +INSERT INTO "__EFMigrationsHistory" ("MigrationId", "ProductVersion") +VALUES ('20200331114826_RemoveBuyerAndWalletAddress', '3.1.2'); + diff --git a/src/Nethereum.eShop.Sqlite/Catalog/Migrations/SqliteCatalogContextModelSnapshot.cs b/src/Nethereum.eShop.Sqlite/Catalog/Migrations/SqliteCatalogContextModelSnapshot.cs index 666095d..dbfa381 100644 --- a/src/Nethereum.eShop.Sqlite/Catalog/Migrations/SqliteCatalogContextModelSnapshot.cs +++ b/src/Nethereum.eShop.Sqlite/Catalog/Migrations/SqliteCatalogContextModelSnapshot.cs @@ -241,14 +241,6 @@ protected override void BuildModel(ModelBuilder modelBuilder) .ValueGeneratedOnAdd() .HasColumnType("INTEGER"); - b.Property("ApproverAddress") - .HasColumnType("TEXT") - .HasMaxLength(43); - - b.Property("BuyerAddress") - .HasColumnType("TEXT") - .HasMaxLength(43); - b.Property("BuyerId") .IsRequired() .HasColumnType("TEXT") @@ -294,8 +286,6 @@ protected override void BuildModel(ModelBuilder modelBuilder) b.HasKey("Id"); - b.HasIndex("BuyerAddress"); - b.HasIndex("BuyerId"); b.ToTable("Orders"); diff --git a/src/Nethereum.eShop/ApplicationCore/Entities/OrderAggregate/Order.cs b/src/Nethereum.eShop/ApplicationCore/Entities/OrderAggregate/Order.cs index f9a06eb..b21eb4c 100644 --- a/src/Nethereum.eShop/ApplicationCore/Entities/OrderAggregate/Order.cs +++ b/src/Nethereum.eShop/ApplicationCore/Entities/OrderAggregate/Order.cs @@ -18,17 +18,10 @@ public class Order : BaseEntity, IAggregateRoot public string BuyerId { get; set; } - /// - /// The Buyer Address - /// - public string BuyerAddress { get; set; } - public string CurrencyAddress { get; set; } public string CurrencySymbol { get; set; } - public string ApproverAddress { get; set; } - /// /// The Purhase Order Number /// @@ -79,17 +72,17 @@ private Order() // required by EF } - public Order(string buyerId, string buyerAddress, PostalAddress billTo, PostalAddress shipTo, List items) + public Order(string buyerId, string buyerWalletAddress, PostalAddress billTo, PostalAddress shipTo, List items) { Guard.Against.NullOrEmpty(buyerId, nameof(buyerId)); - Guard.Against.NullOrEmpty(buyerAddress, nameof(buyerAddress)); + Guard.Against.NullOrEmpty(buyerWalletAddress, nameof(buyerWalletAddress)); // TODO: Reinforce null address guards // Guard.Against.Null(billTo, nameof(billTo)); // Guard.Against.Null(shipTo, nameof(shipTo)); Guard.Against.Null(items, nameof(items)); BuyerId = buyerId; - BuyerAddress = buyerAddress; + BuyerWalletAddress = buyerWalletAddress; ShipTo = shipTo; _orderItems = items; } diff --git a/src/Nethereum.eShop/ApplicationCore/Services/OrderService.cs b/src/Nethereum.eShop/ApplicationCore/Services/OrderService.cs index c097aff..569643a 100644 --- a/src/Nethereum.eShop/ApplicationCore/Services/OrderService.cs +++ b/src/Nethereum.eShop/ApplicationCore/Services/OrderService.cs @@ -52,16 +52,14 @@ private static List MapQuoteItemsToOrderItems(Quote quote) private static Order MapQuoteToOrder(string transactionHash, Po purchaseOrder, Quote quote, List items) { - var order = new Order(quote.BuyerId, purchaseOrder.BuyerAddress, quote.BillTo, quote.ShipTo, items); + var order = new Order(quote.BuyerId, purchaseOrder.BuyerWalletAddress, quote.BillTo, quote.ShipTo, items); order.QuoteId = quote.Id; order.PoDate = DateTimeOffset.FromUnixTimeSeconds((long)purchaseOrder.PoCreateDate); order.PoType = (int)purchaseOrder.PoType; - order.ApproverAddress = purchaseOrder.ApproverAddress; // TODO: define if we should have BuyerId and BuyerAddress // the po will have the address, the quote will have the buyer order.BuyerId = quote.BuyerId; - order.BuyerAddress = purchaseOrder.BuyerAddress; order.BuyerWalletAddress = purchaseOrder.BuyerWalletAddress; order.CurrencyAddress = purchaseOrder.CurrencyAddress; diff --git a/src/WebJobs/Config/EshopConfiguration.cs b/src/WebJobs/Config/EshopConfiguration.cs index 1543e26..e019e98 100644 --- a/src/WebJobs/Config/EshopConfiguration.cs +++ b/src/WebJobs/Config/EshopConfiguration.cs @@ -13,10 +13,12 @@ public class EshopConfiguration public string EthereumRpcUrl { get; set; } public string AccountPrivateKey { get; set; } - public string SellerId { get; set; } + public string EShopId { get; set; } public string BuyerWalletAddress { get; set; } + public string BusinessPartnerStorageServiceAddress { get; set; } + public bool CreateFakePurchaseOrders { get; set; } public PurchaseOrderEventLogProcessingConfiguration PurchaseOrderEventLogConfiguration { get; set; } diff --git a/src/WebJobs/Jobs/CreateFakePurchaseOrders.cs b/src/WebJobs/Jobs/CreateFakePurchaseOrders.cs index bc71a92..376a319 100644 --- a/src/WebJobs/Jobs/CreateFakePurchaseOrders.cs +++ b/src/WebJobs/Jobs/CreateFakePurchaseOrders.cs @@ -1,11 +1,10 @@ using Microsoft.Extensions.Logging; using Nethereum.Commerce.Contracts; +using Nethereum.Commerce.Contracts.BuyerWallet; using Nethereum.Commerce.Contracts.Purchasing.ContractDefinition; -using Nethereum.Commerce.Contracts.WalletBuyer; using Nethereum.Contracts; using Nethereum.eShop.ApplicationCore.Entities.QuoteAggregate; using Nethereum.eShop.ApplicationCore.Interfaces; -using Nethereum.eShop.ApplicationCore.Specifications; using Nethereum.eShop.WebJobs.Configuration; using Nethereum.Web3.Accounts; using System; @@ -14,7 +13,6 @@ using System.Numerics; using System.Threading.Tasks; using static Nethereum.Commerce.Contracts.ContractEnums; -using Storage = Nethereum.Commerce.Contracts.PoStorage.ContractDefinition; namespace Nethereum.eShop.WebJobs.Jobs { @@ -41,7 +39,7 @@ public async Task ExecuteAsync(ILogger logger) var account = new Account(_config.AccountPrivateKey); var web3 = new Web3.Web3(account); - var walletBuyerService = new WalletBuyerService(web3, _config.BuyerWalletAddress); + var walletBuyerService = new BuyerWalletService(web3, _config.BuyerWalletAddress); foreach (var quote in pendingQuotes) { @@ -49,9 +47,9 @@ public async Task ExecuteAsync(ILogger logger) } } - private async Task CreatePoForQuote(ILogger logger, WalletBuyerService walletBuyerService, Quote quote) + private async Task CreatePoForQuote(ILogger logger, BuyerWalletService walletBuyerService, Quote quote) { - var existing = await walletBuyerService.GetPoBySellerAndQuoteQueryAsync(_config.SellerId, quote.Id); + var existing = await walletBuyerService.GetPoQueryAsync(_config.EShopId, quote.Id); if (existing?.Po?.PoNumber > 0) { quote.PoNumber = (long)existing.Po.PoNumber; @@ -62,7 +60,8 @@ private async Task CreatePoForQuote(ILogger logger, WalletBuyerService walletBuy } var po = CreateDummyPoForPurchasingCreate(quote, walletBuyerService.ContractHandler.ContractAddress).ToBuyerPo(); - var receipt = await walletBuyerService.CreatePurchaseOrderRequestAndWaitForReceiptAsync(po); + var poArgs = new Nethereum.Commerce.Contracts.BuyerWallet.ContractDefinition.CreatePurchaseOrderFunction { Po = po }; + var receipt = await walletBuyerService.CreatePurchaseOrderRequestAndWaitForReceiptAsync(poArgs); var createdEvent = receipt.DecodeAllEvents().FirstOrDefault(); @@ -81,31 +80,28 @@ private async Task CreatePoForQuote(ILogger logger, WalletBuyerService walletBuy } } - public Storage.Po CreateDummyPoForPurchasingCreate(Quote quote, string buyerWalletAddress) + public Po CreateDummyPoForPurchasingCreate(Quote quote, string buyerWalletAddress) { - var po = new Storage.Po() + var po = new Po() { // PoNumber assigned by contract - BuyerAddress = "0x94618601fe6cb8912b274e5a00453949a57f8c1e", - ReceiverAddress = "0x94618601fe6cb8912b274e5a00453949a57f8c1e", BuyerWalletAddress = buyerWalletAddress, CurrencySymbol = "DAI", CurrencyAddress = "0xef76bcb4216fbbbd4d6e88082d5654def9b6fe2f", QuoteId = quote.Id, QuoteExpiryDate = DateTimeOffset.UtcNow.AddMonths(1).ToUnixTimeSeconds(), - ApproverAddress = string.Empty, // assigned by contract PoType = PoType.Cash, - SellerId = _config.SellerId, + SellerId = _config.EShopId, // PoCreateDate assigned by contract // PoItemCount assigned by contract - PoItems = new List() + PoItems = new List() }; //gtin1111 foreach (var quoteItem in quote.QuoteItems) { - po.PoItems.Add(new Storage.PoItem + po.PoItems.Add(new PoItem { // PoNumber assigned by contract // PoItemNumber assigned by contract diff --git a/src/WebJobs/Jobs/ProcessPurchaseOrderEventLogs.cs b/src/WebJobs/Jobs/ProcessPurchaseOrderEventLogs.cs index fc4bf91..038d9a1 100644 --- a/src/WebJobs/Jobs/ProcessPurchaseOrderEventLogs.cs +++ b/src/WebJobs/Jobs/ProcessPurchaseOrderEventLogs.cs @@ -5,8 +5,9 @@ using Nethereum.BlockchainProcessing.Orchestrator; using Nethereum.BlockchainProcessing.Processor; using Nethereum.BlockchainProcessing.ProgressRepositories; +using Nethereum.Commerce.Contracts.BusinessPartnerStorage; +using Nethereum.Commerce.Contracts.BuyerWallet; using Nethereum.Commerce.Contracts.Purchasing.ContractDefinition; -using Nethereum.Commerce.Contracts.WalletBuyer; using Nethereum.eShop.ApplicationCore.Exceptions; using Nethereum.eShop.ApplicationCore.Interfaces; using Nethereum.eShop.WebJobs.Configuration; @@ -49,8 +50,11 @@ public async Task ExecuteAsync(ILogger logger) const int RequestRetryWeight = 0; // see below for retry algorithm var web3 = new Web3.Web3(_eshopConfiguration.EthereumRpcUrl); - var walletBuyerService = new WalletBuyerService(web3, _eshopConfiguration.BuyerWalletAddress); - var purchasingContractAddress = await walletBuyerService.PurchasingQueryAsync(); + var walletBuyerService = new BuyerWalletService(web3, _eshopConfiguration.BuyerWalletAddress); + + var businessPartnerStorageService = new BusinessPartnerStorageService(web3, _eshopConfiguration.BusinessPartnerStorageServiceAddress); + var eshop = await businessPartnerStorageService.GetEshopQueryAsync(_eshopConfiguration.EShopId); + var purchasingContractAddress = eshop.EShop.PurchasingContractAddress; var filter = new NewFilterInput { Address = new[] { purchasingContractAddress } }; diff --git a/src/WebJobs/appsettings.json b/src/WebJobs/appsettings.json index 661a752..61cf8f8 100644 --- a/src/WebJobs/appsettings.json +++ b/src/WebJobs/appsettings.json @@ -12,7 +12,7 @@ "EshopConfiguration": { "EthereumRpcUrl": "http://localhost:8545/", "AccountPrivateKey": "0x7580e7fb49df1c861f0050fae31c2224c6aba908e116b8da44ee8cd927b990b0", - "SellerId": "Nethereum.eShop", + "EShopId": "Nethereum.eShop", "BuyerWalletAddress": "0x969b34204c90947822e278d10482b79a51c1544f", "CreateFakePurchaseOrders": true, From dfaa7b56505e3002f9189a62fda6056eb0855998 Mon Sep 17 00:00:00 2001 From: Dave Whiffin Date: Tue, 31 Mar 2020 15:36:24 +0100 Subject: [PATCH 22/27] Sqlite Migration Workaround for Drop Column Restriction --- ...00331114826_RemoveBuyerAndWalletAddress.cs | 80 +++++++++++++------ .../Migrations/Scripts/CreateCatalogDb.sql | 38 +++++++++ 2 files changed, 94 insertions(+), 24 deletions(-) diff --git a/src/Nethereum.eShop.Sqlite/Catalog/Migrations/20200331114826_RemoveBuyerAndWalletAddress.cs b/src/Nethereum.eShop.Sqlite/Catalog/Migrations/20200331114826_RemoveBuyerAndWalletAddress.cs index 45a4da5..e205cba 100644 --- a/src/Nethereum.eShop.Sqlite/Catalog/Migrations/20200331114826_RemoveBuyerAndWalletAddress.cs +++ b/src/Nethereum.eShop.Sqlite/Catalog/Migrations/20200331114826_RemoveBuyerAndWalletAddress.cs @@ -1,4 +1,5 @@ using Microsoft.EntityFrameworkCore.Migrations; +using System; namespace Nethereum.eShop.Sqlite.Catalog.Migrations { @@ -10,36 +11,67 @@ protected override void Up(MigrationBuilder migrationBuilder) name: "IX_Orders_BuyerAddress", table: "Orders"); - //SQLite does not support drop column - // TODO: implement a workaround - create new table with only required columns, copy data to new table, rename - // https://t-heiten.net/ef-core/fix-sqlite-migration/ + // SQLite does not support drop column + // Create new temp table + migrationBuilder.CreateTable( + name: "TmpOrders", + columns: table => new + { + Id = table.Column(nullable: false) + .Annotation("Sqlite:Autoincrement", true), + QuoteId = table.Column(nullable: true), + Status = table.Column(nullable: false), + TransactionHash = table.Column(maxLength: 67, nullable: true), + BuyerId = table.Column(maxLength: 256, nullable: false), + CurrencyAddress = table.Column(maxLength: 43, nullable: true), + CurrencySymbol = table.Column(maxLength: 32, nullable: true), + PoNumber = table.Column(nullable: true), + PoType = table.Column(nullable: false), + BuyerWalletAddress = table.Column(maxLength: 43, nullable: true), + SellerId = table.Column(maxLength: 32, nullable: true), + PoDate = table.Column(nullable: true), + OrderDate = table.Column(nullable: false), + BillTo_RecipientName = table.Column(maxLength: 255, nullable: true), + BillTo_Street = table.Column(maxLength: 180, nullable: true), + BillTo_City = table.Column(maxLength: 100, nullable: true), + BillTo_State = table.Column(maxLength: 60, nullable: true), + BillTo_Country = table.Column(maxLength: 90, nullable: true), + BillTo_ZipCode = table.Column(maxLength: 18, nullable: true), + ShipTo_RecipientName = table.Column(maxLength: 255, nullable: true), + ShipTo_Street = table.Column(maxLength: 180, nullable: true), + ShipTo_City = table.Column(maxLength: 100, nullable: true), + ShipTo_State = table.Column(maxLength: 60, nullable: true), + ShipTo_Country = table.Column(maxLength: 90, nullable: true), + ShipTo_ZipCode = table.Column(maxLength: 18, nullable: true) + }, + constraints: table => + { + table.PrimaryKey("PK_TmpOrders", x => x.Id); + }); - //migrationBuilder.DropColumn( - // name: "ApproverAddress", - // table: "Orders"); - - //migrationBuilder.DropColumn( - // name: "BuyerAddress", - // table: "Orders"); + // Copy existing data to temp table, drop original and rename temp + migrationBuilder.Sql("INSERT INTO TmpOrders SELECT Id, QuoteId, Status, TransactionHash, BuyerId, CurrencyAddress, CurrencySymbol, PoNumber, PoType, BuyerWalletAddress, Sellerid, PoDate, OrderDate, BillTo_RecipientName, BillTo_Street, BillTo_City, BillTo_State, BillTo_Country, BillTo_ZipCode, ShipTo_RecipientName, ShipTo_Street, ShipTo_City, ShipTo_State, ShipTo_Country, ShipTo_ZipCode FROM Orders;"); + migrationBuilder.Sql("PRAGMA foreign_keys=\"0\"", true); + migrationBuilder.Sql("DROP TABLE Orders", true); + migrationBuilder.Sql("ALTER TABLE TmpOrders RENAME TO Orders", true); + migrationBuilder.Sql("PRAGMA foreign_keys=\"1\"", true); } protected override void Down(MigrationBuilder migrationBuilder) { - //SQLite does not support drop column - - //migrationBuilder.AddColumn( - // name: "ApproverAddress", - // table: "Orders", - // type: "TEXT", - // maxLength: 43, - // nullable: true); + migrationBuilder.AddColumn( + name: "ApproverAddress", + table: "Orders", + type: "TEXT", + maxLength: 43, + nullable: true); - //migrationBuilder.AddColumn( - // name: "BuyerAddress", - // table: "Orders", - // type: "TEXT", - // maxLength: 43, - // nullable: true); + migrationBuilder.AddColumn( + name: "BuyerAddress", + table: "Orders", + type: "TEXT", + maxLength: 43, + nullable: true); migrationBuilder.CreateIndex( name: "IX_Orders_BuyerAddress", diff --git a/src/Nethereum.eShop.Sqlite/Catalog/Migrations/Scripts/CreateCatalogDb.sql b/src/Nethereum.eShop.Sqlite/Catalog/Migrations/Scripts/CreateCatalogDb.sql index 552c299..a5fabe9 100644 --- a/src/Nethereum.eShop.Sqlite/Catalog/Migrations/Scripts/CreateCatalogDb.sql +++ b/src/Nethereum.eShop.Sqlite/Catalog/Migrations/Scripts/CreateCatalogDb.sql @@ -237,6 +237,44 @@ VALUES ('20200311172413_BuyerWalletAddress', '3.1.2'); DROP INDEX "IX_Orders_BuyerAddress"; +CREATE TABLE "TmpOrders" ( + "Id" INTEGER NOT NULL CONSTRAINT "PK_TmpOrders" PRIMARY KEY AUTOINCREMENT, + "QuoteId" INTEGER NULL, + "Status" INTEGER NOT NULL, + "TransactionHash" TEXT NULL, + "BuyerId" TEXT NOT NULL, + "CurrencyAddress" TEXT NULL, + "CurrencySymbol" TEXT NULL, + "PoNumber" INTEGER NULL, + "PoType" INTEGER NOT NULL, + "BuyerWalletAddress" TEXT NULL, + "SellerId" TEXT NULL, + "PoDate" TEXT NULL, + "OrderDate" TEXT NOT NULL, + "BillTo_RecipientName" TEXT NULL, + "BillTo_Street" TEXT NULL, + "BillTo_City" TEXT NULL, + "BillTo_State" TEXT NULL, + "BillTo_Country" TEXT NULL, + "BillTo_ZipCode" TEXT NULL, + "ShipTo_RecipientName" TEXT NULL, + "ShipTo_Street" TEXT NULL, + "ShipTo_City" TEXT NULL, + "ShipTo_State" TEXT NULL, + "ShipTo_Country" TEXT NULL, + "ShipTo_ZipCode" TEXT NULL +); + +INSERT INTO TmpOrders SELECT Id, QuoteId, Status, TransactionHash, BuyerId, CurrencyAddress, CurrencySymbol, PoNumber, PoType, BuyerWalletAddress, Sellerid, PoDate, OrderDate, BillTo_RecipientName, BillTo_Street, BillTo_City, BillTo_State, BillTo_Country, BillTo_ZipCode, ShipTo_RecipientName, ShipTo_Street, ShipTo_City, ShipTo_State, ShipTo_Country, ShipTo_ZipCode FROM Orders; + +PRAGMA foreign_keys="0" + +DROP TABLE Orders + +ALTER TABLE TmpOrders RENAME TO Orders + +PRAGMA foreign_keys="1" + INSERT INTO "__EFMigrationsHistory" ("MigrationId", "ProductVersion") VALUES ('20200331114826_RemoveBuyerAndWalletAddress', '3.1.2'); From 8d9527d19b770840eb81e9e5697e791dd7388b3b Mon Sep 17 00:00:00 2001 From: Dave Whiffin Date: Wed, 1 Apr 2020 16:55:39 +0100 Subject: [PATCH 23/27] Wiring up web jobs for creating purchase orders and processing orders. --- .../Catalog/Queries/OrderQueries.cs | 1 - .../Catalog/Queries/OrderQueries.cs | 1 - .../Catalog/Queries/OrderQueries.cs | 1 - .../Queries/Orders/OrderQueryDtos.cs | 1 - src/WebJobs/Config/EshopConfiguration.cs | 10 +- src/WebJobs/Jobs/CreateFakePurchaseOrders.cs | 95 ++++++++++++++----- .../Jobs/ProcessPurchaseOrderEventLogs.cs | 10 +- src/WebJobs/libman.json | 5 + .../Config/ContractDeploymentsFixture.cs | 2 +- ...ontractDeployments.IntegrationTests.csproj | 1 + .../Deployment/ContractDeployment.cs | 31 ++++++ 11 files changed, 121 insertions(+), 37 deletions(-) create mode 100644 src/WebJobs/libman.json diff --git a/src/Nethereum.eShop.MySql/Catalog/Queries/OrderQueries.cs b/src/Nethereum.eShop.MySql/Catalog/Queries/OrderQueries.cs index abba7af..21d8d73 100644 --- a/src/Nethereum.eShop.MySql/Catalog/Queries/OrderQueries.cs +++ b/src/Nethereum.eShop.MySql/Catalog/Queries/OrderQueries.cs @@ -40,7 +40,6 @@ public async Task> GetByBuyerIdAsync(string buyerI SELECT o.Id as OrderId, o.QuoteId as QuoteId, - o.BuyerAddress, o.BuyerId, o.TransactionHash, o.OrderDate, diff --git a/src/Nethereum.eShop.SqlServer/Catalog/Queries/OrderQueries.cs b/src/Nethereum.eShop.SqlServer/Catalog/Queries/OrderQueries.cs index bbaca6a..a9abb7e 100644 --- a/src/Nethereum.eShop.SqlServer/Catalog/Queries/OrderQueries.cs +++ b/src/Nethereum.eShop.SqlServer/Catalog/Queries/OrderQueries.cs @@ -44,7 +44,6 @@ public async Task> GetByBuyerIdAsync(string buyerI SELECT o.Id as OrderId, o.QuoteId as QuoteId, - o.BuyerAddress, o.BuyerId, o.TransactionHash, o.OrderDate, diff --git a/src/Nethereum.eShop.Sqlite/Catalog/Queries/OrderQueries.cs b/src/Nethereum.eShop.Sqlite/Catalog/Queries/OrderQueries.cs index 0d0eb6a..6d392e3 100644 --- a/src/Nethereum.eShop.Sqlite/Catalog/Queries/OrderQueries.cs +++ b/src/Nethereum.eShop.Sqlite/Catalog/Queries/OrderQueries.cs @@ -42,7 +42,6 @@ public async Task> GetByBuyerIdAsync(string buyerI SELECT o.Id as OrderId, o.QuoteId as QuoteId, - o.BuyerAddress, o.BuyerId, o.TransactionHash, o.OrderDate, diff --git a/src/Nethereum.eShop/ApplicationCore/Queries/Orders/OrderQueryDtos.cs b/src/Nethereum.eShop/ApplicationCore/Queries/Orders/OrderQueryDtos.cs index 0ad3061..e2dc1ca 100644 --- a/src/Nethereum.eShop/ApplicationCore/Queries/Orders/OrderQueryDtos.cs +++ b/src/Nethereum.eShop/ApplicationCore/Queries/Orders/OrderQueryDtos.cs @@ -14,7 +14,6 @@ public class OrderExcerpt public string CurrencySymbol { get; set; } public string BuyerId { get; set; } - public string BuyerAddress { get; set; } public DateTimeOffset OrderDate { get; set; } public decimal Total { get; set; } diff --git a/src/WebJobs/Config/EshopConfiguration.cs b/src/WebJobs/Config/EshopConfiguration.cs index e019e98..5cd0eab 100644 --- a/src/WebJobs/Config/EshopConfiguration.cs +++ b/src/WebJobs/Config/EshopConfiguration.cs @@ -15,12 +15,20 @@ public class EshopConfiguration public string EShopId { get; set; } + public string SellerId { get; set; } + public string BuyerWalletAddress { get; set; } - public string BusinessPartnerStorageServiceAddress { get; set; } + public string PurchasingContractAddress { get; set; } + + public string CurrencySymbol { get; set; } + + public string CurrencyAddress { get; set; } public bool CreateFakePurchaseOrders { get; set; } + public string QuantityAddress { get; set; } + public PurchaseOrderEventLogProcessingConfiguration PurchaseOrderEventLogConfiguration { get; set; } } diff --git a/src/WebJobs/Jobs/CreateFakePurchaseOrders.cs b/src/WebJobs/Jobs/CreateFakePurchaseOrders.cs index 376a319..1090d9e 100644 --- a/src/WebJobs/Jobs/CreateFakePurchaseOrders.cs +++ b/src/WebJobs/Jobs/CreateFakePurchaseOrders.cs @@ -13,6 +13,7 @@ using System.Numerics; using System.Threading.Tasks; using static Nethereum.Commerce.Contracts.ContractEnums; +using Storage = Nethereum.Commerce.Contracts.PoStorage.ContractDefinition; namespace Nethereum.eShop.WebJobs.Jobs { @@ -43,13 +44,13 @@ public async Task ExecuteAsync(ILogger logger) foreach (var quote in pendingQuotes) { - await CreatePoForQuote(logger, walletBuyerService, quote); + await CreatePoForQuote(web3, logger, walletBuyerService, quote); } } - private async Task CreatePoForQuote(ILogger logger, BuyerWalletService walletBuyerService, Quote quote) + private async Task CreatePoForQuote(Web3.Web3 web3, ILogger logger, BuyerWalletService walletBuyerService, Quote quote) { - var existing = await walletBuyerService.GetPoQueryAsync(_config.EShopId, quote.Id); + var existing = await walletBuyerService.GetPoByEshopIdAndQuoteQueryAsync(_config.EShopId, quote.Id); if (existing?.Po?.PoNumber > 0) { quote.PoNumber = (long)existing.Po.PoNumber; @@ -59,8 +60,9 @@ private async Task CreatePoForQuote(ILogger logger, BuyerWalletService walletBuy return; } - var po = CreateDummyPoForPurchasingCreate(quote, walletBuyerService.ContractHandler.ContractAddress).ToBuyerPo(); - var poArgs = new Nethereum.Commerce.Contracts.BuyerWallet.ContractDefinition.CreatePurchaseOrderFunction { Po = po }; + var po = CreateDummyPoForPurchasingCreate(web3, quote).ToBuyerPo(); + var signature = po.GetSignatureBytes(web3); + var poArgs = new Nethereum.Commerce.Contracts.BuyerWallet.ContractDefinition.CreatePurchaseOrderFunction { Po = po, Signature = signature }; var receipt = await walletBuyerService.CreatePurchaseOrderRequestAndWaitForReceiptAsync(poArgs); var createdEvent = receipt.DecodeAllEvents().FirstOrDefault(); @@ -80,28 +82,44 @@ private async Task CreatePoForQuote(ILogger logger, BuyerWalletService walletBuy } } - public Po CreateDummyPoForPurchasingCreate(Quote quote, string buyerWalletAddress) + public Po CreateDummyPoForPurchasingCreate(Web3.Web3 web3, Quote quote) { - var po = new Po() + return CreatePoForPurchasingContracts( + buyerUserAddress: web3.TransactionManager.Account.Address.ToLowerInvariant(), + buyerReceiverAddress: web3.TransactionManager.Account.Address.ToLowerInvariant(), + buyerWalletAddress: _config.BuyerWalletAddress.ToLowerInvariant(), + eShopId: _config.EShopId, + sellerId: _config.SellerId, + currencySymbol: _config.CurrencySymbol, + currencyAddress: _config.CurrencyAddress.ToLowerInvariant(), + quote: quote, + isLargeValue: false); + } + + public Po CreatePoForPurchasingContracts( + string buyerUserAddress, + string buyerReceiverAddress, + string buyerWalletAddress, + string eShopId, + string sellerId, + string currencySymbol, + string currencyAddress, + Quote quote, + bool isLargeValue = false) + { + BigInteger valueLine01 = BigInteger.Parse("110000000000000000000"); // eg this is 110 dai + BigInteger valueLine02 = BigInteger.Parse("220000000000000000000"); // eg this is 220 dai + if (isLargeValue) { - // PoNumber assigned by contract - BuyerWalletAddress = buyerWalletAddress, - CurrencySymbol = "DAI", - CurrencyAddress = "0xef76bcb4216fbbbd4d6e88082d5654def9b6fe2f", - QuoteId = quote.Id, - QuoteExpiryDate = DateTimeOffset.UtcNow.AddMonths(1).ToUnixTimeSeconds(), - PoType = PoType.Cash, - SellerId = _config.EShopId, - // PoCreateDate assigned by contract - // PoItemCount assigned by contract - PoItems = new List() - }; + valueLine01 *= 1000; + valueLine02 *= 1000; + } - //gtin1111 + var items = new List(quote.ItemCount()); foreach (var quoteItem in quote.QuoteItems) { - po.PoItems.Add(new PoItem + items.Add(new Storage.PoItem { // PoNumber assigned by contract // PoItemNumber assigned by contract @@ -111,7 +129,7 @@ public Po CreateDummyPoForPurchasingCreate(Quote quote, string buyerWalletAddres Quantity = quoteItem.Quantity, Unit = "EA", QuantitySymbol = "NA", - QuantityAddress = "0x40ed4f49ec2c7bdcce8631b1a7b54ed5d4aa9610", + QuantityAddress = _config.QuantityAddress.ToLowerInvariant(), CurrencyValue = quoteItem.CurrencyValue == null ? 0 : BigInteger.Parse(quoteItem.CurrencyValue), // Status assigned by contract // GoodsIssuedDate assigned by contract @@ -123,7 +141,38 @@ public Po CreateDummyPoForPurchasingCreate(Quote quote, string buyerWalletAddres }); } - return po; + var po = new Storage.Po() + { + // PoNumber assigned by contract + + BuyerUserAddress = buyerUserAddress, + BuyerReceiverAddress = buyerReceiverAddress, + BuyerWalletAddress = buyerWalletAddress, + + EShopId = eShopId, + QuoteId = quote.Id, + QuoteExpiryDate = new BigInteger(DateTimeOffset.Now.AddHours(1).ToUnixTimeSeconds()), + QuoteSignerAddress = string.Empty, // assigned by contract + + SellerId = sellerId, + + CurrencySymbol = currencySymbol, + CurrencyAddress = currencyAddress, + PoType = PoType.Cash, + // PoCreateDate assigned by contract + // PoItemCount assigned by contract + PoItems = items, + // RulesCount assigned by contract + Rules = new List() + { + "rule01".ConvertToBytes32(), + "rule02".ConvertToBytes32(), + "rule03".ConvertToBytes32() + } + }; + + return po.ToPurchasingPo(); + } } } diff --git a/src/WebJobs/Jobs/ProcessPurchaseOrderEventLogs.cs b/src/WebJobs/Jobs/ProcessPurchaseOrderEventLogs.cs index 038d9a1..d8ee3cd 100644 --- a/src/WebJobs/Jobs/ProcessPurchaseOrderEventLogs.cs +++ b/src/WebJobs/Jobs/ProcessPurchaseOrderEventLogs.cs @@ -5,8 +5,8 @@ using Nethereum.BlockchainProcessing.Orchestrator; using Nethereum.BlockchainProcessing.Processor; using Nethereum.BlockchainProcessing.ProgressRepositories; -using Nethereum.Commerce.Contracts.BusinessPartnerStorage; using Nethereum.Commerce.Contracts.BuyerWallet; +using Nethereum.Commerce.Contracts.Purchasing; using Nethereum.Commerce.Contracts.Purchasing.ContractDefinition; using Nethereum.eShop.ApplicationCore.Exceptions; using Nethereum.eShop.ApplicationCore.Interfaces; @@ -50,13 +50,7 @@ public async Task ExecuteAsync(ILogger logger) const int RequestRetryWeight = 0; // see below for retry algorithm var web3 = new Web3.Web3(_eshopConfiguration.EthereumRpcUrl); - var walletBuyerService = new BuyerWalletService(web3, _eshopConfiguration.BuyerWalletAddress); - - var businessPartnerStorageService = new BusinessPartnerStorageService(web3, _eshopConfiguration.BusinessPartnerStorageServiceAddress); - var eshop = await businessPartnerStorageService.GetEshopQueryAsync(_eshopConfiguration.EShopId); - var purchasingContractAddress = eshop.EShop.PurchasingContractAddress; - - var filter = new NewFilterInput { Address = new[] { purchasingContractAddress } }; + var filter = new NewFilterInput { Address = new[] { _eshopConfiguration.PurchasingContractAddress } }; ILog log = logger.ToILog(); diff --git a/src/WebJobs/libman.json b/src/WebJobs/libman.json new file mode 100644 index 0000000..ceee271 --- /dev/null +++ b/src/WebJobs/libman.json @@ -0,0 +1,5 @@ +{ + "version": "1.0", + "defaultProvider": "cdnjs", + "libraries": [] +} \ No newline at end of file diff --git a/src/contracts/Nethereum.Commerce.ContractDeployments.IntegrationTests/Config/ContractDeploymentsFixture.cs b/src/contracts/Nethereum.Commerce.ContractDeployments.IntegrationTests/Config/ContractDeploymentsFixture.cs index cc4abfa..b45a577 100644 --- a/src/contracts/Nethereum.Commerce.ContractDeployments.IntegrationTests/Config/ContractDeploymentsFixture.cs +++ b/src/contracts/Nethereum.Commerce.ContractDeployments.IntegrationTests/Config/ContractDeploymentsFixture.cs @@ -34,7 +34,7 @@ public class ContractDeploymentsFixture : IAsyncLifetime public ContractDeploymentsFixture(IMessageSink diagnosticMessageSink) { _diagnosticMessageSink = diagnosticMessageSink; - var appConfig = ConfigurationUtils.Build(Array.Empty(), "UserSecret"); + var appConfig = ConfigurationUtils.Build(Array.Empty(), "Nethereum.Commerce.ContractDeployments.IntegrationTests"); // Web3 var web3Config = appConfig.GetSection("Web3Config").Get(); diff --git a/src/contracts/Nethereum.Commerce.ContractDeployments.IntegrationTests/Nethereum.Commerce.ContractDeployments.IntegrationTests.csproj b/src/contracts/Nethereum.Commerce.ContractDeployments.IntegrationTests/Nethereum.Commerce.ContractDeployments.IntegrationTests.csproj index d4a6150..dfbc7cc 100644 --- a/src/contracts/Nethereum.Commerce.ContractDeployments.IntegrationTests/Nethereum.Commerce.ContractDeployments.IntegrationTests.csproj +++ b/src/contracts/Nethereum.Commerce.ContractDeployments.IntegrationTests/Nethereum.Commerce.ContractDeployments.IntegrationTests.csproj @@ -4,6 +4,7 @@ netcoreapp3.1 false + Nethereum.Commerce.ContractDeployments.IntegrationTests diff --git a/src/contracts/Nethereum.Commerce.Contracts/Deployment/ContractDeployment.cs b/src/contracts/Nethereum.Commerce.Contracts/Deployment/ContractDeployment.cs index ca092ea..a759853 100644 --- a/src/contracts/Nethereum.Commerce.Contracts/Deployment/ContractDeployment.cs +++ b/src/contracts/Nethereum.Commerce.Contracts/Deployment/ContractDeployment.cs @@ -22,6 +22,8 @@ using System; using System.Threading.Tasks; using System.Diagnostics; +using System.IO; +using Newtonsoft.Json; namespace Nethereum.Commerce.Contracts.Deployment { @@ -126,6 +128,8 @@ public async Task InitializeAsync() // Make a whole new deployment await DeployAndConfigureEShopAsync().ConfigureAwait(false); + await WriteContractAddressesToFile().ConfigureAwait(false); + // With mocks if needed if (ContractNewDeploymentConfig.AlsoDeployMockContracts) { @@ -152,6 +156,33 @@ public async Task InitializeAsync() LogSeparator(); } + // A temporary method which writes the addresses created by the deployment to a file + // This can be used by the web job project for testing + private Task WriteContractAddressesToFile() + { + var configJson = new + { + Web3User = _web3.TransactionManager.Account.Address.ToLowerInvariant(), + ContractNameFunding = FundingService.ContractHandler.ContractAddress.ToLowerInvariant(), + SellerAdminOwner = SellerAdminService.ContractHandler.ContractAddress.ToLowerInvariant(), + AddressRegistry = AddressRegistryService.ContractHandler.ContractAddress.ToLowerInvariant(), + PurchasingContract = PurchasingService.ContractHandler.ContractAddress.ToLowerInvariant(), + BusinessPartnerStorage = BusinessPartnerStorageService.ContractHandler.ContractAddress.ToLowerInvariant(), + BuyerUserAddress = _web3.TransactionManager.Account.Address.ToLowerInvariant(), + BuyerReceiverAddress = _web3.TransactionManager.Account.Address.ToLowerInvariant(), + BuyerWalletAddress = BuyerWalletService.ContractHandler.ContractAddress.ToLowerInvariant(), + CurrencyAddress = MockDaiService.ContractHandler.ContractAddress.ToLowerInvariant(), + EShopId = ContractNewDeploymentConfig.Eshop.EShopId, + SellerId = ContractNewDeploymentConfig.Seller.SellerId, + CurrencySymbol = "DAI", + QuoteSigners = new[] { "0x32A555F2328e85E489f9a5f03669DC820CE7EBe9", "0x94618601FE6cb8912b274E5a00453949A57f8C1e" } + }; + + File.WriteAllText("c:/temp/eshop_contracts.json", JsonConvert.SerializeObject(configJson)); + + return Task.CompletedTask; + } + private async Task DeployAndConfigureEShopAsync() { try From 1342943603c7f6da56ca06cc463896320f72757c Mon Sep 17 00:00:00 2001 From: Dave Whiffin Date: Wed, 1 Apr 2020 17:05:34 +0100 Subject: [PATCH 24/27] Updating appsettings --- src/WebJobs/appsettings.json | 9 +++++++-- 1 file changed, 7 insertions(+), 2 deletions(-) diff --git a/src/WebJobs/appsettings.json b/src/WebJobs/appsettings.json index 61cf8f8..06a6dbf 100644 --- a/src/WebJobs/appsettings.json +++ b/src/WebJobs/appsettings.json @@ -12,8 +12,13 @@ "EshopConfiguration": { "EthereumRpcUrl": "http://localhost:8545/", "AccountPrivateKey": "0x7580e7fb49df1c861f0050fae31c2224c6aba908e116b8da44ee8cd927b990b0", - "EShopId": "Nethereum.eShop", - "BuyerWalletAddress": "0x969b34204c90947822e278d10482b79a51c1544f", + "EShopId": "Satoshi", + "SellerId": "Alice", + "BuyerWalletAddress": "0xc59aa7e0e00946c8dcea379fba766a57dba8cf6b", + "PurchasingContractAddress": "0x3b03ce5637dec7814b1c162de6a5a0e322167013", + "CurrencySymbol": "DAI", + "CurrencyAddress": "0xd2e2982d23b1c80917b2adc4a96a9963e75b2c88", + "QuantityAddress": "0x40ed4f49ec2c7bdcce8631b1a7b54ed5d4aa9610", "CreateFakePurchaseOrders": true, "PurchaseOrderEventLogConfiguration": { From 441d491890ff8039e186ffe0354196c77d30104c Mon Sep 17 00:00:00 2001 From: Dave Whiffin Date: Fri, 3 Apr 2020 16:53:01 +0100 Subject: [PATCH 25/27] DB Configuration --- .../Catalog/CatalogContext.cs | 3 + .../Catalog/EShopDbBootstrapperBase.cs | 1 + .../EntityBuilders/SettingConfiguration.cs | 17 + .../Catalog/Repositories/OrderRepository.cs | 43 - .../Catalog/Repositories/SettingRepository.cs | 28 + ...0403114515_CreateSettingsTable.Designer.cs | 926 +++++++++++++++++ .../20200403114515_CreateSettingsTable.cs | 36 + .../MySqlCatalogContextModelSnapshot.cs | 20 + .../Migrations/Scripts/CreateCatalogDb.sql | 51 + ...0403114458_CreateSettingsTable.Designer.cs | 966 ++++++++++++++++++ .../20200403114458_CreateSettingsTable.cs | 30 + .../Migrations/Scripts/CreateCatalogDb.sql | 20 + .../SqlServerCatalogContextModelSnapshot.cs | 18 + ...0403114507_CreateSettingsTable.Designer.cs | 925 +++++++++++++++++ .../20200403114507_CreateSettingsTable.cs | 35 + .../Migrations/Scripts/CreateCatalogDb.sql | 11 + .../SqliteCatalogContextModelSnapshot.cs | 20 + .../ConfigurationAggregate/Setting.cs | 27 + .../ValueObjects/ConfigurationSettings.cs | 87 ++ ...reateFakePurchaseOrdersJobConfiguration.cs | 20 + .../ValueObjects/EShopConfiguration.cs | 36 + ...cessPurchaseOrderEventsJobConfiguration.cs | 55 + .../ValueObjects/SellerConfiguration.cs | 36 + .../ValueObjects/SettingExtensions.cs | 114 +++ .../Interfaces/IContractDeploymentService.cs | 11 + .../Interfaces/ISettingRepository.cs | 14 + .../Services/ContractDeploymentService.cs | 119 +++ src/Web/Program.cs | 3 + src/Web/Startup.cs | 2 + src/WebJobs/Config/EshopConfiguration.cs | 52 - src/WebJobs/Jobs/CreateFakePurchaseOrders.cs | 49 +- .../Jobs/ProcessPurchaseOrderEventLogs.cs | 35 +- .../JsonFileBlockProgressRepository.cs | 43 +- src/WebJobs/Program.cs | 8 +- src/WebJobs/appsettings.json | 25 +- .../Deployment/ContractDeployment.cs | 28 - 36 files changed, 3718 insertions(+), 196 deletions(-) create mode 100644 src/Nethereum.eShop.EntityFramework/Catalog/EntityBuilders/SettingConfiguration.cs create mode 100644 src/Nethereum.eShop.EntityFramework/Catalog/Repositories/SettingRepository.cs create mode 100644 src/Nethereum.eShop.MySql/Catalog/Migrations/20200403114515_CreateSettingsTable.Designer.cs create mode 100644 src/Nethereum.eShop.MySql/Catalog/Migrations/20200403114515_CreateSettingsTable.cs create mode 100644 src/Nethereum.eShop.SqlServer/Catalog/Migrations/20200403114458_CreateSettingsTable.Designer.cs create mode 100644 src/Nethereum.eShop.SqlServer/Catalog/Migrations/20200403114458_CreateSettingsTable.cs create mode 100644 src/Nethereum.eShop.Sqlite/Catalog/Migrations/20200403114507_CreateSettingsTable.Designer.cs create mode 100644 src/Nethereum.eShop.Sqlite/Catalog/Migrations/20200403114507_CreateSettingsTable.cs create mode 100644 src/Nethereum.eShop/ApplicationCore/Entities/ConfigurationAggregate/Setting.cs create mode 100644 src/Nethereum.eShop/ApplicationCore/Entities/ConfigurationAggregate/ValueObjects/ConfigurationSettings.cs create mode 100644 src/Nethereum.eShop/ApplicationCore/Entities/ConfigurationAggregate/ValueObjects/CreateFakePurchaseOrdersJobConfiguration.cs create mode 100644 src/Nethereum.eShop/ApplicationCore/Entities/ConfigurationAggregate/ValueObjects/EShopConfiguration.cs create mode 100644 src/Nethereum.eShop/ApplicationCore/Entities/ConfigurationAggregate/ValueObjects/ProcessPurchaseOrderEventsJobConfiguration.cs create mode 100644 src/Nethereum.eShop/ApplicationCore/Entities/ConfigurationAggregate/ValueObjects/SellerConfiguration.cs create mode 100644 src/Nethereum.eShop/ApplicationCore/Entities/ConfigurationAggregate/ValueObjects/SettingExtensions.cs create mode 100644 src/Nethereum.eShop/ApplicationCore/Interfaces/IContractDeploymentService.cs create mode 100644 src/Nethereum.eShop/ApplicationCore/Interfaces/ISettingRepository.cs create mode 100644 src/Nethereum.eShop/ApplicationCore/Services/ContractDeploymentService.cs delete mode 100644 src/WebJobs/Config/EshopConfiguration.cs diff --git a/src/Nethereum.eShop.EntityFramework/Catalog/CatalogContext.cs b/src/Nethereum.eShop.EntityFramework/Catalog/CatalogContext.cs index 43a75cf..e827893 100644 --- a/src/Nethereum.eShop.EntityFramework/Catalog/CatalogContext.cs +++ b/src/Nethereum.eShop.EntityFramework/Catalog/CatalogContext.cs @@ -4,6 +4,7 @@ using Nethereum.eShop.ApplicationCore.Entities; using Nethereum.eShop.ApplicationCore.Entities.BasketAggregate; using Nethereum.eShop.ApplicationCore.Entities.BuyerAggregate; +using Nethereum.eShop.ApplicationCore.Entities.ConfigurationAggregate; using Nethereum.eShop.ApplicationCore.Entities.OrderAggregate; using Nethereum.eShop.ApplicationCore.Entities.QuoteAggregate; using Nethereum.eShop.ApplicationCore.Interfaces; @@ -37,6 +38,8 @@ public CatalogContext( public DbSet Orders { get; set; } public DbSet OrderItems { get; set; } + public DbSet Settings { get; set; } + protected override void OnModelCreating(ModelBuilder builder) { base.OnModelCreating(builder); diff --git a/src/Nethereum.eShop.EntityFramework/Catalog/EShopDbBootstrapperBase.cs b/src/Nethereum.eShop.EntityFramework/Catalog/EShopDbBootstrapperBase.cs index e5094a6..9c384ad 100644 --- a/src/Nethereum.eShop.EntityFramework/Catalog/EShopDbBootstrapperBase.cs +++ b/src/Nethereum.eShop.EntityFramework/Catalog/EShopDbBootstrapperBase.cs @@ -23,6 +23,7 @@ public virtual void AddRepositories(IServiceCollection services, IConfiguration services.AddScoped(); services.AddScoped(); services.AddScoped(); + services.AddScoped(); } public virtual void AddSeeders(IServiceCollection services, IConfiguration configuration) diff --git a/src/Nethereum.eShop.EntityFramework/Catalog/EntityBuilders/SettingConfiguration.cs b/src/Nethereum.eShop.EntityFramework/Catalog/EntityBuilders/SettingConfiguration.cs new file mode 100644 index 0000000..5fb9bad --- /dev/null +++ b/src/Nethereum.eShop.EntityFramework/Catalog/EntityBuilders/SettingConfiguration.cs @@ -0,0 +1,17 @@ +using Microsoft.EntityFrameworkCore; +using Microsoft.EntityFrameworkCore.Metadata.Builders; +using Nethereum.eShop.ApplicationCore.Entities.ConfigurationAggregate; + +namespace Nethereum.eShop.EntityFramework.Catalog.EntityBuilders +{ + public class SettingConfiguration : IEntityTypeConfiguration + { + public virtual void Configure(EntityTypeBuilder builder) + { + builder.Property(b => b.Key).HasMaxLength(100); + builder.Property(b => b.Value); + + builder.HasIndex(b => b.Key); + } + } +} diff --git a/src/Nethereum.eShop.EntityFramework/Catalog/Repositories/OrderRepository.cs b/src/Nethereum.eShop.EntityFramework/Catalog/Repositories/OrderRepository.cs index 1fc2e70..f37f9d8 100644 --- a/src/Nethereum.eShop.EntityFramework/Catalog/Repositories/OrderRepository.cs +++ b/src/Nethereum.eShop.EntityFramework/Catalog/Repositories/OrderRepository.cs @@ -19,48 +19,5 @@ public Task GetByIdWithItemsAsync(int id) .Include($"{nameof(Order.OrderItems)}.{nameof(OrderItem.ItemOrdered)}") .FirstOrDefaultAsync(x => x.Id == id); } - - /* - public Buyer Add(Buyer buyer) - { - if (buyer.IsTransient()) - { - return _context.Buyers - .Add(buyer) - .Entity; - } - else - { - return buyer; - } - } - - public Buyer Update(Buyer buyer) - { - return _context.Buyers - .Update(buyer) - .Entity; - } - - public async Task FindAsync(string identity) - { - var buyer = await _context.Buyers - .Include(b => b.PaymentMethods) - .Where(b => b.IdentityGuid == identity) - .SingleOrDefaultAsync(); - - return buyer; - } - - public async Task FindByIdAsync(string id) - { - var buyer = await _context.Buyers - .Include(b => b.PaymentMethods) - .Where(b => b.Id == int.Parse(id)) - .SingleOrDefaultAsync(); - - return buyer; - } - */ } } diff --git a/src/Nethereum.eShop.EntityFramework/Catalog/Repositories/SettingRepository.cs b/src/Nethereum.eShop.EntityFramework/Catalog/Repositories/SettingRepository.cs new file mode 100644 index 0000000..aed0303 --- /dev/null +++ b/src/Nethereum.eShop.EntityFramework/Catalog/Repositories/SettingRepository.cs @@ -0,0 +1,28 @@ +using Nethereum.eShop.ApplicationCore.Entities.ConfigurationAggregate; +using Nethereum.eShop.ApplicationCore.Interfaces; +using System.Linq; +using System.Threading.Tasks; + +namespace Nethereum.eShop.EntityFramework.Catalog.Repositories +{ + public class SettingRepository : EfRepository, ISettingRepository + { + public SettingRepository(CatalogContext dbContext) : base(dbContext) + { + } + + public async Task GetEShopConfigurationSettingsAsync() + { + var settings = await ListAllAsync().ConfigureAwait(false); + return new EShopConfigurationSettings(settings); + } + + public async Task UpdateAsync(EShopConfigurationSettings configurationSettings) + { + var settings = await ListAllAsync().ConfigureAwait(false); + var list = settings.ToList(); + configurationSettings.UpdateSettings(list); + _dbContext.UpdateRange(list); + } + } +} diff --git a/src/Nethereum.eShop.MySql/Catalog/Migrations/20200403114515_CreateSettingsTable.Designer.cs b/src/Nethereum.eShop.MySql/Catalog/Migrations/20200403114515_CreateSettingsTable.Designer.cs new file mode 100644 index 0000000..474c0ac --- /dev/null +++ b/src/Nethereum.eShop.MySql/Catalog/Migrations/20200403114515_CreateSettingsTable.Designer.cs @@ -0,0 +1,926 @@ +// +using System; +using Microsoft.EntityFrameworkCore; +using Microsoft.EntityFrameworkCore.Infrastructure; +using Microsoft.EntityFrameworkCore.Migrations; +using Microsoft.EntityFrameworkCore.Storage.ValueConversion; +using Nethereum.eShop.MySql.Catalog; + +namespace Nethereum.eShop.MySql.Catalog.Migrations +{ + [DbContext(typeof(MySqlCatalogContext))] + [Migration("20200403114515_CreateSettingsTable")] + partial class CreateSettingsTable + { + protected override void BuildTargetModel(ModelBuilder modelBuilder) + { +#pragma warning disable 612, 618 + modelBuilder + .HasAnnotation("ProductVersion", "3.1.2") + .HasAnnotation("Relational:MaxIdentifierLength", 64); + + modelBuilder.Entity("Nethereum.eShop.ApplicationCore.Entities.BasketAggregate.Basket", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("int"); + + b.Property("BuyerAddress") + .IsRequired() + .HasColumnType("varchar(43) CHARACTER SET utf8mb4") + .HasMaxLength(43); + + b.Property("BuyerId") + .IsRequired() + .HasColumnType("varchar(256) CHARACTER SET utf8mb4") + .HasMaxLength(256); + + b.Property("TransactionHash") + .HasColumnType("varchar(67) CHARACTER SET utf8mb4") + .HasMaxLength(67); + + b.HasKey("Id"); + + b.HasIndex("BuyerAddress"); + + b.HasIndex("BuyerId"); + + b.ToTable("Baskets"); + }); + + modelBuilder.Entity("Nethereum.eShop.ApplicationCore.Entities.BasketAggregate.BasketItem", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("int"); + + b.Property("BasketId") + .HasColumnType("int"); + + b.Property("CatalogItemId") + .HasColumnType("int"); + + b.Property("Quantity") + .HasColumnType("int"); + + b.Property("UnitPrice") + .HasColumnType("decimal(18,2)"); + + b.HasKey("Id"); + + b.HasIndex("BasketId"); + + b.ToTable("BasketItems"); + }); + + modelBuilder.Entity("Nethereum.eShop.ApplicationCore.Entities.BuyerAggregate.Buyer", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("int"); + + b.Property("BuyerAddress") + .HasColumnType("varchar(43) CHARACTER SET utf8mb4") + .HasMaxLength(43); + + b.Property("BuyerId") + .IsRequired() + .HasColumnType("varchar(256) CHARACTER SET utf8mb4") + .HasMaxLength(256); + + b.Property("BuyerWalletAddress") + .HasColumnType("varchar(43) CHARACTER SET utf8mb4") + .HasMaxLength(43); + + b.HasKey("Id"); + + b.HasIndex("BuyerAddress") + .IsUnique(); + + b.HasIndex("BuyerId") + .IsUnique(); + + b.HasIndex("BuyerWalletAddress") + .IsUnique(); + + b.ToTable("Buyers"); + }); + + modelBuilder.Entity("Nethereum.eShop.ApplicationCore.Entities.BuyerAggregate.BuyerPostalAddress", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("int"); + + b.Property("BuyerId") + .HasColumnType("int"); + + b.Property("Name") + .HasColumnType("longtext CHARACTER SET utf8mb4"); + + b.HasKey("Id"); + + b.HasIndex("BuyerId"); + + b.ToTable("BuyerPostalAddress"); + }); + + modelBuilder.Entity("Nethereum.eShop.ApplicationCore.Entities.CatalogBrand", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("int"); + + b.Property("Brand") + .IsRequired() + .HasColumnType("varchar(100) CHARACTER SET utf8mb4") + .HasMaxLength(100); + + b.HasKey("Id"); + + b.ToTable("CatalogBrands"); + }); + + modelBuilder.Entity("Nethereum.eShop.ApplicationCore.Entities.CatalogItem", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("int"); + + b.Property("AttributeJson") + .HasColumnType("longtext CHARACTER SET utf8mb4"); + + b.Property("CatalogBrandId") + .HasColumnType("int"); + + b.Property("CatalogTypeId") + .HasColumnType("int"); + + b.Property("Depth") + .HasColumnType("int"); + + b.Property("Description") + .HasColumnType("longtext CHARACTER SET utf8mb4"); + + b.Property("Gtin") + .IsRequired() + .HasColumnType("varchar(14) CHARACTER SET utf8mb4") + .HasMaxLength(14); + + b.Property("GtinRegistryId") + .HasColumnType("int"); + + b.Property("Height") + .HasColumnType("int"); + + b.Property("Name") + .IsRequired() + .HasColumnType("varchar(50) CHARACTER SET utf8mb4") + .HasMaxLength(50); + + b.Property("PictureLargeUri") + .HasColumnType("varchar(512) CHARACTER SET utf8mb4") + .HasMaxLength(512); + + b.Property("PictureMediumUri") + .HasColumnType("varchar(512) CHARACTER SET utf8mb4") + .HasMaxLength(512); + + b.Property("PictureSmallUri") + .HasColumnType("varchar(512) CHARACTER SET utf8mb4") + .HasMaxLength(512); + + b.Property("PictureUri") + .HasColumnType("varchar(512) CHARACTER SET utf8mb4") + .HasMaxLength(512); + + b.Property("Price") + .HasColumnType("decimal(18,2)"); + + b.Property("Rank") + .HasColumnType("int"); + + b.Property("Status") + .HasColumnType("int"); + + b.Property("Unit") + .HasColumnType("varchar(8) CHARACTER SET utf8mb4") + .HasMaxLength(8); + + b.Property("Weight") + .HasColumnType("int"); + + b.Property("Width") + .HasColumnType("int"); + + b.HasKey("Id"); + + b.HasIndex("CatalogBrandId"); + + b.HasIndex("CatalogTypeId"); + + b.ToTable("Catalog"); + }); + + modelBuilder.Entity("Nethereum.eShop.ApplicationCore.Entities.CatalogType", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("int"); + + b.Property("Type") + .IsRequired() + .HasColumnType("varchar(100) CHARACTER SET utf8mb4") + .HasMaxLength(100); + + b.HasKey("Id"); + + b.ToTable("CatalogTypes"); + }); + + modelBuilder.Entity("Nethereum.eShop.ApplicationCore.Entities.ConfigurationAggregate.Setting", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("int"); + + b.Property("Key") + .HasColumnType("varchar(100) CHARACTER SET utf8mb4") + .HasMaxLength(100); + + b.Property("Value") + .HasColumnType("longtext CHARACTER SET utf8mb4"); + + b.HasKey("Id"); + + b.HasIndex("Key"); + + b.ToTable("Settings"); + }); + + modelBuilder.Entity("Nethereum.eShop.ApplicationCore.Entities.OrderAggregate.Order", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("int"); + + b.Property("BuyerId") + .IsRequired() + .HasColumnType("varchar(256) CHARACTER SET utf8mb4") + .HasMaxLength(256); + + b.Property("BuyerWalletAddress") + .HasColumnType("varchar(43) CHARACTER SET utf8mb4") + .HasMaxLength(43); + + b.Property("CurrencyAddress") + .HasColumnType("varchar(43) CHARACTER SET utf8mb4") + .HasMaxLength(43); + + b.Property("CurrencySymbol") + .HasColumnType("varchar(32) CHARACTER SET utf8mb4") + .HasMaxLength(32); + + b.Property("OrderDate") + .HasColumnType("datetime(6)"); + + b.Property("PoDate") + .HasColumnType("datetime(6)"); + + b.Property("PoNumber") + .HasColumnType("bigint"); + + b.Property("PoType") + .HasColumnType("int"); + + b.Property("QuoteId") + .HasColumnType("int"); + + b.Property("SellerId") + .HasColumnType("varchar(32) CHARACTER SET utf8mb4") + .HasMaxLength(32); + + b.Property("Status") + .HasColumnType("int"); + + b.Property("TransactionHash") + .HasColumnType("varchar(67) CHARACTER SET utf8mb4") + .HasMaxLength(67); + + b.HasKey("Id"); + + b.HasIndex("BuyerId"); + + b.ToTable("Orders"); + }); + + modelBuilder.Entity("Nethereum.eShop.ApplicationCore.Entities.OrderAggregate.OrderItem", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("int"); + + b.Property("ActualEscrowReleaseDate") + .HasColumnType("datetime(6)"); + + b.Property("CurrencyValue") + .HasColumnType("varchar(100) CHARACTER SET utf8mb4") + .HasMaxLength(100); + + b.Property("GoodsIssueDate") + .HasColumnType("datetime(6)"); + + b.Property("IsEscrowReleased") + .HasColumnType("tinyint(1)"); + + b.Property("OrderId") + .HasColumnType("int"); + + b.Property("PlannedEscrowReleaseDate") + .HasColumnType("datetime(6)"); + + b.Property("PoItemNumber") + .HasColumnType("int"); + + b.Property("PoItemStatus") + .HasColumnType("int"); + + b.Property("Quantity") + .HasColumnType("int"); + + b.Property("QuantityAddress") + .HasColumnType("varchar(43) CHARACTER SET utf8mb4") + .HasMaxLength(43); + + b.Property("QuantitySymbol") + .HasColumnType("varchar(32) CHARACTER SET utf8mb4") + .HasMaxLength(32); + + b.Property("Status") + .HasColumnType("int"); + + b.Property("Unit") + .HasColumnType("varchar(50) CHARACTER SET utf8mb4") + .HasMaxLength(50); + + b.Property("UnitPrice") + .HasColumnType("decimal(18,2)"); + + b.HasKey("Id"); + + b.HasIndex("OrderId"); + + b.ToTable("OrderItems"); + }); + + modelBuilder.Entity("Nethereum.eShop.ApplicationCore.Entities.QuoteAggregate.Quote", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("int"); + + b.Property("ApproverAddress") + .HasColumnType("varchar(43) CHARACTER SET utf8mb4") + .HasMaxLength(43); + + b.Property("BuyerAddress") + .HasColumnType("varchar(43) CHARACTER SET utf8mb4") + .HasMaxLength(43); + + b.Property("BuyerId") + .IsRequired() + .HasColumnType("varchar(256) CHARACTER SET utf8mb4") + .HasMaxLength(256); + + b.Property("BuyerWalletAddress") + .HasColumnType("varchar(43) CHARACTER SET utf8mb4") + .HasMaxLength(43); + + b.Property("CurrencyAddress") + .HasColumnType("varchar(43) CHARACTER SET utf8mb4") + .HasMaxLength(43); + + b.Property("CurrencySymbol") + .HasColumnType("varchar(32) CHARACTER SET utf8mb4") + .HasMaxLength(32); + + b.Property("Date") + .HasColumnType("datetime(6)"); + + b.Property("Expiry") + .HasColumnType("datetime(6)"); + + b.Property("PoNumber") + .HasColumnType("bigint"); + + b.Property("PoType") + .HasColumnType("int"); + + b.Property("SellerId") + .HasColumnType("varchar(32) CHARACTER SET utf8mb4") + .HasMaxLength(32); + + b.Property("Status") + .HasColumnType("int"); + + b.Property("TransactionHash") + .HasColumnType("varchar(67) CHARACTER SET utf8mb4") + .HasMaxLength(67); + + b.HasKey("Id"); + + b.HasIndex("BuyerAddress"); + + b.HasIndex("BuyerId"); + + b.ToTable("Quotes"); + }); + + modelBuilder.Entity("Nethereum.eShop.ApplicationCore.Entities.QuoteAggregate.QuoteItem", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("int"); + + b.Property("CurrencyValue") + .HasColumnType("longtext CHARACTER SET utf8mb4"); + + b.Property("EscrowReleaseDate") + .HasColumnType("datetime(6)"); + + b.Property("PoItemNumber") + .HasColumnType("int"); + + b.Property("Quantity") + .HasColumnType("int"); + + b.Property("QuantityAddress") + .HasColumnType("longtext CHARACTER SET utf8mb4"); + + b.Property("QuantitySymbol") + .HasColumnType("longtext CHARACTER SET utf8mb4"); + + b.Property("QuoteId") + .HasColumnType("int"); + + b.Property("Unit") + .HasColumnType("longtext CHARACTER SET utf8mb4"); + + b.Property("UnitPrice") + .HasColumnType("decimal(18,2)"); + + b.HasKey("Id"); + + b.HasIndex("QuoteId"); + + b.ToTable("QuoteItems"); + }); + + modelBuilder.Entity("Nethereum.eShop.ApplicationCore.Entities.StockItem", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("int"); + + b.Property("CatalogItemId") + .HasColumnType("int"); + + b.Property("Location") + .IsRequired() + .HasColumnType("varchar(50) CHARACTER SET utf8mb4") + .HasMaxLength(50); + + b.Property("Quantity") + .HasColumnType("int"); + + b.HasKey("Id"); + + b.HasIndex("CatalogItemId"); + + b.ToTable("Stock"); + }); + + modelBuilder.Entity("Nethereum.eShop.ApplicationCore.Entities.BasketAggregate.Basket", b => + { + b.OwnsOne("Nethereum.eShop.ApplicationCore.Entities.PostalAddress", "BillTo", b1 => + { + b1.Property("BasketId") + .HasColumnType("int"); + + b1.Property("City") + .IsRequired() + .HasColumnType("varchar(100) CHARACTER SET utf8mb4") + .HasMaxLength(100); + + b1.Property("Country") + .IsRequired() + .HasColumnType("varchar(90) CHARACTER SET utf8mb4") + .HasMaxLength(90); + + b1.Property("RecipientName") + .IsRequired() + .HasColumnType("varchar(255) CHARACTER SET utf8mb4") + .HasMaxLength(255); + + b1.Property("State") + .HasColumnType("varchar(60) CHARACTER SET utf8mb4") + .HasMaxLength(60); + + b1.Property("Street") + .IsRequired() + .HasColumnType("varchar(180) CHARACTER SET utf8mb4") + .HasMaxLength(180); + + b1.Property("ZipCode") + .IsRequired() + .HasColumnType("varchar(18) CHARACTER SET utf8mb4") + .HasMaxLength(18); + + b1.HasKey("BasketId"); + + b1.ToTable("Baskets"); + + b1.WithOwner() + .HasForeignKey("BasketId"); + }); + + b.OwnsOne("Nethereum.eShop.ApplicationCore.Entities.PostalAddress", "ShipTo", b1 => + { + b1.Property("BasketId") + .HasColumnType("int"); + + b1.Property("City") + .IsRequired() + .HasColumnType("varchar(100) CHARACTER SET utf8mb4") + .HasMaxLength(100); + + b1.Property("Country") + .IsRequired() + .HasColumnType("varchar(90) CHARACTER SET utf8mb4") + .HasMaxLength(90); + + b1.Property("RecipientName") + .IsRequired() + .HasColumnType("varchar(255) CHARACTER SET utf8mb4") + .HasMaxLength(255); + + b1.Property("State") + .HasColumnType("varchar(60) CHARACTER SET utf8mb4") + .HasMaxLength(60); + + b1.Property("Street") + .IsRequired() + .HasColumnType("varchar(180) CHARACTER SET utf8mb4") + .HasMaxLength(180); + + b1.Property("ZipCode") + .IsRequired() + .HasColumnType("varchar(18) CHARACTER SET utf8mb4") + .HasMaxLength(18); + + b1.HasKey("BasketId"); + + b1.ToTable("Baskets"); + + b1.WithOwner() + .HasForeignKey("BasketId"); + }); + }); + + modelBuilder.Entity("Nethereum.eShop.ApplicationCore.Entities.BasketAggregate.BasketItem", b => + { + b.HasOne("Nethereum.eShop.ApplicationCore.Entities.BasketAggregate.Basket", null) + .WithMany("Items") + .HasForeignKey("BasketId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + }); + + modelBuilder.Entity("Nethereum.eShop.ApplicationCore.Entities.BuyerAggregate.BuyerPostalAddress", b => + { + b.HasOne("Nethereum.eShop.ApplicationCore.Entities.BuyerAggregate.Buyer", null) + .WithMany("PostalAddresses") + .HasForeignKey("BuyerId"); + + b.OwnsOne("Nethereum.eShop.ApplicationCore.Entities.PostalAddress", "PostalAddress", b1 => + { + b1.Property("BuyerPostalAddressId") + .HasColumnType("int"); + + b1.Property("City") + .IsRequired() + .HasColumnType("varchar(100) CHARACTER SET utf8mb4") + .HasMaxLength(100); + + b1.Property("Country") + .IsRequired() + .HasColumnType("varchar(90) CHARACTER SET utf8mb4") + .HasMaxLength(90); + + b1.Property("RecipientName") + .IsRequired() + .HasColumnType("varchar(255) CHARACTER SET utf8mb4") + .HasMaxLength(255); + + b1.Property("State") + .HasColumnType("varchar(60) CHARACTER SET utf8mb4") + .HasMaxLength(60); + + b1.Property("Street") + .IsRequired() + .HasColumnType("varchar(180) CHARACTER SET utf8mb4") + .HasMaxLength(180); + + b1.Property("ZipCode") + .IsRequired() + .HasColumnType("varchar(18) CHARACTER SET utf8mb4") + .HasMaxLength(18); + + b1.HasKey("BuyerPostalAddressId"); + + b1.ToTable("BuyerPostalAddress"); + + b1.WithOwner() + .HasForeignKey("BuyerPostalAddressId"); + }); + }); + + modelBuilder.Entity("Nethereum.eShop.ApplicationCore.Entities.CatalogItem", b => + { + b.HasOne("Nethereum.eShop.ApplicationCore.Entities.CatalogBrand", "CatalogBrand") + .WithMany() + .HasForeignKey("CatalogBrandId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.HasOne("Nethereum.eShop.ApplicationCore.Entities.CatalogType", "CatalogType") + .WithMany() + .HasForeignKey("CatalogTypeId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + }); + + modelBuilder.Entity("Nethereum.eShop.ApplicationCore.Entities.OrderAggregate.Order", b => + { + b.OwnsOne("Nethereum.eShop.ApplicationCore.Entities.PostalAddress", "BillTo", b1 => + { + b1.Property("OrderId") + .HasColumnType("int"); + + b1.Property("City") + .IsRequired() + .HasColumnType("varchar(100) CHARACTER SET utf8mb4") + .HasMaxLength(100); + + b1.Property("Country") + .IsRequired() + .HasColumnType("varchar(90) CHARACTER SET utf8mb4") + .HasMaxLength(90); + + b1.Property("RecipientName") + .IsRequired() + .HasColumnType("varchar(255) CHARACTER SET utf8mb4") + .HasMaxLength(255); + + b1.Property("State") + .HasColumnType("varchar(60) CHARACTER SET utf8mb4") + .HasMaxLength(60); + + b1.Property("Street") + .IsRequired() + .HasColumnType("varchar(180) CHARACTER SET utf8mb4") + .HasMaxLength(180); + + b1.Property("ZipCode") + .IsRequired() + .HasColumnType("varchar(18) CHARACTER SET utf8mb4") + .HasMaxLength(18); + + b1.HasKey("OrderId"); + + b1.ToTable("Orders"); + + b1.WithOwner() + .HasForeignKey("OrderId"); + }); + + b.OwnsOne("Nethereum.eShop.ApplicationCore.Entities.PostalAddress", "ShipTo", b1 => + { + b1.Property("OrderId") + .HasColumnType("int"); + + b1.Property("City") + .IsRequired() + .HasColumnType("varchar(100) CHARACTER SET utf8mb4") + .HasMaxLength(100); + + b1.Property("Country") + .IsRequired() + .HasColumnType("varchar(90) CHARACTER SET utf8mb4") + .HasMaxLength(90); + + b1.Property("RecipientName") + .IsRequired() + .HasColumnType("varchar(255) CHARACTER SET utf8mb4") + .HasMaxLength(255); + + b1.Property("State") + .HasColumnType("varchar(60) CHARACTER SET utf8mb4") + .HasMaxLength(60); + + b1.Property("Street") + .IsRequired() + .HasColumnType("varchar(180) CHARACTER SET utf8mb4") + .HasMaxLength(180); + + b1.Property("ZipCode") + .IsRequired() + .HasColumnType("varchar(18) CHARACTER SET utf8mb4") + .HasMaxLength(18); + + b1.HasKey("OrderId"); + + b1.ToTable("Orders"); + + b1.WithOwner() + .HasForeignKey("OrderId"); + }); + }); + + modelBuilder.Entity("Nethereum.eShop.ApplicationCore.Entities.OrderAggregate.OrderItem", b => + { + b.HasOne("Nethereum.eShop.ApplicationCore.Entities.OrderAggregate.Order", null) + .WithMany("OrderItems") + .HasForeignKey("OrderId"); + + b.OwnsOne("Nethereum.eShop.ApplicationCore.Entities.CatalogItemExcerpt", "ItemOrdered", b1 => + { + b1.Property("OrderItemId") + .HasColumnType("int"); + + b1.Property("CatalogItemId") + .HasColumnType("int"); + + b1.Property("Gtin") + .HasColumnType("varchar(14) CHARACTER SET utf8mb4") + .HasMaxLength(14); + + b1.Property("GtinRegistryId") + .HasColumnType("int"); + + b1.Property("PictureUri") + .HasColumnType("varchar(512) CHARACTER SET utf8mb4") + .HasMaxLength(512); + + b1.Property("ProductName") + .IsRequired() + .HasColumnType("varchar(50) CHARACTER SET utf8mb4") + .HasMaxLength(50); + + b1.HasKey("OrderItemId"); + + b1.ToTable("OrderItems"); + + b1.WithOwner() + .HasForeignKey("OrderItemId"); + }); + }); + + modelBuilder.Entity("Nethereum.eShop.ApplicationCore.Entities.QuoteAggregate.Quote", b => + { + b.OwnsOne("Nethereum.eShop.ApplicationCore.Entities.PostalAddress", "BillTo", b1 => + { + b1.Property("QuoteId") + .HasColumnType("int"); + + b1.Property("City") + .IsRequired() + .HasColumnType("varchar(100) CHARACTER SET utf8mb4") + .HasMaxLength(100); + + b1.Property("Country") + .IsRequired() + .HasColumnType("varchar(90) CHARACTER SET utf8mb4") + .HasMaxLength(90); + + b1.Property("RecipientName") + .IsRequired() + .HasColumnType("varchar(255) CHARACTER SET utf8mb4") + .HasMaxLength(255); + + b1.Property("State") + .HasColumnType("varchar(60) CHARACTER SET utf8mb4") + .HasMaxLength(60); + + b1.Property("Street") + .IsRequired() + .HasColumnType("varchar(180) CHARACTER SET utf8mb4") + .HasMaxLength(180); + + b1.Property("ZipCode") + .IsRequired() + .HasColumnType("varchar(18) CHARACTER SET utf8mb4") + .HasMaxLength(18); + + b1.HasKey("QuoteId"); + + b1.ToTable("Quotes"); + + b1.WithOwner() + .HasForeignKey("QuoteId"); + }); + + b.OwnsOne("Nethereum.eShop.ApplicationCore.Entities.PostalAddress", "ShipTo", b1 => + { + b1.Property("QuoteId") + .HasColumnType("int"); + + b1.Property("City") + .IsRequired() + .HasColumnType("varchar(100) CHARACTER SET utf8mb4") + .HasMaxLength(100); + + b1.Property("Country") + .IsRequired() + .HasColumnType("varchar(90) CHARACTER SET utf8mb4") + .HasMaxLength(90); + + b1.Property("RecipientName") + .IsRequired() + .HasColumnType("varchar(255) CHARACTER SET utf8mb4") + .HasMaxLength(255); + + b1.Property("State") + .HasColumnType("varchar(60) CHARACTER SET utf8mb4") + .HasMaxLength(60); + + b1.Property("Street") + .IsRequired() + .HasColumnType("varchar(180) CHARACTER SET utf8mb4") + .HasMaxLength(180); + + b1.Property("ZipCode") + .IsRequired() + .HasColumnType("varchar(18) CHARACTER SET utf8mb4") + .HasMaxLength(18); + + b1.HasKey("QuoteId"); + + b1.ToTable("Quotes"); + + b1.WithOwner() + .HasForeignKey("QuoteId"); + }); + }); + + modelBuilder.Entity("Nethereum.eShop.ApplicationCore.Entities.QuoteAggregate.QuoteItem", b => + { + b.HasOne("Nethereum.eShop.ApplicationCore.Entities.QuoteAggregate.Quote", null) + .WithMany("QuoteItems") + .HasForeignKey("QuoteId"); + + b.OwnsOne("Nethereum.eShop.ApplicationCore.Entities.CatalogItemExcerpt", "ItemOrdered", b1 => + { + b1.Property("QuoteItemId") + .HasColumnType("int"); + + b1.Property("CatalogItemId") + .HasColumnType("int"); + + b1.Property("Gtin") + .HasColumnType("varchar(14) CHARACTER SET utf8mb4") + .HasMaxLength(14); + + b1.Property("GtinRegistryId") + .HasColumnType("int"); + + b1.Property("PictureUri") + .HasColumnType("varchar(512) CHARACTER SET utf8mb4") + .HasMaxLength(512); + + b1.Property("ProductName") + .IsRequired() + .HasColumnType("varchar(50) CHARACTER SET utf8mb4") + .HasMaxLength(50); + + b1.HasKey("QuoteItemId"); + + b1.ToTable("QuoteItems"); + + b1.WithOwner() + .HasForeignKey("QuoteItemId"); + }); + }); + + modelBuilder.Entity("Nethereum.eShop.ApplicationCore.Entities.StockItem", b => + { + b.HasOne("Nethereum.eShop.ApplicationCore.Entities.CatalogItem", "CatalogItem") + .WithMany() + .HasForeignKey("CatalogItemId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + }); +#pragma warning restore 612, 618 + } + } +} diff --git a/src/Nethereum.eShop.MySql/Catalog/Migrations/20200403114515_CreateSettingsTable.cs b/src/Nethereum.eShop.MySql/Catalog/Migrations/20200403114515_CreateSettingsTable.cs new file mode 100644 index 0000000..d24c876 --- /dev/null +++ b/src/Nethereum.eShop.MySql/Catalog/Migrations/20200403114515_CreateSettingsTable.cs @@ -0,0 +1,36 @@ +using Microsoft.EntityFrameworkCore.Metadata; +using Microsoft.EntityFrameworkCore.Migrations; + +namespace Nethereum.eShop.MySql.Catalog.Migrations +{ + public partial class CreateSettingsTable : Migration + { + protected override void Up(MigrationBuilder migrationBuilder) + { + migrationBuilder.CreateTable( + name: "Settings", + columns: table => new + { + Id = table.Column(nullable: false) + .Annotation("MySql:ValueGenerationStrategy", MySqlValueGenerationStrategy.IdentityColumn), + Key = table.Column(maxLength: 100, nullable: true), + Value = table.Column(nullable: true) + }, + constraints: table => + { + table.PrimaryKey("PK_Settings", x => x.Id); + }); + + migrationBuilder.CreateIndex( + name: "IX_Settings_Key", + table: "Settings", + column: "Key"); + } + + protected override void Down(MigrationBuilder migrationBuilder) + { + migrationBuilder.DropTable( + name: "Settings"); + } + } +} diff --git a/src/Nethereum.eShop.MySql/Catalog/Migrations/MySqlCatalogContextModelSnapshot.cs b/src/Nethereum.eShop.MySql/Catalog/Migrations/MySqlCatalogContextModelSnapshot.cs index eaf5ffa..8ffec0d 100644 --- a/src/Nethereum.eShop.MySql/Catalog/Migrations/MySqlCatalogContextModelSnapshot.cs +++ b/src/Nethereum.eShop.MySql/Catalog/Migrations/MySqlCatalogContextModelSnapshot.cs @@ -236,6 +236,26 @@ protected override void BuildModel(ModelBuilder modelBuilder) b.ToTable("CatalogTypes"); }); + modelBuilder.Entity("Nethereum.eShop.ApplicationCore.Entities.ConfigurationAggregate.Setting", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("int"); + + b.Property("Key") + .HasColumnType("varchar(100) CHARACTER SET utf8mb4") + .HasMaxLength(100); + + b.Property("Value") + .HasColumnType("longtext CHARACTER SET utf8mb4"); + + b.HasKey("Id"); + + b.HasIndex("Key"); + + b.ToTable("Settings"); + }); + modelBuilder.Entity("Nethereum.eShop.ApplicationCore.Entities.OrderAggregate.Order", b => { b.Property("Id") diff --git a/src/Nethereum.eShop.MySql/Catalog/Migrations/Scripts/CreateCatalogDb.sql b/src/Nethereum.eShop.MySql/Catalog/Migrations/Scripts/CreateCatalogDb.sql index e1d6b95..ef482d3 100644 --- a/src/Nethereum.eShop.MySql/Catalog/Migrations/Scripts/CreateCatalogDb.sql +++ b/src/Nethereum.eShop.MySql/Catalog/Migrations/Scripts/CreateCatalogDb.sql @@ -682,3 +682,54 @@ DELIMITER ; CALL MigrationsScript(); DROP PROCEDURE MigrationsScript; + +DROP PROCEDURE IF EXISTS MigrationsScript; +DELIMITER // +CREATE PROCEDURE MigrationsScript() +BEGIN + IF NOT EXISTS(SELECT 1 FROM `__EFMigrationsHistory` WHERE `MigrationId` = '20200403114515_CreateSettingsTable') THEN + + CREATE TABLE `Settings` ( + `Id` int NOT NULL AUTO_INCREMENT, + `Key` varchar(100) CHARACTER SET utf8mb4 NULL, + `Value` longtext CHARACTER SET utf8mb4 NULL, + CONSTRAINT `PK_Settings` PRIMARY KEY (`Id`) + ); + + END IF; +END // +DELIMITER ; +CALL MigrationsScript(); +DROP PROCEDURE MigrationsScript; + + +DROP PROCEDURE IF EXISTS MigrationsScript; +DELIMITER // +CREATE PROCEDURE MigrationsScript() +BEGIN + IF NOT EXISTS(SELECT 1 FROM `__EFMigrationsHistory` WHERE `MigrationId` = '20200403114515_CreateSettingsTable') THEN + + CREATE INDEX `IX_Settings_Key` ON `Settings` (`Key`); + + END IF; +END // +DELIMITER ; +CALL MigrationsScript(); +DROP PROCEDURE MigrationsScript; + + +DROP PROCEDURE IF EXISTS MigrationsScript; +DELIMITER // +CREATE PROCEDURE MigrationsScript() +BEGIN + IF NOT EXISTS(SELECT 1 FROM `__EFMigrationsHistory` WHERE `MigrationId` = '20200403114515_CreateSettingsTable') THEN + + INSERT INTO `__EFMigrationsHistory` (`MigrationId`, `ProductVersion`) + VALUES ('20200403114515_CreateSettingsTable', '3.1.2'); + + END IF; +END // +DELIMITER ; +CALL MigrationsScript(); +DROP PROCEDURE MigrationsScript; + diff --git a/src/Nethereum.eShop.SqlServer/Catalog/Migrations/20200403114458_CreateSettingsTable.Designer.cs b/src/Nethereum.eShop.SqlServer/Catalog/Migrations/20200403114458_CreateSettingsTable.Designer.cs new file mode 100644 index 0000000..3c74af2 --- /dev/null +++ b/src/Nethereum.eShop.SqlServer/Catalog/Migrations/20200403114458_CreateSettingsTable.Designer.cs @@ -0,0 +1,966 @@ +// +using System; +using Microsoft.EntityFrameworkCore; +using Microsoft.EntityFrameworkCore.Infrastructure; +using Microsoft.EntityFrameworkCore.Metadata; +using Microsoft.EntityFrameworkCore.Migrations; +using Microsoft.EntityFrameworkCore.Storage.ValueConversion; +using Nethereum.eShop.SqlServer.Catalog; + +namespace Nethereum.eShop.SqlServer.Catalog.Migrations +{ + [DbContext(typeof(SqlServerCatalogContext))] + [Migration("20200403114458_CreateSettingsTable")] + partial class CreateSettingsTable + { + protected override void BuildTargetModel(ModelBuilder modelBuilder) + { +#pragma warning disable 612, 618 + modelBuilder + .HasAnnotation("ProductVersion", "3.1.2") + .HasAnnotation("Relational:MaxIdentifierLength", 128) + .HasAnnotation("Relational:Sequence:.catalog_brand_hilo", "'catalog_brand_hilo', '', '1', '10', '', '', 'Int64', 'False'") + .HasAnnotation("Relational:Sequence:.catalog_hilo", "'catalog_hilo', '', '1', '10', '', '', 'Int64', 'False'") + .HasAnnotation("Relational:Sequence:.catalog_type_hilo", "'catalog_type_hilo', '', '1', '10', '', '', 'Int64', 'False'") + .HasAnnotation("Relational:Sequence:.stock_hilo", "'stock_hilo', '', '1', '10', '', '', 'Int64', 'False'") + .HasAnnotation("SqlServer:ValueGenerationStrategy", SqlServerValueGenerationStrategy.IdentityColumn); + + modelBuilder.Entity("Nethereum.eShop.ApplicationCore.Entities.BasketAggregate.Basket", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("int") + .HasAnnotation("SqlServer:ValueGenerationStrategy", SqlServerValueGenerationStrategy.IdentityColumn); + + b.Property("BuyerAddress") + .IsRequired() + .HasColumnType("nvarchar(43)") + .HasMaxLength(43); + + b.Property("BuyerId") + .IsRequired() + .HasColumnType("nvarchar(256)") + .HasMaxLength(256); + + b.Property("TransactionHash") + .HasColumnType("nvarchar(67)") + .HasMaxLength(67); + + b.HasKey("Id"); + + b.HasIndex("BuyerAddress"); + + b.HasIndex("BuyerId"); + + b.ToTable("Baskets"); + }); + + modelBuilder.Entity("Nethereum.eShop.ApplicationCore.Entities.BasketAggregate.BasketItem", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("int") + .HasAnnotation("SqlServer:ValueGenerationStrategy", SqlServerValueGenerationStrategy.IdentityColumn); + + b.Property("BasketId") + .HasColumnType("int"); + + b.Property("CatalogItemId") + .HasColumnType("int"); + + b.Property("Quantity") + .HasColumnType("int"); + + b.Property("UnitPrice") + .HasColumnType("decimal(18,2)"); + + b.HasKey("Id"); + + b.HasIndex("BasketId"); + + b.ToTable("BasketItems"); + }); + + modelBuilder.Entity("Nethereum.eShop.ApplicationCore.Entities.BuyerAggregate.Buyer", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("int") + .HasAnnotation("SqlServer:ValueGenerationStrategy", SqlServerValueGenerationStrategy.IdentityColumn); + + b.Property("BuyerAddress") + .HasColumnType("nvarchar(43)") + .HasMaxLength(43); + + b.Property("BuyerId") + .IsRequired() + .HasColumnType("nvarchar(256)") + .HasMaxLength(256); + + b.Property("BuyerWalletAddress") + .HasColumnType("nvarchar(43)") + .HasMaxLength(43); + + b.HasKey("Id"); + + b.HasIndex("BuyerAddress") + .IsUnique() + .HasFilter("[BuyerAddress] IS NOT NULL"); + + b.HasIndex("BuyerId") + .IsUnique(); + + b.HasIndex("BuyerWalletAddress") + .IsUnique() + .HasFilter("[BuyerWalletAddress] IS NOT NULL"); + + b.ToTable("Buyers"); + }); + + modelBuilder.Entity("Nethereum.eShop.ApplicationCore.Entities.BuyerAggregate.BuyerPostalAddress", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("int") + .HasAnnotation("SqlServer:ValueGenerationStrategy", SqlServerValueGenerationStrategy.IdentityColumn); + + b.Property("BuyerId") + .HasColumnType("int"); + + b.Property("Name") + .HasColumnType("nvarchar(max)"); + + b.HasKey("Id"); + + b.HasIndex("BuyerId"); + + b.ToTable("BuyerPostalAddress"); + }); + + modelBuilder.Entity("Nethereum.eShop.ApplicationCore.Entities.CatalogBrand", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("int") + .HasAnnotation("SqlServer:HiLoSequenceName", "catalog_brand_hilo") + .HasAnnotation("SqlServer:ValueGenerationStrategy", SqlServerValueGenerationStrategy.SequenceHiLo); + + b.Property("Brand") + .IsRequired() + .HasColumnType("nvarchar(100)") + .HasMaxLength(100); + + b.HasKey("Id"); + + b.ToTable("CatalogBrands"); + }); + + modelBuilder.Entity("Nethereum.eShop.ApplicationCore.Entities.CatalogItem", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("int") + .HasAnnotation("SqlServer:HiLoSequenceName", "catalog_hilo") + .HasAnnotation("SqlServer:ValueGenerationStrategy", SqlServerValueGenerationStrategy.SequenceHiLo); + + b.Property("AttributeJson") + .HasColumnType("nvarchar(max)"); + + b.Property("CatalogBrandId") + .HasColumnType("int"); + + b.Property("CatalogTypeId") + .HasColumnType("int"); + + b.Property("Depth") + .HasColumnType("int"); + + b.Property("Description") + .HasColumnType("nvarchar(max)"); + + b.Property("Gtin") + .IsRequired() + .HasColumnType("nvarchar(14)") + .HasMaxLength(14); + + b.Property("GtinRegistryId") + .HasColumnType("int"); + + b.Property("Height") + .HasColumnType("int"); + + b.Property("Name") + .IsRequired() + .HasColumnType("nvarchar(50)") + .HasMaxLength(50); + + b.Property("PictureLargeUri") + .HasColumnType("nvarchar(512)") + .HasMaxLength(512); + + b.Property("PictureMediumUri") + .HasColumnType("nvarchar(512)") + .HasMaxLength(512); + + b.Property("PictureSmallUri") + .HasColumnType("nvarchar(512)") + .HasMaxLength(512); + + b.Property("PictureUri") + .HasColumnType("nvarchar(512)") + .HasMaxLength(512); + + b.Property("Price") + .HasColumnType("decimal(18,2)"); + + b.Property("Rank") + .HasColumnType("int"); + + b.Property("Status") + .HasColumnType("int"); + + b.Property("Unit") + .HasColumnType("nvarchar(8)") + .HasMaxLength(8); + + b.Property("Weight") + .HasColumnType("int"); + + b.Property("Width") + .HasColumnType("int"); + + b.HasKey("Id"); + + b.HasIndex("CatalogBrandId"); + + b.HasIndex("CatalogTypeId"); + + b.ToTable("Catalog"); + }); + + modelBuilder.Entity("Nethereum.eShop.ApplicationCore.Entities.CatalogType", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("int") + .HasAnnotation("SqlServer:HiLoSequenceName", "catalog_type_hilo") + .HasAnnotation("SqlServer:ValueGenerationStrategy", SqlServerValueGenerationStrategy.SequenceHiLo); + + b.Property("Type") + .IsRequired() + .HasColumnType("nvarchar(100)") + .HasMaxLength(100); + + b.HasKey("Id"); + + b.ToTable("CatalogTypes"); + }); + + modelBuilder.Entity("Nethereum.eShop.ApplicationCore.Entities.ConfigurationAggregate.Setting", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("int") + .HasAnnotation("SqlServer:ValueGenerationStrategy", SqlServerValueGenerationStrategy.IdentityColumn); + + b.Property("Key") + .HasColumnType("nvarchar(max)"); + + b.Property("Value") + .HasColumnType("nvarchar(max)"); + + b.HasKey("Id"); + + b.ToTable("Settings"); + }); + + modelBuilder.Entity("Nethereum.eShop.ApplicationCore.Entities.OrderAggregate.Order", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("int") + .HasAnnotation("SqlServer:ValueGenerationStrategy", SqlServerValueGenerationStrategy.IdentityColumn); + + b.Property("BuyerId") + .IsRequired() + .HasColumnType("nvarchar(256)") + .HasMaxLength(256); + + b.Property("BuyerWalletAddress") + .HasColumnType("nvarchar(43)") + .HasMaxLength(43); + + b.Property("CurrencyAddress") + .HasColumnType("nvarchar(43)") + .HasMaxLength(43); + + b.Property("CurrencySymbol") + .HasColumnType("nvarchar(32)") + .HasMaxLength(32); + + b.Property("OrderDate") + .HasColumnType("datetimeoffset"); + + b.Property("PoDate") + .HasColumnType("datetimeoffset"); + + b.Property("PoNumber") + .HasColumnType("bigint"); + + b.Property("PoType") + .HasColumnType("int"); + + b.Property("QuoteId") + .HasColumnType("int"); + + b.Property("SellerId") + .HasColumnType("nvarchar(32)") + .HasMaxLength(32); + + b.Property("Status") + .HasColumnType("int"); + + b.Property("TransactionHash") + .HasColumnType("nvarchar(67)") + .HasMaxLength(67); + + b.HasKey("Id"); + + b.HasIndex("BuyerId"); + + b.ToTable("Orders"); + }); + + modelBuilder.Entity("Nethereum.eShop.ApplicationCore.Entities.OrderAggregate.OrderItem", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("int") + .HasAnnotation("SqlServer:ValueGenerationStrategy", SqlServerValueGenerationStrategy.IdentityColumn); + + b.Property("ActualEscrowReleaseDate") + .HasColumnType("datetimeoffset"); + + b.Property("CurrencyValue") + .HasColumnType("nvarchar(100)") + .HasMaxLength(100); + + b.Property("GoodsIssueDate") + .HasColumnType("datetimeoffset"); + + b.Property("IsEscrowReleased") + .HasColumnType("bit"); + + b.Property("OrderId") + .HasColumnType("int"); + + b.Property("PlannedEscrowReleaseDate") + .HasColumnType("datetimeoffset"); + + b.Property("PoItemNumber") + .HasColumnType("int"); + + b.Property("PoItemStatus") + .HasColumnType("int"); + + b.Property("Quantity") + .HasColumnType("int"); + + b.Property("QuantityAddress") + .HasColumnType("nvarchar(43)") + .HasMaxLength(43); + + b.Property("QuantitySymbol") + .HasColumnType("nvarchar(32)") + .HasMaxLength(32); + + b.Property("Status") + .HasColumnType("int"); + + b.Property("Unit") + .HasColumnType("nvarchar(50)") + .HasMaxLength(50); + + b.Property("UnitPrice") + .HasColumnType("decimal(18,2)"); + + b.HasKey("Id"); + + b.HasIndex("OrderId"); + + b.ToTable("OrderItems"); + }); + + modelBuilder.Entity("Nethereum.eShop.ApplicationCore.Entities.QuoteAggregate.Quote", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("int") + .HasAnnotation("SqlServer:ValueGenerationStrategy", SqlServerValueGenerationStrategy.IdentityColumn); + + b.Property("ApproverAddress") + .HasColumnType("nvarchar(43)") + .HasMaxLength(43); + + b.Property("BuyerAddress") + .HasColumnType("nvarchar(43)") + .HasMaxLength(43); + + b.Property("BuyerId") + .IsRequired() + .HasColumnType("nvarchar(256)") + .HasMaxLength(256); + + b.Property("BuyerWalletAddress") + .HasColumnType("nvarchar(43)") + .HasMaxLength(43); + + b.Property("CurrencyAddress") + .HasColumnType("nvarchar(43)") + .HasMaxLength(43); + + b.Property("CurrencySymbol") + .HasColumnType("nvarchar(32)") + .HasMaxLength(32); + + b.Property("Date") + .HasColumnType("datetimeoffset"); + + b.Property("Expiry") + .HasColumnType("datetimeoffset"); + + b.Property("PoNumber") + .HasColumnType("bigint"); + + b.Property("PoType") + .HasColumnType("int"); + + b.Property("SellerId") + .HasColumnType("nvarchar(32)") + .HasMaxLength(32); + + b.Property("Status") + .HasColumnType("int"); + + b.Property("TransactionHash") + .HasColumnType("nvarchar(67)") + .HasMaxLength(67); + + b.HasKey("Id"); + + b.HasIndex("BuyerAddress"); + + b.HasIndex("BuyerId"); + + b.ToTable("Quotes"); + }); + + modelBuilder.Entity("Nethereum.eShop.ApplicationCore.Entities.QuoteAggregate.QuoteItem", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("int") + .HasAnnotation("SqlServer:ValueGenerationStrategy", SqlServerValueGenerationStrategy.IdentityColumn); + + b.Property("CurrencyValue") + .HasColumnType("nvarchar(max)"); + + b.Property("EscrowReleaseDate") + .HasColumnType("datetimeoffset"); + + b.Property("PoItemNumber") + .HasColumnType("int"); + + b.Property("Quantity") + .HasColumnType("int"); + + b.Property("QuantityAddress") + .HasColumnType("nvarchar(max)"); + + b.Property("QuantitySymbol") + .HasColumnType("nvarchar(max)"); + + b.Property("QuoteId") + .HasColumnType("int"); + + b.Property("Unit") + .HasColumnType("nvarchar(max)"); + + b.Property("UnitPrice") + .HasColumnType("decimal(18,2)"); + + b.HasKey("Id"); + + b.HasIndex("QuoteId"); + + b.ToTable("QuoteItems"); + }); + + modelBuilder.Entity("Nethereum.eShop.ApplicationCore.Entities.StockItem", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("int") + .HasAnnotation("SqlServer:HiLoSequenceName", "stock_hilo") + .HasAnnotation("SqlServer:ValueGenerationStrategy", SqlServerValueGenerationStrategy.SequenceHiLo); + + b.Property("CatalogItemId") + .HasColumnType("int"); + + b.Property("Location") + .IsRequired() + .HasColumnType("nvarchar(50)") + .HasMaxLength(50); + + b.Property("Quantity") + .HasColumnType("int"); + + b.HasKey("Id"); + + b.HasIndex("CatalogItemId"); + + b.ToTable("Stock"); + }); + + modelBuilder.Entity("Nethereum.eShop.ApplicationCore.Entities.BasketAggregate.Basket", b => + { + b.OwnsOne("Nethereum.eShop.ApplicationCore.Entities.PostalAddress", "BillTo", b1 => + { + b1.Property("BasketId") + .ValueGeneratedOnAdd() + .HasColumnType("int") + .HasAnnotation("SqlServer:ValueGenerationStrategy", SqlServerValueGenerationStrategy.IdentityColumn); + + b1.Property("City") + .IsRequired() + .HasColumnType("nvarchar(100)") + .HasMaxLength(100); + + b1.Property("Country") + .IsRequired() + .HasColumnType("nvarchar(90)") + .HasMaxLength(90); + + b1.Property("RecipientName") + .IsRequired() + .HasColumnType("nvarchar(255)") + .HasMaxLength(255); + + b1.Property("State") + .HasColumnType("nvarchar(60)") + .HasMaxLength(60); + + b1.Property("Street") + .IsRequired() + .HasColumnType("nvarchar(180)") + .HasMaxLength(180); + + b1.Property("ZipCode") + .IsRequired() + .HasColumnType("nvarchar(18)") + .HasMaxLength(18); + + b1.HasKey("BasketId"); + + b1.ToTable("Baskets"); + + b1.WithOwner() + .HasForeignKey("BasketId"); + }); + + b.OwnsOne("Nethereum.eShop.ApplicationCore.Entities.PostalAddress", "ShipTo", b1 => + { + b1.Property("BasketId") + .ValueGeneratedOnAdd() + .HasColumnType("int") + .HasAnnotation("SqlServer:ValueGenerationStrategy", SqlServerValueGenerationStrategy.IdentityColumn); + + b1.Property("City") + .IsRequired() + .HasColumnType("nvarchar(100)") + .HasMaxLength(100); + + b1.Property("Country") + .IsRequired() + .HasColumnType("nvarchar(90)") + .HasMaxLength(90); + + b1.Property("RecipientName") + .IsRequired() + .HasColumnType("nvarchar(255)") + .HasMaxLength(255); + + b1.Property("State") + .HasColumnType("nvarchar(60)") + .HasMaxLength(60); + + b1.Property("Street") + .IsRequired() + .HasColumnType("nvarchar(180)") + .HasMaxLength(180); + + b1.Property("ZipCode") + .IsRequired() + .HasColumnType("nvarchar(18)") + .HasMaxLength(18); + + b1.HasKey("BasketId"); + + b1.ToTable("Baskets"); + + b1.WithOwner() + .HasForeignKey("BasketId"); + }); + }); + + modelBuilder.Entity("Nethereum.eShop.ApplicationCore.Entities.BasketAggregate.BasketItem", b => + { + b.HasOne("Nethereum.eShop.ApplicationCore.Entities.BasketAggregate.Basket", null) + .WithMany("Items") + .HasForeignKey("BasketId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + }); + + modelBuilder.Entity("Nethereum.eShop.ApplicationCore.Entities.BuyerAggregate.BuyerPostalAddress", b => + { + b.HasOne("Nethereum.eShop.ApplicationCore.Entities.BuyerAggregate.Buyer", null) + .WithMany("PostalAddresses") + .HasForeignKey("BuyerId"); + + b.OwnsOne("Nethereum.eShop.ApplicationCore.Entities.PostalAddress", "PostalAddress", b1 => + { + b1.Property("BuyerPostalAddressId") + .ValueGeneratedOnAdd() + .HasColumnType("int") + .HasAnnotation("SqlServer:ValueGenerationStrategy", SqlServerValueGenerationStrategy.IdentityColumn); + + b1.Property("City") + .IsRequired() + .HasColumnType("nvarchar(100)") + .HasMaxLength(100); + + b1.Property("Country") + .IsRequired() + .HasColumnType("nvarchar(90)") + .HasMaxLength(90); + + b1.Property("RecipientName") + .IsRequired() + .HasColumnType("nvarchar(255)") + .HasMaxLength(255); + + b1.Property("State") + .HasColumnType("nvarchar(60)") + .HasMaxLength(60); + + b1.Property("Street") + .IsRequired() + .HasColumnType("nvarchar(180)") + .HasMaxLength(180); + + b1.Property("ZipCode") + .IsRequired() + .HasColumnType("nvarchar(18)") + .HasMaxLength(18); + + b1.HasKey("BuyerPostalAddressId"); + + b1.ToTable("BuyerPostalAddress"); + + b1.WithOwner() + .HasForeignKey("BuyerPostalAddressId"); + }); + }); + + modelBuilder.Entity("Nethereum.eShop.ApplicationCore.Entities.CatalogItem", b => + { + b.HasOne("Nethereum.eShop.ApplicationCore.Entities.CatalogBrand", "CatalogBrand") + .WithMany() + .HasForeignKey("CatalogBrandId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.HasOne("Nethereum.eShop.ApplicationCore.Entities.CatalogType", "CatalogType") + .WithMany() + .HasForeignKey("CatalogTypeId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + }); + + modelBuilder.Entity("Nethereum.eShop.ApplicationCore.Entities.OrderAggregate.Order", b => + { + b.OwnsOne("Nethereum.eShop.ApplicationCore.Entities.PostalAddress", "BillTo", b1 => + { + b1.Property("OrderId") + .ValueGeneratedOnAdd() + .HasColumnType("int") + .HasAnnotation("SqlServer:ValueGenerationStrategy", SqlServerValueGenerationStrategy.IdentityColumn); + + b1.Property("City") + .IsRequired() + .HasColumnType("nvarchar(100)") + .HasMaxLength(100); + + b1.Property("Country") + .IsRequired() + .HasColumnType("nvarchar(90)") + .HasMaxLength(90); + + b1.Property("RecipientName") + .IsRequired() + .HasColumnType("nvarchar(255)") + .HasMaxLength(255); + + b1.Property("State") + .HasColumnType("nvarchar(60)") + .HasMaxLength(60); + + b1.Property("Street") + .IsRequired() + .HasColumnType("nvarchar(180)") + .HasMaxLength(180); + + b1.Property("ZipCode") + .IsRequired() + .HasColumnType("nvarchar(18)") + .HasMaxLength(18); + + b1.HasKey("OrderId"); + + b1.ToTable("Orders"); + + b1.WithOwner() + .HasForeignKey("OrderId"); + }); + + b.OwnsOne("Nethereum.eShop.ApplicationCore.Entities.PostalAddress", "ShipTo", b1 => + { + b1.Property("OrderId") + .ValueGeneratedOnAdd() + .HasColumnType("int") + .HasAnnotation("SqlServer:ValueGenerationStrategy", SqlServerValueGenerationStrategy.IdentityColumn); + + b1.Property("City") + .IsRequired() + .HasColumnType("nvarchar(100)") + .HasMaxLength(100); + + b1.Property("Country") + .IsRequired() + .HasColumnType("nvarchar(90)") + .HasMaxLength(90); + + b1.Property("RecipientName") + .IsRequired() + .HasColumnType("nvarchar(255)") + .HasMaxLength(255); + + b1.Property("State") + .HasColumnType("nvarchar(60)") + .HasMaxLength(60); + + b1.Property("Street") + .IsRequired() + .HasColumnType("nvarchar(180)") + .HasMaxLength(180); + + b1.Property("ZipCode") + .IsRequired() + .HasColumnType("nvarchar(18)") + .HasMaxLength(18); + + b1.HasKey("OrderId"); + + b1.ToTable("Orders"); + + b1.WithOwner() + .HasForeignKey("OrderId"); + }); + }); + + modelBuilder.Entity("Nethereum.eShop.ApplicationCore.Entities.OrderAggregate.OrderItem", b => + { + b.HasOne("Nethereum.eShop.ApplicationCore.Entities.OrderAggregate.Order", null) + .WithMany("OrderItems") + .HasForeignKey("OrderId"); + + b.OwnsOne("Nethereum.eShop.ApplicationCore.Entities.CatalogItemExcerpt", "ItemOrdered", b1 => + { + b1.Property("OrderItemId") + .ValueGeneratedOnAdd() + .HasColumnType("int") + .HasAnnotation("SqlServer:ValueGenerationStrategy", SqlServerValueGenerationStrategy.IdentityColumn); + + b1.Property("CatalogItemId") + .HasColumnType("int"); + + b1.Property("Gtin") + .HasColumnType("nvarchar(14)") + .HasMaxLength(14); + + b1.Property("GtinRegistryId") + .HasColumnType("int"); + + b1.Property("PictureUri") + .HasColumnType("nvarchar(512)") + .HasMaxLength(512); + + b1.Property("ProductName") + .IsRequired() + .HasColumnType("nvarchar(50)") + .HasMaxLength(50); + + b1.HasKey("OrderItemId"); + + b1.ToTable("OrderItems"); + + b1.WithOwner() + .HasForeignKey("OrderItemId"); + }); + }); + + modelBuilder.Entity("Nethereum.eShop.ApplicationCore.Entities.QuoteAggregate.Quote", b => + { + b.OwnsOne("Nethereum.eShop.ApplicationCore.Entities.PostalAddress", "BillTo", b1 => + { + b1.Property("QuoteId") + .ValueGeneratedOnAdd() + .HasColumnType("int") + .HasAnnotation("SqlServer:ValueGenerationStrategy", SqlServerValueGenerationStrategy.IdentityColumn); + + b1.Property("City") + .IsRequired() + .HasColumnType("nvarchar(100)") + .HasMaxLength(100); + + b1.Property("Country") + .IsRequired() + .HasColumnType("nvarchar(90)") + .HasMaxLength(90); + + b1.Property("RecipientName") + .IsRequired() + .HasColumnType("nvarchar(255)") + .HasMaxLength(255); + + b1.Property("State") + .HasColumnType("nvarchar(60)") + .HasMaxLength(60); + + b1.Property("Street") + .IsRequired() + .HasColumnType("nvarchar(180)") + .HasMaxLength(180); + + b1.Property("ZipCode") + .IsRequired() + .HasColumnType("nvarchar(18)") + .HasMaxLength(18); + + b1.HasKey("QuoteId"); + + b1.ToTable("Quotes"); + + b1.WithOwner() + .HasForeignKey("QuoteId"); + }); + + b.OwnsOne("Nethereum.eShop.ApplicationCore.Entities.PostalAddress", "ShipTo", b1 => + { + b1.Property("QuoteId") + .ValueGeneratedOnAdd() + .HasColumnType("int") + .HasAnnotation("SqlServer:ValueGenerationStrategy", SqlServerValueGenerationStrategy.IdentityColumn); + + b1.Property("City") + .IsRequired() + .HasColumnType("nvarchar(100)") + .HasMaxLength(100); + + b1.Property("Country") + .IsRequired() + .HasColumnType("nvarchar(90)") + .HasMaxLength(90); + + b1.Property("RecipientName") + .IsRequired() + .HasColumnType("nvarchar(255)") + .HasMaxLength(255); + + b1.Property("State") + .HasColumnType("nvarchar(60)") + .HasMaxLength(60); + + b1.Property("Street") + .IsRequired() + .HasColumnType("nvarchar(180)") + .HasMaxLength(180); + + b1.Property("ZipCode") + .IsRequired() + .HasColumnType("nvarchar(18)") + .HasMaxLength(18); + + b1.HasKey("QuoteId"); + + b1.ToTable("Quotes"); + + b1.WithOwner() + .HasForeignKey("QuoteId"); + }); + }); + + modelBuilder.Entity("Nethereum.eShop.ApplicationCore.Entities.QuoteAggregate.QuoteItem", b => + { + b.HasOne("Nethereum.eShop.ApplicationCore.Entities.QuoteAggregate.Quote", null) + .WithMany("QuoteItems") + .HasForeignKey("QuoteId"); + + b.OwnsOne("Nethereum.eShop.ApplicationCore.Entities.CatalogItemExcerpt", "ItemOrdered", b1 => + { + b1.Property("QuoteItemId") + .ValueGeneratedOnAdd() + .HasColumnType("int") + .HasAnnotation("SqlServer:ValueGenerationStrategy", SqlServerValueGenerationStrategy.IdentityColumn); + + b1.Property("CatalogItemId") + .HasColumnType("int"); + + b1.Property("Gtin") + .HasColumnType("nvarchar(14)") + .HasMaxLength(14); + + b1.Property("GtinRegistryId") + .HasColumnType("int"); + + b1.Property("PictureUri") + .HasColumnType("nvarchar(512)") + .HasMaxLength(512); + + b1.Property("ProductName") + .IsRequired() + .HasColumnType("nvarchar(50)") + .HasMaxLength(50); + + b1.HasKey("QuoteItemId"); + + b1.ToTable("QuoteItems"); + + b1.WithOwner() + .HasForeignKey("QuoteItemId"); + }); + }); + + modelBuilder.Entity("Nethereum.eShop.ApplicationCore.Entities.StockItem", b => + { + b.HasOne("Nethereum.eShop.ApplicationCore.Entities.CatalogItem", "CatalogItem") + .WithMany() + .HasForeignKey("CatalogItemId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + }); +#pragma warning restore 612, 618 + } + } +} diff --git a/src/Nethereum.eShop.SqlServer/Catalog/Migrations/20200403114458_CreateSettingsTable.cs b/src/Nethereum.eShop.SqlServer/Catalog/Migrations/20200403114458_CreateSettingsTable.cs new file mode 100644 index 0000000..7fd6e30 --- /dev/null +++ b/src/Nethereum.eShop.SqlServer/Catalog/Migrations/20200403114458_CreateSettingsTable.cs @@ -0,0 +1,30 @@ +using Microsoft.EntityFrameworkCore.Migrations; + +namespace Nethereum.eShop.SqlServer.Catalog.Migrations +{ + public partial class CreateSettingsTable : Migration + { + protected override void Up(MigrationBuilder migrationBuilder) + { + migrationBuilder.CreateTable( + name: "Settings", + columns: table => new + { + Id = table.Column(nullable: false) + .Annotation("SqlServer:Identity", "1, 1"), + Key = table.Column(nullable: true), + Value = table.Column(nullable: true) + }, + constraints: table => + { + table.PrimaryKey("PK_Settings", x => x.Id); + }); + } + + protected override void Down(MigrationBuilder migrationBuilder) + { + migrationBuilder.DropTable( + name: "Settings"); + } + } +} diff --git a/src/Nethereum.eShop.SqlServer/Catalog/Migrations/Scripts/CreateCatalogDb.sql b/src/Nethereum.eShop.SqlServer/Catalog/Migrations/Scripts/CreateCatalogDb.sql index a3c6559..08432b7 100644 --- a/src/Nethereum.eShop.SqlServer/Catalog/Migrations/Scripts/CreateCatalogDb.sql +++ b/src/Nethereum.eShop.SqlServer/Catalog/Migrations/Scripts/CreateCatalogDb.sql @@ -477,3 +477,23 @@ END; GO +IF NOT EXISTS(SELECT * FROM [__EFMigrationsHistory] WHERE [MigrationId] = N'20200403114458_CreateSettingsTable') +BEGIN + CREATE TABLE [Settings] ( + [Id] int NOT NULL IDENTITY, + [Key] nvarchar(max) NULL, + [Value] nvarchar(max) NULL, + CONSTRAINT [PK_Settings] PRIMARY KEY ([Id]) + ); +END; + +GO + +IF NOT EXISTS(SELECT * FROM [__EFMigrationsHistory] WHERE [MigrationId] = N'20200403114458_CreateSettingsTable') +BEGIN + INSERT INTO [__EFMigrationsHistory] ([MigrationId], [ProductVersion]) + VALUES (N'20200403114458_CreateSettingsTable', N'3.1.2'); +END; + +GO + diff --git a/src/Nethereum.eShop.SqlServer/Catalog/Migrations/SqlServerCatalogContextModelSnapshot.cs b/src/Nethereum.eShop.SqlServer/Catalog/Migrations/SqlServerCatalogContextModelSnapshot.cs index 200696b..d3b8c8f 100644 --- a/src/Nethereum.eShop.SqlServer/Catalog/Migrations/SqlServerCatalogContextModelSnapshot.cs +++ b/src/Nethereum.eShop.SqlServer/Catalog/Migrations/SqlServerCatalogContextModelSnapshot.cs @@ -254,6 +254,24 @@ protected override void BuildModel(ModelBuilder modelBuilder) b.ToTable("CatalogTypes"); }); + modelBuilder.Entity("Nethereum.eShop.ApplicationCore.Entities.ConfigurationAggregate.Setting", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("int") + .HasAnnotation("SqlServer:ValueGenerationStrategy", SqlServerValueGenerationStrategy.IdentityColumn); + + b.Property("Key") + .HasColumnType("nvarchar(max)"); + + b.Property("Value") + .HasColumnType("nvarchar(max)"); + + b.HasKey("Id"); + + b.ToTable("Settings"); + }); + modelBuilder.Entity("Nethereum.eShop.ApplicationCore.Entities.OrderAggregate.Order", b => { b.Property("Id") diff --git a/src/Nethereum.eShop.Sqlite/Catalog/Migrations/20200403114507_CreateSettingsTable.Designer.cs b/src/Nethereum.eShop.Sqlite/Catalog/Migrations/20200403114507_CreateSettingsTable.Designer.cs new file mode 100644 index 0000000..d2f514b --- /dev/null +++ b/src/Nethereum.eShop.Sqlite/Catalog/Migrations/20200403114507_CreateSettingsTable.Designer.cs @@ -0,0 +1,925 @@ +// +using System; +using Microsoft.EntityFrameworkCore; +using Microsoft.EntityFrameworkCore.Infrastructure; +using Microsoft.EntityFrameworkCore.Migrations; +using Microsoft.EntityFrameworkCore.Storage.ValueConversion; +using Nethereum.eShop.Sqlite.Catalog; + +namespace Nethereum.eShop.Sqlite.Catalog.Migrations +{ + [DbContext(typeof(SqliteCatalogContext))] + [Migration("20200403114507_CreateSettingsTable")] + partial class CreateSettingsTable + { + protected override void BuildTargetModel(ModelBuilder modelBuilder) + { +#pragma warning disable 612, 618 + modelBuilder + .HasAnnotation("ProductVersion", "3.1.2"); + + modelBuilder.Entity("Nethereum.eShop.ApplicationCore.Entities.BasketAggregate.Basket", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("INTEGER"); + + b.Property("BuyerAddress") + .IsRequired() + .HasColumnType("TEXT") + .HasMaxLength(43); + + b.Property("BuyerId") + .IsRequired() + .HasColumnType("TEXT") + .HasMaxLength(256); + + b.Property("TransactionHash") + .HasColumnType("TEXT") + .HasMaxLength(67); + + b.HasKey("Id"); + + b.HasIndex("BuyerAddress"); + + b.HasIndex("BuyerId"); + + b.ToTable("Baskets"); + }); + + modelBuilder.Entity("Nethereum.eShop.ApplicationCore.Entities.BasketAggregate.BasketItem", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("INTEGER"); + + b.Property("BasketId") + .HasColumnType("INTEGER"); + + b.Property("CatalogItemId") + .HasColumnType("INTEGER"); + + b.Property("Quantity") + .HasColumnType("INTEGER"); + + b.Property("UnitPrice") + .HasColumnType("decimal(18,2)"); + + b.HasKey("Id"); + + b.HasIndex("BasketId"); + + b.ToTable("BasketItems"); + }); + + modelBuilder.Entity("Nethereum.eShop.ApplicationCore.Entities.BuyerAggregate.Buyer", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("INTEGER"); + + b.Property("BuyerAddress") + .HasColumnType("TEXT") + .HasMaxLength(43); + + b.Property("BuyerId") + .IsRequired() + .HasColumnType("TEXT") + .HasMaxLength(256); + + b.Property("BuyerWalletAddress") + .HasColumnType("TEXT") + .HasMaxLength(43); + + b.HasKey("Id"); + + b.HasIndex("BuyerAddress") + .IsUnique(); + + b.HasIndex("BuyerId") + .IsUnique(); + + b.HasIndex("BuyerWalletAddress") + .IsUnique(); + + b.ToTable("Buyers"); + }); + + modelBuilder.Entity("Nethereum.eShop.ApplicationCore.Entities.BuyerAggregate.BuyerPostalAddress", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("INTEGER"); + + b.Property("BuyerId") + .HasColumnType("INTEGER"); + + b.Property("Name") + .HasColumnType("TEXT"); + + b.HasKey("Id"); + + b.HasIndex("BuyerId"); + + b.ToTable("BuyerPostalAddress"); + }); + + modelBuilder.Entity("Nethereum.eShop.ApplicationCore.Entities.CatalogBrand", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("INTEGER"); + + b.Property("Brand") + .IsRequired() + .HasColumnType("TEXT") + .HasMaxLength(100); + + b.HasKey("Id"); + + b.ToTable("CatalogBrands"); + }); + + modelBuilder.Entity("Nethereum.eShop.ApplicationCore.Entities.CatalogItem", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("INTEGER"); + + b.Property("AttributeJson") + .HasColumnType("TEXT"); + + b.Property("CatalogBrandId") + .HasColumnType("INTEGER"); + + b.Property("CatalogTypeId") + .HasColumnType("INTEGER"); + + b.Property("Depth") + .HasColumnType("INTEGER"); + + b.Property("Description") + .HasColumnType("TEXT"); + + b.Property("Gtin") + .IsRequired() + .HasColumnType("TEXT") + .HasMaxLength(14); + + b.Property("GtinRegistryId") + .HasColumnType("INTEGER"); + + b.Property("Height") + .HasColumnType("INTEGER"); + + b.Property("Name") + .IsRequired() + .HasColumnType("TEXT") + .HasMaxLength(50); + + b.Property("PictureLargeUri") + .HasColumnType("TEXT") + .HasMaxLength(512); + + b.Property("PictureMediumUri") + .HasColumnType("TEXT") + .HasMaxLength(512); + + b.Property("PictureSmallUri") + .HasColumnType("TEXT") + .HasMaxLength(512); + + b.Property("PictureUri") + .HasColumnType("TEXT") + .HasMaxLength(512); + + b.Property("Price") + .HasColumnType("decimal(18,2)"); + + b.Property("Rank") + .HasColumnType("INTEGER"); + + b.Property("Status") + .HasColumnType("INTEGER"); + + b.Property("Unit") + .HasColumnType("TEXT") + .HasMaxLength(8); + + b.Property("Weight") + .HasColumnType("INTEGER"); + + b.Property("Width") + .HasColumnType("INTEGER"); + + b.HasKey("Id"); + + b.HasIndex("CatalogBrandId"); + + b.HasIndex("CatalogTypeId"); + + b.ToTable("Catalog"); + }); + + modelBuilder.Entity("Nethereum.eShop.ApplicationCore.Entities.CatalogType", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("INTEGER"); + + b.Property("Type") + .IsRequired() + .HasColumnType("TEXT") + .HasMaxLength(100); + + b.HasKey("Id"); + + b.ToTable("CatalogTypes"); + }); + + modelBuilder.Entity("Nethereum.eShop.ApplicationCore.Entities.ConfigurationAggregate.Setting", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("INTEGER"); + + b.Property("Key") + .HasColumnType("TEXT") + .HasMaxLength(100); + + b.Property("Value") + .HasColumnType("TEXT"); + + b.HasKey("Id"); + + b.HasIndex("Key"); + + b.ToTable("Settings"); + }); + + modelBuilder.Entity("Nethereum.eShop.ApplicationCore.Entities.OrderAggregate.Order", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("INTEGER"); + + b.Property("BuyerId") + .IsRequired() + .HasColumnType("TEXT") + .HasMaxLength(256); + + b.Property("BuyerWalletAddress") + .HasColumnType("TEXT") + .HasMaxLength(43); + + b.Property("CurrencyAddress") + .HasColumnType("TEXT") + .HasMaxLength(43); + + b.Property("CurrencySymbol") + .HasColumnType("TEXT") + .HasMaxLength(32); + + b.Property("OrderDate") + .HasColumnType("TEXT"); + + b.Property("PoDate") + .HasColumnType("TEXT"); + + b.Property("PoNumber") + .HasColumnType("INTEGER"); + + b.Property("PoType") + .HasColumnType("INTEGER"); + + b.Property("QuoteId") + .HasColumnType("INTEGER"); + + b.Property("SellerId") + .HasColumnType("TEXT") + .HasMaxLength(32); + + b.Property("Status") + .HasColumnType("INTEGER"); + + b.Property("TransactionHash") + .HasColumnType("TEXT") + .HasMaxLength(67); + + b.HasKey("Id"); + + b.HasIndex("BuyerId"); + + b.ToTable("Orders"); + }); + + modelBuilder.Entity("Nethereum.eShop.ApplicationCore.Entities.OrderAggregate.OrderItem", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("INTEGER"); + + b.Property("ActualEscrowReleaseDate") + .HasColumnType("TEXT"); + + b.Property("CurrencyValue") + .HasColumnType("TEXT") + .HasMaxLength(100); + + b.Property("GoodsIssueDate") + .HasColumnType("TEXT"); + + b.Property("IsEscrowReleased") + .HasColumnType("INTEGER"); + + b.Property("OrderId") + .HasColumnType("INTEGER"); + + b.Property("PlannedEscrowReleaseDate") + .HasColumnType("TEXT"); + + b.Property("PoItemNumber") + .HasColumnType("INTEGER"); + + b.Property("PoItemStatus") + .HasColumnType("INTEGER"); + + b.Property("Quantity") + .HasColumnType("INTEGER"); + + b.Property("QuantityAddress") + .HasColumnType("TEXT") + .HasMaxLength(43); + + b.Property("QuantitySymbol") + .HasColumnType("TEXT") + .HasMaxLength(32); + + b.Property("Status") + .HasColumnType("INTEGER"); + + b.Property("Unit") + .HasColumnType("TEXT") + .HasMaxLength(50); + + b.Property("UnitPrice") + .HasColumnType("decimal(18,2)"); + + b.HasKey("Id"); + + b.HasIndex("OrderId"); + + b.ToTable("OrderItems"); + }); + + modelBuilder.Entity("Nethereum.eShop.ApplicationCore.Entities.QuoteAggregate.Quote", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("INTEGER"); + + b.Property("ApproverAddress") + .HasColumnType("TEXT") + .HasMaxLength(43); + + b.Property("BuyerAddress") + .HasColumnType("TEXT") + .HasMaxLength(43); + + b.Property("BuyerId") + .IsRequired() + .HasColumnType("TEXT") + .HasMaxLength(256); + + b.Property("BuyerWalletAddress") + .HasColumnType("TEXT") + .HasMaxLength(43); + + b.Property("CurrencyAddress") + .HasColumnType("TEXT") + .HasMaxLength(43); + + b.Property("CurrencySymbol") + .HasColumnType("TEXT") + .HasMaxLength(32); + + b.Property("Date") + .HasColumnType("TEXT"); + + b.Property("Expiry") + .HasColumnType("TEXT"); + + b.Property("PoNumber") + .HasColumnType("INTEGER"); + + b.Property("PoType") + .HasColumnType("INTEGER"); + + b.Property("SellerId") + .HasColumnType("TEXT") + .HasMaxLength(32); + + b.Property("Status") + .HasColumnType("INTEGER"); + + b.Property("TransactionHash") + .HasColumnType("TEXT") + .HasMaxLength(67); + + b.HasKey("Id"); + + b.HasIndex("BuyerAddress"); + + b.HasIndex("BuyerId"); + + b.ToTable("Quotes"); + }); + + modelBuilder.Entity("Nethereum.eShop.ApplicationCore.Entities.QuoteAggregate.QuoteItem", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("INTEGER"); + + b.Property("CurrencyValue") + .HasColumnType("TEXT"); + + b.Property("EscrowReleaseDate") + .HasColumnType("TEXT"); + + b.Property("PoItemNumber") + .HasColumnType("INTEGER"); + + b.Property("Quantity") + .HasColumnType("INTEGER"); + + b.Property("QuantityAddress") + .HasColumnType("TEXT"); + + b.Property("QuantitySymbol") + .HasColumnType("TEXT"); + + b.Property("QuoteId") + .HasColumnType("INTEGER"); + + b.Property("Unit") + .HasColumnType("TEXT"); + + b.Property("UnitPrice") + .HasColumnType("decimal(18,2)"); + + b.HasKey("Id"); + + b.HasIndex("QuoteId"); + + b.ToTable("QuoteItems"); + }); + + modelBuilder.Entity("Nethereum.eShop.ApplicationCore.Entities.StockItem", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("INTEGER"); + + b.Property("CatalogItemId") + .HasColumnType("INTEGER"); + + b.Property("Location") + .IsRequired() + .HasColumnType("TEXT") + .HasMaxLength(50); + + b.Property("Quantity") + .HasColumnType("INTEGER"); + + b.HasKey("Id"); + + b.HasIndex("CatalogItemId"); + + b.ToTable("Stock"); + }); + + modelBuilder.Entity("Nethereum.eShop.ApplicationCore.Entities.BasketAggregate.Basket", b => + { + b.OwnsOne("Nethereum.eShop.ApplicationCore.Entities.PostalAddress", "BillTo", b1 => + { + b1.Property("BasketId") + .HasColumnType("INTEGER"); + + b1.Property("City") + .IsRequired() + .HasColumnType("TEXT") + .HasMaxLength(100); + + b1.Property("Country") + .IsRequired() + .HasColumnType("TEXT") + .HasMaxLength(90); + + b1.Property("RecipientName") + .IsRequired() + .HasColumnType("TEXT") + .HasMaxLength(255); + + b1.Property("State") + .HasColumnType("TEXT") + .HasMaxLength(60); + + b1.Property("Street") + .IsRequired() + .HasColumnType("TEXT") + .HasMaxLength(180); + + b1.Property("ZipCode") + .IsRequired() + .HasColumnType("TEXT") + .HasMaxLength(18); + + b1.HasKey("BasketId"); + + b1.ToTable("Baskets"); + + b1.WithOwner() + .HasForeignKey("BasketId"); + }); + + b.OwnsOne("Nethereum.eShop.ApplicationCore.Entities.PostalAddress", "ShipTo", b1 => + { + b1.Property("BasketId") + .HasColumnType("INTEGER"); + + b1.Property("City") + .IsRequired() + .HasColumnType("TEXT") + .HasMaxLength(100); + + b1.Property("Country") + .IsRequired() + .HasColumnType("TEXT") + .HasMaxLength(90); + + b1.Property("RecipientName") + .IsRequired() + .HasColumnType("TEXT") + .HasMaxLength(255); + + b1.Property("State") + .HasColumnType("TEXT") + .HasMaxLength(60); + + b1.Property("Street") + .IsRequired() + .HasColumnType("TEXT") + .HasMaxLength(180); + + b1.Property("ZipCode") + .IsRequired() + .HasColumnType("TEXT") + .HasMaxLength(18); + + b1.HasKey("BasketId"); + + b1.ToTable("Baskets"); + + b1.WithOwner() + .HasForeignKey("BasketId"); + }); + }); + + modelBuilder.Entity("Nethereum.eShop.ApplicationCore.Entities.BasketAggregate.BasketItem", b => + { + b.HasOne("Nethereum.eShop.ApplicationCore.Entities.BasketAggregate.Basket", null) + .WithMany("Items") + .HasForeignKey("BasketId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + }); + + modelBuilder.Entity("Nethereum.eShop.ApplicationCore.Entities.BuyerAggregate.BuyerPostalAddress", b => + { + b.HasOne("Nethereum.eShop.ApplicationCore.Entities.BuyerAggregate.Buyer", null) + .WithMany("PostalAddresses") + .HasForeignKey("BuyerId"); + + b.OwnsOne("Nethereum.eShop.ApplicationCore.Entities.PostalAddress", "PostalAddress", b1 => + { + b1.Property("BuyerPostalAddressId") + .HasColumnType("INTEGER"); + + b1.Property("City") + .IsRequired() + .HasColumnType("TEXT") + .HasMaxLength(100); + + b1.Property("Country") + .IsRequired() + .HasColumnType("TEXT") + .HasMaxLength(90); + + b1.Property("RecipientName") + .IsRequired() + .HasColumnType("TEXT") + .HasMaxLength(255); + + b1.Property("State") + .HasColumnType("TEXT") + .HasMaxLength(60); + + b1.Property("Street") + .IsRequired() + .HasColumnType("TEXT") + .HasMaxLength(180); + + b1.Property("ZipCode") + .IsRequired() + .HasColumnType("TEXT") + .HasMaxLength(18); + + b1.HasKey("BuyerPostalAddressId"); + + b1.ToTable("BuyerPostalAddress"); + + b1.WithOwner() + .HasForeignKey("BuyerPostalAddressId"); + }); + }); + + modelBuilder.Entity("Nethereum.eShop.ApplicationCore.Entities.CatalogItem", b => + { + b.HasOne("Nethereum.eShop.ApplicationCore.Entities.CatalogBrand", "CatalogBrand") + .WithMany() + .HasForeignKey("CatalogBrandId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.HasOne("Nethereum.eShop.ApplicationCore.Entities.CatalogType", "CatalogType") + .WithMany() + .HasForeignKey("CatalogTypeId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + }); + + modelBuilder.Entity("Nethereum.eShop.ApplicationCore.Entities.OrderAggregate.Order", b => + { + b.OwnsOne("Nethereum.eShop.ApplicationCore.Entities.PostalAddress", "BillTo", b1 => + { + b1.Property("OrderId") + .HasColumnType("INTEGER"); + + b1.Property("City") + .IsRequired() + .HasColumnType("TEXT") + .HasMaxLength(100); + + b1.Property("Country") + .IsRequired() + .HasColumnType("TEXT") + .HasMaxLength(90); + + b1.Property("RecipientName") + .IsRequired() + .HasColumnType("TEXT") + .HasMaxLength(255); + + b1.Property("State") + .HasColumnType("TEXT") + .HasMaxLength(60); + + b1.Property("Street") + .IsRequired() + .HasColumnType("TEXT") + .HasMaxLength(180); + + b1.Property("ZipCode") + .IsRequired() + .HasColumnType("TEXT") + .HasMaxLength(18); + + b1.HasKey("OrderId"); + + b1.ToTable("Orders"); + + b1.WithOwner() + .HasForeignKey("OrderId"); + }); + + b.OwnsOne("Nethereum.eShop.ApplicationCore.Entities.PostalAddress", "ShipTo", b1 => + { + b1.Property("OrderId") + .HasColumnType("INTEGER"); + + b1.Property("City") + .IsRequired() + .HasColumnType("TEXT") + .HasMaxLength(100); + + b1.Property("Country") + .IsRequired() + .HasColumnType("TEXT") + .HasMaxLength(90); + + b1.Property("RecipientName") + .IsRequired() + .HasColumnType("TEXT") + .HasMaxLength(255); + + b1.Property("State") + .HasColumnType("TEXT") + .HasMaxLength(60); + + b1.Property("Street") + .IsRequired() + .HasColumnType("TEXT") + .HasMaxLength(180); + + b1.Property("ZipCode") + .IsRequired() + .HasColumnType("TEXT") + .HasMaxLength(18); + + b1.HasKey("OrderId"); + + b1.ToTable("Orders"); + + b1.WithOwner() + .HasForeignKey("OrderId"); + }); + }); + + modelBuilder.Entity("Nethereum.eShop.ApplicationCore.Entities.OrderAggregate.OrderItem", b => + { + b.HasOne("Nethereum.eShop.ApplicationCore.Entities.OrderAggregate.Order", null) + .WithMany("OrderItems") + .HasForeignKey("OrderId"); + + b.OwnsOne("Nethereum.eShop.ApplicationCore.Entities.CatalogItemExcerpt", "ItemOrdered", b1 => + { + b1.Property("OrderItemId") + .HasColumnType("INTEGER"); + + b1.Property("CatalogItemId") + .HasColumnType("INTEGER"); + + b1.Property("Gtin") + .HasColumnType("TEXT") + .HasMaxLength(14); + + b1.Property("GtinRegistryId") + .HasColumnType("INTEGER"); + + b1.Property("PictureUri") + .HasColumnType("TEXT") + .HasMaxLength(512); + + b1.Property("ProductName") + .IsRequired() + .HasColumnType("TEXT") + .HasMaxLength(50); + + b1.HasKey("OrderItemId"); + + b1.ToTable("OrderItems"); + + b1.WithOwner() + .HasForeignKey("OrderItemId"); + }); + }); + + modelBuilder.Entity("Nethereum.eShop.ApplicationCore.Entities.QuoteAggregate.Quote", b => + { + b.OwnsOne("Nethereum.eShop.ApplicationCore.Entities.PostalAddress", "BillTo", b1 => + { + b1.Property("QuoteId") + .HasColumnType("INTEGER"); + + b1.Property("City") + .IsRequired() + .HasColumnType("TEXT") + .HasMaxLength(100); + + b1.Property("Country") + .IsRequired() + .HasColumnType("TEXT") + .HasMaxLength(90); + + b1.Property("RecipientName") + .IsRequired() + .HasColumnType("TEXT") + .HasMaxLength(255); + + b1.Property("State") + .HasColumnType("TEXT") + .HasMaxLength(60); + + b1.Property("Street") + .IsRequired() + .HasColumnType("TEXT") + .HasMaxLength(180); + + b1.Property("ZipCode") + .IsRequired() + .HasColumnType("TEXT") + .HasMaxLength(18); + + b1.HasKey("QuoteId"); + + b1.ToTable("Quotes"); + + b1.WithOwner() + .HasForeignKey("QuoteId"); + }); + + b.OwnsOne("Nethereum.eShop.ApplicationCore.Entities.PostalAddress", "ShipTo", b1 => + { + b1.Property("QuoteId") + .HasColumnType("INTEGER"); + + b1.Property("City") + .IsRequired() + .HasColumnType("TEXT") + .HasMaxLength(100); + + b1.Property("Country") + .IsRequired() + .HasColumnType("TEXT") + .HasMaxLength(90); + + b1.Property("RecipientName") + .IsRequired() + .HasColumnType("TEXT") + .HasMaxLength(255); + + b1.Property("State") + .HasColumnType("TEXT") + .HasMaxLength(60); + + b1.Property("Street") + .IsRequired() + .HasColumnType("TEXT") + .HasMaxLength(180); + + b1.Property("ZipCode") + .IsRequired() + .HasColumnType("TEXT") + .HasMaxLength(18); + + b1.HasKey("QuoteId"); + + b1.ToTable("Quotes"); + + b1.WithOwner() + .HasForeignKey("QuoteId"); + }); + }); + + modelBuilder.Entity("Nethereum.eShop.ApplicationCore.Entities.QuoteAggregate.QuoteItem", b => + { + b.HasOne("Nethereum.eShop.ApplicationCore.Entities.QuoteAggregate.Quote", null) + .WithMany("QuoteItems") + .HasForeignKey("QuoteId"); + + b.OwnsOne("Nethereum.eShop.ApplicationCore.Entities.CatalogItemExcerpt", "ItemOrdered", b1 => + { + b1.Property("QuoteItemId") + .HasColumnType("INTEGER"); + + b1.Property("CatalogItemId") + .HasColumnType("INTEGER"); + + b1.Property("Gtin") + .HasColumnType("TEXT") + .HasMaxLength(14); + + b1.Property("GtinRegistryId") + .HasColumnType("INTEGER"); + + b1.Property("PictureUri") + .HasColumnType("TEXT") + .HasMaxLength(512); + + b1.Property("ProductName") + .IsRequired() + .HasColumnType("TEXT") + .HasMaxLength(50); + + b1.HasKey("QuoteItemId"); + + b1.ToTable("QuoteItems"); + + b1.WithOwner() + .HasForeignKey("QuoteItemId"); + }); + }); + + modelBuilder.Entity("Nethereum.eShop.ApplicationCore.Entities.StockItem", b => + { + b.HasOne("Nethereum.eShop.ApplicationCore.Entities.CatalogItem", "CatalogItem") + .WithMany() + .HasForeignKey("CatalogItemId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + }); +#pragma warning restore 612, 618 + } + } +} diff --git a/src/Nethereum.eShop.Sqlite/Catalog/Migrations/20200403114507_CreateSettingsTable.cs b/src/Nethereum.eShop.Sqlite/Catalog/Migrations/20200403114507_CreateSettingsTable.cs new file mode 100644 index 0000000..4cb9a78 --- /dev/null +++ b/src/Nethereum.eShop.Sqlite/Catalog/Migrations/20200403114507_CreateSettingsTable.cs @@ -0,0 +1,35 @@ +using Microsoft.EntityFrameworkCore.Migrations; + +namespace Nethereum.eShop.Sqlite.Catalog.Migrations +{ + public partial class CreateSettingsTable : Migration + { + protected override void Up(MigrationBuilder migrationBuilder) + { + migrationBuilder.CreateTable( + name: "Settings", + columns: table => new + { + Id = table.Column(nullable: false) + .Annotation("Sqlite:Autoincrement", true), + Key = table.Column(maxLength: 100, nullable: true), + Value = table.Column(nullable: true) + }, + constraints: table => + { + table.PrimaryKey("PK_Settings", x => x.Id); + }); + + migrationBuilder.CreateIndex( + name: "IX_Settings_Key", + table: "Settings", + column: "Key"); + } + + protected override void Down(MigrationBuilder migrationBuilder) + { + migrationBuilder.DropTable( + name: "Settings"); + } + } +} diff --git a/src/Nethereum.eShop.Sqlite/Catalog/Migrations/Scripts/CreateCatalogDb.sql b/src/Nethereum.eShop.Sqlite/Catalog/Migrations/Scripts/CreateCatalogDb.sql index a5fabe9..9027aa1 100644 --- a/src/Nethereum.eShop.Sqlite/Catalog/Migrations/Scripts/CreateCatalogDb.sql +++ b/src/Nethereum.eShop.Sqlite/Catalog/Migrations/Scripts/CreateCatalogDb.sql @@ -278,3 +278,14 @@ PRAGMA foreign_keys="1" INSERT INTO "__EFMigrationsHistory" ("MigrationId", "ProductVersion") VALUES ('20200331114826_RemoveBuyerAndWalletAddress', '3.1.2'); +CREATE TABLE "Settings" ( + "Id" INTEGER NOT NULL CONSTRAINT "PK_Settings" PRIMARY KEY AUTOINCREMENT, + "Key" TEXT NULL, + "Value" TEXT NULL +); + +CREATE INDEX "IX_Settings_Key" ON "Settings" ("Key"); + +INSERT INTO "__EFMigrationsHistory" ("MigrationId", "ProductVersion") +VALUES ('20200403114507_CreateSettingsTable', '3.1.2'); + diff --git a/src/Nethereum.eShop.Sqlite/Catalog/Migrations/SqliteCatalogContextModelSnapshot.cs b/src/Nethereum.eShop.Sqlite/Catalog/Migrations/SqliteCatalogContextModelSnapshot.cs index dbfa381..e3bf27f 100644 --- a/src/Nethereum.eShop.Sqlite/Catalog/Migrations/SqliteCatalogContextModelSnapshot.cs +++ b/src/Nethereum.eShop.Sqlite/Catalog/Migrations/SqliteCatalogContextModelSnapshot.cs @@ -235,6 +235,26 @@ protected override void BuildModel(ModelBuilder modelBuilder) b.ToTable("CatalogTypes"); }); + modelBuilder.Entity("Nethereum.eShop.ApplicationCore.Entities.ConfigurationAggregate.Setting", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("INTEGER"); + + b.Property("Key") + .HasColumnType("TEXT") + .HasMaxLength(100); + + b.Property("Value") + .HasColumnType("TEXT"); + + b.HasKey("Id"); + + b.HasIndex("Key"); + + b.ToTable("Settings"); + }); + modelBuilder.Entity("Nethereum.eShop.ApplicationCore.Entities.OrderAggregate.Order", b => { b.Property("Id") diff --git a/src/Nethereum.eShop/ApplicationCore/Entities/ConfigurationAggregate/Setting.cs b/src/Nethereum.eShop/ApplicationCore/Entities/ConfigurationAggregate/Setting.cs new file mode 100644 index 0000000..5c6ca23 --- /dev/null +++ b/src/Nethereum.eShop/ApplicationCore/Entities/ConfigurationAggregate/Setting.cs @@ -0,0 +1,27 @@ +using Nethereum.eShop.ApplicationCore.Interfaces; + +namespace Nethereum.eShop.ApplicationCore.Entities.ConfigurationAggregate +{ + + public class Setting : BaseEntity, IAggregateRoot + { + public Setting(string key, string val) + { + Key = key; + Value = val; + } + + private Setting() + { + // for EF + } + + public string Key { get; private set; } + public string Value { get; private set; } + + public void SetValue(string val) + { + Value = val; + } + } +} diff --git a/src/Nethereum.eShop/ApplicationCore/Entities/ConfigurationAggregate/ValueObjects/ConfigurationSettings.cs b/src/Nethereum.eShop/ApplicationCore/Entities/ConfigurationAggregate/ValueObjects/ConfigurationSettings.cs new file mode 100644 index 0000000..8b5826a --- /dev/null +++ b/src/Nethereum.eShop/ApplicationCore/Entities/ConfigurationAggregate/ValueObjects/ConfigurationSettings.cs @@ -0,0 +1,87 @@ +using System.Collections.Generic; + +namespace Nethereum.eShop.ApplicationCore.Entities.ConfigurationAggregate +{ + public class EShopConfigurationSettings + { + public static class Keys + { + public const string PREFIX = ""; + private static string PrefixedKey(string key) => $"{PREFIX}{key}"; + + public static readonly string BuyerWalletAddress = PrefixedKey("BuyerWalletAddress"); + public static readonly string PurchasingContractAddress = PrefixedKey("PurchasingContractAddress"); + public static readonly string CurrencySymbol = PrefixedKey("CurrencySymbol"); + public static readonly string CurrencyAddress = PrefixedKey("CurrencyAddress"); + public static readonly string QuantityAddress = PrefixedKey("QuantityAddress"); + + public static readonly string AddressRegistryAddress = PrefixedKey("AddressRegistryAddress"); + public static readonly string PoStorageAddress = PrefixedKey("PoStorageAddress"); + public static readonly string FundingAddress = PrefixedKey("FundingAddress"); + public static readonly string BusinessPartnerStorageAddress = PrefixedKey("BusinessPartnerStorageAddress"); + public static readonly string SellerAdminAddress = PrefixedKey("SellerAdminAddress"); + } + + public EShopConfigurationSettings(IEnumerable settings) + { + EShop = new EShopConfiguration(settings); + Seller = new SellerConfiguration(settings); + CreateFakePurchaseOrdersJob = new CreateFakePurchaseOrdersJobConfiguration(settings); + ProcessPurchaseOrderEvents = new ProcessPurchaseOrderEventsJobConfiguration(settings); + + BuyerWalletAddress = settings.GetString(Keys.BuyerWalletAddress); + PurchasingContractAddress = settings.GetString(Keys.PurchasingContractAddress); + CurrencySymbol = settings.GetString(Keys.CurrencySymbol); + CurrencyAddress = settings.GetString(Keys.CurrencyAddress); + + AddressRegistryAddress = settings.GetString(Keys.AddressRegistryAddress); + PoStorageAddress = settings.GetString(Keys.PoStorageAddress); + FundingAddress = settings.GetString(Keys.FundingAddress); + BusinessPartnerStorageAddress = settings.GetString(Keys.BusinessPartnerStorageAddress); + SellerAdminAddress = settings.GetString(Keys.SellerAdminAddress); + + } + + public void UpdateSettings(List settings) + { + settings.SetOrCreateString(Keys.BuyerWalletAddress, BuyerWalletAddress); + settings.SetOrCreateString(Keys.PurchasingContractAddress, PurchasingContractAddress); + settings.SetOrCreateString(Keys.CurrencySymbol, CurrencySymbol); + settings.SetOrCreateString(Keys.CurrencyAddress, CurrencyAddress); + + settings.SetOrCreateString(Keys.AddressRegistryAddress, AddressRegistryAddress); + settings.SetOrCreateString(Keys.PoStorageAddress, PoStorageAddress); + settings.SetOrCreateString(Keys.FundingAddress, FundingAddress); + settings.SetOrCreateString(Keys.BusinessPartnerStorageAddress, BusinessPartnerStorageAddress); + settings.SetOrCreateString(Keys.SellerAdminAddress, SellerAdminAddress); + + EShop.UpdateSettings(settings); + Seller.UpdateSettings(settings); + CreateFakePurchaseOrdersJob.UpdateSettings(settings); + ProcessPurchaseOrderEvents.UpdateSettings(settings); + } + + public EShopConfiguration EShop { get; set; } + + public SellerConfiguration Seller { get; set; } + + public CreateFakePurchaseOrdersJobConfiguration CreateFakePurchaseOrdersJob { get; set; } + + public ProcessPurchaseOrderEventsJobConfiguration ProcessPurchaseOrderEvents { get; set; } + + public string BuyerWalletAddress { get; set; } + public string PurchasingContractAddress { get; set; } + public string CurrencySymbol { get; set; } + public string CurrencyAddress { get; set; } + + public string PoStorageAddress { get; set; } + + public string FundingAddress { get; set; } + + public string AddressRegistryAddress { get; set; } + + public string BusinessPartnerStorageAddress { get; set; } + + public string SellerAdminAddress { get; set; } + } +} diff --git a/src/Nethereum.eShop/ApplicationCore/Entities/ConfigurationAggregate/ValueObjects/CreateFakePurchaseOrdersJobConfiguration.cs b/src/Nethereum.eShop/ApplicationCore/Entities/ConfigurationAggregate/ValueObjects/CreateFakePurchaseOrdersJobConfiguration.cs new file mode 100644 index 0000000..a557d99 --- /dev/null +++ b/src/Nethereum.eShop/ApplicationCore/Entities/ConfigurationAggregate/ValueObjects/CreateFakePurchaseOrdersJobConfiguration.cs @@ -0,0 +1,20 @@ +using System; +using System.Collections.Generic; + +namespace Nethereum.eShop.ApplicationCore.Entities.ConfigurationAggregate +{ + public class CreateFakePurchaseOrdersJobConfiguration // Value Object + { + public CreateFakePurchaseOrdersJobConfiguration(IEnumerable settings) + { + Enabled = settings.GetBool("CreateFakePurchaseOrdersJob.Enabled", false); + } + + public bool Enabled { get; set; } + + public void UpdateSettings(List settings) + { + settings.SetOrCreateBool("CreateFakePurchaseOrdersJob.Enabled", Enabled); + } + } +} diff --git a/src/Nethereum.eShop/ApplicationCore/Entities/ConfigurationAggregate/ValueObjects/EShopConfiguration.cs b/src/Nethereum.eShop/ApplicationCore/Entities/ConfigurationAggregate/ValueObjects/EShopConfiguration.cs new file mode 100644 index 0000000..b63d22c --- /dev/null +++ b/src/Nethereum.eShop/ApplicationCore/Entities/ConfigurationAggregate/ValueObjects/EShopConfiguration.cs @@ -0,0 +1,36 @@ +using System; +using System.Collections.Generic; + +namespace Nethereum.eShop.ApplicationCore.Entities.ConfigurationAggregate +{ + public class EShopConfiguration // Value Object + { + public static class Keys + { + public const string PREFIX = "EShop"; + private static string PrefixedKey(string key) => $"{PREFIX}.{key}"; + + public static readonly string Id = PrefixedKey("Id"); + public static readonly string Description = PrefixedKey("Description"); + public static readonly string QuoteSigners = PrefixedKey("QuoteSigners"); + } + + public EShopConfiguration(IEnumerable settings) + { + Id = settings.GetString(Keys.Id); + Description = settings.GetString(Keys.Description); + QuoteSigners = settings.GetStringArray(Keys.QuoteSigners, Array.Empty()); + } + + public string Id { get; set; } + public string Description { get; set; } + public string[] QuoteSigners { get; set; } + + internal void UpdateSettings(List settings) + { + settings.SetOrCreateString(Keys.Id, Id); + settings.SetOrCreateString(Keys.Description, Description); + settings.SetOrCreateStringArray(Keys.QuoteSigners, QuoteSigners); + } + } +} diff --git a/src/Nethereum.eShop/ApplicationCore/Entities/ConfigurationAggregate/ValueObjects/ProcessPurchaseOrderEventsJobConfiguration.cs b/src/Nethereum.eShop/ApplicationCore/Entities/ConfigurationAggregate/ValueObjects/ProcessPurchaseOrderEventsJobConfiguration.cs new file mode 100644 index 0000000..0bc051e --- /dev/null +++ b/src/Nethereum.eShop/ApplicationCore/Entities/ConfigurationAggregate/ValueObjects/ProcessPurchaseOrderEventsJobConfiguration.cs @@ -0,0 +1,55 @@ +using System.Collections.Generic; +using System.Numerics; + +namespace Nethereum.eShop.ApplicationCore.Entities.ConfigurationAggregate +{ + public class ProcessPurchaseOrderEventsJobConfiguration // Value Object + { + public static class Keys + { + public const string PREFIX = "ProcessPurchaseOrderEventsJob"; + private static string PrefixedKey(string key) => $"{PREFIX}.{key}"; + + public static readonly string Enabled = PrefixedKey("Enabled"); + public static readonly string BlockProgressJsonFile = PrefixedKey("BlockProgressJsonFile"); + public static readonly string MinimumStartingBlock = PrefixedKey("MinimumStartingBlock"); + public static readonly string NumberOfBlocksPerBatch = PrefixedKey("NumberOfBlocksPerBatch"); + public static readonly string MinimumBlockConfirmations = PrefixedKey("MinimumBlockConfirmations"); + public static readonly string TimeoutMs = PrefixedKey("TimeoutMs"); + } + + public ProcessPurchaseOrderEventsJobConfiguration(IEnumerable settings) + { + Load(settings); + } + + private void Load(IEnumerable settings) + { + Enabled = settings.GetBool(Keys.Enabled, false); + BlockProgressJsonFile = settings.GetString(Keys.BlockProgressJsonFile); + MinimumStartingBlock = settings.GetBigIntegerOrNull(Keys.MinimumStartingBlock); + NumberOfBlocksPerBatch = settings.GetInt(Keys.NumberOfBlocksPerBatch); + MinimumBlockConfirmations = settings.GetInt(Keys.MinimumBlockConfirmations); + TimeoutMs = settings.GetInt(Keys.TimeoutMs); + } + + public void UpdateSettings(List settings) + { + settings.SetOrCreateBool(Keys.Enabled, Enabled); + settings.SetOrCreateString(Keys.BlockProgressJsonFile, BlockProgressJsonFile); + settings.SetOrCreateNullableBigInteger(Keys.MinimumStartingBlock, MinimumStartingBlock); + settings.SetOrCreateInt(Keys.NumberOfBlocksPerBatch, NumberOfBlocksPerBatch); + settings.SetOrCreateInt(Keys.MinimumBlockConfirmations, MinimumBlockConfirmations); + settings.SetOrCreateInt(Keys.TimeoutMs, TimeoutMs); + } + + public bool Enabled { get; set; } + public string BlockProgressJsonFile { get; set; } + public BigInteger? MinimumStartingBlock { get; set; } + public int NumberOfBlocksPerBatch { get; set; } + public int MinimumBlockConfirmations { get; set; } + public int TimeoutMs { get; set; } + + + } +} diff --git a/src/Nethereum.eShop/ApplicationCore/Entities/ConfigurationAggregate/ValueObjects/SellerConfiguration.cs b/src/Nethereum.eShop/ApplicationCore/Entities/ConfigurationAggregate/ValueObjects/SellerConfiguration.cs new file mode 100644 index 0000000..33d6eda --- /dev/null +++ b/src/Nethereum.eShop/ApplicationCore/Entities/ConfigurationAggregate/ValueObjects/SellerConfiguration.cs @@ -0,0 +1,36 @@ +using System; +using System.Collections.Generic; + +namespace Nethereum.eShop.ApplicationCore.Entities.ConfigurationAggregate +{ + public class SellerConfiguration // Value Object + { + public static class Keys + { + public const string PREFIX = "Seller"; + private static string PrefixedKey(string key) => $"{PREFIX}.{key}"; + + public static readonly string Id = PrefixedKey("Id"); + public static readonly string Description = PrefixedKey("Description"); + public static readonly string AdminContractAddress = PrefixedKey("AdminContractAddress"); + } + + public SellerConfiguration(IEnumerable settings) + { + Id = settings.GetString(Keys.Id); + Description = settings.GetString(Keys.Description); + AdminContractAddress = settings.GetString(Keys.AdminContractAddress); + } + + public void UpdateSettings(List settings) + { + settings.SetOrCreateString(Keys.Id, Id); + settings.SetOrCreateString(Keys.Description, Description); + settings.SetOrCreateString(Keys.AdminContractAddress, AdminContractAddress); + } + + public string Id { get; set; } + public string Description { get; set; } + public string AdminContractAddress { get; set; } + } +} diff --git a/src/Nethereum.eShop/ApplicationCore/Entities/ConfigurationAggregate/ValueObjects/SettingExtensions.cs b/src/Nethereum.eShop/ApplicationCore/Entities/ConfigurationAggregate/ValueObjects/SettingExtensions.cs new file mode 100644 index 0000000..4ea6c28 --- /dev/null +++ b/src/Nethereum.eShop/ApplicationCore/Entities/ConfigurationAggregate/ValueObjects/SettingExtensions.cs @@ -0,0 +1,114 @@ +using System.Collections.Generic; +using System.Linq; +using System.Numerics; + +namespace Nethereum.eShop.ApplicationCore.Entities.ConfigurationAggregate +{ + public static class SettingExtensions + { + private static Setting GetSingle(this IEnumerable settings, string key) + => settings.FirstOrDefault(s => s.Key.Equals(key, System.StringComparison.OrdinalIgnoreCase)); + + public static string GetString(this IEnumerable settings, string key, string defaultValue = null) + { + var setting = settings.GetSingle(key); + return setting?.Value ?? defaultValue; + } + + public static string[] GetStringArray(this IEnumerable settings, string key, string[] defaultValue = null) + { + var setting = settings.GetSingle(key); + return setting?.Value?.Split(new char[] { ',' }, System.StringSplitOptions.RemoveEmptyEntries) ?? defaultValue; + } + + public static int GetInt(this IEnumerable settings, string key, int defaultValue = 0) + { + var setting = settings.GetSingle(key); + if (setting == null) return defaultValue; + return int.TryParse(setting.Value, out int val) ? val : defaultValue; + } + + public static bool GetBool(this IEnumerable settings, string key, bool defaultValue = false) + { + var setting = settings.GetSingle(key); + if (setting == null) return defaultValue; + return bool.TryParse(setting.Value, out bool val) ? val : defaultValue; + } + + public static BigInteger? GetBigIntegerOrNull(this IEnumerable settings, string key) + { + var setting = settings.GetSingle(key); + if (setting == null) return null; + return BigInteger.TryParse(setting.Value, out BigInteger val) ? val : (BigInteger?)null; + } + + public static void SetOrCreateString(this List settings, string key, string val) + { + var setting = settings.GetSingle(key); + if (setting == null) + { + settings.Add(new Setting(key, val)); + } + else + { + setting.SetValue(val); + } + } + + public static void SetOrCreateStringArray(this List settings, string key, string[] val, char delimeter = ',') + { + var setting = settings.GetSingle(key); + var valueAsString = val == null ? string.Empty : string.Join(delimeter, val); + + if (setting == null) + { + settings.Add(new Setting(key, valueAsString)); + } + else + { + setting.SetValue(valueAsString); + } + } + + public static void SetOrCreateBool(this List settings, string key, bool val) + { + var setting = settings.GetSingle(key); + if (setting == null) + { + settings.Add(new Setting(key, val.ToString())); + } + else + { + setting.SetValue(val.ToString()); + } + } + + public static void SetOrCreateInt(this List settings, string key, int val) + { + var setting = settings.GetSingle(key); + if (setting == null) + { + settings.Add(new Setting(key, val.ToString())); + } + else + { + setting.SetValue(val.ToString()); + } + } + + public static void SetOrCreateNullableBigInteger(this List settings, string key, BigInteger? val) + { + var valToWrite = val == null ? null : val.ToString(); + + var setting = settings.GetSingle(key); + if (setting == null) + { + settings.Add(new Setting(key, valToWrite)); + } + else + { + setting.SetValue(valToWrite); + } + } + } +} diff --git a/src/Nethereum.eShop/ApplicationCore/Interfaces/IContractDeploymentService.cs b/src/Nethereum.eShop/ApplicationCore/Interfaces/IContractDeploymentService.cs new file mode 100644 index 0000000..7bf29d7 --- /dev/null +++ b/src/Nethereum.eShop/ApplicationCore/Interfaces/IContractDeploymentService.cs @@ -0,0 +1,11 @@ +using Microsoft.Extensions.Logging; +using System.Threading; +using System.Threading.Tasks; + +namespace Nethereum.eShop.ApplicationCore.Interfaces +{ + public interface IContractDeploymentService + { + Task EnsureDeployedAsync(ILoggerFactory loggerFactory, CancellationToken cancellationToken = default); + } +} diff --git a/src/Nethereum.eShop/ApplicationCore/Interfaces/ISettingRepository.cs b/src/Nethereum.eShop/ApplicationCore/Interfaces/ISettingRepository.cs new file mode 100644 index 0000000..e1c1ec4 --- /dev/null +++ b/src/Nethereum.eShop/ApplicationCore/Interfaces/ISettingRepository.cs @@ -0,0 +1,14 @@ +using Nethereum.eShop.ApplicationCore.Entities.ConfigurationAggregate; +using System.Threading.Tasks; + +namespace Nethereum.eShop.ApplicationCore.Interfaces +{ + + public interface ISettingRepository : IAsyncRepository, IRepository + { + Setting Add(Setting setting); + Setting Update(Setting setting); + Task GetEShopConfigurationSettingsAsync(); + Task UpdateAsync(EShopConfigurationSettings configurationSettings); + } +} diff --git a/src/Nethereum.eShop/ApplicationCore/Services/ContractDeploymentService.cs b/src/Nethereum.eShop/ApplicationCore/Services/ContractDeploymentService.cs new file mode 100644 index 0000000..ff6963f --- /dev/null +++ b/src/Nethereum.eShop/ApplicationCore/Services/ContractDeploymentService.cs @@ -0,0 +1,119 @@ +using Microsoft.Extensions.Configuration; +using Microsoft.Extensions.Logging; +using Nethereum.Commerce.Contracts.Deployment; +using Nethereum.eShop.ApplicationCore.Interfaces; +using Nethereum.Web3.Accounts; +using System.Linq; +using System.Threading; +using System.Threading.Tasks; + +namespace Nethereum.eShop.ApplicationCore.Services +{ + public class ContractDeploymentService : IContractDeploymentService + { + private readonly IConfiguration _configuration; + private readonly ISettingRepository _settingRepository; + + public ContractDeploymentService(IConfiguration configuration, ISettingRepository settingRepository) + { + _configuration = configuration; + _settingRepository = settingRepository; + } + + public async Task EnsureDeployedAsync(ILoggerFactory loggerFactory, CancellationToken cancellationToken = default) + { + var logger = loggerFactory.CreateLogger(); + + var dbBasedConfig = await _settingRepository.GetEShopConfigurationSettingsAsync().ConfigureAwait(false); + + if (string.IsNullOrWhiteSpace(dbBasedConfig.BuyerWalletAddress) == false) return; + + if (string.IsNullOrEmpty(dbBasedConfig.EShop.Id)) + { + dbBasedConfig.EShop.Id = "Nethereum.EShop"; + dbBasedConfig.EShop.Description = "Nethereum EShop"; + } + + if (string.IsNullOrEmpty(dbBasedConfig.Seller.Id)) + { + dbBasedConfig.Seller.Id = "Nethereum.EShop.Seller.1"; + dbBasedConfig.Seller.Description = "Nethereum.EShop Seller One"; + } + + if (string.IsNullOrEmpty(dbBasedConfig.CurrencySymbol)) + { + dbBasedConfig.CurrencySymbol = "DAI"; + } + + if(dbBasedConfig.EShop.QuoteSigners?.Length == 0) + { + //TODO: remove this hardcoded stuff + dbBasedConfig.EShop.QuoteSigners = new[] { "0x32A555F2328e85E489f9a5f03669DC820CE7EBe9", "0x94618601FE6cb8912b274E5a00453949A57f8C1e" }; + } + + if(dbBasedConfig.ProcessPurchaseOrderEvents.TimeoutMs < 1) + { + dbBasedConfig.ProcessPurchaseOrderEvents.TimeoutMs = 3600000; + } + + if(dbBasedConfig.ProcessPurchaseOrderEvents.NumberOfBlocksPerBatch < 1) + { + dbBasedConfig.ProcessPurchaseOrderEvents.NumberOfBlocksPerBatch = 100; + } + + if(dbBasedConfig.ProcessPurchaseOrderEvents.MinimumBlockConfirmations < 1) + { + dbBasedConfig.ProcessPurchaseOrderEvents.MinimumBlockConfirmations = 12; + } + + if (string.IsNullOrEmpty(dbBasedConfig.ProcessPurchaseOrderEvents.BlockProgressJsonFile)) + { + dbBasedConfig.ProcessPurchaseOrderEvents.BlockProgressJsonFile = "c:/temp/po_blockprogress.json"; + } + + var url = _configuration["EthereumRpcUrl"]; + var privateKey = _configuration["AccountPrivateKey"]; + + var web3 = new Web3.Web3(new Account(privateKey), url); + + var contractDeploymentConfig = new ContractNewDeploymentConfig + { + AlsoDeployMockContracts = true, + Eshop = new Commerce.Contracts.BusinessPartnerStorage.ContractDefinition.Eshop + { + EShopId = dbBasedConfig.EShop.Id, + EShopDescription = dbBasedConfig.EShop.Description, + QuoteSigners = dbBasedConfig.EShop.QuoteSigners.ToList() + }, + Seller = new Commerce.Contracts.BusinessPartnerStorage.ContractDefinition.Seller + { + SellerId = dbBasedConfig.Seller.Id, + SellerDescription = dbBasedConfig.Seller.Description, + AdminContractAddress = dbBasedConfig.Seller.AdminContractAddress + } + }; + + var contractDeployment = new ContractDeployment(web3, contractDeploymentConfig, logger); + + await contractDeployment.InitializeAsync().ConfigureAwait(false); + + dbBasedConfig.BuyerWalletAddress = contractDeployment.BuyerWalletService.ContractHandler.ContractAddress; + dbBasedConfig.PurchasingContractAddress = contractDeployment.PurchasingService.ContractHandler.ContractAddress; + dbBasedConfig.CurrencyAddress = contractDeployment.MockDaiService.ContractHandler.ContractAddress; + + dbBasedConfig.AddressRegistryAddress = contractDeployment.AddressRegistryService?.ContractHandler?.ContractAddress; + dbBasedConfig.FundingAddress = contractDeployment.FundingService?.ContractHandler?.ContractAddress; + dbBasedConfig.PoStorageAddress = contractDeployment.PoStorageService?.ContractHandler?.ContractAddress; + dbBasedConfig.BusinessPartnerStorageAddress = contractDeployment.BusinessPartnerStorageService?.ContractHandler?.ContractAddress; + dbBasedConfig.SellerAdminAddress = contractDeployment.SellerAdminService?.ContractHandler?.ContractAddress; + + // if deployment has succeeded, presume it's ok to enable web jobs + dbBasedConfig.CreateFakePurchaseOrdersJob.Enabled = true; + dbBasedConfig.ProcessPurchaseOrderEvents.Enabled = true; + + await _settingRepository.UpdateAsync(dbBasedConfig); + + await _settingRepository.UnitOfWork.SaveChangesAsync(cancellationToken).ConfigureAwait(false); + } + } +} diff --git a/src/Web/Program.cs b/src/Web/Program.cs index 64595dc..2f842ef 100644 --- a/src/Web/Program.cs +++ b/src/Web/Program.cs @@ -36,6 +36,9 @@ public async static Task Main(string[] args) var userManager = services.GetRequiredService>(); var roleManager = services.GetRequiredService>(); await AppIdentityDbContextSeed.SeedAsync(userManager, roleManager); + + var contractDeploymentService = services.GetRequiredService(); + await contractDeploymentService.EnsureDeployedAsync(loggerFactory); } catch (Exception ex) { diff --git a/src/Web/Startup.cs b/src/Web/Startup.cs index ee9f9d4..c1e5ecb 100644 --- a/src/Web/Startup.cs +++ b/src/Web/Startup.cs @@ -98,6 +98,8 @@ public void ConfigureServices( dbBootstrapper.AddSeeders(services, Configuration); + services.AddScoped(); + var rulesEngineSettings = Configuration.Get(); services.AddSingleton(new RulesEngineInitializer(rulesEngineSettings)); diff --git a/src/WebJobs/Config/EshopConfiguration.cs b/src/WebJobs/Config/EshopConfiguration.cs deleted file mode 100644 index 5cd0eab..0000000 --- a/src/WebJobs/Config/EshopConfiguration.cs +++ /dev/null @@ -1,52 +0,0 @@ -using System; -using System.Configuration; -using System.Numerics; -using Microsoft.Azure; -using Microsoft.WindowsAzure; - - -namespace Nethereum.eShop.WebJobs.Configuration -{ - - public class EshopConfiguration - { - public string EthereumRpcUrl { get; set; } - public string AccountPrivateKey { get; set; } - - public string EShopId { get; set; } - - public string SellerId { get; set; } - - public string BuyerWalletAddress { get; set; } - - public string PurchasingContractAddress { get; set; } - - public string CurrencySymbol { get; set; } - - public string CurrencyAddress { get; set; } - - public bool CreateFakePurchaseOrders { get; set; } - - public string QuantityAddress { get; set; } - - public PurchaseOrderEventLogProcessingConfiguration PurchaseOrderEventLogConfiguration { get; set; } - } - - public class PurchaseOrderEventLogProcessingConfiguration - { - public bool Enabled { get; set; } = true; - - public string BlockProgressJsonFile { get; set; } - - public string MinimumStartingBlock { get; set; } = "0"; - - public uint NumberOfBlocksPerBatch { get; set; } = 10; - - public uint MinimumBlockConfirmations { get; set; } = 12; - - public BigInteger GetMinimumStartingBlock() => BigInteger.Parse(MinimumStartingBlock); - - public int TimeoutMs { get; set; } - } - -} \ No newline at end of file diff --git a/src/WebJobs/Jobs/CreateFakePurchaseOrders.cs b/src/WebJobs/Jobs/CreateFakePurchaseOrders.cs index 1090d9e..eadc925 100644 --- a/src/WebJobs/Jobs/CreateFakePurchaseOrders.cs +++ b/src/WebJobs/Jobs/CreateFakePurchaseOrders.cs @@ -1,11 +1,12 @@ -using Microsoft.Extensions.Logging; +using Microsoft.Extensions.Configuration; +using Microsoft.Extensions.Logging; using Nethereum.Commerce.Contracts; using Nethereum.Commerce.Contracts.BuyerWallet; using Nethereum.Commerce.Contracts.Purchasing.ContractDefinition; using Nethereum.Contracts; +using Nethereum.eShop.ApplicationCore.Entities.ConfigurationAggregate; using Nethereum.eShop.ApplicationCore.Entities.QuoteAggregate; using Nethereum.eShop.ApplicationCore.Interfaces; -using Nethereum.eShop.WebJobs.Configuration; using Nethereum.Web3.Accounts; using System; using System.Collections.Generic; @@ -19,18 +20,22 @@ namespace Nethereum.eShop.WebJobs.Jobs { public class CreateFakePurchaseOrders : ICreateFakePurchaseOrders { - private readonly EshopConfiguration _config; + private readonly IConfiguration _configuration; + private readonly ISettingRepository _settingRepository; private readonly IQuoteRepository _quoteRepository; - public CreateFakePurchaseOrders(EshopConfiguration config, IQuoteRepository quoteRepository) + public CreateFakePurchaseOrders(IConfiguration configuration, ISettingRepository settingRepository, IQuoteRepository quoteRepository) { - this._config = config; + _configuration = configuration; + _settingRepository = settingRepository; this._quoteRepository = quoteRepository; } public async Task ExecuteAsync(ILogger logger) { - if (!_config.CreateFakePurchaseOrders) return; + var dbBasedConfig = await _settingRepository.GetEShopConfigurationSettingsAsync().ConfigureAwait(false); + + if (!dbBasedConfig.CreateFakePurchaseOrdersJob.Enabled) return; var pendingQuotes = await _quoteRepository.GetQuotesRequiringPurchaseOrderAsync(); @@ -38,19 +43,22 @@ public async Task ExecuteAsync(ILogger logger) if (!pendingQuotes.Any()) return; - var account = new Account(_config.AccountPrivateKey); - var web3 = new Web3.Web3(account); - var walletBuyerService = new BuyerWalletService(web3, _config.BuyerWalletAddress); + var url = _configuration["EthereumRpcUrl"]; + var privateKey = _configuration["AccountPrivateKey"]; + + var web3 = new Web3.Web3(new Account(privateKey), url); + + var walletBuyerService = new BuyerWalletService(web3, dbBasedConfig.BuyerWalletAddress); foreach (var quote in pendingQuotes) { - await CreatePoForQuote(web3, logger, walletBuyerService, quote); + await CreatePoForQuote(dbBasedConfig, web3, logger, walletBuyerService, quote); } } - private async Task CreatePoForQuote(Web3.Web3 web3, ILogger logger, BuyerWalletService walletBuyerService, Quote quote) + private async Task CreatePoForQuote(EShopConfigurationSettings dbBasedConfig, Web3.Web3 web3, ILogger logger, BuyerWalletService walletBuyerService, Quote quote) { - var existing = await walletBuyerService.GetPoByEshopIdAndQuoteQueryAsync(_config.EShopId, quote.Id); + var existing = await walletBuyerService.GetPoByEshopIdAndQuoteQueryAsync(dbBasedConfig.EShop.Id, quote.Id); if (existing?.Po?.PoNumber > 0) { quote.PoNumber = (long)existing.Po.PoNumber; @@ -60,7 +68,7 @@ private async Task CreatePoForQuote(Web3.Web3 web3, ILogger logger, BuyerWalletS return; } - var po = CreateDummyPoForPurchasingCreate(web3, quote).ToBuyerPo(); + var po = CreateDummyPoForPurchasingCreate(dbBasedConfig, web3, quote).ToBuyerPo(); var signature = po.GetSignatureBytes(web3); var poArgs = new Nethereum.Commerce.Contracts.BuyerWallet.ContractDefinition.CreatePurchaseOrderFunction { Po = po, Signature = signature }; var receipt = await walletBuyerService.CreatePurchaseOrderRequestAndWaitForReceiptAsync(poArgs); @@ -82,16 +90,16 @@ private async Task CreatePoForQuote(Web3.Web3 web3, ILogger logger, BuyerWalletS } } - public Po CreateDummyPoForPurchasingCreate(Web3.Web3 web3, Quote quote) + public Po CreateDummyPoForPurchasingCreate(EShopConfigurationSettings dbBasedConfig, Web3.Web3 web3, Quote quote) { return CreatePoForPurchasingContracts( buyerUserAddress: web3.TransactionManager.Account.Address.ToLowerInvariant(), buyerReceiverAddress: web3.TransactionManager.Account.Address.ToLowerInvariant(), - buyerWalletAddress: _config.BuyerWalletAddress.ToLowerInvariant(), - eShopId: _config.EShopId, - sellerId: _config.SellerId, - currencySymbol: _config.CurrencySymbol, - currencyAddress: _config.CurrencyAddress.ToLowerInvariant(), + buyerWalletAddress: dbBasedConfig.BuyerWalletAddress.ToLowerInvariant(), + eShopId: dbBasedConfig.EShop.Id, + sellerId: dbBasedConfig.Seller.Id, + currencySymbol: dbBasedConfig.CurrencySymbol, + currencyAddress: dbBasedConfig.CurrencyAddress.ToLowerInvariant(), quote: quote, isLargeValue: false); } @@ -129,7 +137,8 @@ public Po CreatePoForPurchasingContracts( Quantity = quoteItem.Quantity, Unit = "EA", QuantitySymbol = "NA", - QuantityAddress = _config.QuantityAddress.ToLowerInvariant(), + // TODO: remove or replace Quantity Address + QuantityAddress = "0x40ed4f49ec2c7bdcce8631b1a7b54ed5d4aa9610".ToLowerInvariant(), CurrencyValue = quoteItem.CurrencyValue == null ? 0 : BigInteger.Parse(quoteItem.CurrencyValue), // Status assigned by contract // GoodsIssuedDate assigned by contract diff --git a/src/WebJobs/Jobs/ProcessPurchaseOrderEventLogs.cs b/src/WebJobs/Jobs/ProcessPurchaseOrderEventLogs.cs index d8ee3cd..ddcd142 100644 --- a/src/WebJobs/Jobs/ProcessPurchaseOrderEventLogs.cs +++ b/src/WebJobs/Jobs/ProcessPurchaseOrderEventLogs.cs @@ -1,16 +1,14 @@ using Common.Logging; +using Microsoft.Extensions.Configuration; using Microsoft.Extensions.Logging; using Nethereum.BlockchainProcessing; using Nethereum.BlockchainProcessing.LogProcessing; using Nethereum.BlockchainProcessing.Orchestrator; using Nethereum.BlockchainProcessing.Processor; using Nethereum.BlockchainProcessing.ProgressRepositories; -using Nethereum.Commerce.Contracts.BuyerWallet; -using Nethereum.Commerce.Contracts.Purchasing; using Nethereum.Commerce.Contracts.Purchasing.ContractDefinition; using Nethereum.eShop.ApplicationCore.Exceptions; using Nethereum.eShop.ApplicationCore.Interfaces; -using Nethereum.eShop.WebJobs.Configuration; using Nethereum.Microsoft.Logging.Utils; using Nethereum.RPC.Eth.Blocks; using Nethereum.RPC.Eth.DTOs; @@ -22,26 +20,29 @@ namespace Nethereum.eShop.WebJobs.Jobs { public class ProcessPurchaseOrderEventLogs : IProcessPuchaseOrderEventLogs { - private readonly EshopConfiguration _eshopConfiguration; - private readonly PurchaseOrderEventLogProcessingConfiguration _config; + private readonly IConfiguration _configuration; + private readonly ISettingRepository _settingRepository; private readonly IOrderService _orderService; private readonly IBlockProgressRepository BlockProgressRepository = null; public ProcessPurchaseOrderEventLogs( - EshopConfiguration eshopConfiguration, + IConfiguration configuration, + ISettingRepository settingRepository, IOrderService orderService, IBlockProgressRepository blockProgressRepository ) { - _eshopConfiguration = eshopConfiguration; + _configuration = configuration; + _settingRepository = settingRepository; _orderService = orderService; - _config = eshopConfiguration.PurchaseOrderEventLogConfiguration; BlockProgressRepository = blockProgressRepository; } public async Task ExecuteAsync(ILogger logger) { - if (!_config.Enabled) + var dbConfigSettings = await _settingRepository.GetEShopConfigurationSettingsAsync(); + + if (!dbConfigSettings.ProcessPurchaseOrderEvents.Enabled) { logger.LogInformation($"{nameof(ProcessPurchaseOrderEventLogs)} is not enabled - see app settings"); return; @@ -49,8 +50,10 @@ public async Task ExecuteAsync(ILogger logger) const int RequestRetryWeight = 0; // see below for retry algorithm - var web3 = new Web3.Web3(_eshopConfiguration.EthereumRpcUrl); - var filter = new NewFilterInput { Address = new[] { _eshopConfiguration.PurchasingContractAddress } }; + var url = _configuration["EthereumRpcUrl"]; + + var web3 = new Web3.Web3(url); + var filter = new NewFilterInput { Address = new[] { dbConfigSettings.PurchasingContractAddress } }; ILog log = logger.ToILog(); @@ -64,7 +67,7 @@ public async Task ExecuteAsync(ILogger logger) ethApi: web3.Eth, logProcessors: logProcessorHandlers, filterInput: filter, - defaultNumberOfBlocksPerRequest: (int)_config.NumberOfBlocksPerBatch, + defaultNumberOfBlocksPerRequest: dbConfigSettings.ProcessPurchaseOrderEvents.NumberOfBlocksPerBatch, retryWeight: RequestRetryWeight); IWaitStrategy waitForBlockConfirmationsStrategy = new WaitStrategy(); @@ -73,18 +76,18 @@ public async Task ExecuteAsync(ILogger logger) new LastConfirmedBlockNumberService( web3.Eth.Blocks.GetBlockNumber, waitForBlockConfirmationsStrategy, - _config.MinimumBlockConfirmations, + (uint)dbConfigSettings.ProcessPurchaseOrderEvents.MinimumBlockConfirmations, log); var processor = new BlockchainProcessor( orchestrator, BlockProgressRepository, lastConfirmedBlockNumberService); - var cancellationToken = new CancellationTokenSource(_config.TimeoutMs); + var cancellationToken = new CancellationTokenSource(dbConfigSettings.ProcessPurchaseOrderEvents.TimeoutMs); var currentBlockOnChain = await web3.Eth.Blocks.GetBlockNumber.SendRequestAsync(); - var blockToProcessTo = currentBlockOnChain.Value - _config.MinimumBlockConfirmations; + var blockToProcessTo = currentBlockOnChain.Value - dbConfigSettings.ProcessPurchaseOrderEvents.MinimumBlockConfirmations; var lastBlockProcessed = await BlockProgressRepository.GetLastBlockNumberProcessedAsync(); - var minStartingBlock = _config.GetMinimumStartingBlock(); + var minStartingBlock = dbConfigSettings.ProcessPurchaseOrderEvents.MinimumStartingBlock; logger.LogInformation( $"Processing logs. To Block: {blockToProcessTo}, Last Block Processed: {lastBlockProcessed ?? 0}, Min Block: {minStartingBlock}"); diff --git a/src/WebJobs/JsonFileBlockProgressRepository.cs b/src/WebJobs/JsonFileBlockProgressRepository.cs index a3404f9..43ad1c4 100644 --- a/src/WebJobs/JsonFileBlockProgressRepository.cs +++ b/src/WebJobs/JsonFileBlockProgressRepository.cs @@ -1,24 +1,51 @@ using Nethereum.BlockchainProcessing.ProgressRepositories; -using Nethereum.eShop.WebJobs.Configuration; +using Nethereum.eShop.ApplicationCore.Interfaces; using System.IO; +using System.Numerics; using System.Threading.Tasks; namespace Nethereum.eShop.WebJobs { - public class JsonFileBlockProgressRepository: JsonBlockProgressRepository + public class JsonFileBlockProgressRepository : IBlockProgressRepository { - public JsonFileBlockProgressRepository(EshopConfiguration eshopConfiguration): - this(eshopConfiguration.PurchaseOrderEventLogConfiguration.BlockProgressJsonFile) + private readonly ISettingRepository _settingRepository; + private IBlockProgressRepository _innerRepo; + + public JsonFileBlockProgressRepository(ISettingRepository settingRepository) { + _settingRepository = settingRepository; + } + public async Task GetLastBlockNumberProcessedAsync() + { + await InitRepo(); + return await _innerRepo.GetLastBlockNumberProcessedAsync().ConfigureAwait(false); + } + public async Task UpsertProgressAsync(BigInteger blockNumber) + { + await InitRepo(); + await _innerRepo.UpsertProgressAsync(blockNumber).ConfigureAwait(false); } - private JsonFileBlockProgressRepository(string jsonFile):base( - () => Task.FromResult(File.Exists(jsonFile)), - async (json) => await File.WriteAllTextAsync(jsonFile, json), - async () => await File.ReadAllTextAsync(jsonFile)) + private async Task InitRepo() { + if (_innerRepo == null) + { + var config = await _settingRepository.GetEShopConfigurationSettingsAsync().ConfigureAwait(false); + _innerRepo = new PrivateJsonFileBlockProgressRepository(config.ProcessPurchaseOrderEvents.BlockProgressJsonFile); + } + } + + public class PrivateJsonFileBlockProgressRepository : JsonBlockProgressRepository + { + public PrivateJsonFileBlockProgressRepository(string jsonFile) : base( + () => Task.FromResult(File.Exists(jsonFile)), + async (json) => await File.WriteAllTextAsync(jsonFile, json), + async () => await File.ReadAllTextAsync(jsonFile)) + { + } } } + } diff --git a/src/WebJobs/Program.cs b/src/WebJobs/Program.cs index 5433077..98c31d9 100644 --- a/src/WebJobs/Program.cs +++ b/src/WebJobs/Program.cs @@ -7,7 +7,6 @@ using Nethereum.eShop.ApplicationCore.Interfaces; using Nethereum.eShop.ApplicationCore.Services; using Nethereum.eShop.DbFactory; -using Nethereum.eShop.WebJobs.Configuration; using Nethereum.eShop.WebJobs.Jobs; namespace Nethereum.eShop.WebJobs @@ -17,7 +16,6 @@ class Program static void Main(string[] args) { IConfiguration config = null; - EshopConfiguration eShopConfig = null; var hostBuilder = Host.CreateDefaultBuilder(args); hostBuilder.ConfigureServices(services => @@ -25,9 +23,6 @@ static void Main(string[] args) // TODO: Configure MediatR properly - this is just a place holder services.AddMediatR(typeof(Program)); - // config - services.AddSingleton(eShopConfig); - // db var dbBootstrapper = EShopDbBootstrapper.CreateDbBootstrapper(config); dbBootstrapper.AddDbContext(services, config); @@ -55,7 +50,7 @@ static void Main(string[] args) //} //IBlockProgressRepository progressRepo = new BlockProgressRepository(blockchainDbContextFactory); - services.AddSingleton(); + services.AddScoped(); // jobs services.AddScoped(); @@ -75,7 +70,6 @@ static void Main(string[] args) c.AddUserSecrets(typeof(Program).Assembly); config = c.Build(); - eShopConfig = config.GetSection("EshopConfiguration").Get(); }); hostBuilder.ConfigureLogging((context, b) => diff --git a/src/WebJobs/appsettings.json b/src/WebJobs/appsettings.json index 06a6dbf..0af2719 100644 --- a/src/WebJobs/appsettings.json +++ b/src/WebJobs/appsettings.json @@ -6,28 +6,9 @@ "CatalogConnection_Sqlite": "Data Source=C:/temp/eshop_catalog.db", "BlockchainProcessingProgressDb": "Server=localhost;Integrated Security=true;Initial Catalog=eShopWebJobs;" }, - // SqlServer, Sqlite (InMemory is no use - as the main Web app can't share the same db state) + // SqlServer, Sqlite, MySql (InMemory is no good for the WebJobs project as it needs to share the same DB as the main Web app) "CatalogDbProvider": "SqlServer", "AzureWebJobsStorage": "", - "EshopConfiguration": { - "EthereumRpcUrl": "http://localhost:8545/", - "AccountPrivateKey": "0x7580e7fb49df1c861f0050fae31c2224c6aba908e116b8da44ee8cd927b990b0", - "EShopId": "Satoshi", - "SellerId": "Alice", - "BuyerWalletAddress": "0xc59aa7e0e00946c8dcea379fba766a57dba8cf6b", - "PurchasingContractAddress": "0x3b03ce5637dec7814b1c162de6a5a0e322167013", - "CurrencySymbol": "DAI", - "CurrencyAddress": "0xd2e2982d23b1c80917b2adc4a96a9963e75b2c88", - "QuantityAddress": "0x40ed4f49ec2c7bdcce8631b1a7b54ed5d4aa9610", - "CreateFakePurchaseOrders": true, - - "PurchaseOrderEventLogConfiguration": { - "Enabled": true, - "BlockProgressJsonFile": "c:/temp/po_blockprogress.json", - "MinimumStartingBlock": 0, - "NumberOfBlocksPerBatch": 100, - "MinimumBlockConfirmations": 12, - "TimeoutMs": 3600000 - } - } + "EthereumRpcUrl": "http://localhost:8545/", + "AccountPrivateKey": "0x7580e7fb49df1c861f0050fae31c2224c6aba908e116b8da44ee8cd927b990b0" } \ No newline at end of file diff --git a/src/contracts/Nethereum.Commerce.Contracts/Deployment/ContractDeployment.cs b/src/contracts/Nethereum.Commerce.Contracts/Deployment/ContractDeployment.cs index a759853..9611add 100644 --- a/src/contracts/Nethereum.Commerce.Contracts/Deployment/ContractDeployment.cs +++ b/src/contracts/Nethereum.Commerce.Contracts/Deployment/ContractDeployment.cs @@ -128,8 +128,6 @@ public async Task InitializeAsync() // Make a whole new deployment await DeployAndConfigureEShopAsync().ConfigureAwait(false); - await WriteContractAddressesToFile().ConfigureAwait(false); - // With mocks if needed if (ContractNewDeploymentConfig.AlsoDeployMockContracts) { @@ -156,32 +154,6 @@ public async Task InitializeAsync() LogSeparator(); } - // A temporary method which writes the addresses created by the deployment to a file - // This can be used by the web job project for testing - private Task WriteContractAddressesToFile() - { - var configJson = new - { - Web3User = _web3.TransactionManager.Account.Address.ToLowerInvariant(), - ContractNameFunding = FundingService.ContractHandler.ContractAddress.ToLowerInvariant(), - SellerAdminOwner = SellerAdminService.ContractHandler.ContractAddress.ToLowerInvariant(), - AddressRegistry = AddressRegistryService.ContractHandler.ContractAddress.ToLowerInvariant(), - PurchasingContract = PurchasingService.ContractHandler.ContractAddress.ToLowerInvariant(), - BusinessPartnerStorage = BusinessPartnerStorageService.ContractHandler.ContractAddress.ToLowerInvariant(), - BuyerUserAddress = _web3.TransactionManager.Account.Address.ToLowerInvariant(), - BuyerReceiverAddress = _web3.TransactionManager.Account.Address.ToLowerInvariant(), - BuyerWalletAddress = BuyerWalletService.ContractHandler.ContractAddress.ToLowerInvariant(), - CurrencyAddress = MockDaiService.ContractHandler.ContractAddress.ToLowerInvariant(), - EShopId = ContractNewDeploymentConfig.Eshop.EShopId, - SellerId = ContractNewDeploymentConfig.Seller.SellerId, - CurrencySymbol = "DAI", - QuoteSigners = new[] { "0x32A555F2328e85E489f9a5f03669DC820CE7EBe9", "0x94618601FE6cb8912b274E5a00453949A57f8C1e" } - }; - - File.WriteAllText("c:/temp/eshop_contracts.json", JsonConvert.SerializeObject(configJson)); - - return Task.CompletedTask; - } private async Task DeployAndConfigureEShopAsync() { From e3c2e15b2948e5666a248721e51c05920e9009bb Mon Sep 17 00:00:00 2001 From: Dave Whiffin Date: Fri, 3 Apr 2020 16:57:05 +0100 Subject: [PATCH 26/27] tidying appsettings file --- src/Web/appsettings.json | 2 ++ 1 file changed, 2 insertions(+) diff --git a/src/Web/appsettings.json b/src/Web/appsettings.json index 477be89..c12a92d 100644 --- a/src/Web/appsettings.json +++ b/src/Web/appsettings.json @@ -14,6 +14,8 @@ "AppIdentityDbProvider": "InMemory", "CatalogApplyMigrationsOnStartup": true, "IdentityApplyMigrationsOnStartup": true, + "EthereumRpcUrl": "http://localhost:8545/", + "AccountPrivateKey": "0x7580e7fb49df1c861f0050fae31c2224c6aba908e116b8da44ee8cd927b990b0", "CatalogSeedJsonFile": "../../resources/data/TopRankBooks/ImportData/TopRankBooksForCatalogImport.json", "CatalogBaseUrl": "", "BizEngineRetriesUponFailure": 3, From d51605696f76ee74df7555b776b4aa31725b6c5c Mon Sep 17 00:00:00 2001 From: Dave Whiffin Date: Fri, 3 Apr 2020 17:11:55 +0100 Subject: [PATCH 27/27] Updating DB based docs --- docs/eShop-Db-Design.md | 20 +++++++++++++++++--- docs/eShop-Db-Setup.md | 3 +++ 2 files changed, 20 insertions(+), 3 deletions(-) diff --git a/docs/eShop-Db-Design.md b/docs/eShop-Db-Design.md index 26450d1..f223d15 100644 --- a/docs/eShop-Db-Design.md +++ b/docs/eShop-Db-Design.md @@ -4,8 +4,22 @@ The eShop takes a hybrid approach to decentralisation. It attempts to balance B ## Data Layer -The core business services in the Nethereum.eShop are agnostic of the actual data persistence provider. A mixture of the repository and CQRS patterns are present. The repositories are typically involved in business unit transactions whilst queries are for highly optimised, performance intensive requirements which may require a provider specific implementation or additional resources such as data warehouses, external API's, search services etc. As a basic example, Entity Framework Core can provide a repository layer implementation whilst Dapper can help provide optimised queries which in some organisations remain under DBA control. +The core business services in the Nethereum.eShop are agnostic of the actual data persistence provider. A mixture of the repository and CQRS patterns are present. The repositories are typically involved in business unit transactions whilst queries are for highly optimised, performance intensive requirements which may require a provider specific implementation or additional resources such as data warehouses, external API's, search services etc. As a basic example, Entity Framework Core can provide a repository layer implementation whilst Dapper can help provide optimised queries which in some organisations remain under DBA control. -One of the primary reasons for this was that some entities would be likely to move from one storage solution to another over time. Some entities which can't be stored on chain at present may be able to go on chain in the future once specific privacy concerns have been addressed in core Blockchain technology. +One of the primary reasons for the design was that some entities would be likely to move from one storage solution to another in the near future. Some entities which can't be stored on chain at present may be able to go on chain in the future once specific privacy concerns have been addressed in core Blockchain technology. Abstracting the storage implementation via a repository or query interface will make it easier to move entity storage in the future. -Both the repository or query interfaces are agnostic of provider. +## Currently Supported Db's + +* Sql Server +* Sqlite +* MySql +* InMemory + +All of these are currently supported with a mixture of Entity Framework core for Repository implementations and Dapper backed Query implementations. + +Non Entity Framework Core providers could be written as neither the repository or query interfaces are dependent on EF and Dapper. + +Entity Framework Core was chosen because: +* it's already widely used by .net developers +* minimal code is required to implement other EF core based providers +* it provides a migration solution (whatever you may think of it!) diff --git a/docs/eShop-Db-Setup.md b/docs/eShop-Db-Setup.md index 545002e..2e18024 100644 --- a/docs/eShop-Db-Setup.md +++ b/docs/eShop-Db-Setup.md @@ -43,6 +43,7 @@ Supported values are: * InMemory * SqlServer * Sqlite +* MySql ``` json "ConnectionStrings": { @@ -50,6 +51,8 @@ Supported values are: "IdentityConnection_SqlServer": "Server=localhost;Integrated Security=true;Initial Catalog=eShop;", "CatalogConnection_Sqlite": "Data Source=C:/temp/eshop_catalog.db", "IdentityConnection_Sqlite": "Data Source=C:/temp/eshop_app_identity.db", + "CatalogConnection_MySql": "server=localhost;database=eShop;user=eShop;password=oDEcHyOmr1ujVIWLBtQp;Allow User Variables=True", + "IdentityConnection_MySql": "server=localhost;database=eShop;user=eShop;password=oDEcHyOmr1ujVIWLBtQp;Allow User Variables=True", "BlockchainProcessingProgressDb": "Server=localhost\\sqldev;Integrated Security=true;Initial Catalog=eShopWebJobs;" }, "CatalogDbProvider": "SqlServer",