使用linq和PropertyValueCollection

时间:2012-08-27 17:19:49

标签: linq

我想知道使用Linq是否有办法或更有效的方法。而不是使用while循环,是否可以使用 Linq查询进行选择?

  public UserPrincipal GetUser(string sUserName, string spwd, string domain, string ou)
    {
        PrincipalContext oPrincipalContext = new PrincipalContext(ContextType.Domain, domain, ou, sUserName, spwd);


        UserPrincipal oUserPrincipal = UserPrincipal.FindByIdentity(oPrincipalContext, sUserName);

        DirectoryEntry user = (DirectoryEntry)oUserPrincipal.GetUnderlyingObject();
        PropertyCollection pc = user.Properties;
        IDictionaryEnumerator ide = pc.GetEnumerator();

        ide.Reset();

        while (ide.MoveNext())
        {
            PropertyValueCollection pvc = ide.Entry.Value as PropertyValueCollection;
            if (ide.Entry.Key.ToString() == "XYZ")
            {
                //Response.Write(string.Format("name: {0}", ide.Entry.Key.ToString()));
                //Response.Write(string.Format("Value: {0}", pvc.Value));

            }

        }
    .......;
    .......;


    }

谢谢!

3 个答案:

答案 0 :(得分:1)

您无法在Where()上使用PropertyCollection的原因是因为当IEnumerable是仅包含通用版本的方法时,它会实现非通用Where() 。您可以使用Cast<T>()PropertyCollection转换为通用IEnumerable

var matches = pc.Cast<DictionaryEntry>().Where(p => p.Key.ToString() == "XYZ");

foreach( var match in matches )
{
    Response.Write(string.Format("name: {0}", match.Key));
    Response.Write(string.Format("Value: {0}", match.Value));
}

这种方式无疑更有效率。

答案 1 :(得分:0)

试试这个:

        foreach (PropertyValueCollection pvc in pc.OfType<PropertyValueCollection>().Where(v => v.PropertyName == "XYZ"))
        {
            Response.Write(string.Format("name: {0}", pvc.PropertyName));
            Response.Write(string.Format("Value: {0}", pvc.Value));
        }

此外,您可以尝试使用ForEach

        pc.OfType<PropertyValueCollection>()
          .Where(v => v.PropertyName == "XYZ")
          .ToList()
          .ForEach(pvc =>
          {
              Response.Write(string.Format("name: {0}", pvc.PropertyName));
              Response.Write(string.Format("Value: {0}", pvc.Value));
          });

答案 2 :(得分:0)

这是一个非常古老的线程,但我正在寻找一种使用LINQ来使用PropertyCollection的方法。我尝试了建议的方法,但在转换为DictionaryEntry时总是得到一个无效的强制转换异常。使用DictionaryEntry,像FirstOrDefault这样的东西很时髦。所以,我只是这样做:

var directoryEntry = adUser.GetUnderlyingObject() as DirectoryEntry;
directoryEntry.RefreshCache();
var propNames = directoryEntry.Properties.PropertyNames.Cast<string>();
var props = propNames
    .Select(x => new { Key = x, Value = directoryEntry.Properties[x].Value.ToString() })
    .ToList();

有了这个,我就可以直接通过Key轻松查询任何属性。使用合并和安全导航操作符允许默认为空字符串或其他..

var myProp = props.FirstOrDefault(x => x.Key == "someKey"))?.Value ?? string.Empty;

请注意&#34; adUser&#34; object是UserPrincipal对象。