Czołem
Mam kolejną rozkminkę...
Mam sobie obiekt wartościowy, który jest reprezentowany jako rekord.
public sealed record UserName(string Name)
{
public const int MaxCharactersNumber = 100;
private UserName() : this(nameof(UserName)) { }
public string Value { get; } = string.IsNullOrWhiteSpace(Name) || Name.Length > MaxCharactersNumber ? throw new InvalidUserNameException() : Name.RemovePolishDiacritics();
public static implicit operator UserName(string userName) => new(userName);
public static implicit operator string(UserName userName) => userName.Value;
public override string ToString() => Value;
public bool Contains(string value) => Value.Contains(value);
}
Do kontekstu jest on wczytywany za pomocą takiej konfiguracji.
builder.ComplexProperty(x => x.UserName, cpb =>
{
cpb.Property(x => x.Value)
.HasColumnName(nameof(User.UserName))
.HasMaxLength(100)
.IsRequired();
cpb.Ignore(x => x.Name);
cpb.IsRequired();
});
W przypadku rekordów gdy użyje się operatora porównania "==" to porównywane są wartości właściwości (i prawidłowo).
Problem jest taki, że każdy parametr w konstruktorze typu "primary" jest konwertowany na właściwość.
W przypadku odczytywania danych z bazy potrzebny jest pusty konstruktor, a żeby stworzyć drugi konstruktor to muszę po jego definicji użyć this() i przekazać parametr tego samego typu do głównego konstruktora.
Psuje to później wynik porównania gdyż w podanym przykładzie parametr "Name" posiada wartość przekazaną w this(), a parametr Value posiada wartość odczytaną z bazy.
Tak, wiem, mogę użyć klasycznego konstruktora gdzie jego parametr nie jest konwertowany do właściwości. Jednak chciałbym znaleźć jakieś rozwiązanie gdzie używam "primary constructor".
Jakieś pomysły?