Entity Framework: context.CreateObjectSet<T> derived entity issue

3.5k views Asked by At

I am using EF6 ObjectContext generator which means our entities inherit from EntityObject.

I am trying to implement a generic repository for simple CRUD operations but I've got a specific problem when it comes to derived entities. I can't get the right code to handle this generically despite many different attempts!

public DataRepository(ObjectContext context)
    {
        _context = context;
        _objectSet = _context.CreateObjectSet<T>();

        Type baseType = GetBaseEntityType();

        if (baseType == typeof(T))
            _objectSet = _context.CreateObjectSet<T>();
        else
            // how to create the objectset here?
            // I have tried the below but it blows up at runtime with an invalid cast exception
            _objectSet = (IObjectSet<T>)Activator.CreateInstance(typeof(ObjectSetProxy<,>).MakeGenericType(typeof(T), baseType), context);
    }

I have read through

Entity Framework: ObjectSet and its (generics) variance

but this seems to be targeted at getting an ObjectQuery rather than an ObjectContext. Any help greatly appreciated. :o)

Update: If there aren't any clean solutions for this are there any workarounds people can think of? I considered an auto-generated list of derived entities with a check on the type etc but as it's a generic repo it must ultimately use IObjectSet, so the following lines fail anyway with an invalid cast _objectSet = (IObjectSet) _context.CreateObjectSet();

2

There are 2 answers

1
Francis Ducharme On

This might be of interest. I don't know if the behaviour was changed in version 6 though.

0
Rick Blyth On

I've ended up sorting this out myself. Passing in the base and derived entities (we only ever have one level of inheritance). Here's a flavour of how it looks in case anybody else needs a pointer ....

public class DataRepository : IRepository where TBaseEntity : EntityObject where TDerivedEntity : TBaseEntity { protected static Ent ctx{get{return DBContextManager.GetDBContext();}}

    private ObjectContext _context;
    private readonly ObjectSet<TBaseEntity> _objectSet;
    public DataRepository(): this(DBContextManager.GetDBContext()){}

    public DataRepository(ObjectContext context)
    {
        _context = context;
        _objectSet = _context.CreateObjectSet<TBaseEntity>();
    }

    private ObjectQuery<TDerivedEntity> TypedObjectSet
    {
        get
        {
            return _objectSet.OfType<TDerivedEntity>();
        }
    }

    public IEnumerable<TDerivedEntity> Find(Expression<Func<TDerivedEntity, bool>> predicate)
    {
        return TypedObjectSet.Where(predicate);
    }

    public TDerivedEntity Single(Func<TDerivedEntity, bool> predicate)
    {
        return TypedObjectSet.Single(predicate);
    }

    // etc etc