一尘不染

如何在LINQ中执行子查询?

c#

这是我尝试转换为LINQ的查询的示例:

SELECT *
FROM Users
WHERE Users.lastname LIKE '%fra%'
    AND Users.Id IN (
         SELECT UserId 
         FROM CompanyRolesToUsers 
         WHERE CompanyRoleId in (2,3,4) )

CompanyRolesToUsers和之间存在FK关系Users,但它是多对多关系,并且CompanyRolesToUsers是联结表。

我们已经构建了大部分站点,并且已经通过使用PredicateExtensions类构建Expressions来完成了大部分过滤工作。

简单过滤器的代码如下所示:

 if (!string.IsNullOrEmpty(TextBoxLastName.Text))
 {
     predicateAnd = predicateAnd.And(c => c.LastName.Contains(
                                     TextBoxLastName.Text.Trim()));
 }

e.Result = context.Users.Where(predicateAnd);

我正在尝试为另一个表中的子选择添加谓词。(CompanyRolesToUsers

我想要添加的是执行以下操作的操作:

int[] selectedRoles = GetSelectedRoles();
if( selectedRoles.Length > 0 )
{
    //somehow only select the userid from here ???:
    var subquery = from u in CompanyRolesToUsers
                   where u.RoleID in selectedRoles
                   select u.UserId;

    //somehow transform this into an Expression ???:
    var subExpression = Expression.Invoke(subquery);

    //and add it on to the existing expressions ???:
    predicateAnd = predicateAnd.And(subExpression);
}

有什么办法吗?这很令人沮丧,因为我可以轻松地编写存储过程,但是我对LINQ并不陌生,而且我有一个截止日期。我找不到匹配的示例,但我确定它在某个地方。


阅读 375

收藏
2020-05-19

共1个答案

一尘不染

这是适合您的子查询!

List<int> IdsToFind = new List<int>() {2, 3, 4};

db.Users
.Where(u => SqlMethods.Like(u.LastName, "%fra%"))
.Where(u =>
    db.CompanyRolesToUsers
    .Where(crtu => IdsToFind.Contains(crtu.CompanyRoleId))
    .Select(crtu =>  crtu.UserId)
    .Contains(u.Id)
)

关于这部分问题:

predicateAnd = predicateAnd.And(c => c.LastName.Contains(
                                TextBoxLastName.Text.Trim()));

我强烈建议在创作查询之前从文本框中提取字符串。

string searchString = TextBoxLastName.Text.Trim();
predicateAnd = predicateAnd.And(c => c.LastName.Contains( searchString));

您希望对发送到数据库的内容保持良好的控制。在原始代码中,一种可能的读取结果是未修剪的字符串被发送到数据库中进行修整-这对数据库来说并不是一件好事。

2020-05-19