Can we use ValueObjects in EF Query Where Clause?

52 Views Asked by At

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?

0

There are 0 best solutions below