Note that there are some explanatory texts on larger screens.

plurals
  1. PO
    primarykey
    data
    text
    <p>You can try creating a dynamic expression at runtime. You shouldn't have to explicitly cast the IQueryable back to it's generic type, as long as you don't change the element types with a "Select". </p> <p>Example:</p> <pre><code> public class SecurityHandler : ICallHandler { public IMethodReturn Invoke(IMethodInvocation input, GetNextHandlerDelegate getNext) { var message = getNext()(input, getNext); var returnType = message.ReturnValue.GetType(); if (typeof(IQueryable).IsAssignableFrom(returnType)) { var entityType = returnType.GetGenericArguments().Single(); var securableAttribute = entityType.GetAttribute&lt;SecurableTypeAttribute&gt;(); if (securableAttribute != null) { //Build expression to filter the list from the attribute and primary key of the entity //Return the new IQueryable message.ReturnValue = AddWhereExpression( (IQueryable)message.ReturnValue, securableAttribute.FilterValues, securableAttribute.FilterPropertyName); } } return message; } public int Order { get; set; } private static IQueryable AddWhereExpression(IQueryable query, IEnumerable ids, string filterPropertyName) { // Build this expression: // item =&gt; ids.Contains(item.[PrimaryKeyPropertyName]) var itemParameter = Expression.Parameter(query.ElementType, "item"); var itemParameterProperty = Expression.Property(itemParameter, filterPropertyName); var listParameter = Expression.Constant(ids); var containsExpression = Expression.Call( typeof(System.Linq.Enumerable), "Contains", new[] { typeof(int) }, listParameter, itemParameterProperty); var delegateTypeExpression = Expression.GetFuncType(new[] { query.ElementType, typeof(bool) }); var whereExpression = Expression.Lambda( delegateTypeExpression, containsExpression, new[] { itemParameter } ); Expression callWhere = Expression.Call( typeof(Queryable), "Where", new Type[] { query.ElementType }, // type args for Where&lt;T&gt;() query.Expression, whereExpression ); return query.Provider.CreateQuery(callWhere); } } </code></pre> <p>I am assuming your attribute will provide some array of allowable values.</p> <p>Here are some extension methods that will help with this process:</p> <pre><code>public static class TypeExtensions { public static TAttribute GetAttribute&lt;TAttribute&gt;(this Type type) { var attributes = type.GetCustomAttributes(typeof(TAttribute), true); if (attributes.Length == 0) return default(TAttribute); return (TAttribute)attributes[0]; } public static PropertyInfo GetPropertyWithAttributeValue&lt;TAttribute&gt;( this IEnumerable&lt;PropertyInfo&gt; properties, Func&lt;TAttribute, bool&gt; findPredicate) where TAttribute : Attribute { var property = from p in properties where p.HasAttribute&lt;TAttribute&gt;() &amp;&amp; findPredicate.Invoke(p.GetAttribute&lt;TAttribute&gt;()) select p; return property.FirstOrDefault(); } public static bool HasAttribute&lt;TAttribute&gt;(this PropertyInfo propertyInfo) { return propertyInfo.GetCustomAttributes(typeof(TAttribute), true).Any(); } public static TAttribute GetAttribute&lt;TAttribute&gt;(this PropertyInfo propertyInfo) { var attributes = propertyInfo.GetCustomAttributes(typeof(TAttribute), true); if (attributes.Length == 0) return default(TAttribute); return (TAttribute)attributes[0]; } } </code></pre> <p>I haven't tried running this myself, but hopefully it's enough to get you started.</p>
    singulars
    1. This table or related slice is empty.
    plurals
    1. This table or related slice is empty.
    1. This table or related slice is empty.
    1. This table or related slice is empty.
    1. VO
      singulars
      1. This table or related slice is empty.
    2. VO
      singulars
      1. This table or related slice is empty.
 

Querying!

 
Guidance

SQuiL has stopped working due to an internal error.

If you are curious you may find further information in the browser console, which is accessible through the devtools (F12).

Reload