LINQ to entities seulement prend en charge la conversion EDM primitive ou une énumération des types avec IEntity interface
J'ai le générique suivant la méthode d'extension:
public static T GetById<T>(this IQueryable<T> collection, Guid id)
where T : IEntity
{
Expression<Func<T, bool>> predicate = e => e.Id == id;
T entity;
//Allow reporting more descriptive error messages.
try
{
entity = collection.SingleOrDefault(predicate);
}
catch (Exception ex)
{
throw new InvalidOperationException(string.Format(
"There was an error retrieving an {0} with id {1}. {2}",
typeof(T).Name, id, ex.Message), ex);
}
if (entity == null)
{
throw new KeyNotFoundException(string.Format(
"{0} with id {1} was not found.",
typeof(T).Name, id));
}
return entity;
}
Malheureusement Entity Framework ne sais pas comment gérer la predicate
depuis C# converti le prédicat suivant:
e => ((IEntity)e).Id == id
Entity Framework lève l'exception suivante:
Impossible de convertir le type "IEntity' de type 'SomeEntity'. LINQ to
Seules entités prend en charge la conversion EDM primitive ou une énumération des types.
Comment pouvons-nous faire Entité Cadre de notre travail avec nos IEntity
interface?
Vous devez vous connecter pour publier un commentaire.
J'ai été en mesure de résoudre ce problème en ajoutant la
class
générique type de contrainte à l'extension de la méthode. Je ne sais pas pourquoi ça marche, même si.Quelques explications supplémentaires concernant la
class
"fix".Cette réponse montre deux expressions différentes, l'une avec et l'autre sans
where T: class
contrainte. Sans leclass
contrainte que nous avons:et avec la contrainte:
Ces deux expressions sont traitées différemment par l'entity framework. En regardant les EF 6 sources, on peut trouver que l'exception vient de ici, reportez-vous à
ValidateAndAdjustCastTypes()
.Ce qui se passe, que EF essaie de lancer
IEntity
en quelque chose qui a du sens le modèle de domaine du monde, mais il ne parvient pas à le faire, d'où l'exception est levée.L'expression avec la
class
contrainte ne contient pas leConvert()
opérateur de cast n'est pas essayé et tout va bien.Il reste ouvert à la question, pourquoi LINQ construit des expressions différentes? J'espère que certains C# assistant sera en mesure de l'expliquer.