How to query the actual value in Entity Framework core when using a Value Converter?
Asked Answered
S

1

7

We have a fairly simple situation where an EF Core entity contains a value object that we map to a string:

builder.Property(_ => _.Nummer)
    .HasConversion(i => i.ToString(), i => ZijdeNummer.FromString(i))
    .IsRequired().HasMaxLength(9);

This works fine for retrieval and storage, but for filtering we're looking for a way to filter rows by substring. If it'd be a normal string column you can simply do something like this:

dbSet.TheTable.Where(t => t.Nummer.Contains("some text")).ToList()

Obviously the custom ZijdeNummer doesn't contain a recognized .Contains() method. I've tried using .ToString().Contains() but alas, this also doesn't work.

Finally, I've also tried accessing the column as if it were a shadow-property:

dbSet.TheTable.Where(t => EF.Property<string>(t, "Nummer").Contains("some text"))

But it won't be fooled as it still knows that EF.Property<T>(t, "Nummer") is not actually a string :(

Is there a way to make EF-Core just query the raw column type?

Sumner answered 1/4, 2022 at 8:50 Comment(0)
S
15

It turns out this is much easier than you'd expect. Simply cast the type to string (if no conversion exists, then first cast to object) and perform the comparison:

dbSet.TheTable.Where(t => ((string)(object)t.Nummer).Contains("some text")).ToList()
Sumner answered 1/4, 2022 at 10:13 Comment(2)
Thanks for this I never would have thought to do this myself. This is particularly useful when trying to do the common task of trying to sum a group of timespan fields which are mapped from a long holding ticks.Darrel
Please mark this post as answer, even if it's your own. This helps users better find it when they see this question has an accepted answer.Weanling

© 2022 - 2024 — McMap. All rights reserved.