diff --git a/src/Services/Catalog/Catalog.API/Catalog.API.csproj b/src/Services/Catalog/Catalog.API/Catalog.API.csproj index 7f55b6432..de280179f 100644 --- a/src/Services/Catalog/Catalog.API/Catalog.API.csproj +++ b/src/Services/Catalog/Catalog.API/Catalog.API.csproj @@ -12,6 +12,9 @@ + + Always + PreserveNewest diff --git a/src/Services/Catalog/Catalog.API/Infrastructure/CatalogContext.cs b/src/Services/Catalog/Catalog.API/Infrastructure/CatalogContext.cs index f58541b62..b0dd2a082 100644 --- a/src/Services/Catalog/Catalog.API/Infrastructure/CatalogContext.cs +++ b/src/Services/Catalog/Catalog.API/Infrastructure/CatalogContext.cs @@ -1,9 +1,8 @@ namespace Microsoft.eShopOnContainers.Services.Catalog.API.Infrastructure { - using EntityFrameworkCore.Metadata.Builders; using Microsoft.EntityFrameworkCore; + using EntityConfigurations; using Model; - using Microsoft.eShopOnContainers.BuildingBlocks.IntegrationEventLogEF; public class CatalogContext : DbContext { @@ -16,68 +15,9 @@ protected override void OnModelCreating(ModelBuilder builder) { - builder.Entity(ConfigureCatalogBrand); - builder.Entity(ConfigureCatalogType); - builder.Entity(ConfigureCatalogItem); + builder.ApplyConfiguration(new CatalogBrandEntityTypeConfiguration()); + builder.ApplyConfiguration(new CatalogTypeEntityTypeConfiguration()); + builder.ApplyConfiguration(new CatalogItemEntityTypeConfiguration()); } - - void ConfigureCatalogItem(EntityTypeBuilder builder) - { - builder.ToTable("Catalog"); - - builder.Property(ci => ci.Id) - .ForSqlServerUseSequenceHiLo("catalog_hilo") - .IsRequired(); - - builder.Property(ci => ci.Name) - .IsRequired(true) - .HasMaxLength(50); - - builder.Property(ci => ci.Price) - .IsRequired(true); - - builder.Property(ci => ci.PictureFileName) - .IsRequired(false); - - builder.Ignore(ci => ci.PictureUri); - - builder.HasOne(ci => ci.CatalogBrand) - .WithMany() - .HasForeignKey(ci => ci.CatalogBrandId); - - builder.HasOne(ci => ci.CatalogType) - .WithMany() - .HasForeignKey(ci => ci.CatalogTypeId); - } - - void ConfigureCatalogBrand(EntityTypeBuilder builder) - { - builder.ToTable("CatalogBrand"); - - builder.HasKey(ci => ci.Id); - - builder.Property(ci => ci.Id) - .ForSqlServerUseSequenceHiLo("catalog_brand_hilo") - .IsRequired(); - - builder.Property(cb => cb.Brand) - .IsRequired() - .HasMaxLength(100); - } - - void ConfigureCatalogType(EntityTypeBuilder builder) - { - builder.ToTable("CatalogType"); - - builder.HasKey(ci => ci.Id); - - builder.Property(ci => ci.Id) - .ForSqlServerUseSequenceHiLo("catalog_type_hilo") - .IsRequired(); - - builder.Property(cb => cb.Type) - .IsRequired() - .HasMaxLength(100); - } } } diff --git a/src/Services/Catalog/Catalog.API/Infrastructure/EntityConfigurations/CatalogBrandEntityTypeConfiguration.cs b/src/Services/Catalog/Catalog.API/Infrastructure/EntityConfigurations/CatalogBrandEntityTypeConfiguration.cs new file mode 100644 index 000000000..8312b023d --- /dev/null +++ b/src/Services/Catalog/Catalog.API/Infrastructure/EntityConfigurations/CatalogBrandEntityTypeConfiguration.cs @@ -0,0 +1,25 @@ +using Microsoft.EntityFrameworkCore; +using Microsoft.EntityFrameworkCore.Metadata.Builders; +using Microsoft.eShopOnContainers.Services.Catalog.API.Model; + +namespace Microsoft.eShopOnContainers.Services.Catalog.API.Infrastructure.EntityConfigurations +{ + class CatalogBrandEntityTypeConfiguration + : IEntityTypeConfiguration + { + public void Configure(EntityTypeBuilder builder) + { + builder.ToTable("CatalogBrand"); + + builder.HasKey(ci => ci.Id); + + builder.Property(ci => ci.Id) + .ForSqlServerUseSequenceHiLo("catalog_brand_hilo") + .IsRequired(); + + builder.Property(cb => cb.Brand) + .IsRequired() + .HasMaxLength(100); + } + } +} diff --git a/src/Services/Catalog/Catalog.API/Infrastructure/EntityConfigurations/CatalogItemEntityTypeConfiguration.cs b/src/Services/Catalog/Catalog.API/Infrastructure/EntityConfigurations/CatalogItemEntityTypeConfiguration.cs new file mode 100644 index 000000000..f7f093ce8 --- /dev/null +++ b/src/Services/Catalog/Catalog.API/Infrastructure/EntityConfigurations/CatalogItemEntityTypeConfiguration.cs @@ -0,0 +1,39 @@ +using Microsoft.EntityFrameworkCore; +using Microsoft.EntityFrameworkCore.Metadata.Builders; +using Microsoft.eShopOnContainers.Services.Catalog.API.Model; + +namespace Microsoft.eShopOnContainers.Services.Catalog.API.Infrastructure.EntityConfigurations +{ + class CatalogItemEntityTypeConfiguration + : IEntityTypeConfiguration + { + public void Configure(EntityTypeBuilder builder) + { + builder.ToTable("Catalog"); + + builder.Property(ci => ci.Id) + .ForSqlServerUseSequenceHiLo("catalog_hilo") + .IsRequired(); + + builder.Property(ci => ci.Name) + .IsRequired(true) + .HasMaxLength(50); + + builder.Property(ci => ci.Price) + .IsRequired(true); + + builder.Property(ci => ci.PictureFileName) + .IsRequired(false); + + builder.Ignore(ci => ci.PictureUri); + + builder.HasOne(ci => ci.CatalogBrand) + .WithMany() + .HasForeignKey(ci => ci.CatalogBrandId); + + builder.HasOne(ci => ci.CatalogType) + .WithMany() + .HasForeignKey(ci => ci.CatalogTypeId); + } + } +} diff --git a/src/Services/Catalog/Catalog.API/Infrastructure/EntityConfigurations/CatalogTypeEntityTypeConfiguration.cs b/src/Services/Catalog/Catalog.API/Infrastructure/EntityConfigurations/CatalogTypeEntityTypeConfiguration.cs new file mode 100644 index 000000000..4c30bb3b6 --- /dev/null +++ b/src/Services/Catalog/Catalog.API/Infrastructure/EntityConfigurations/CatalogTypeEntityTypeConfiguration.cs @@ -0,0 +1,25 @@ +using Microsoft.EntityFrameworkCore; +using Microsoft.EntityFrameworkCore.Metadata.Builders; +using Microsoft.eShopOnContainers.Services.Catalog.API.Model; + +namespace Microsoft.eShopOnContainers.Services.Catalog.API.Infrastructure.EntityConfigurations +{ + class CatalogTypeEntityTypeConfiguration + : IEntityTypeConfiguration + { + public void Configure(EntityTypeBuilder builder) + { + builder.ToTable("CatalogType"); + + builder.HasKey(ci => ci.Id); + + builder.Property(ci => ci.Id) + .ForSqlServerUseSequenceHiLo("catalog_type_hilo") + .IsRequired(); + + builder.Property(cb => cb.Type) + .IsRequired() + .HasMaxLength(100); + } + } +} diff --git a/src/Services/Catalog/Catalog.API/settings.json b/src/Services/Catalog/Catalog.API/appsettings.json similarity index 100% rename from src/Services/Catalog/Catalog.API/settings.json rename to src/Services/Catalog/Catalog.API/appsettings.json diff --git a/src/Services/Marketing/Marketing.API/Infrastructure/EntityConfigurations/CampaignEntityTypeConfiguration.cs b/src/Services/Marketing/Marketing.API/Infrastructure/EntityConfigurations/CampaignEntityTypeConfiguration.cs new file mode 100644 index 000000000..833133dae --- /dev/null +++ b/src/Services/Marketing/Marketing.API/Infrastructure/EntityConfigurations/CampaignEntityTypeConfiguration.cs @@ -0,0 +1,46 @@ +using Microsoft.EntityFrameworkCore; +using Microsoft.EntityFrameworkCore.Metadata.Builders; +using Microsoft.eShopOnContainers.Services.Marketing.API.Model; + +namespace Microsoft.eShopOnContainers.Services.Marketing.API.Infrastructure.EntityConfigurations +{ + class CampaignEntityTypeConfiguration + : IEntityTypeConfiguration + { + public void Configure(EntityTypeBuilder builder) + { + builder.ToTable("Campaign"); + + builder.HasKey(m => m.Id); + + builder.Property(m => m.Id) + .ForSqlServerUseSequenceHiLo("campaign_hilo") + .IsRequired(); + + builder.Property(m => m.Name) + .HasColumnName("Name") + .IsRequired(); + + builder.Property(m => m.From) + .HasColumnName("From") + .IsRequired(); + + builder.Property(m => m.To) + .HasColumnName("To") + .IsRequired(); + + builder.Property(m => m.Description) + .HasColumnName("Description") + .IsRequired(); + + builder.Property(m => m.PictureUri) + .HasColumnName("PictureUri") + .IsRequired(); + + builder.HasMany(m => m.Rules) + .WithOne(r => r.Campaign) + .HasForeignKey(r => r.CampaignId) + .IsRequired(); + } + } +} diff --git a/src/Services/Marketing/Marketing.API/Infrastructure/EntityConfigurations/RuleEntityTypeConfiguration.cs b/src/Services/Marketing/Marketing.API/Infrastructure/EntityConfigurations/RuleEntityTypeConfiguration.cs new file mode 100644 index 000000000..49c015014 --- /dev/null +++ b/src/Services/Marketing/Marketing.API/Infrastructure/EntityConfigurations/RuleEntityTypeConfiguration.cs @@ -0,0 +1,30 @@ +using Microsoft.EntityFrameworkCore; +using Microsoft.EntityFrameworkCore.Metadata.Builders; +using Microsoft.eShopOnContainers.Services.Marketing.API.Model; + +namespace Microsoft.eShopOnContainers.Services.Marketing.API.Infrastructure.EntityConfigurations +{ + class RuleEntityTypeConfiguration + : IEntityTypeConfiguration + { + public void Configure(EntityTypeBuilder builder) + { + builder.ToTable("Rule"); + + builder.HasKey(r => r.Id); + + builder.Property(r => r.Id) + .ForSqlServerUseSequenceHiLo("rule_hilo") + .IsRequired(); + + builder.HasDiscriminator("RuleTypeId") + .HasValue(RuleType.UserProfileRule.Id) + .HasValue(RuleType.PurchaseHistoryRule.Id) + .HasValue(RuleType.UserLocationRule.Id); + + builder.Property(r => r.Description) + .HasColumnName("Description") + .IsRequired(); + } + } +} diff --git a/src/Services/Marketing/Marketing.API/Infrastructure/EntityConfigurations/UserLocationRuleEntityTypeConfiguration.cs b/src/Services/Marketing/Marketing.API/Infrastructure/EntityConfigurations/UserLocationRuleEntityTypeConfiguration.cs new file mode 100644 index 000000000..84840d3a5 --- /dev/null +++ b/src/Services/Marketing/Marketing.API/Infrastructure/EntityConfigurations/UserLocationRuleEntityTypeConfiguration.cs @@ -0,0 +1,17 @@ +using Microsoft.EntityFrameworkCore; +using Microsoft.EntityFrameworkCore.Metadata.Builders; +using Microsoft.eShopOnContainers.Services.Marketing.API.Model; + +namespace Microsoft.eShopOnContainers.Services.Marketing.API.Infrastructure.EntityConfigurations +{ + class UserLocationRuleEntityTypeConfiguration + : IEntityTypeConfiguration + { + public void Configure(EntityTypeBuilder builder) + { + builder.Property(r => r.LocationId) + .HasColumnName("LocationId") + .IsRequired(); + } + } +} diff --git a/src/Services/Marketing/Marketing.API/Infrastructure/MarketingContext.cs b/src/Services/Marketing/Marketing.API/Infrastructure/MarketingContext.cs index f530fae37..c843f9b5b 100644 --- a/src/Services/Marketing/Marketing.API/Infrastructure/MarketingContext.cs +++ b/src/Services/Marketing/Marketing.API/Infrastructure/MarketingContext.cs @@ -1,7 +1,7 @@ namespace Microsoft.eShopOnContainers.Services.Marketing.API.Infrastructure { + using EntityConfigurations; using Microsoft.EntityFrameworkCore; - using Microsoft.EntityFrameworkCore.Metadata.Builders; using Microsoft.eShopOnContainers.Services.Marketing.API.Model; public class MarketingContext : DbContext @@ -16,72 +16,9 @@ protected override void OnModelCreating(ModelBuilder builder) { - builder.Entity(ConfigureCampaigns); - builder.Entity(ConfigureRules); - builder.Entity(ConfigureUserLocationRules); - } - - void ConfigureCampaigns(EntityTypeBuilder builder) - { - builder.ToTable("Campaign"); - - builder.HasKey(m => m.Id); - - builder.Property(m => m.Id) - .ForSqlServerUseSequenceHiLo("campaign_hilo") - .IsRequired(); - - builder.Property(m => m.Name) - .HasColumnName("Name") - .IsRequired(); - - builder.Property(m => m.From) - .HasColumnName("From") - .IsRequired(); - - builder.Property(m => m.To) - .HasColumnName("To") - .IsRequired(); - - builder.Property(m => m.Description) - .HasColumnName("Description") - .IsRequired(); - - builder.Property(m => m.PictureUri) - .HasColumnName("PictureUri") - .IsRequired(); - - builder.HasMany(m => m.Rules) - .WithOne(r => r.Campaign) - .HasForeignKey(r => r.CampaignId) - .IsRequired(); - } - - void ConfigureRules(EntityTypeBuilder builder) - { - builder.ToTable("Rule"); - - builder.HasKey(r => r.Id); - - builder.Property(r => r.Id) - .ForSqlServerUseSequenceHiLo("rule_hilo") - .IsRequired(); - - builder.HasDiscriminator("RuleTypeId") - .HasValue(RuleType.UserProfileRule.Id) - .HasValue(RuleType.PurchaseHistoryRule.Id) - .HasValue(RuleType.UserLocationRule.Id); - - builder.Property(r => r.Description) - .HasColumnName("Description") - .IsRequired(); - } - - void ConfigureUserLocationRules(EntityTypeBuilder builder) - { - builder.Property(r => r.LocationId) - .HasColumnName("LocationId") - .IsRequired(); + builder.ApplyConfiguration(new CampaignEntityTypeConfiguration()); + builder.ApplyConfiguration(new RuleEntityTypeConfiguration()); + builder.ApplyConfiguration(new UserLocationRuleEntityTypeConfiguration()); } } } \ No newline at end of file diff --git a/src/Services/Ordering/Ordering.Infrastructure/EntityConfigurations/BuyerEntityTYpeConfiguration.cs b/src/Services/Ordering/Ordering.Infrastructure/EntityConfigurations/BuyerEntityTYpeConfiguration.cs new file mode 100644 index 000000000..177f68d91 --- /dev/null +++ b/src/Services/Ordering/Ordering.Infrastructure/EntityConfigurations/BuyerEntityTYpeConfiguration.cs @@ -0,0 +1,39 @@ +using Microsoft.EntityFrameworkCore; +using Microsoft.EntityFrameworkCore.Metadata.Builders; +using Microsoft.eShopOnContainers.Services.Ordering.Domain.AggregatesModel.BuyerAggregate; +using Microsoft.eShopOnContainers.Services.Ordering.Infrastructure; + +namespace Ordering.Infrastructure.EntityConfigurations +{ + class BuyerEntityTypeConfiguration + : IEntityTypeConfiguration + { + public void Configure(EntityTypeBuilder buyerConfiguration) + { + buyerConfiguration.ToTable("buyers", OrderingContext.DEFAULT_SCHEMA); + + buyerConfiguration.HasKey(b => b.Id); + + buyerConfiguration.Ignore(b => b.DomainEvents); + + buyerConfiguration.Property(b => b.Id) + .ForSqlServerUseSequenceHiLo("buyerseq", OrderingContext.DEFAULT_SCHEMA); + + buyerConfiguration.Property(b => b.IdentityGuid) + .HasMaxLength(200) + .IsRequired(); + + buyerConfiguration.HasIndex("IdentityGuid") + .IsUnique(true); + + buyerConfiguration.HasMany(b => b.PaymentMethods) + .WithOne() + .HasForeignKey("BuyerId") + .OnDelete(DeleteBehavior.Cascade); + + var navigation = buyerConfiguration.Metadata.FindNavigation(nameof(Buyer.PaymentMethods)); + + navigation.SetPropertyAccessMode(PropertyAccessMode.Field); + } + } +} diff --git a/src/Services/Ordering/Ordering.Infrastructure/EntityConfigurations/CardTypeEntityTypeConfiguration.cs b/src/Services/Ordering/Ordering.Infrastructure/EntityConfigurations/CardTypeEntityTypeConfiguration.cs new file mode 100644 index 000000000..cdac780a1 --- /dev/null +++ b/src/Services/Ordering/Ordering.Infrastructure/EntityConfigurations/CardTypeEntityTypeConfiguration.cs @@ -0,0 +1,27 @@ +using Microsoft.EntityFrameworkCore; +using Microsoft.EntityFrameworkCore.Metadata.Builders; +using Microsoft.eShopOnContainers.Services.Ordering.Domain.AggregatesModel.BuyerAggregate; +using Microsoft.eShopOnContainers.Services.Ordering.Infrastructure; + +namespace Ordering.Infrastructure.EntityConfigurations +{ + class CardTypeEntityTypeConfiguration + : IEntityTypeConfiguration + { + public void Configure(EntityTypeBuilder cardTypesConfiguration) + { + cardTypesConfiguration.ToTable("cardtypes", OrderingContext.DEFAULT_SCHEMA); + + cardTypesConfiguration.HasKey(ct => ct.Id); + + cardTypesConfiguration.Property(ct => ct.Id) + .HasDefaultValue(1) + .ValueGeneratedNever() + .IsRequired(); + + cardTypesConfiguration.Property(ct => ct.Name) + .HasMaxLength(200) + .IsRequired(); + } + } +} diff --git a/src/Services/Ordering/Ordering.Infrastructure/EntityConfigurations/ClientRequestEntityTypeConfiguration.cs b/src/Services/Ordering/Ordering.Infrastructure/EntityConfigurations/ClientRequestEntityTypeConfiguration.cs new file mode 100644 index 000000000..5a5f8547e --- /dev/null +++ b/src/Services/Ordering/Ordering.Infrastructure/EntityConfigurations/ClientRequestEntityTypeConfiguration.cs @@ -0,0 +1,19 @@ +using Microsoft.EntityFrameworkCore; +using Microsoft.EntityFrameworkCore.Metadata.Builders; +using Microsoft.eShopOnContainers.Services.Ordering.Infrastructure; +using Microsoft.eShopOnContainers.Services.Ordering.Infrastructure.Idempotency; + +namespace Ordering.Infrastructure.EntityConfigurations +{ + class ClientRequestEntityTypeConfiguration + : IEntityTypeConfiguration + { + public void Configure(EntityTypeBuilder requestConfiguration) + { + requestConfiguration.ToTable("requests", OrderingContext.DEFAULT_SCHEMA); + requestConfiguration.HasKey(cr => cr.Id); + requestConfiguration.Property(cr => cr.Name).IsRequired(); + requestConfiguration.Property(cr => cr.Time).IsRequired(); + } + } +} diff --git a/src/Services/Ordering/Ordering.Infrastructure/EntityConfigurations/OrderEntityTypeConfiguration.cs b/src/Services/Ordering/Ordering.Infrastructure/EntityConfigurations/OrderEntityTypeConfiguration.cs new file mode 100644 index 000000000..19684d5e3 --- /dev/null +++ b/src/Services/Ordering/Ordering.Infrastructure/EntityConfigurations/OrderEntityTypeConfiguration.cs @@ -0,0 +1,54 @@ +using Microsoft.EntityFrameworkCore; +using Microsoft.EntityFrameworkCore.Metadata.Builders; +using Microsoft.eShopOnContainers.Services.Ordering.Domain.AggregatesModel.BuyerAggregate; +using Microsoft.eShopOnContainers.Services.Ordering.Domain.AggregatesModel.OrderAggregate; +using Microsoft.eShopOnContainers.Services.Ordering.Infrastructure; +using System; + +namespace Ordering.Infrastructure.EntityConfigurations +{ + class OrderEntityTypeConfiguration + : IEntityTypeConfiguration + { + public void Configure(EntityTypeBuilder orderConfiguration) + { + orderConfiguration.ToTable("orders", OrderingContext.DEFAULT_SCHEMA); + + orderConfiguration.HasKey(o => o.Id); + + orderConfiguration.Ignore(b => b.DomainEvents); + + orderConfiguration.Property(o => o.Id) + .ForSqlServerUseSequenceHiLo("orderseq", OrderingContext.DEFAULT_SCHEMA); + + orderConfiguration.OwnsOne(o => o.Address); + + orderConfiguration.Property("OrderDate").IsRequired(); + orderConfiguration.Property("BuyerId").IsRequired(false); + orderConfiguration.Property("OrderStatusId").IsRequired(); + orderConfiguration.Property("PaymentMethodId").IsRequired(false); + orderConfiguration.Property("Description").IsRequired(false); + + var navigation = orderConfiguration.Metadata.FindNavigation(nameof(Order.OrderItems)); + + // DDD Patterns comment: + //Set as Field (New since EF 1.1) to access the OrderItem collection property through its field + navigation.SetPropertyAccessMode(PropertyAccessMode.Field); + + orderConfiguration.HasOne() + .WithMany() + .HasForeignKey("PaymentMethodId") + .IsRequired(false) + .OnDelete(DeleteBehavior.Restrict); + + orderConfiguration.HasOne() + .WithMany() + .IsRequired(false) + .HasForeignKey("BuyerId"); + + orderConfiguration.HasOne(o => o.OrderStatus) + .WithMany() + .HasForeignKey("OrderStatusId"); + } + } +} diff --git a/src/Services/Ordering/Ordering.Infrastructure/EntityConfigurations/OrderItemEntityTypeConfiguration.cs b/src/Services/Ordering/Ordering.Infrastructure/EntityConfigurations/OrderItemEntityTypeConfiguration.cs new file mode 100644 index 000000000..ca16eddad --- /dev/null +++ b/src/Services/Ordering/Ordering.Infrastructure/EntityConfigurations/OrderItemEntityTypeConfiguration.cs @@ -0,0 +1,44 @@ +using Microsoft.EntityFrameworkCore; +using Microsoft.EntityFrameworkCore.Metadata.Builders; +using Microsoft.eShopOnContainers.Services.Ordering.Domain.AggregatesModel.OrderAggregate; +using Microsoft.eShopOnContainers.Services.Ordering.Infrastructure; + +namespace Ordering.Infrastructure.EntityConfigurations +{ + class OrderItemEntityTypeConfiguration + : IEntityTypeConfiguration + { + public void Configure(EntityTypeBuilder orderItemConfiguration) + { + orderItemConfiguration.ToTable("orderItems", OrderingContext.DEFAULT_SCHEMA); + + orderItemConfiguration.HasKey(o => o.Id); + + orderItemConfiguration.Ignore(b => b.DomainEvents); + + orderItemConfiguration.Property(o => o.Id) + .ForSqlServerUseSequenceHiLo("orderitemseq"); + + orderItemConfiguration.Property("OrderId") + .IsRequired(); + + orderItemConfiguration.Property("Discount") + .IsRequired(); + + orderItemConfiguration.Property("ProductId") + .IsRequired(); + + orderItemConfiguration.Property("ProductName") + .IsRequired(); + + orderItemConfiguration.Property("UnitPrice") + .IsRequired(); + + orderItemConfiguration.Property("Units") + .IsRequired(); + + orderItemConfiguration.Property("PictureUrl") + .IsRequired(false); + } + } +} diff --git a/src/Services/Ordering/Ordering.Infrastructure/EntityConfigurations/OrderStatusEntityTypeConfiguration.cs b/src/Services/Ordering/Ordering.Infrastructure/EntityConfigurations/OrderStatusEntityTypeConfiguration.cs new file mode 100644 index 000000000..f968d9011 --- /dev/null +++ b/src/Services/Ordering/Ordering.Infrastructure/EntityConfigurations/OrderStatusEntityTypeConfiguration.cs @@ -0,0 +1,27 @@ +using Microsoft.EntityFrameworkCore; +using Microsoft.EntityFrameworkCore.Metadata.Builders; +using Microsoft.eShopOnContainers.Services.Ordering.Domain.AggregatesModel.OrderAggregate; +using Microsoft.eShopOnContainers.Services.Ordering.Infrastructure; + +namespace Ordering.Infrastructure.EntityConfigurations +{ + class OrderStatusEntityTypeConfiguration + : IEntityTypeConfiguration + { + public void Configure(EntityTypeBuilder orderStatusConfiguration) + { + orderStatusConfiguration.ToTable("orderstatus", OrderingContext.DEFAULT_SCHEMA); + + orderStatusConfiguration.HasKey(o => o.Id); + + orderStatusConfiguration.Property(o => o.Id) + .HasDefaultValue(1) + .ValueGeneratedNever() + .IsRequired(); + + orderStatusConfiguration.Property(o => o.Name) + .HasMaxLength(200) + .IsRequired(); + } + } +} diff --git a/src/Services/Ordering/Ordering.Infrastructure/EntityConfigurations/PaymentMethodEntityTypeConfiguration.cs b/src/Services/Ordering/Ordering.Infrastructure/EntityConfigurations/PaymentMethodEntityTypeConfiguration.cs new file mode 100644 index 000000000..871c2057e --- /dev/null +++ b/src/Services/Ordering/Ordering.Infrastructure/EntityConfigurations/PaymentMethodEntityTypeConfiguration.cs @@ -0,0 +1,49 @@ +using Microsoft.EntityFrameworkCore; +using Microsoft.EntityFrameworkCore.Metadata.Builders; +using Microsoft.eShopOnContainers.Services.Ordering.Domain.AggregatesModel.BuyerAggregate; +using Microsoft.eShopOnContainers.Services.Ordering.Infrastructure; +using System; + +namespace Ordering.Infrastructure.EntityConfigurations +{ + class PaymentMethodEntityTypeConfiguration + : IEntityTypeConfiguration + { + public void Configure(EntityTypeBuilder paymentConfiguration) + { + paymentConfiguration.ToTable("paymentmethods", OrderingContext.DEFAULT_SCHEMA); + + paymentConfiguration.HasKey(b => b.Id); + + paymentConfiguration.Ignore(b => b.DomainEvents); + + paymentConfiguration.Property(b => b.Id) + .ForSqlServerUseSequenceHiLo("paymentseq", OrderingContext.DEFAULT_SCHEMA); + + paymentConfiguration.Property("BuyerId") + .IsRequired(); + + paymentConfiguration.Property("CardHolderName") + .HasMaxLength(200) + .IsRequired(); + + paymentConfiguration.Property("Alias") + .HasMaxLength(200) + .IsRequired(); + + paymentConfiguration.Property("CardNumber") + .HasMaxLength(25) + .IsRequired(); + + paymentConfiguration.Property("Expiration") + .IsRequired(); + + paymentConfiguration.Property("CardTypeId") + .IsRequired(); + + paymentConfiguration.HasOne(p => p.CardType) + .WithMany() + .HasForeignKey("CardTypeId"); + } + } +} diff --git a/src/Services/Ordering/Ordering.Infrastructure/OrderingContext.cs b/src/Services/Ordering/Ordering.Infrastructure/OrderingContext.cs index 85e2cb0f9..3fe60a2c2 100644 --- a/src/Services/Ordering/Ordering.Infrastructure/OrderingContext.cs +++ b/src/Services/Ordering/Ordering.Infrastructure/OrderingContext.cs @@ -1,12 +1,10 @@ using MediatR; using Microsoft.EntityFrameworkCore; -using Microsoft.EntityFrameworkCore.Metadata; -using Microsoft.EntityFrameworkCore.Metadata.Builders; using Microsoft.eShopOnContainers.Services.Ordering.Domain.AggregatesModel.BuyerAggregate; using Microsoft.eShopOnContainers.Services.Ordering.Domain.AggregatesModel.OrderAggregate; using Microsoft.eShopOnContainers.Services.Ordering.Domain.Seedwork; -using Microsoft.eShopOnContainers.Services.Ordering.Infrastructure.Idempotency; using Ordering.Infrastructure; +using Ordering.Infrastructure.EntityConfigurations; using System; using System.Threading; using System.Threading.Tasks; @@ -17,7 +15,7 @@ namespace Microsoft.eShopOnContainers.Services.Ordering.Infrastructure : DbContext,IUnitOfWork { - const string DEFAULT_SCHEMA = "ordering"; + public const string DEFAULT_SCHEMA = "ordering"; public DbSet Orders { get; set; } @@ -40,6 +38,7 @@ namespace Microsoft.eShopOnContainers.Services.Ordering.Infrastructure } private OrderingContext(DbContextOptions options) : base (options) { } + public OrderingContext(DbContextOptions options, IMediator mediator) : base(options) { _mediator = mediator ?? throw new ArgumentNullException(nameof(mediator)); @@ -50,193 +49,13 @@ namespace Microsoft.eShopOnContainers.Services.Ordering.Infrastructure protected override void OnModelCreating(ModelBuilder modelBuilder) { - - modelBuilder.Entity(ConfigureRequests); - modelBuilder.Entity(ConfigurePayment); - modelBuilder.Entity(ConfigureOrder); - modelBuilder.Entity(ConfigureOrderItems); - modelBuilder.Entity(ConfigureCardTypes); - modelBuilder.Entity(ConfigureOrderStatus); - modelBuilder.Entity(ConfigureBuyer); - } - - private void ConfigureRequests(EntityTypeBuilder requestConfiguration) - { - requestConfiguration.ToTable("requests", DEFAULT_SCHEMA); - requestConfiguration.HasKey(cr => cr.Id); - requestConfiguration.Property(cr => cr.Name).IsRequired(); - requestConfiguration.Property(cr => cr.Time).IsRequired(); - } - - - void ConfigureBuyer(EntityTypeBuilder buyerConfiguration) - { - buyerConfiguration.ToTable("buyers", DEFAULT_SCHEMA); - - buyerConfiguration.HasKey(b => b.Id); - - buyerConfiguration.Ignore(b => b.DomainEvents); - - buyerConfiguration.Property(b => b.Id) - .ForSqlServerUseSequenceHiLo("buyerseq", DEFAULT_SCHEMA); - - buyerConfiguration.Property(b=>b.IdentityGuid) - .HasMaxLength(200) - .IsRequired(); - - buyerConfiguration.HasIndex("IdentityGuid") - .IsUnique(true); - - buyerConfiguration.HasMany(b => b.PaymentMethods) - .WithOne() - .HasForeignKey("BuyerId") - .OnDelete(DeleteBehavior.Cascade); - - var navigation = buyerConfiguration.Metadata.FindNavigation(nameof(Buyer.PaymentMethods)); - - navigation.SetPropertyAccessMode(PropertyAccessMode.Field); - } - - void ConfigurePayment(EntityTypeBuilder paymentConfiguration) - { - paymentConfiguration.ToTable("paymentmethods", DEFAULT_SCHEMA); - - paymentConfiguration.HasKey(b => b.Id); - - paymentConfiguration.Ignore(b => b.DomainEvents); - - paymentConfiguration.Property(b => b.Id) - .ForSqlServerUseSequenceHiLo("paymentseq", DEFAULT_SCHEMA); - - paymentConfiguration.Property("BuyerId") - .IsRequired(); - - paymentConfiguration.Property("CardHolderName") - .HasMaxLength(200) - .IsRequired(); - - paymentConfiguration.Property("Alias") - .HasMaxLength(200) - .IsRequired(); - - paymentConfiguration.Property("CardNumber") - .HasMaxLength(25) - .IsRequired(); - - paymentConfiguration.Property("Expiration") - .IsRequired(); - - paymentConfiguration.Property("CardTypeId") - .IsRequired(); - - paymentConfiguration.HasOne(p => p.CardType) - .WithMany() - .HasForeignKey("CardTypeId"); - } - - void ConfigureOrder(EntityTypeBuilder orderConfiguration) - { - orderConfiguration.ToTable("orders", DEFAULT_SCHEMA); - - orderConfiguration.HasKey(o => o.Id); - - orderConfiguration.Ignore(b => b.DomainEvents); - - orderConfiguration.Property(o => o.Id) - .ForSqlServerUseSequenceHiLo("orderseq", DEFAULT_SCHEMA); - - orderConfiguration.OwnsOne(o => o.Address); - - orderConfiguration.Property("OrderDate").IsRequired(); - orderConfiguration.Property("BuyerId").IsRequired(false); - orderConfiguration.Property("OrderStatusId").IsRequired(); - orderConfiguration.Property("PaymentMethodId").IsRequired(false); - orderConfiguration.Property("Description").IsRequired(false); - - var navigation = orderConfiguration.Metadata.FindNavigation(nameof(Order.OrderItems)); - // DDD Patterns comment: - //Set as Field (New since EF 1.1) to access the OrderItem collection property through its field - navigation.SetPropertyAccessMode(PropertyAccessMode.Field); - - orderConfiguration.HasOne() - .WithMany() - .HasForeignKey("PaymentMethodId") - .IsRequired(false) - .OnDelete(DeleteBehavior.Restrict); - - orderConfiguration.HasOne() - .WithMany() - .IsRequired(false) - .HasForeignKey("BuyerId"); - - orderConfiguration.HasOne(o => o.OrderStatus) - .WithMany() - .HasForeignKey("OrderStatusId"); - } - - void ConfigureOrderItems(EntityTypeBuilder orderItemConfiguration) - { - orderItemConfiguration.ToTable("orderItems", DEFAULT_SCHEMA); - - orderItemConfiguration.HasKey(o => o.Id); - - orderItemConfiguration.Ignore(b => b.DomainEvents); - - orderItemConfiguration.Property(o => o.Id) - .ForSqlServerUseSequenceHiLo("orderitemseq"); - - orderItemConfiguration.Property("OrderId") - .IsRequired(); - - orderItemConfiguration.Property("Discount") - .IsRequired(); - - orderItemConfiguration.Property("ProductId") - .IsRequired(); - - orderItemConfiguration.Property("ProductName") - .IsRequired(); - - orderItemConfiguration.Property("UnitPrice") - .IsRequired(); - - orderItemConfiguration.Property("Units") - .IsRequired(); - - orderItemConfiguration.Property("PictureUrl") - .IsRequired(false); - } - - void ConfigureOrderStatus(EntityTypeBuilder orderStatusConfiguration) - { - orderStatusConfiguration.ToTable("orderstatus", DEFAULT_SCHEMA); - - orderStatusConfiguration.HasKey(o => o.Id); - - orderStatusConfiguration.Property(o => o.Id) - .HasDefaultValue(1) - .ValueGeneratedNever() - .IsRequired(); - - orderStatusConfiguration.Property(o => o.Name) - .HasMaxLength(200) - .IsRequired(); - } - - void ConfigureCardTypes(EntityTypeBuilder cardTypesConfiguration) - { - cardTypesConfiguration.ToTable("cardtypes", DEFAULT_SCHEMA); - - cardTypesConfiguration.HasKey(ct => ct.Id); - - cardTypesConfiguration.Property(ct => ct.Id) - .HasDefaultValue(1) - .ValueGeneratedNever() - .IsRequired(); - - cardTypesConfiguration.Property(ct => ct.Name) - .HasMaxLength(200) - .IsRequired(); + modelBuilder.ApplyConfiguration(new ClientRequestEntityTypeConfiguration()); + modelBuilder.ApplyConfiguration(new PaymentMethodEntityTypeConfiguration()); + modelBuilder.ApplyConfiguration(new OrderEntityTypeConfiguration()); + modelBuilder.ApplyConfiguration(new OrderItemEntityTypeConfiguration()); + modelBuilder.ApplyConfiguration(new CardTypeEntityTypeConfiguration()); + modelBuilder.ApplyConfiguration(new OrderStatusEntityTypeConfiguration()); + modelBuilder.ApplyConfiguration(new BuyerEntityTypeConfiguration()); } public async Task SaveEntitiesAsync(CancellationToken cancellationToken = default(CancellationToken))