I use: EntityFramework + POCO
Here is the thing:
public interface IBaseType
{
int Id { get; set; }
}
public class BaseType : IBaseType
{
public virtual int Id { get; set; }
}
public class DerivedType : BaseType
{
}
The problem:
public class EntityFetcher<T> where T : BaseType
{
public object GetById(int id)
{
ObjectSet<T> objectSet = (ObjectSet<T>)GetTheObjectSet(typeof(T));
return objectSet.SingleOrDefault((o) => o.Id == id);
}
}
If T
is BaseType
this all works perfectly, but:
The problem is that in EntityFramework when one class inherits another they share the ObjectSet
and, therefore, if T
is DerivedType
then the GetTheObjectSet
returns ObjectSet<BaseType>
, which cannot be cast to ObjectSet<DerivedType>
.
Is there a way to actually cast this this thing or somehow else execute the SingleOrDefault
? Can those things be cast using the IObjectSet<>
and IBaseType
?
The answer to this casting problem was as follows:
The solution was to cast ObjectSet to ObjectQuery and do the query there. The most important part here is that ObjectQuery is not generic, so the cast goes through fine.
I must give some credits to Bennor McCarthy as he was the one to point me to OfType + casting to ObjectQuery (the fact that ObjectSet : ObjectQuery). Thanks!
I checked one of my test projects which is currently far away from buildable state but this worked for me before:
The main point is that Entity class is not modeled in EDMX file. All entities modeled in EDMX file has its own Id and Timestamp but my POCO classes use shared base class. I used Repository<PocoData> without any problem.
I think you're looking for this:
The OfType method of an ObjectQuery (which ObjectSet derives from) will return objects of the derived type.