0

我有一个IList<User>包含具有一对值的对象:NameSurname。在数据库上,我有一个表,其中包含带有姓名和姓氏字段的行。我想在代码隐藏上返回与我的列表匹配的行列表,所以假设姓名和姓氏(分别)相等。

我的实际代码是:

utenti = (from User utente in db.User.AsEnumerable()
          join amico in amiciParsed 
               on new { utente.Nome, utente.Cognome } equals 
                  new { Nome = amico.first_name, Cognome = amico.last_name }
          select utente).OrderBy(p => p.Nome)
                        .OrderBy(p => p.Cognome)
                        .OrderBy(p => p.Nickname)
                        .ToList();

但这并不好,原因有两个:

  1. 它将在客户端下载数据库的全部记录;
  2. 我无法将姓名和姓氏匹配为区分大小写(例如 Marco cordi != Marco Cordi);在 DB 上,我有各种上/下字符。

正如之前的问题所建议的那样,这个答案似乎对我没有帮助,因为我必须加入(也因为第一个问题它不相关)。

解决这个问题的方法是什么?

4

3 回答 3

0

在 SO 上提出问题时,您可能希望将其翻译成英文——不要指望人们知道“uente”、“amico”或“Cognome”是什么。

一个问题:你为什么使用..in db.User.AsEnumerable()而不只是..in db.User

让查询中的所有内容都保留IQueryable(而不是IEnumerable)。这让 Linq2Sql 创建尽可能优化的 SQL,而不是下载所有记录并在客户端加入记录。这也可能是您的搜索变为区分大小写的原因。客户端内存中的字符串比较将始终区分大小写,而 SQL 中的字符串比较取决于数据库的配置。

尝试放弃.AsEnumerable(),看看你是否能得到更好的结果:

utenti = (from User foo in db.User
          join bar in amiciParsed 
          ...
于 2013-11-08T22:49:56.087 回答
0

我不知道这是否适用于您的情况,但您可以尝试一下。

首先,创建一个新的字符串列表:

List<string> amici = aimiciParsed.Select(x => x.first_name + "|" + x.last_name).ToList();

然后,根据此列表从 DB 中选择用户

var utenti = db.User.AsEnumerable().Where(utente => 
    amici.Contains(utente.Nome + "|" + utente.Cognome)).ToList();

它将字符串列表作为参数列表发送到数据库,并将其转换为类似的查询

SELECT * FROM User WHERE User.Nome + "|" + User.Cognome IN (@p1, @p2, @p3 ...)

不幸的是,无法使用类似的方式调用 Contains StringComparison.OrdinalIgnoreCase,因此您可能必须更改列的排序规则。

于 2013-11-06T11:36:38.483 回答
0

这可以通过PredicateBuilder来完成:

using LinqKit;

var predicate = PredicateBuilder.False<User>();

foreach(var amico in amiciParsed)
{
    var a1 = amico; // Prevent modified closure (pre .Net 4.5)
    predicate = predicate.Or(user => user.Nome == a1.first_name 
                                  && user.Cognome == a1.last_name);
}

var query = db.User.Where(predicate.Expand())
              .OrderBy(p => p.Nome)
              ...

优点是可以使用索引Nome并且Cognome可以使用(如果您搜索连接的值,这是不可能的)。另一方面,OR子句的数量可能会变得非常大,这可能会达到 SQL Server 中的某些限制 ( https://stackoverflow.com/a/1869810/861716 )。您必须对此进行压力测试(尽管IN子句也是如此)。

于 2013-11-06T13:41:19.940 回答