0

I've ran into a problem while creating an data access layer for my application. I am working with derived entities in Entity Framework. If I try to create an ObjectSet for a derived Entity, I get this Exception:

Blockquote There are no EntitySets defined for the specified entity type 'Type Name'. If 'Type Name' is a derived type, use the base type instead.

I've tried to resolve this problem via Reflection. (if the Entity Type is derived by an Entity Type => get an ObjectSet for the base Type)

I found this: How can I obtain ObjectSet<T> from Entity-Framework at runtime where T is dynamic? but I haven't found how to use Include and Where on the built up ObjectSet.

protected IEnumerable<IDataObject> GetData(Type entityType, Expression<Func<dynamic, bool>> whereClause, Expression<Func<dynamic, dynamic>>[] includes)
    {
        if (typeof(IDataObject).IsAssignableFrom(entityType.BaseType))
        {
            return GetData(entityType.BaseType, whereClause, includes);
        }
        var contextType = this.Context.GetType();
        MethodInfo createObjectSetMethod = contextType.GetMethod("CreateObjectSet", new Type[] {}).MakeGenericMethod(entityType);
        // Builds up an ObjectSet<EntityType> 
        dynamic objectSet = createObjectSetMethod.Invoke(this.Context, new object[] { });
        dynamic query = objectSet;
        if (includes != null)
        {
            foreach (var include in includes)
            {
                query = query.Include(include);
            }
        }
        if (whereClause == null)
        {
            whereClause = (item) => true;
        }
        query = query.Where(whereClause);
        return query.ToList().OfType<IDataObject>();
    }

The code runs as intended, as long I don't use the Includes and WhereClause. When I call this function I dont know the resolved ObjectSet (T-Parameter) at compile time.
Is there any way to use dynamic Expressions in an generic ObjectSet?

Thanks in advance.

Community
  • 1
  • 1
greg-e
  • 152
  • 1
  • 9

1 Answers1

1

The issue looks to be with the

query = query.Include(include);

the var include would be an Expression<Func<dynamic,dynamic>>

The Include Method you access is expecting a string or Expression<Func<T, TProperty>>

Have you tried to pass the include as a string path? I would expect that to work.

Otherwise you need to construct the expression tree with code since you cant pass Dynamic objects to

 public static IQueryable<T> Include<T, TProperty>(this IQueryable<T> source, Expression<Func<T, TProperty>> path) where T : class;

There is also dynamic linq library to can check out. System.Linq.Dynamic can be found at following links http://msdn.microsoft.com/en-US/vstudio/bb894665.aspx with an intro here http://www.scottgu.com/blogposts/dynquery/dynamiclinqcsharp.zip

This is an easier alternative using text to build expression trees. Building expressions trees with code is more powerful and flexible but harder.

phil soady
  • 10,013
  • 4
  • 44
  • 82
  • I've found this: http://stackoverflow.com/questions/2789504/get-the-property-as-a-string-from-an-expressionfunctmodel-tproperty . This does the job of converting Expressions to strings. Combined with your solution it allows to Include on unknown EntityType. Thanks a lot. – greg-e Jul 18 '13 at 09:41