Comment avez-vous jeté un tableau LinqToSql comme table où TEntity: IEntity?
-
26-09-2019 - |
Question
Je suis en train d'utiliser DbLinq avec une base de données SQLite, mais je suis en cours d'exécution dans un problème lorsque je tente de jeter un coup ITable
comme Queryable<TEntity>
.
Il y a un bug connu dans DbLinq ( d'émission 211 ), ce qui pourrait être la source de mon problème, mais je voulais vous assurer que mon code est son et, si elle est, savoir s'il pourrait y avoir quelque chose que je peux faire pour travailler autour du bug.
Voici la méthode référentiel générique qui tente de faire le casting:
public IQueryable<TEntity> GetAll()
{
return Table.Cast<TEntity>(); // Table is an ITable
}
Cette compiles, mais si je passe dans le IPerson
d'interface pour TEntity
et le type des entités dans le tableau est Person
(où Person : IPerson
), je reçois cette erreur DbLinq:
S0133:. Mettre en œuvre QueryMethod Queryable.Cast
Pourquoi je tente de le faire?
J'ai un projet de bibliothèque qui ne connaît pas le type de l'entité avant l'exécution, mais il ne connaît l'interface pour l'entité. Donc, je suis en train de caster le type d'interface pour que mon projet de bibliothèque peut consommer les données.
Questions:
- Suis-je tentais un casting impossible ou est-ce vraiment un bug dans DbLinq?
- Comment pourrais-je aller sur la résolution de mon problème?
Mise à jour
Je retravaillé ma classe repository donc il faut maintenant un TEntity
et un TEntityBase
, où TEntity
est le type réel de l'entité, et TEntityBase
est l'interface que je suis en train de caster. Il est important, j'ai maintenant la clause where
suivante dans ma définition de la classe:
where TEntity : class, TEntityBase
Cela me permet de stocker ma propriété Table
comme Table<TEntity>
au lieu d'un ITable
, ce qui me permet d'utiliser AsEnumerable()
(comme Stephen suggéré). Voici la méthode révisée:
public IEnumerable<TEntityBase> GetAll()
{
return Table.AsEnumerable().Select(e => (TEntityBase)e);
}
Et à ce jour, que semble pour faire l'affaire.
La solution
Cela ressemble à un bug, mais comprendre que la mise en œuvre d'un fournisseur de LINQ est un effort absolument énorme. Même le LINQ (Microsoft de) à SQL et LINQ aux entités ont leurs propres restrictions sur exactement les requêtes LINQ / opérations qu'ils soutiennent ou ne prennent pas en charge.
Si le retour IEnumerable<T>
est acceptable, alors vous pouvez contourner le manque de soutien pour Queryable.Cast
en appelant AsEnumerable
avant d'appeler Cast
. Cependant, ce qui limite la façon dont votre DAL peut être utilisé. IQueryable<T>
puisque n'est plus retourné, d'autres requêtes (par exemple, les clauses de Where
) ne seront pas transmises à travers la couche DB
Autres conseils
Je suis d'accord que cela ressemble à un bug. Vous pouvez essayer ceci qui va faire la même chose
return Table.Select<TEntity>(tbl => (TEntity)tbl)
Vous pourriez avoir à ajouter un où:. Itableau à la définition de la méthode et