Note that there are some explanatory texts on larger screens.

plurals
  1. PO
    primarykey
    data
    text
    <p>This can be done, as mentioned, with the help of Reflection Emit and a helper class I've included below. The code below is a work in progress, so take it for what it's worth... 'it works on my box'. The SelectDynamic method class should be tossed in a static extension method class.</p> <p>As expected, you won't get any Intellisense since the type isn't created until runtime. Works good on late-bound data controls.</p> <pre><code>public static IQueryable SelectDynamic(this IQueryable source, IEnumerable&lt;string&gt; fieldNames) { Dictionary&lt;string, PropertyInfo&gt; sourceProperties = fieldNames.ToDictionary(name =&gt; name, name =&gt; source.ElementType.GetProperty(name)); Type dynamicType = LinqRuntimeTypeBuilder.GetDynamicType(sourceProperties.Values); ParameterExpression sourceItem = Expression.Parameter(source.ElementType, "t"); IEnumerable&lt;MemberBinding&gt; bindings = dynamicType.GetFields().Select(p =&gt; Expression.Bind(p, Expression.Property(sourceItem, sourceProperties[p.Name]))).OfType&lt;MemberBinding&gt;(); Expression selector = Expression.Lambda(Expression.MemberInit( Expression.New(dynamicType.GetConstructor(Type.EmptyTypes)), bindings), sourceItem); return source.Provider.CreateQuery(Expression.Call(typeof(Queryable), "Select", new Type[] { source.ElementType, dynamicType }, Expression.Constant(source), selector)); } public static class LinqRuntimeTypeBuilder { private static readonly ILog log = LogManager.GetLogger(System.Reflection.MethodBase.GetCurrentMethod().DeclaringType); private static AssemblyName assemblyName = new AssemblyName() { Name = "DynamicLinqTypes" }; private static ModuleBuilder moduleBuilder = null; private static Dictionary&lt;string, Type&gt; builtTypes = new Dictionary&lt;string, Type&gt;(); static LinqRuntimeTypeBuilder() { moduleBuilder = Thread.GetDomain().DefineDynamicAssembly(assemblyName, AssemblyBuilderAccess.Run).DefineDynamicModule(assemblyName.Name); } private static string GetTypeKey(Dictionary&lt;string, Type&gt; fields) { //TODO: optimize the type caching -- if fields are simply reordered, that doesn't mean that they're actually different types, so this needs to be smarter string key = string.Empty; foreach (var field in fields) key += field.Key + ";" + field.Value.Name + ";"; return key; } public static Type GetDynamicType(Dictionary&lt;string, Type&gt; fields) { if (null == fields) throw new ArgumentNullException("fields"); if (0 == fields.Count) throw new ArgumentOutOfRangeException("fields", "fields must have at least 1 field definition"); try { Monitor.Enter(builtTypes); string className = GetTypeKey(fields); if (builtTypes.ContainsKey(className)) return builtTypes[className]; TypeBuilder typeBuilder = moduleBuilder.DefineType(className, TypeAttributes.Public | TypeAttributes.Class | TypeAttributes.Serializable); foreach (var field in fields) typeBuilder.DefineField(field.Key, field.Value, FieldAttributes.Public); builtTypes[className] = typeBuilder.CreateType(); return builtTypes[className]; } catch (Exception ex) { log.Error(ex); } finally { Monitor.Exit(builtTypes); } return null; } private static string GetTypeKey(IEnumerable&lt;PropertyInfo&gt; fields) { return GetTypeKey(fields.ToDictionary(f =&gt; f.Name, f =&gt; f.PropertyType)); } public static Type GetDynamicType(IEnumerable&lt;PropertyInfo&gt; fields) { return GetDynamicType(fields.ToDictionary(f =&gt; f.Name, f =&gt; f.PropertyType)); } } </code></pre>
    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.
    3. 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