How to make LinqToSql <TEntity> table as <IEntity> table where TEntity: IEntity?
I am trying to use DbLinq with a SQLite database, but I am having a problem when I try to use ITable
both Queryable<TEntity>
.
There is a known bug in DbLinq ( Issue 211 ) that may be the source of my problem, but I wanted to make sure my code sounds good, and if so, find out if there is something I can do to work around the bug.
Here is a common repository method that tries to throw:
public IQueryable<TEntity> GetAll()
{
return Table.Cast<TEntity>(); // Table is an ITable
}
This compiles, but if I pass in the interface IPerson
for TEntity
and the type of entities in the table is Person
(where Person : IPerson
) I get this error from DbLinq:
S0133: Execute QueryMethod Queryable.Cast.
Why am I trying to do this?
I have a library project that doesn't know the type of the object until runtime, but it knows the interface for the object. So I am trying to use the interface type so that the library project can use the data.
Questions:
- Am I trying to do the impossible or is this definitely a bug in DbLinq?
- How else can I fix the problem?
Update
I reworked my repository class so it now accepts TEntity
and TEntityBase
, where TEntity
is the actual type of the object, and TEntityBase
is the interface I am trying to implement. It's important to note that I now have the following suggestion where
in the class definition:
where TEntity : class, TEntityBase
This allows me to store the property Table
as Table<TEntity>
instead ITable
, which allows me to use AsEnumerable()
(as Steven suggested). Here's the revised method:
public IEnumerable<TEntityBase> GetAll()
{
return Table.AsEnumerable().Select(e => (TEntityBase)e);
}
For now, it looks like a trick.
a source to share
Sounds like a bug, but I understand that implementing a LINQ provider is an absolutely huge job. Even (Microsoft) LINQ to SQL and LINQ to Entities have their own limitations on what LINQ queries / operations they support or not.
If the return is IEnumerable<T>
acceptable, you can work around the lack of support Queryable.Cast
by calling AsEnumerable
before calling Cast
. However, this limits the use of DAL: since it is IQueryable<T>
no longer returned, further requests (for example Where
) will not be passed to the DB layer.
a source to share