Feb 25, 2012 at 1:21 PM
Edited Mar 20, 2012 at 3:09 PM
|
1)
Take isn't supported, but it's pretty easy to add it yourself. All of these changes are made to the DirectorySource class. Just create a nullable class variable that gets set in the Parse method for Take. I've highlighted the changes below:
public void Parse(Expression ex)
{
var ce = ex as ConstantExpression;
var mce = ex as MethodCallExpression;
if (ce != null)
{
_source = ce.Value as IDirectorySource;
originalType = _source.OriginalType;
}
else if (mce != null)
{
//
// Should be extension methods on Queryable.
//
if (mce.Method.DeclaringType != typeof(Queryable))
throw new NotSupportedException("Detected invalid top-level method-call.");
Parse(mce.Arguments[0]);
//
// First parameter to the method call represents the (unary) lambda in LINQ style.
// E.g. (user => user.Name == "Bart") for a Where clause
// (user => new { user.Name }) for a Select clause
//
switch (mce.Method.Name)
{
//
// Builds the query LDAP expression.
//
case "Where":
BuildPredicate(((UnaryExpression)mce.Arguments[1]).Operand as LambdaExpression);
break;
//
// Builds the projection and filters the required properties.
//
case "Select":
BuildProjection(((UnaryExpression)mce.Arguments[1]).Operand as LambdaExpression);
break;
case "Take":
_takeValue = (int)((ConstantantExpression)mce.Arguments[0]).Value;
break;
default:
throw new NotSupportedException("Unsupported query operator: " + mce.Method.Name);
}
}
else
throw new NotSupportedException("Invalid expression node detected.");
}
Once that's done you just need to check it and set it when you perform a search:
private IEnumerator<T> GetResults()
{
DirectorySchemaAttribute[] attr = (DirectorySchemaAttribute[])originalType.GetCustomAttributes(typeof(DirectorySchemaAttribute), false);
if (attr == null || attr.Length == 0)
throw new InvalidOperationException("Missing schema mapping attribute.");
string classQuery = String.Format("(objectClass={0})", attr[0].Schema);
DirectorySearcher s = Helpers.CloneSearcher(
_source.Searcher,
!string.IsNullOrEmpty(query) ? String.Format("(&{0}{1})", classQuery, query) : classQuery,
properties.ToArray()
);
if (_takeValue.HasValue) s.SizeLimit = _takeValue.Value;
//rest of method to perform search...
}
As for paging the results, LDAP doesn't really support paging the way LINQ expects it to work. Paging is kind of abstracted away and only exposed through a cookie returned from the server. You can read more about it here:
http://tools.ietf.org/html/rfc2696.
You can tell the DirectorySearcher to get everything by setting a sufficiently large PageSize, but getting a subset and then going to get more is not possible from what I can tell.
2)
You can filter by group. Just map the memberOf property as a string[] and do something like this:
context.Where(u => u.memberOf.Contains("[distinguished name of group]"))
This will find all users that are a member of that group.
|