Cannot convert immutable type of StronglyTypedId
Hi,
So I'm getting this error:
Mapster.CompileException: Error while compiling source=Domain.Orders.Models.Order destination=Infrastructure.SQL.Orders.Models.DB_Order type=Map ---> Mapster.CompileException: Error while compiling source=System.Nullable
1[Domain.Orders.Models.OrderId] destination=System.Nullable1[System.Int32] type=Map ---> System.InvalidOperationException: Cannot convert immutable type, please consider using 'MapWith' method to create mapping
When I'm trying to do this:
var dbOrder = order.Adapt<DB_Order>();
DB_Order looks like:
internal record DB_Order
{
public int Id { get; init; }
public string? OrderNumber { get; init; }
...
Order looks like:
public record Order {
public OrderId Id { get; init; }
public OrderNumber? OrderNumber { get; init; }
OrderId is a StronglyTypedId struct backed with an Int.
I'm converting an Immutable type into a int, so I don't know why I'm getting this error I have added a whole host of Map and MapWiths to no effect:
public async Task<Order> CreateOrderAsync(Order order, CancellationToken token = default)
{
TypeAdapterConfig<int, OrderId>
.NewConfig()
.ConstructUsing(x => new OrderId(x));
TypeAdapterConfig<OrderId, int>
.NewConfig()
.MapWith(x => x.Value);
var dbOrder = order.Adapt<DB_Order>(); <-- error
and I've tried:
public async Task<Order> CreateOrderAsync(Order order, CancellationToken token = default)
{
var conf = TypeAdapterConfig<Order, DB_Order>
.NewConfig()
.Map(dbOrder => dbOrder.Id, order => order.Id.Value).Config;
var dbOrder = order.Adapt<DB_Order>(conf); <-- error
Any ideas?
If you are unfamiliar with StronglyTypedIds it generates this:
readonly partial struct OrderId : System.IComparable<OrderId>, System.IEquatable<OrderId>
{
public int Value { get; }
public OrderId(int value)
{
Value = value;
}
public static readonly OrderId Empty = new OrderId(0);
public bool Equals(OrderId other) => this.Value.Equals(other.Value);
public override bool Equals(object obj)
{
if (ReferenceEquals(null, obj)) return false;
return obj is OrderId other && Equals(other);
}
public override int GetHashCode() => Value.GetHashCode();
public override string ToString() => Value.ToString();
public static bool operator ==(OrderId a, OrderId b) => a.Equals(b);
public static bool operator !=(OrderId a, OrderId b) => !(a == b);
public int CompareTo(OrderId other) => Value.CompareTo(other.Value);
class OrderIdSystemTextJsonConverter : System.Text.Json.Serialization.JsonConverter<OrderId>
{
public override OrderId Read(ref System.Text.Json.Utf8JsonReader reader, System.Type typeToConvert, System.Text.Json.JsonSerializerOptions options)
{
return new OrderId(reader.GetInt32());
}
public override void Write(System.Text.Json.Utf8JsonWriter writer, OrderId value, System.Text.Json.JsonSerializerOptions options)
{
writer.WriteNumberValue(value.Value);
}
}
}
I figured it out I had another nullable OrderId further down the model. I didn't realise that you needed to cover both OrderId and OrderId?