我有一个IList<User>
,其中包含一对值为Name
和Surname
的对象。
在数据库上,我有一个包含Name和Surname字段的行的表。我想在codebehind上返回与我的List匹配的行列表,所以让我们说Name和Surname(分别)等于。
我的实际代码是:
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();
但这有两个原因并不好:
正如之前的问题所示,似乎这个answer无法帮助我,因为我必须做一个连接(并且因为第一个问题与之无关)。
解决此问题的方法是什么?
答案 0 :(得分: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();
它将字符串列表作为参数列表发送到DB,并将其转换为类似
的查询SELECT * FROM User WHERE User.Nome + "|" + User.Cognome IN (@p1, @p2, @p3 ...)
很遗憾,无法使用StringComparison.OrdinalIgnoreCase
之类的内容调用Contains,因此您可能需要更改列的排序规则。
答案 1 :(得分: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
条款也是如此)。
答案 2 :(得分: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
...