1

Currently my code is:

using (var context = new PrincipalContext(ContextType.Domain, adDomain))
{
    using (var searcher = new PrincipalSearcher(new UserPrincipal(context)))
    {
        foreach (Principal result in searcher.FindAll())
        {
            DirectoryEntry entry = result.GetUnderlyingObject() as DirectoryEntry;
            if (entry.Properties["Company"].Value?.ToString() == "My Company")
            {
                // do some stuff
            }
        }
    }
}

I was just wondering if it would be possible to do a LINQ statement instead of the if statement to only get entries I am interested in.

Something like this:

foreach (var entry in searcher.FindAll()
    .Where(x => x.GetUnderlyingObject<DirectoryEntries>()
    .Properties["Company"].Value?.ToString() == "MY Company"))
{
    // do some stuff
}
Lews Therin
  • 3,707
  • 2
  • 27
  • 53
Bryan Dellinger
  • 4,724
  • 7
  • 33
  • 79
  • It actually returns object. And Bryan you don't have generic `GetUnderlayingObject` method add `Cast()` after `Where`... – Johnny Mar 12 '19 at 18:13
  • Please take a look again. I follow your link. Return type is object. – Johnny Mar 12 '19 at 18:16
  • 1
    @Johnny My mistake. The wording in the description that I pasted is what made me think that. You are correct. I've deleted my comments to eliminate confusion. – Lews Therin Mar 12 '19 at 18:17

3 Answers3

3

It should be possible. You can use Select() first to cast the object to the DirectoryEntry's. Something like this should work:

var entry = searcher.FindAll()
    .Select(x => (DirectoryEntry)x.GetUnderlyingObject())
    .Where(x => x.Properties["Company"].Value?.ToString() == "My Company")
    .FirstOrDefault();  // or .ToList() depending on your requirements

if (entry != null)
{
    // do some stuff
}
haldo
  • 14,512
  • 5
  • 46
  • 52
  • Good call on the `Select` to do the casting and the `GetDirectoryEntry()` call. I fixed my answer after reading this. Upvoted. – Lews Therin Mar 12 '19 at 18:19
1

You shouldn't need the foreach. Try this:

var myCompany = searcher.FindAll()
    .Select(x => (DirectoryEntry)x.GetUnderlyingObject())
    .Where(x => x.Properties["Company"].Value?.ToString() == "MY Company")
    .ToList();

if (myCompany != null)
    // Do something with myCompany

Off-topic: You can stack using statements to eliminate some nesting:

using (var context = new PrincipalContext(ContextType.Domain, adDomain))
using (var searcher = new PrincipalSearcher(new UserPrincipal(context)))
{
    // Do stuff
}
Lews Therin
  • 3,707
  • 2
  • 27
  • 53
0

Yeah Bryan, that looks like a solution. I don´t have the types of everything to test it, but that with a ToList() at the end to allow the foreach to iterate should work.

I would put it above the foreach in a var to see the list it produces before iterating.

Matt
  • 319
  • 2
  • 7
  • well at the moment it gives a compile error stating PrincipalGetInderLyingObject() cannot be used with type arguments. hold on I'll make a fiddle. – Bryan Dellinger Mar 12 '19 at 18:08