【问题标题】:Find Partial String Matches Using LINQ Without Loops使用没有循环的 LINQ 查找部分字符串匹配
【发布时间】:2014-07-16 02:27:14
【问题描述】:

问题:我正在搜索自定义身份对象中的用户角色集合。这些角色有一个连接到它们的部门,因此该角色不仅仅是“角色”,而是具有“部门:角色”的模式。

由于角色是在不知道“部门”部分的对象中定义的,因此在构建授权列表时需要忽略此部分。 实际上,我正在每个“Department:Role”项目中寻找“:Role”。

我正在使用 LINQ 来执行此操作并使其正常工作(发布在下面),但如果可能的话,我想通过删除 foreach 循环来简化它。我已经在网上搜索了几个小时,并尝试了许多不同的解决方案。最接近我想要完成的两个似乎是herehere。也许答案就在这些里面,我只是不明白。

提前感谢您的帮助/建议。

我的代码:

protected static void AddObjectAuthorizationRules() {

    //Code that gets current user context...

    string[] pDefinedRoles = new string[] { "Developer", "Admin", "User" };
    List<string> _createRoles = ProcessAuthorizationRoles(pDefinedRoles, pIdentity);

    //Object authorization code that uses _createRoles...
}

private List<string> ProcessAuthorizationRoles(string[] pDefinedRoles, CustomIdentityClass pIdentity) {
    List<string> _allowRoles = new List<string>();
    foreach (var _role in pDefinedRoles) {
        var partial = string.Format(":{0}", _role);
        string[] tmp = (from r in pIdentity.Roles 
                        where r.Contains(partial) 
                        select r).ToArray();
        foreach (string found in tmp) {
            _allowRoles.Add(found);
        }
    }
    return _allowRoles;
}

【问题讨论】:

    标签: c# string linq


    【解决方案1】:

    如果你可以使用列表而不是数组,你可以试试这样的。

    private List<string> ProcessAuthorizationRoles(List<string> pDefinedRoles, CustomIdentityClass pIdentity)
    {
        return pIdentity.Roles.FindAll(x => pDefinedRoles.Exists(y => x.Contains(string.format(":{0}", y))));
    }
    

    【讨论】:

    • 标记为已回答,因为它解决了我的问题并且很简单。起初我对将字符串数组更改为列表犹豫不决,但团队无论如何都会触及那部分代码,没有什么能阻止我们使用列表。谢谢@derbal213!
    【解决方案2】:

    我想我可能会将它归结为一个单一的返回语句,但我没有提到“CustomIdentityClass”,所以我无法为你测试。

    private List<string> ProcessAuthorizationRoles(string[] pDefinedRoles, CustomIdentityClass pIdentity)
    {
        return (from role in (from r in pDefinedRoles
                              select new
                              {
                                  Partial = string.Format(":{0}", r)
                              })
                from r in pIdentity.Roles
                where r.Contains(role.Partial)
                select r).ToList();
    }
    

    【讨论】:

    • 谢谢@SpikeX。;我正在查看的 CustomIdentityClass 中的主要内容是 .Roles 属性,它只是一个 List。您的答案有效,但在性能方面,这与@derbal213 的建议相比如何?我对 LINQ 的内部工作方式不够熟悉,无法知道其中一个是否会比另一个更好。如果有帮助,可以对 pDefinedRoles 参数使用列表而不是数组。
    • 列表和数组在性能方面大致相同(存在一些差异,但除非您处理大数据,否则通常没关系)。通常来说,LINQ 更“漂亮”,但性能不如其他笨重的代码。当然,每种情况都不同,LINQ 当然也有它的位置。如果您的数组/列表/集合中没有数千个要查询的项目,则通常可以使用 LINQ 而不会产生明显的开销。
    猜你喜欢
    • 1970-01-01
    • 2013-02-25
    • 2022-08-11
    • 2014-11-23
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多