当前位置:  开发笔记 > 编程语言 > 正文

使LINQ Query可以访问NameValueCollection

如何解决《使LINQQuery可以访问NameValueCollection》经验,为你挑选了4个好方法。

如何使NameValueCollectionLINQ查询运算符可以访问,例如where,join,groupby?

我试过以下:

private NameValueCollection RequestFields()
{
    NameValueCollection nvc = new NameValueCollection()
                                  {
                                      {"emailOption: blah Blah", "true"},
                                      {"emailOption: blah Blah2", "false"},
                                      {"nothing", "false"},
                                      {"nothinger", "true"}
                                  };
    return nvc;

}

public void GetSelectedEmail()
{
    NameValueCollection nvc = RequestFields();
    IQueryable queryable = nvc.AsQueryable();
}

但我得到一个ArgumentException告诉我源不是IEnumerable <>.



1> Bryan Watts..:

你需要的"升降机"的非通用IEnumerableIEnumerable.有人建议您使用OfType但这是一种过滤方法.你正在做的是相当于一个演员,有Cast运营商:

var fields = RequestFields().Cast();

正如弗兰斯指出的那样,这只能提供对密钥的访问.您仍然需要为值集合索引.这是一个KeyValuePair从以下方法中提取s 的扩展方法NameValueCollection:

public static IEnumerable> ToPairs(this NameValueCollection collection)
{
    if(collection == null)
    {
        throw new ArgumentNullException("collection");
    }

    return collection.Cast().Select(key => new KeyValuePair(key, collection[key]));
}

编辑:为响应@Ruben Bartelink的请求,以下是如何使用以下方法访问每个密钥的完整值集ToLookup:

public static ILookup ToLookup(this NameValueCollection collection)
{
    if(collection == null)
    {
        throw new ArgumentNullException("collection");
    }

    var pairs =
        from key in collection.Cast()
        from value in collection.GetValues(key)
        select new { key, value };

    return pairs.ToLookup(pair => pair.key, pair => pair.value);
}

或者,使用C#7.0元组:

public static IEnumerable<(String name, String value)> ToTuples(this NameValueCollection collection)
{
    if(collection == null)
    {
        throw new ArgumentNullException("collection");
    }

    return
        from key in collection.Cast()
        from value in collection.GetValues(key)
        select (key, value);
}


警告.你可以用这种方式错过一些价值观.一个键可以分配多个值,请参阅方法GetValues.
一个用于utils lib :)

2> Amy B..:

AsQueryable必须采取IEnumerable一个通用的.NameValueCollection工具IEnumerable,这是不同的.

而不是这个:

{
    NameValueCollection nvc = RequestFields();
    IQueryable queryable = nvc.AsQueryable();
}

试试OfType(它接受非通用接口)

{
    NameValueCollection nvc = RequestFields();
    IEnumerable canBeQueried = nvc.OfType();
    IEnumerable query =
       canBeQueried.Where(s => s.StartsWith("abc"));
}


-1如其他答案中所述,如果我再次看到并且文本中没有OfType,则应该是Cast,而不是OfType,注释和downvote会消失.
来自Heljsberg的http://social.msdn.microsoft.com/forums/en-US/linqprojectgeneral/thread/fe6c7c84-5f99-484a-99de-b331d4c88b76/:"所有这一切都在SP1中得到修复"

3> Orion Adrian..:

字典实际上可能更接近您想要使用的字典,因为它实际上将填充NameValueCollection填充的更多角色.这是Bryan Watts解决方案的变体:

public static class CollectionExtensions
{
    public static IDictionary ToDictionary(this NameValueCollection source)
    {
        return source.Cast().Select(s => new { Key = s, Value = source[s] }).ToDictionary(p => p.Key, p => p.Value); 
    }
}


仍然不是很好.NameValueCollection实际上大致是`IDictionary >`.对于一些应该保留的用例.`ILookup`是你真正需要的.类似于`souce.Cast ().SelectMany(s => source.GetValues(s).Select(t => new {Key = s,Value = t})).ToLookup(p => p.Key ,p值=> p.Value)`.由于ILookup是专门为Linq创建的,所以这对Linq非常有用.

4> NinjaNye..:

我知道我迟到了,但只是想添加我的答案,不涉及.Cast扩展方法,而是使用AllKeys属性:

var fields = RequestFields().AllKeys;

这将允许以下扩展方法:

public static IEnumerable> ToPairs(this NameValueCollection collection)
{
    if(collection == null)
    {
        throw new ArgumentNullException("collection");
    }

    return collection.AllKeys.Select(key => new KeyValuePair(key, collection[key]));
}

希望这有助于未来的访客

推荐阅读
U友50081205_653
这个屌丝很懒,什么也没留下!
DevBox开发工具箱 | 专业的在线开发工具网站    京公网安备 11010802040832号  |  京ICP备19059560号-6
Copyright © 1998 - 2020 DevBox.CN. All Rights Reserved devBox.cn 开发工具箱 版权所有