我能够使用VS2008示例中的Dynamic Linq扩展,以一种非常合理的方式做到这一点。这是表示上述第二个伪代码示例的代码。它通过了我最初的单元测试,但我需要让它更健壮。
用途:
[RoleOrMemberAuthorization( UserTable = "Participants",
UserNameProperty = "UserName",
UserSelectionProperty = "ParticipantID",
JoinTable = "GroupLeaders",
EntityProperty = "GroupID",
UserEntityProperty = "ParticipantID",
RouteParameter = "id",
Roles = "SuperUser, ViewGroups" )]
被称为:
else if (IsRelated( filterContext,
this.GetTable( dc, this.JoinTable ),
this.GetTable( dc, this.UserTable ) ))
{
SetCachePolicy( filterContext );
}
相关来源:
protected bool IsRelated( AuthorizationContext filterContext,
IQueryable joinTable,
IQueryable userTable )
{
bool result = false;
try
{
object entityIdentifier = filterContext.RouteData
.Values[this.RouteParameter];
object userIdentifier = this.GetUserIdentifer( filterContext, userTable );
if (userIdentifier != null && entityIdentifier != null)
{
result = joinTable.Where( this.EntityProperty + "=@0 and "
+ this.UserEntityProperty + "=@1",
entityIdentifier,
userIdentifier )
.Count() > 0;
}
}
catch (NullReferenceException) { }
return result;
}
private object GetUserIdentifer( AuthorizationContext filterContext,
IQueryable userTable )
{
string userName = filterContext.HttpContext.User.Identity.Name;
var query = userTable.Where( this.UserNameProperty + "=@0", userName )
.Select( this.UserSelectionProperty );
object userIdentifer = null;
foreach (var value in query)
{
userIdentifer = value;
break;
}
return userIdentifer;
}
private IQueryable GetTable( DataContext context, string name )
{
PropertyInfo info = context.GetType().GetProperty( name );
if (info != null)
{
return info.GetValue( context, null ) as IQueryable;
}
else
{
return null;
}
}