In my User Repository, I want to use:
class UserRepository
{
readonly DbContext _context;
Task<User> GetByUsernameAsync(Username username)
{
// Query based on Username ValueObject
return await _context.Users.SingleOrDefaultAsync(
u => u.Username.Equals(username));
}
}
But this gives me:
System.InvalidOperationException : No backing field could be found for property 'Username.UserDbId' and the property does not have a getter.
Instead, I have to use:
class UserRepository
{
readonly DbContext _context;
Task<User> GetByUsernameAsync(Username username)
{
// Query based on Value property of Username
return await _context.Users.SingleOrDefaultAsync(
u => u.Username.Value.Equals(username.Value));
}
}
My setup ...
Username
public class Username : ValueObject
{
public string Value { get; private set; }
public Username(string value)
{
// Some guard conditions
// Set property
Value = value;
}
}
User
public class User : Entity
{
public Username Username { get; private set; }
public User(Username username)
{
Username = username;
}
}
UserMap
internal class UserMap : IEntityTypeConfiguration<User>
{
public void Configure(EntityTypeBuilder<User> builder)
{
builder.ToTable("Users");
builder.Property<int>("DbId").HasColumnName("DbId").UseIdentityColumn();
builder.HasKey("DbId");
builder.OwnsOne<Username>("Username", b =>
{
b.Property("Value").HasColumnName("Username").IsRequired();
b.HasIndex("Value").IsUnique();
});
builder.Navigation("Username").IsRequired();
}
}
I note that the first version of my query does not invoke the Equals function on my ValueObject base class.
Does EF need a value converter for this?