Dynamic Querying
Sometimes you may want to forgo mapping. I can't support .Net's dynamics for byte array
performance reasons so I created the DirectoryAttributes class. Whenever you perform a query without specifying a type, IDirectoryAttributes will be the return type. You can't use property expressions, but
custom filters can be used:
var query = context.Query(namingContext, objectClass: "Person")
.Where(da => (Filter.Equal(da, "givenname", "Andrew") &&
Filter.Equal(da, "sn", "Fuller")) || Filter.Equal(da, "cn", "Andrew Fuller"));
IDirectoryAttributes user = query.FirstOrDefault();
//Produces this filter:
(&(objectClass=Person)(|(&(givenname=Andrew)(sn=Fuller))(cn=Andrew Fuller)))
Selects
You can either pass in an array of attributes or use a projection. The projection will use the attribute names passed to the Get methods to determine which attributes to retrieve.
var query = context.Query(namingContext, objectClass: "Person")
.Where("cn=Andrew Fuller")
.Select("cn", "objectguid", "employeeid");
var query = context.Query(namingContext, objectClass: "Person")
.Where("cn=Andrew Fuller")
.Select(da => new { EmployeeId = da.GetInt("employeeid"), CommonName = da.GetString("cn"), Guid = da.GetGuid("objectguid") });
Accessing Results
Retrieving results from the DirectoryAttributes class is case insensitive. If the attribute is not found then null will be returned. Since everything is either a string or byte array from the directory, if it fails to convert then a FormatException will be thrown. This primarily applies to numbers, bools, Guids, DateTimes, and SecurityIdentifiers. DateTimes can be accessed similarly to the mapping rules
here.
IDirectoryAttributes user = query.FirstOrDefault();
if (user != null)
{
int? employeeId = user.GetInt("EMPLOYEEID");
Guid? guid = user.GetGuid("ObjectGuid");
DateTime? whenChanged = user.GetDateTime("WhenChanged", "yyyyMMddHHmmss.0Z");
DateTime? passwordLastSet = user.GetDateTime("passwordlastset", null);
SecurityIdentifier sid = user.GetSecurityIdentifier("objectsid");
DirectoryAttribute photoAttribute = user.Get("photo");
}