问题
I create a generic function to get a specific page for an EntityObject collection:
public static IList<EntityObject> GetPageItemsOfCollection(IQueryable<EntityObject> collectionIQueryable,
int startIndex,
int pageSize)
{
if (collectionIQueryable == null)
return null;
return collectionIQueryable.Skip(startIndex).Take(pageSize).ToList();
}
When I try to user this function like this:
IQueryable<EntityObjectSubClass> entityObjectSubClassIQueryable = GetEntityObjectSubClassIQueryableBySomeFilter(filter);
IList<EntityObjectSubClass> entityObjectSubClass = (IList<EntityObjectSubClass>) GetPageItemsOfCollection(entityObjectSubClassIQueryable, startIndex, pageSize)
Allways getting a cast error:
Unable to cast object of type
System.Collections.Generic.List[System.Data.Objects.DataClasses.EntityObject] to type System.Collections.Generic.IList[Models.EntityObjectSubClass].
Why this happen if the IList returned by the GetPageItemsOfCollection function contain elements of the EntityObjectSubClass type?
回答1:
IList<EntityObjectSubClass>
will not inherit from IList<EntityObjectClass>
, nor does it have the sort of contravariance that would allow this.
Consider that if we have an object that implements IList<EntityObjectClass>
, there's no reason why it need not be full of EntityObjectSomeOtherSubClass
objects. It is not capable of acting like IList<EntityObjectSubClass>
, so it can't be cast to that.
Your best approach is perhaps to reduce the GetPageItemsOfCollection
method down to doing the single task of obtaining a page, rather than of obtaining a page and putting it into a list:
public static IQueryable<EntityObject> GetPageItemsOfCollection(IQueryable<EntityObject> collectionIQueryable, int startIndex, int pageSize)
{
if (collectionIQueryable == null)
return null;
return collectionIQueryable.Skip(startIndex).Take(pageSize);
}
(Note that I return IQueryable
rather than IEnumerable
, you could opt to return IEnumerable
instead, but there's no reason not to allow further Linq operations to be done against the original query provider, so that e.g. GetPageItemsOfCollection(fromADB, 10, 10).Any()
could be executed fully on a database).
Then you could use the likes of:
GetPageItemsOfCollection(entityObjectSubClassIQueryable, startIndex, pageSize).Cast<EntityObjectSubClass>().ToList()
Of course, you could just use that anyway, without changing GetPageItemsOfCollection
, but you'd be creating a list, just to throw it away again when you create the second list you actually want.
回答2:
Try using the Cast<T>() method
GetPageItemsOfCollection(entityObjectSubClassIQueryable, startIndex,pageSize)
.Cast<EntityObjectSubClass>.ToList();
来源:https://stackoverflow.com/questions/23935200/cast-error-with-entity-framework-and-lists-in-c-sharp