LINQ;具有文化不变性的搜索

发布于 2024-10-26 18:02:07 字数 1205 浏览 1 评论 0原文


这是我的问题。我们有一个企业、用户或任何东西的列表,我们必须使用“StartsWith”搜索类型来搜索它。因此,在我们的网站上,我们没有诸如文本框之类的搜索字段,但我们有一个搜索标题,其中包括 27 个按钮“#”、“A”、“B”、“C”、[...]” Z”。

我们遇到的问题是,如果用户单击“E”按钮,当我们查询从数据库中获取值时,企业名称可能以“É”、“È”、“Ê”开头,因为是的,我们的网站是法语。知道如何在 LINQ 中执行此操作。

了解我们正在使用 LLBLGen Pro 也很重要。所以我想它需要有一些东西可以转换成有效的 SQL 查询。

这是我们已经尝试过的:

IList<Enterprise> enterprises;
switch (searchChar){
  [...]
  case "E":
     enterprises = from ent in ourContext.Enterprises
                   where "eèéêë".Any(param => ent.name[0] == param)
                   select ent;
     break;
  [...]
}

这给我们带来了与不可转换查询相关的错误:
无法将“System.Linq.Expressions.ConstantExpression”类型的对象转换为“SD.LLBLGen.Pro.LinqSupportClasses.ExpressionClasses.SetExpression”类型。

因此,我们尝试使用简单的方法来实现它LINQ 查询,无需查询数据库即可知道是否可行。

IList<string> test = new List<string>() { "École", "enlever", "avoir" };
IList<string> result = (from value in test
                        where "eéèêë".Contains(value[0].ToString())
                        select value).ToList();

这个查询的奇怪之处在于它没有崩溃。但是,这也行不通!调试时,它会遍历它,但是当我们尝试查看“结果”列表中的内容时,就像里面什么都没有一样。我的意思是,该列表根本就是空的。但 try catch 中没有任何失败!

请帮忙!

Here is my problem. We've got a list of enterprises, users or anything and we must search into it with a "StartsWith" search type. So on our site, we ain't got a Search field such as a Textbox but we've got a search header including 27 buttons "#", "A", "B", "C", [...] "Z".

The problem we have is that if user click on "E" button, when we querying to get value from database, entreprises name may start with an "É", "È", "Ê", bacause yes, our site is in french. Any idea of how to do it in LINQ.

This is important to know too that we're using LLBLGen Pro. So I guess it need to have something he can convert into a valid SQL Query.

Here is what we've already tryied :

IList<Enterprise> enterprises;
switch (searchChar){
  [...]
  case "E":
     enterprises = from ent in ourContext.Enterprises
                   where "eèéêë".Any(param => ent.name[0] == param)
                   select ent;
     break;
  [...]
}

Which give us this error something relatively to a unconvertable query:
Unable to cast object of type 'System.Linq.Expressions.ConstantExpression' to type 'SD.LLBLGen.Pro.LinqSupportClasses.ExpressionClasses.SetExpression'.

So we've tried to make it basicaly with a simple LINQ query, without querying to DB to know if it's possible.

IList<string> test = new List<string>() { "École", "enlever", "avoir" };
IList<string> result = (from value in test
                        where "eéèêë".Contains(value[0].ToString())
                        select value).ToList();

What is weird with this query, is that it ain't crash. But, it ain't work too! When debugging, it go throught it, but when we try to see what is into "result" list, it's like if there's nothing in it. I mean, the list is simply null. But nothing fail into the try catch!

Please help !

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(5

殤城〤 2024-11-02 18:02:07

真正的解决方案是在数据库中为可搜索名称创建一个额外的列,因此每当您添加新公司时,您也会向可搜索名称列添加一个值。您可以将所有字符转换为大写(或小写,如果您愿意)不变,并将“干净”名称添加到可搜索名称列中。您也可以在此时删除标点符号,因为这在搜索中通常是一个痛苦的事情。

这将为您留下一个永远不会显示的列,但在此列中搜索匹配项会更容易(也更快),因为您永远不需要在搜索时担心重音字符。

The real solution is here is to create an extra column in your database for a searchable name, so whenever you add a new company you also add a value to the searchable name column. You would convert all characters to upper (or lower if you like) invariant and add the "clean" name to the searchable name column. You could also remove punctuation at this point too, as that is often a pain in searches.

This will leave you with a column you will never display but it will be much easier (and also much quicker) to search for matches in this column as you will never need to worry about accented characters at search time.

倚栏听风 2024-11-02 18:02:07

只需使用字符串的 StartsWith 方法

IList<string> test = new List<string>() { "École", "enlever", "avoir" };

var result = test
    .Where(s => s.StartsWith("e", StringComparison.CurrentCultureIgnoreCase))
    .ToList();

Just use StartsWith method of the string

IList<string> test = new List<string>() { "École", "enlever", "avoir" };

var result = test
    .Where(s => s.StartsWith("e", StringComparison.CurrentCultureIgnoreCase))
    .ToList();
做个少女永远怀春 2024-11-02 18:02:07

如果我在这里找到你就是你想要的:

var result = test.Where(x => "eéèêë".Contains(Char.ToLowerInvariant(x.FirstOrDefault())));

If i got you right here is what you want:

var result = test.Where(x => "eéèêë".Contains(Char.ToLowerInvariant(x.FirstOrDefault())));
梦幻的心爱 2024-11-02 18:02:07

Any 似乎不起作用。使用包含代替。这是工作中。

enterprises = from ent in ourContext.Enterprises
              where "eèéêëEÈÉÊËE".Contains(ent.name[0])
              select ent;

The Any seem to be not working. Use Contains instead. This is workin.

enterprises = from ent in ourContext.Enterprises
              where "eèéêëEÈÉÊËE".Contains(ent.name[0])
              select ent;
怼怹恏 2024-11-02 18:02:07

我不确定您是否对数据库有任何控制,以及您正在使用哪个 RDMBS,但一种简单的方法似乎是在查询中使用不区分大小写、不区分重音的排序规则 - 这样 SQL 就能完成艰苦的工作。

-- Assuming that your existing table is Accent Sensitive
create table Enterprises
(
name nvarchar(200) collate SQL_Latin1_General_CP1_CI_AS
)
GO

-- We can still use an Accent Insensitive View
create view vEnterprises
as
    select name collate SQL_Latin1_General_CP1_CI_AI AS name
        from Enterprises

GO

insert into Enterprises values ('e')
insert into Enterprises values ('è')
insert into Enterprises values ('é')
insert into Enterprises values ('ê')
insert into Enterprises values ('ë')

insert into Enterprises values ('E')
insert into Enterprises values ('É')
insert into Enterprises values ('È')
insert into Enterprises values ('Ê')


-- returns 'e' and 'E'
select * from Enterprises where name like 'e%'

-- returns everything
select * from vEnterprises where name like 'e%'

即假设您可以将不区分重音的视图添加到 LLBLGen,您只需将“e”传递给查询即可。

I'm not sure whether you have any control over the database, and which RDMBS you are using, but an easy way seems to be using a case insensitive, accent insensitive collation in your query - this way SQL does the hard work.

-- Assuming that your existing table is Accent Sensitive
create table Enterprises
(
name nvarchar(200) collate SQL_Latin1_General_CP1_CI_AS
)
GO

-- We can still use an Accent Insensitive View
create view vEnterprises
as
    select name collate SQL_Latin1_General_CP1_CI_AI AS name
        from Enterprises

GO

insert into Enterprises values ('e')
insert into Enterprises values ('è')
insert into Enterprises values ('é')
insert into Enterprises values ('ê')
insert into Enterprises values ('ë')

insert into Enterprises values ('E')
insert into Enterprises values ('É')
insert into Enterprises values ('È')
insert into Enterprises values ('Ê')


-- returns 'e' and 'E'
select * from Enterprises where name like 'e%'

-- returns everything
select * from vEnterprises where name like 'e%'

i.e. Assuming that you can add the accent insensitive view to LLBLGen you can just pass 'e' to the query.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文