英文:
Use Soundex search with EF Core
问题
我正在尝试在 EF Core 中实现 Soundex 搜索,我已经编写了这个 LINQ 查询,应该查询名为 'Customers' 的表,根据名和姓进行查询。
using System.Data.Entity.SqlServer;
//更多代码
customers = hisDb.Customers.Where(p => SqlFunctions.SoundCode(p.Fname.Trim()) == SqlFunctions.SoundCode(FName.Trim()) && SqlFunctions.SoundCode(p.Lname.Trim()) == SqlFunctions.SoundCode(LName.Trim())).AsEnumerable().ToList();
然而,我遇到了这个错误。
> System.NotSupportedException: 只能在 LINQ to Entities 中调用此函数。
at System.Data.Entity.SqlServer.SqlFunctions.SoundCode(String arg)
在 EF Core 6 中如何使 Soundex 搜索工作?
英文:
I am trying to implement Soundex searching in EF Core, I have written this LINQ that should query a table called 'Customers' by first and last name.
using System.Data.Entity.SqlServer;
//More code
customers = hisDb.Customers.Where(p => SqlFunctions.SoundCode(p.Fname.Trim()) == SqlFunctions.SoundCode(FName.Trim()) && SqlFunctions.SoundCode(p.Lname.Trim()) == SqlFunctions.SoundCode(LName.Trim())).AsEnumerable().ToList();
However, I am getting this error.
> System.NotSupportedException: This function can only be invoked from LINQ to Entities.
at System.Data.Entity.SqlServer.SqlFunctions.SoundCode(String arg)
Anyway getting Soundex search to work with EF Core 6?
答案1
得分: 1
你应该做的是预先计算所有客户的名字的Soundex值,并将这些值存储(并建立索引)在你的数据库中。然后使用搜索参数的Soundex值来对这些值进行查询。
例如:
ALTER TABLE Customers
ADD FirstNameSoundex AS SOUNDEX(FirstName);
CREATE INDEX Customers_FirstName_Soundex ON Customers (FirstNameSoundex);
更新DbContext以添加这个新计算列并进行查询
var soundCode = SqlFunctions.SoundCode(arg);
hisDb.Customers.Where(cust => cust.FirstNameSoundex == soundCode)
这样你就不必在每次查询时扫描整个表并使用SOUNDEX(),数据库也不必知道你特定的SqlFunction。
(免责声明:我不知道SqlFunctions.SoundCode是否实际上与T-SQL的SOUNDEX()相同,但如果是这样,上述操作应该没问题)
英文:
What you should do is pre-calculate the Soundex-values for all of your Customers' first names, and store (and index) those values in your database. Then query against those values using the Soundex-value of you search argument.
For instance
ALTER TABLE Customers
ADD FirstNameSoundex AS SOUNDEX(FirstName);
CREATE INDEX Customers_FirstName_Soundex ON Customers (FirstNameSoundex);
Update the DbContext to add this new computed column and query
var soundCode = SqlFunctions.SoundCode(arg);
hisDb.Customers.Where(cust => cust.FirstNameSoundex == soundCode)
This way you won't have to scan and SOUNDEX() the entire table at every query, and the database doesn't have to know about your particular SqlFunction.
(disclaimer: I don't know if SqlFunctions.SoundCode is in fact the same as T-SQL SOUNDEX() but if so, the above should be fine)
答案2
得分: 0
自从Stack Overflow允许用户回答自己的问题以来,我找到了这个解决方案,但我不知道EF Core是否友好。
在DbContext
中,我添加了
[DbFunction(Name = "SoundEx", IsBuiltIn = true]
public static string SoundEx(string input)
{
throw new NotImplementedException();
}
并在我的代码中调用它
customers = hisDb.Customers.Where(p => DbContext.SoundEx(p.Fname.Trim()) == DbContext.SoundEx(FName.Trim()) && DbContext.SoundEx(p.Lname.Trim()) == DbContext.SoundEx(LName.Trim())).ToList();
英文:
Since SO allows a user to answer his own question. I have found this solution, but I do not know how EF Core friendly is.
In DbContext
, I added
[DbFunction(Name = "SoundEx", IsBuiltIn = true]
public static string SoundEx(string input)
{
throw new NotImplementedException();
}
and called it in my code
customers = hisDb.Customers.Where(p => DbContext.SoundEx(p.Fname.Trim()) == DbContext.SoundEx(FName.Trim()) && DbContext.SoundEx(p.Lname.Trim()) == DbContext.SoundEx(LName.Trim())).ToList();
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。
评论