使用EF Core进行Soundex搜索。

huangapple go评论78阅读模式
英文:

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();

huangapple
  • 本文由 发表于 2023年7月3日 19:51:55
  • 转载请务必保留本文链接:https://go.coder-hub.com/76604472.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定