My goal is to make Entity Framework 2 play nice with the following code:
public class Foo
{
public Guid Id { get; } // This should NOT change
public string NotRequiredProperty {get; set;}
public Foo(Guid id) => Id = id;
private Foo() { } // Empty constructor is necessary for EF Core I believe?
}
I have read this blog post that says the following can be done:
// Class
private Guid _id;
public Guid Id => _id;
// Configuration
modelBuilder.Entity<Foo>()
.Property(b => b.Id)
.UsePropertyAccessMode(PropertyAccessMode.FieldDuringConstruction);
Which COULD work.
The only improvement I see here is that I am required to explicitly declare a private backing field even though a { get; }
means that one is created implicitly.
How can I make EF Core work with JUST a { get; }
(and of course some required entity configuration)
What you are asking is possible in general with EF Core 2.1 introduced Entity types with constructors with parameters feature. You don't need the empty constructor anymore - EF Core will be able to use the constructor with Guid id
parameter.
However there are two limitations which apply to your Id
property. First, it's a read-only property (hence is backed by readonly
field which can be set only from a constructor). The equivalent in your explicit backing field example would be if you define it as private readonly Guid _id;
. Then the sample configuration WON'T work.
The documentation section for Read-only properties says:
Once properties are being set via the constructor it can make sense to make some of them read-only. EF Core supports this, but there are some things to look out for:
- Properties without setters are not mapped by convention. (Doing so tends to map properties that should not be mapped, such as computed properties.)
- Using automatically generated key values requires a key property that is read-write, since the key value needs to be set by the key generator when inserting new entities.
Pay attention to the second bullet, because that's the second problem. The Id
property by convention is a PK, and Guid
and numeric type PKs by convention are auto-generated.
So you need to choose between two options - either make the Id
non read-only by adding private set;
as suggested in the link, or (which is the answer of the question "How can I make EF Core work with JUST a { get; }
") make it non auto-generated by using the following fluent configuration:
modelBuilder.Entity<Foo>()
.Property(e => e.Id)
.ValueGeneratedNever();
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With