From b4463566c51e519e26e4208737eb8c39d25808a9 Mon Sep 17 00:00:00 2001 From: MatthiasDT93 Date: Mon, 11 Aug 2025 15:53:32 +0200 Subject: [PATCH 1/2] feat(schema): value objects as properties --- .../Value-Objects/ValueObjectsAsProperties.cs | 119 ++++++++++++++++++ 1 file changed, 119 insertions(+) create mode 100644 EntityFramework.Explained/Schema/Value-Objects/ValueObjectsAsProperties.cs diff --git a/EntityFramework.Explained/Schema/Value-Objects/ValueObjectsAsProperties.cs b/EntityFramework.Explained/Schema/Value-Objects/ValueObjectsAsProperties.cs new file mode 100644 index 0000000..f7751a7 --- /dev/null +++ b/EntityFramework.Explained/Schema/Value-Objects/ValueObjectsAsProperties.cs @@ -0,0 +1,119 @@ +using EntityFramework.Explained._Tools.Helpers; +using Microsoft.EntityFrameworkCore; +using QuickPulse.Explains; +using QuickPulse.Explains.Text; +// Model and appdbcontext generated by AI + + +[DocFile] +public class ValueObjectProperties +{ + // Value Object: CustomerName + public class CustomerName + { + public string FirstName { get; private set; } + public string LastName { get; private set; } + + private CustomerName() { } + public CustomerName(string firstName, string lastName) + { + if (string.IsNullOrWhiteSpace(firstName)) throw new ArgumentException("First name is required"); + if (string.IsNullOrWhiteSpace(lastName)) throw new ArgumentException("Last name is required"); + + FirstName = firstName; + LastName = lastName; + } + + // Equality methods omitted for brevity + } + + // Value Object: Address + public class Address + { + public string Street { get; private set; } + public string City { get; private set; } + public string PostalCode { get; private set; } + + private Address() { } + public Address(string street, string city, string postalCode) + { + Street = street; + City = city; + PostalCode = postalCode; + } + + // Equality methods omitted for brevity + } + + // Aggregate Root: Order + public class Order + { + public int Id { get; private set; } + public CustomerName CustomerName { get; private set; } + public Address ShippingAddress { get; private set; } + public DateTime OrderDate { get; private set; } + + private Order() { } + public Order(CustomerName customerName, Address shippingAddress) + { + CustomerName = customerName; + ShippingAddress = shippingAddress; + OrderDate = DateTime.UtcNow; + } + + // Other domain logic here... + } + + + + + public class AppDbContext : DbContext + { + public DbSet Orders { get; set; } + + protected override void OnConfiguring(DbContextOptionsBuilder optionsBuilder) + => optionsBuilder.UseSqlServer("DoesNotMatter"); // Required by EF, never actually used + protected override void OnModelCreating(ModelBuilder modelBuilder) + { + modelBuilder.Entity(order => + { + order.HasKey(o => o.Id); + + order.OwnsOne(o => o.CustomerName, cn => + { + cn.Property(c => c.FirstName).HasColumnName("CustomerFirstName").IsRequired(); + cn.Property(c => c.LastName).HasColumnName("CustomerLastName").IsRequired(); + }); + + order.OwnsOne(o => o.ShippingAddress, addr => + { + addr.Property(a => a.Street).HasColumnName("Street").IsRequired(); + addr.Property(a => a.City).HasColumnName("City").IsRequired(); + addr.Property(a => a.PostalCode).HasColumnName("PostalCode").IsRequired(); + }); + }); + } + } + + + [Fact] + [DocHeader("Value Objects")] + [DocContent("checking what SQL is generated for value objects in model")] + public void VOChecker() + { + using var context = new AppDbContext(); + var sql = context.Database.GenerateCreateScript(); + var reader = LinesReader.FromText(sql); + Assert.Equal("CREATE TABLE [Orders] (", reader.NextLine()); + Assert.Equal(" [Id] int NOT NULL IDENTITY,", reader.NextLine()); + Assert.Equal(" [CustomerFirstName] nvarchar(max) NOT NULL,", reader.NextLine()); + Assert.Equal(" [CustomerLastName] nvarchar(max) NOT NULL,", reader.NextLine()); + Assert.Equal(" [Street] nvarchar(max) NOT NULL,", reader.NextLine()); + Assert.Equal(" [City] nvarchar(max) NOT NULL,", reader.NextLine()); + Assert.Equal(" [PostalCode] nvarchar(max) NOT NULL,", reader.NextLine()); + Assert.Equal(" [OrderDate] datetime2 NOT NULL,", reader.NextLine()); + Assert.Equal(" CONSTRAINT [PK_Orders] PRIMARY KEY ([Id])", reader.NextLine()); + Assert.Equal(");", reader.NextLine()); + Assert.Equal("GO", reader.NextLine()); + } +} \ No newline at end of file From 266236d3e30cb45514b65836547769b5238cf265 Mon Sep 17 00:00:00 2001 From: MatthiasDT93 Date: Wed, 13 Aug 2025 13:46:19 +0200 Subject: [PATCH 2/2] feat(schema): updating Value-Objects code --- .../Value-Objects/ValueObjectsAsProperties.cs | 80 +++++-------------- 1 file changed, 18 insertions(+), 62 deletions(-) diff --git a/EntityFramework.Explained/Schema/Value-Objects/ValueObjectsAsProperties.cs b/EntityFramework.Explained/Schema/Value-Objects/ValueObjectsAsProperties.cs index f7751a7..1764236 100644 --- a/EntityFramework.Explained/Schema/Value-Objects/ValueObjectsAsProperties.cs +++ b/EntityFramework.Explained/Schema/Value-Objects/ValueObjectsAsProperties.cs @@ -11,85 +11,48 @@ public class ValueObjectProperties // Value Object: CustomerName public class CustomerName { - public string FirstName { get; private set; } - public string LastName { get; private set; } + public string FullName { get; private set; } private CustomerName() { } - public CustomerName(string firstName, string lastName) + public CustomerName(string fullname) { - if (string.IsNullOrWhiteSpace(firstName)) throw new ArgumentException("First name is required"); - if (string.IsNullOrWhiteSpace(lastName)) throw new ArgumentException("Last name is required"); - - FirstName = firstName; - LastName = lastName; + FullName = fullname; } // Equality methods omitted for brevity } // Value Object: Address - public class Address + public class Customer { - public string Street { get; private set; } - public string City { get; private set; } - public string PostalCode { get; private set; } + public int Id { get; set; } - private Address() { } - public Address(string street, string city, string postalCode) - { - Street = street; - City = city; - PostalCode = postalCode; - } + public CustomerName Name { get; set; } - // Equality methods omitted for brevity - } - - // Aggregate Root: Order - public class Order - { - public int Id { get; private set; } - public CustomerName CustomerName { get; private set; } - public Address ShippingAddress { get; private set; } - public DateTime OrderDate { get; private set; } + public Customer() { } - private Order() { } - public Order(CustomerName customerName, Address shippingAddress) + public Customer(int id, CustomerName name) { - CustomerName = customerName; - ShippingAddress = shippingAddress; - OrderDate = DateTime.UtcNow; + Id = id; + Name = name; } - - // Other domain logic here... } - - - public class AppDbContext : DbContext { - public DbSet Orders { get; set; } + public DbSet Customers { get; set; } protected override void OnConfiguring(DbContextOptionsBuilder optionsBuilder) => optionsBuilder.UseSqlServer("DoesNotMatter"); // Required by EF, never actually used protected override void OnModelCreating(ModelBuilder modelBuilder) { - modelBuilder.Entity(order => + modelBuilder.Entity(customer => { - order.HasKey(o => o.Id); - - order.OwnsOne(o => o.CustomerName, cn => - { - cn.Property(c => c.FirstName).HasColumnName("CustomerFirstName").IsRequired(); - cn.Property(c => c.LastName).HasColumnName("CustomerLastName").IsRequired(); - }); + customer.HasKey(o => o.Id); - order.OwnsOne(o => o.ShippingAddress, addr => + customer.OwnsOne(o => o.Name, cn => { - addr.Property(a => a.Street).HasColumnName("Street").IsRequired(); - addr.Property(a => a.City).HasColumnName("City").IsRequired(); - addr.Property(a => a.PostalCode).HasColumnName("PostalCode").IsRequired(); + cn.Property(c => c.FullName).HasColumnName("CustomerFullName").IsRequired(); }); }); } @@ -104,16 +67,9 @@ public void VOChecker() using var context = new AppDbContext(); var sql = context.Database.GenerateCreateScript(); var reader = LinesReader.FromText(sql); - Assert.Equal("CREATE TABLE [Orders] (", reader.NextLine()); + Assert.Equal("CREATE TABLE [Customers] (", reader.NextLine()); Assert.Equal(" [Id] int NOT NULL IDENTITY,", reader.NextLine()); - Assert.Equal(" [CustomerFirstName] nvarchar(max) NOT NULL,", reader.NextLine()); - Assert.Equal(" [CustomerLastName] nvarchar(max) NOT NULL,", reader.NextLine()); - Assert.Equal(" [Street] nvarchar(max) NOT NULL,", reader.NextLine()); - Assert.Equal(" [City] nvarchar(max) NOT NULL,", reader.NextLine()); - Assert.Equal(" [PostalCode] nvarchar(max) NOT NULL,", reader.NextLine()); - Assert.Equal(" [OrderDate] datetime2 NOT NULL,", reader.NextLine()); - Assert.Equal(" CONSTRAINT [PK_Orders] PRIMARY KEY ([Id])", reader.NextLine()); - Assert.Equal(");", reader.NextLine()); - Assert.Equal("GO", reader.NextLine()); + Assert.Equal(" [CustomerFullName] nvarchar(max) NOT NULL,", reader.NextLine()); + Assert.Equal(" CONSTRAINT [PK_Customers] PRIMARY KEY ([Id])", reader.NextLine()); } } \ No newline at end of file