C
C#15mo ago
demndev

✅ ef core can't translate a query

query:
var username = "some username";
var user = await _db.Users
.FirstOrDefaultAsync(u => u.Username.Value == username);
var username = "some username";
var user = await _db.Users
.FirstOrDefaultAsync(u => u.Username.Value == username);
UserConfiguration:
public void Configure(EntityTypeBuilder<UserEntity> builder)
{
builder.HasKey(u => u.Id);

builder.Property(u => u.Username)
.HasConversion(
u => u.Value,
value => new Username(value));

builder.Property(u => u.Password)
.HasConversion(
p => p.Value,
value => Password.FromValue(value));
}
public void Configure(EntityTypeBuilder<UserEntity> builder)
{
builder.HasKey(u => u.Id);

builder.Property(u => u.Username)
.HasConversion(
u => u.Value,
value => new Username(value));

builder.Property(u => u.Password)
.HasConversion(
p => p.Value,
value => Password.FromValue(value));
}
Password VO:
public class Password
{
public string Value { get; private set; }
private readonly IPasswordHasher _passwordHasher;

private Password(string value)
{
Value = value;
_passwordHasher = null!;
}

private Password(string value, IPasswordHasher passwordHasher)
{
_passwordHasher = passwordHasher;
Value = value;
}

public static Password Create(string value, IPasswordHasher passwordHasher)
{
Validate(value);

return new(passwordHasher.GetHash(value), passwordHasher);
}

public static Password FromValue(string value)
{
return new Password(value);
}

public void Update(string newValue)
{
Validate(newValue);

Value = _passwordHasher.GetHash(newValue);
}

private static void Validate(string value)
{
if (value.Length is not (<= 100 and >= 8))
throw new Exceptions.InvalidPasswordLengthException();
}
}
public class Password
{
public string Value { get; private set; }
private readonly IPasswordHasher _passwordHasher;

private Password(string value)
{
Value = value;
_passwordHasher = null!;
}

private Password(string value, IPasswordHasher passwordHasher)
{
_passwordHasher = passwordHasher;
Value = value;
}

public static Password Create(string value, IPasswordHasher passwordHasher)
{
Validate(value);

return new(passwordHasher.GetHash(value), passwordHasher);
}

public static Password FromValue(string value)
{
return new Password(value);
}

public void Update(string newValue)
{
Validate(newValue);

Value = _passwordHasher.GetHash(newValue);
}

private static void Validate(string value)
{
if (value.Length is not (<= 100 and >= 8))
throw new Exceptions.InvalidPasswordLengthException();
}
}
10 Replies
demndev
demndev15mo ago
and the UserEntity:
public class UserEntity : EntityBase
{
public Username Username { get; }
public Password Password { get; } // TODO: work with password hashing
private List<NoteEntity> _notes = new();
public IEnumerable<NoteEntity> Notes => _notes.AsReadOnly();

public UserEntity(Password password, Username username)
{
Password = password;
Username = username;
}

public bool Authenticate(Username username, Password password)
{
return Username.Value == username.Value && Password.Value == password.Value;
}
public class UserEntity : EntityBase
{
public Username Username { get; }
public Password Password { get; } // TODO: work with password hashing
private List<NoteEntity> _notes = new();
public IEnumerable<NoteEntity> Notes => _notes.AsReadOnly();

public UserEntity(Password password, Username username)
{
Password = password;
Username = username;
}

public bool Authenticate(Username username, Password password)
{
return Username.Value == username.Value && Password.Value == password.Value;
}
what am i doing wrong? exception:
The LINQ expression 'DbSet<UserEntity>()
.Where(u => u.Username.Value == __username_0)' could not be translated. Either rewrite the query in a form that can be translated, or switch to client evaluation explicitly by inserting a call to 'AsEnumerable', 'AsAsyncEnumerable', 'ToList', or 'ToListAsync'. See https://go.microsoft.com/fwlink/?linkid=2101038 for more information.
The LINQ expression 'DbSet<UserEntity>()
.Where(u => u.Username.Value == __username_0)' could not be translated. Either rewrite the query in a form that can be translated, or switch to client evaluation explicitly by inserting a call to 'AsEnumerable', 'AsAsyncEnumerable', 'ToList', or 'ToListAsync'. See https://go.microsoft.com/fwlink/?linkid=2101038 for more information.
i also tried using .HasColumnName, but it didn't help
JakenVeina
JakenVeina15mo ago
why in the world is Username its own class? or struct? u.Username.Value is invalid Username is not an entity type you've registered with EF, so it doesn't know how to navigate .Value and the value conversion you've defined doesn't help all that does is tell EF to store that column as a string, and how to convert the two back and forth as yhey go to and from the database
jcotton42
jcotton4215mo ago
smells of DDD
private List<NoteEntity> _notes = new();
public IEnumerable<NoteEntity> Notes => _notes.AsReadOnly();
private List<NoteEntity> _notes = new();
public IEnumerable<NoteEntity> Notes => _notes.AsReadOnly();
what's up with this? @demndev you're trying to be wayyyyyy too clever with your entities some cleverness is fine, like in my Discord bots I have a value converter for Snowflake that converts it to/from ulong but generally your database entities should just be data no cleverness
demndev
demndev15mo ago
it's a value object yes, it's something like DDD
jcotton42
jcotton4215mo ago
you can set up a value converter but then you need to use Username opaquely i.e. just do someUsername == anotherUsername not someUsername.Value == anotherUsername.Value
demndev
demndev15mo ago
okay… what is a value converter and how can i set up it?
jcotton42
jcotton4215mo ago
it's the HasConversion stuff you're already doing so if the drop the .Value stuff, it should all work
demndev
demndev15mo ago
thanks!
jcotton42
jcotton4215mo ago
remember, EF isn't actually running the expressions you give it it's translating them to SQL so it's looking for a column to act on and your Username column doesn't have a Value property in the database
Accord
Accord15mo ago
Was this issue resolved? If so, run /close - otherwise I will mark this as stale and this post will be archived until there is new activity.
Want results from more Discord servers?
Add your server
More Posts
❔ Is the functionality of my code in the right placeI created a valueobject for my sitemap. I'm wondering if it's in the right place or shouldn't it be ❔ Microsoft SQL Server Management Studio ("authority that is not trusted")I'm trying to connect my local server from SSMS but there's an error after I connect.❔ ✅ Trying to understand HID device response dataI have a wireless mouse that I'm trying to make my own software for. So far, it has been quite straiIssue with FolderBrowserDialog in console applicationHey, when I start my application via Visual Studio everything works, but as soon as I start the cons❔ How to restart a BackgroundServiceSearching the internets, I seem to be finding answers that don't really seem right, and not good eve❔ Whats the difference between classes and public classes?Tried looking at Microsoft docs earlier but the don't really answer the question. I already know wh❔ Questions on validating columns and types (updating a single column in a table via REST API)I'm new to .NET and C#. I'm trying to implement a somewhat more difficult endpoint where the user pr❔ Trying to save location data using JSON. Need help!I am very new to coding, and I need to make 3 different scripts (or one script with all 3 functions)❔ Advice on Data modeling-ef coreBasically I've got a lesson which is an aggregate root, On said lesson i got phases and each phase hASP.NET Web API base API route / route prefix?Is there a way to specify that I'd like all my API routes to begin with a prefix? So that I can make