Using filters for ef core conversion #72
-
Hi.
From this object I form lines such as AFF-01.2022-00001 etc. In the database I store this value as a string, by using conversion in the ef core. And it does a great job of filtering that value for the Equal operator. Because your library expands the expression to look like this .Where(p => p.Number == new Number("AFF-01.2022-00001")) But the problem arises when it comes to the Contains operator. I get an error that you can't call the Contains method on the Number class. Can you advise me what to do in this situation? |
Beta Was this translation helpful? Give feedback.
Replies: 5 comments 7 replies
-
Can you use contains method without gridify? I want to find where is the problem exactly.
|
Beta Was this translation helpful? Give feedback.
-
Thank you for your answer. No, this query will not work, because my implementation of the Number class does not contain the Contains method. |
Beta Was this translation helpful? Give feedback.
-
GridifyMapper could also help,
var lst = new List<TestEntitiy>();
lst.Add(new TestEntitiy() { Number = "AFF-01.2022-00001" });
lst.Add(new TestEntitiy() { Number = "AFF-01.2022-00002" });
lst.Add(new TestEntitiy() { Number = "AFF-01.2021-00001" });
var gm = new GridifyMapper<TestEntitiy>()
.AddMap("number", q => q.Number.ToString());
var test1 = lst.AsQueryable().ApplyFiltering("number=*01.2022", gm);
var test2 = lst.AsQueryable().ApplyFiltering("number=*00002", gm);
var test3 = lst.AsQueryable().ApplyFiltering("number=*AFF", gm);
Debug.Assert(test1.Count() == 2);
Debug.Assert(test2.Count() == 1);
Debug.Assert(test3.Count() == 3);
public class TestEntitiy
{
public Number Number {get; set; }
}
public record Number
{
public Number(string val)
{
var pattern = @"^([a-zA-Z]{3})-(\d{2}\.\d{4})-(\d{5})$";
var match = Regex.Match(val, pattern);
if (match.Success)
{
if (match.Groups[1].Success)
{
Prefix = match.Groups[1].Value;
}
if (match.Groups[2].Success)
{
var sp = match.Groups[2].Value.Split(".");
Date = new DateTime( int.Parse(sp[1]), int.Parse(sp[0]), 1);
}
if (match.Groups[3].Success && int.TryParse(match.Groups[3].Value, out var s))
Sequence = s;
}
}
public string Prefix { get; init; }
public DateTime Date { get; init; }
public int Sequence { get; init; }
public static implicit operator Number(string b) => new Number(b);
public override string ToString() => $"{Prefix}-{Date.ToString("MM")}.{Date.ToString("yyyy")}-{Sequence.ToString("00000")}";
} |
Beta Was this translation helpful? Give feedback.
-
@alirezanet Hi, your record class is similar to mine. Thanks for the example. I've done some research and it seems the problem lies in EF Core. I have this code:
And it fails The LINQ expression 'DbSet() .Where(i => i.Number.ToString() == "AFF-01.01.2020")' could not be translated. Additional information: Translation of method 'object.ToString' failed. If this method can be mapped to your custom function, see https://go.microsoft.com/fwlink/?linkid=2132413 for more information. 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. This is my Conversion code in Ef Core
And as far as I understand, Conversion in Ef core is very restrictive, which makes it impossible to execute an instruction like Maybe I'm mistaken. Maybe I should rethink this. And store Number not through Conversion, but some other way? I'm confused 🤔. |
Beta Was this translation helpful? Give feedback.
-
@alirezanet I think I have solved this issue.
And it works perfectly through Convert. Thank you for your attention and hint that there is such a beautiful thing as implicit and explicit operators |
Beta Was this translation helpful? Give feedback.
@alirezanet I think I have solved this issue.
And it works perfectly through Convert. Thank you for your attention and hint that there is such a beautiful thing as implicit and explicit operators