So I’ve inherited an app that I’ve recently upgraded from .NET Core 2 to .NET 8. It uses entityframework and a lot of .OwnsOne().
After updating I ran into the problem that, in the previous version of EF (2.2.6) whenever I select anything that uses those I get an instance of a class with everything set to default
. This has changed and it will only create an instance of a class if I tell it to, or I create that class if it’s null. As in I’d have to find all places that uses that navigation property and do
protected void UpdateSelf(Tour tour)
{
// Has a lot of property updates that I've ommitted
// It also calls .UpdateSelf() on other owned types. In this case they would have already be created with values, and won't be null on select
if (Completion == null)
Completion = new Completion(null, null);
Completion.UpdateSelf(tour.Completion);
}
To avoid exceptions. The class itself is this:
[Owned]
public class Completion : IEquatable<Completion>
{
#nullable enable
public DateTime? CompletedTime { get; private set; }
public string? Comment { get; private set; }
//private Completion() { }
public Completion(DateTime? completedTime, string? comment)
{
CompletedTime = completedTime;
Comment = comment;
}
#nullable disable
internal void UpdateSelf(Completion completion)
{
if (completion == null) return;
CompletedTime = completion.CompletedTime;
Comment = completion.Comment;
}
// And the IEquatable implementation
}
And is configured on the entity like so:
builder.OwnsOne(t => t.Completion);
And selecting it
var target = await _dbContext.PlantToDepotTours
.Where(t => t.Id == dto.Id)
.FirstOrDefaultAsync();
Not really anything groundbreaking. But I’d really like to know if there was a way to configure EF to make Completion
not be null on select. It’s not marked as nullable either.
I also know I can do
builder.OwnsOne(t => t.Completion);
builder.Navigation(t => t.Completion).IsRequired().AutoInclude();
But that would require me to add it on all the navigation properties, and it doesn’t seem like it would produce the same behaviour either.
3
Okay so looking more into it I think what I needed was ComplexProperty
. At least from this: https://devblogs.microsoft.com/dotnet/announcing-ef8-rc1/#configuration-of-complex-types4
I’m gonna have to test this (and edit this reply). But if I do
builder.ComplexProperty(t => t.Completion).IsRequired();
in the configuration I seem to get the same behaviour as the previous version
4