TGViewer
StepOne | Степан Минин StepOne | Степан Минин @steponeit · 3.27K subscribers
Post #230 1.84K
В EF Core 8 узаконили Value Object 🤩

Одно из тех обновлений, которое не следует пропускать 😱

Например, есть следующая сущность заказа Order вместе с сущностью клиента Customer:

public class Customer
{
public int Id { get; set; }
public required string Name { get; set; }
public required Address Address { get; set; }
public List<Order> Orders { get; } = new();
}

public class Order
{
public int Id { get; set; }
public required string Contents { get; set; }
public required Address ShippingAddress { get; set; }
public required Address BillingAddress { get; set; }
public Customer Customer { get; set; } = null!;
}


Кажется, что уже существует семантика работы с типами значениями, ведь никто не отменял атрибут [Owned].

Однако, при попытке сохранить сущность, которая использует один инстанс на несколько полей возникнет ошибка:

var address = GetAddress();

customer.Orders.Add(
new Order { Contents = "Tesco Tasty Treats", BillingAddress = address, ShippingAddress = address, });

await context.SaveChangesAsync();


Кажется, что всё будет хорошо, но получим исключение InvalidOperationException с сообщением

«Cannot save instance of 'Order.ShippingAddress#Address' because it is an owned entity without any reference to its owner. Owned entities can only be saved as part of an aggregate also including the owner entity.
at Microsoft.EntityFrameworkCore.ChangeTracking.Internal.InternalEntityEntry.PrepareToSave()»

Теперь, достаточно разметить тип данных атрибутом [ComplexType].
При этом он может быть иммутабельным!

[ComplexType]
public record Address(string Line1, string? Line2, string City, string Country, string PostCode);


Соответственно, такое обновление сущности:

customer.Address = customer.Address with { Line1 = "Peacock Lodge" };

await context.SaveChangesAsync();


Сгенерирует следующий SQL:

UPDATE [Customers] SET [Address_Line1] = @p0
OUTPUT 1
WHERE [Id] = @p1;


То есть, это собственный тип на стероидах 💉
  • 🔥 11
  • 👍 2
  • 🎉 1
  • 🤣 1
  • 🏆 1
More from @steponeit
  1. Sep 29, 2026Рассказал как автоматизировал сборку лексера компилятором для своего языка программировани…
  2. Sep 28, 2026Пошутил про джавистов в прямом эфире 😅 Шарпизм победил окончательно и бесповоротно!
  3. Sep 27, 2026Post #860
  4. Sep 25, 2026Рассказал как я добавил в HydraScript объекты и методы без классов и сделал протоколы. Стр…
  5. Sep 22, 2026Post #858
  6. Sep 21, 2026Post #857
Threads Profile ViewerView any public Threads profile without an account.Open ThreadLook →Writing with AI? Make it sound human.Metric37 rewrites AI drafts so they read naturally. Free AI detector, 1,500 words free.Try Metric37 →