C
C#2y ago
flow_state

❔ Help with record types and Ef Core

I have created an entity that uses several value objects. The value objects are all properties on the entity, and they are record types that contain validation login in the ctor, like so
public sealed record DisplayName
{
private const long MAX_LENGTH = 255;
public string Value { get; init; }

public DisplayName(string name)
{
name ??= string.Empty;

if (name.Length > MAX_LENGTH)
{
var error = DomainErrors.Common.MaxLengthExcceded(nameof(DisplayName), nameof(DisplayName), name, MAX_LENGTH);
throw new DomainException(error);
}

Value = name;
}

public static implicit operator string(DisplayName name) => name.Value;
public static implicit operator DisplayName(string name) => new(name);
public override string ToString() => Value;
}
public sealed record DisplayName
{
private const long MAX_LENGTH = 255;
public string Value { get; init; }

public DisplayName(string name)
{
name ??= string.Empty;

if (name.Length > MAX_LENGTH)
{
var error = DomainErrors.Common.MaxLengthExcceded(nameof(DisplayName), nameof(DisplayName), name, MAX_LENGTH);
throw new DomainException(error);
}

Value = name;
}

public static implicit operator string(DisplayName name) => name.Value;
public static implicit operator DisplayName(string name) => new(name);
public override string ToString() => Value;
}
The problem is that I run into this error when trying to build the Asp.net core app to generate a swagger json file
Unhandled exception. System.AggregateException: One or more errors occurred. (No suitable constructor was found for entity type 'DisplayName'. The following constructors had parameters that could not be bound to properties of the entity type: cannot bind 'name' in 'DisplayName(string name)'; cannot bind 'original' in 'DisplayName(DisplayName original)'.)
Unhandled exception. System.AggregateException: One or more errors occurred. (No suitable constructor was found for entity type 'DisplayName'. The following constructors had parameters that could not be bound to properties of the entity type: cannot bind 'name' in 'DisplayName(string name)'; cannot bind 'original' in 'DisplayName(DisplayName original)'.)
Here is a snippet of the ef core configuration for this property
builder.Property(r => r.DisplayName)
.HasConversion(d => d.Value, d => new DisplayName(d))
.IsRequired()
.HasMaxLength(255)
.HasColumnName("display_name");
builder.Property(r => r.DisplayName)
.HasConversion(d => d.Value, d => new DisplayName(d))
.IsRequired()
.HasMaxLength(255)
.HasColumnName("display_name");
Note: The entity class itself is a regular class. Not sure how to proceed from here. Any help is appreciated.
20 Replies
phaseshift
phaseshift2y ago
Don't use db models for controller egress But maybe this will work if the param name exactly match
flow_state
flow_state2y ago
For context, i'm using this example https://github.com/devmentors/MySpot/blob/master/src/MySpot.Infrastructure/DAL/Configurations/VehicleReservationConfiguration.cs as a guide, and I've seen this pattern replicated in various repos
GitHub
MySpot/VehicleReservationConfiguration.cs at master · devmentors/My...
Web API Fundamentals course project. Contribute to devmentors/MySpot development by creating an account on GitHub.
flow_state
flow_state2y ago
One thing i've noticed is that my record objects all have another ctor that I did not create See the attached image. Looks like that is causing the confusion with ef core. But i dont know how to fix it
phaseshift
phaseshift2y ago
Just change your main record ctor param name to match the property name
flow_state
flow_state2y ago
I changed the records param name to displayname, but it unfortunately didn't help. I still get same error
phaseshift
phaseshift2y ago
But the property name is Value
flow_state
flow_state2y ago
I tried that and got an error error CS0542: 'DisplayName': member names cannot be the same as their enclosing type
phaseshift
phaseshift2y ago
That's not what I said
flow_state
flow_state2y ago
did you mean change the ctor param name to value to match the Value property?
phaseshift
phaseshift2y ago
That is what I said
flow_state
flow_state2y ago
Sorry for the misunderstanding, but I tried that as well and got same error
Unhandled exception. System.AggregateException: One or more errors occurred. (No suitable constructor was found for entity type 'DisplayName'. The following constructors had parameters that could not be bound to properties of the entity type: cannot bind 'value' in 'DisplayName(string value)'; cannot bind 'original' in 'DisplayName(DisplayName original)'.)
phaseshift
phaseshift2y ago
That copy ctor is not present in the repo you linked to Is it because your don't have a primary ctor like in that repo as well? What version EF core are you on?
flow_state
flow_state2y ago
6.0.13. This is a .NET6 app sorry i'm using Include="Npgsql.EntityFrameworkCore.PostgreSQL" Version="6.0.8"
phaseshift
phaseshift2y ago
You might need net7 to use binding to init; properties
flow_state
flow_state2y ago
🤔... I guess i'll have to look into that but thanks for your help either way
phaseshift
phaseshift2y ago
Your linked repo is net6, I checked But their properties are get only, not init But they do have the record DName(string val) syntax
flow_state
flow_state2y ago
My guess is that the implicit operators on the record type is the cause. I use it as a convenient way to map from a string to the record type without invoking new all over the place
phaseshift
phaseshift2y ago
No, don't think so
flow_state
flow_state2y ago
Actually you're right. It should not convert since i'm passing the value in via the ctor in the ef core value converter Still a head scratcher though
Accord
Accord2y ago
Looks like nothing has happened here. I will mark this as stale and this post will be archived until there is new activity.