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 ExpressionTyp开发者_StackOverflow中文版e 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.
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.
精彩评论