2

I used a modified version of this answer: How to dynamically create a class in C#? to create a dynamic object that represents a typed class.

public static object CreateNewObject(string[] columnNames)
{
    var myType = CompileResultType(columnNames);
    return Activator.CreateInstance(myType) as IQueryable;

}

Then in the main app:

var obj = MyTypeBuilder.CreateNewObject(rs.ColumnNames);

I need to somehow convert that to an IQueryable so I can do some Linq calls off it, such as .where(), .select() ect. Naturally, I am not currently able to because my app doesn't know what is exactly in that object, or what that object is.

So what I need is:

var obj = MyTypeBuilder.CreateNewObject(rs.ColumnNames);
List<obj> aListICanFill = new List<obj>();

..

aListICanFill.where(x => x.Equals("")).take(3);

I've blindly tried different casts, and even failed to try an iterate through the object - and now I'm completley stuck.

Is there any way to do this?

http://msdn.microsoft.com/en-us/library/bb882637.aspx seems to be something I should hook onto.
What my object looks like:

enter image description here

Community
  • 1
  • 1
TheGeekZn
  • 3,696
  • 10
  • 55
  • 91
  • What syntax exactly do you need? {array of your objects}.Select(...) or {your object}.Select(...) ? – galenus Nov 03 '14 at 07:48
  • Have you tried implementing `IQueryable` on your class? Or maybe what you really want is a `List` that you can do `.Where()` on? – Rufus L Nov 03 '14 at 07:52
  • So this object will be my class - something like `List` would be the best case scenario. – TheGeekZn Nov 03 '14 at 07:58
  • @RufusL it returns as an object though, not a class... – TheGeekZn Nov 03 '14 at 07:59
  • @SemiDemented if you want this, an anonymous class is NOT the way you should go. Check this thread http://stackoverflow.com/questions/191013/can-a-c-sharp-anonymous-class-implement-an-interface However, you can make a List of Objects `List` – Royal Bg Nov 03 '14 at 08:07
  • @RoyalBg I really do need to create this class dynamically though... – TheGeekZn Nov 03 '14 at 08:08
  • Them you can try with `List` but you will have hard time invoking properties from the object while querying ... – Royal Bg Nov 03 '14 at 08:10
  • Can you use a List? Then you can use Where and Select Linq methods. `var items = new List() { new { Name = "A", Age = 10 }, new { Name = "B", Age = 20 }, new { Name = "C", Age = 30 }, }; items.Where(item => item.Age > 20).Dump();` – Shane Nov 03 '14 at 08:10
  • @Shane Sorry for the ignorance, but how could I use the object in a dynamic list? Could you maybe provide more info in an answer? – TheGeekZn Nov 03 '14 at 08:12
  • @Shane I feel that the same issue with the types will have here after querying the collection. One cannot explicitly invoke `item.Name` while iterating through the List for example. Oh, I now saw the whole comment. Is that really possible in the `Where`, because I think it will not let you call `Age`, but I don't have anywhere to test it now – Royal Bg Nov 03 '14 at 08:14

2 Answers2

2

If you can use List<dynamic> you can use Where and Select IEnumerable<T> extension methods like below. This does not work with IQueryable because those methods require an Expression which cannot be dynamic.

using System;
using System.Collections.Generic;
using System.Linq;

namespace DynamicListTest
{
   internal class Program
   {
      private static void Main(string[] args)
      {
         var dynamicObjects = GetDynamicObjects().Cast<dynamic>().AsEnumerable();

         var itemsToPrint = dynamicObjects
            .Where(item => item.Age > 30);

         foreach (var item in itemsToPrint)
         {
            Console.WriteLine(item);
         }

         Console.ReadKey();
      }

      private static IQueryable GetDynamicObjects()
      {
         return new List<dynamic>()
         {
            new { Name = "A", Age = 10 },
            new { Name = "B", Age = 20 },
            new { Name = "C", Age = 30 },
            new { Name = "D", Age = 40 },
            new { Name = "E", Age = 50 },
         }.AsQueryable();
      }
   }
}

This prints

{ Name = D, Age = 40 }

{ Name = E, Age = 50 }

Shane
  • 429
  • 3
  • 6
  • In my case, `GetDynamicObjects` returns an object dynamically filled, not a convenient List. This will work if I could convert the object to a List, which I was originally trying to do. – TheGeekZn Nov 03 '14 at 08:23
  • @SemiDemented Oh OK it helps seeing the code. I have edited my answer to use an IQueryable as the source data, does this help you? Note that it has to be converted to IEnumerable first. – Shane Nov 03 '14 at 08:37
0

check out linq to objects

http://msdn.microsoft.com/en-us/library/bb397919.aspx

Hopefully your object contains an array?

Could you give a sample of how you want to query it? And also what CompileResultType does?

var myType = CompileResultType(columnNames); 

EDIT

For future reference - as suggested by Shane - OP is trying out - Dynamic Linq dynamiclinq.codeplex.com

Chris McKelt
  • 1,378
  • 2
  • 17
  • 38
  • I've updated my Q with what my object looks like - so something like `myType.Where(x => x.CompanyName == "Test").Take(3);` – TheGeekZn Nov 03 '14 at 08:29
  • ok try something like this -- return ((IEnumerable)Activator.CreateInstance(myType)).AsQueryable(); – Chris McKelt Nov 03 '14 at 08:30
  • Remember this is just the names for a dynamic class - there is no data yet... However I get this error: `Unable to cast object of type 'MyDynamic' to type 'System.Collections.IEnumerable'.` – TheGeekZn Nov 03 '14 at 08:33
  • try using an ExpandoObject - http://msdn.microsoft.com/en-us/library/system.dynamic.expandoobject(v=vs.110).aspx sample - http://stackoverflow.com/questions/18747058/is-it-possible-to-query-list-of-expandoobject – Chris McKelt Nov 03 '14 at 08:40
  • That seems to have very specific types - I can't see how I will be able to create an ExpandoObject without knowing what I want. – TheGeekZn Nov 03 '14 at 08:43
  • ExpandoObject allows you to add/remove properties add runtime - all dynamically - your linq will run but not be type safe -- to clarify your problem - are you trying to create a dynamic object from given column names? With values stored against these column keys? – Chris McKelt Nov 03 '14 at 08:46
  • Let us [continue this discussion in chat](http://chat.stackoverflow.com/rooms/64158/discussion-between-semidemented-and-chris-mckelt). – TheGeekZn Nov 03 '14 at 08:48
  • For future reference - as suggested by Shane - OP is trying out - Dynamic Linq http://dynamiclinq.codeplex.com/ – Chris McKelt Nov 03 '14 at 09:10