1

I am trying to create a completely dynamic way to query entity framework using entity sql, where the type T in ObjectQuery (the table name, or entity name) is not known at compile time, and is passed into a method as a string,

    public class EntityQuery
    {
         public ObjectContext Context { get; private set; }
         public string TableName { get; private set; }

         public EntityQuery(ObjectContext context, string sourceObject)
         {
              MemberInfo[] mInfo = context.GetType().GetMembers();

              TableName = sourceObject; 
              Context = context;

              if (!mInfo.Any<MemberInfo>(MemberInfo => MemberInfo.Name == TableName))
                   throw new EntityOperationException("Entity '" + TableName + "' does not exist in the object context.");
         }

         public ObjectQuery<dynamic> InitiateQuery(List<EntityFilter> filters)
         {
              string predicate = DynamicESQLBuilder.GetESQL(filters, Context.DefaultContainerName, TableName);
              string format = String.Format("[{0}]", predicate);

              ObjectQuery<dynamic> query = new ObjectQuery<dynamic>(predicate, Context, MergeOption.NoTracking);

              return query;
         }
}

The class DynamicESQLBuilder creates an entity sql command string based on the context name, table name, and entity filters passed in. The 'EntityFilter' class essentially encapsulates a single 'where' clause,

  public class EntityFilter
  {
      public ExpressionType OpType { get; private set; }
      public string PropertyName { get; private set; }
      public object Value { get; private set; }
  }

When I try to use it like this,

        MyDBModel db = new MyDBModel();

        List<EntityFilter> filters = new List<EntityFilter>()
        {
            new EntityFilter("Name", ExpressionType.Equal, "Sean")
        };

        EntityQuery query = new EntityQuery(db, "Person");

        var results = query.InitiateQuery(filters);

I get an error stating:

'Name' is not a member of type 'MyDBModel.Person' in the currently loaded schemas. Near simple identifier, line 1, column 74.

I am open to an entirely different way of doing this. But basically what I am trying to achieve is similar to what WCF OData services do behind the scenes -- I can query my model with just strings passed in - the name of the entity, the operation, the value, etc. No need for a strongly typed 'T' in my query.

Sean Thoman
  • 7,429
  • 6
  • 56
  • 103
  • Do you get this error only for the `Name` property of your `Person` class or for every property and every class? Did you check in the debugger what's exactly the content of `predicate` when you instantiate the `ObjectQuery`? – Slauma Jun 02 '11 at 17:22
  • It happens for all properties. Also if I modify this code only slightly so that I do have to pass in T (meaning strongly define the entity I want to query), then it works. The entity sql string (predicate) is identical though in the working and not working cases, so its not the string. – Sean Thoman Jun 02 '11 at 17:52

1 Answers1

1

If you have Entity SQL as a string and you don't mind doing things the old-school ADO.NET way, you can always use EntityConnection, EntityCommand, and EntityDataReader directly.

Joel Mueller
  • 28,324
  • 9
  • 63
  • 88
  • Thank you, this basically solved the problem. Had to do some other footwork using the System.Data.Metadata.Edm namespace as well. I do still get the error for certain columns though, but I think its some other issue. – Sean Thoman Jun 02 '11 at 18:23