2011-04-23 1 views
1

Lorsque vous utilisez le code suivant (simplifié), je reçois l'erreurEntity Framework 4.1: référentiel avec "la propriété DefaultOrder"

« Impossible de lancer le type 'System.DateTime' taper 'System.Object'. LINQ to Entities ne prend en charge que les types de primitive Entity Data Model. "

dans la ligne de la déclaration de retour:

public MyRepository<Post> 
{ 
    public Expression<Func<Post, object>> DefaultOrder; 

    public MyRepository() 
    { 
    DefaultOrder = p => p.PublishedOn; 
    } 

    public IQueryable<Post> All() 
    { 
    var entities = new MyDbContext().Set<Post>(); 
    return entities.OrderByDescending(DefaultOrder); 
    } 
} 

J'utilise le même code avec db4o/db4o.Linq au lieu de Entity Framework et il n'y avait pas de problème.

Voici mes questions:

  1. Pourquoi cette erreur se produit?
  2. Existe-t-il une solution alternative, qui me permet de définir mon DefaultOrder de la même manière (similaire) que maintenant?

EDIT:

trouvé une solution , qui fonctionne pour moi, remplacé l'expression de commande par défaut avec une méthode de commande:

public MyRepository<T> 
{ 
    public Func<IQueryable<T>, IOrderedQueryable<T>> DefaultOrderMethod; 

    public MyRepository() 
    { 
    DefaultOrderMethod = o => o.OrderBy(x => x.PublishedOn); 
    } 

    public IQueryable<T> All() 
    { 
    var entities = new MyDbContext().Set<T>(); 
    return DefaultOrderMethod(entities); 
    } 
} 
+0

avez-vous essayé de faire le casting auparavant? ('DefaultOrder = p => (objet) p.PublishedOn;') – AbdouMoumen

+0

Bonne idée! - mais malheureusement ne fonctionne pas ... – davehauser

Répondre

1

Le deuxième type de l'expression passée dans la méthode d'extension OrderBy est déduite du type renvoyé par l'expression. Il attend une Expression>. Donc, si vous voulez stocker l'expression de tri, vous devez lui donner explicitement le type TOrderBy.

public MyRepository<Post> 
{ 
    public Expression<Func<Post, DateTime>> DefaultOrder; 

    public MyRepository() 
    { 
    DefaultOrder = p => p.PublishedOn; 
    } 

    public IQueryable<Post> All() 
    { 
    var entities = new MyDbContext().Set<Post>(); 
    return entities.OrderByDescending(DefaultOrder); 
    } 
} 

.NET ne prend pas en charge la boxe/unboxing un type de paramètre générique, sauf si vous utilisez .NET 4.0 et des interfaces d'utilisation via covariance et contravariance qui ne fonctionnerait pas pour votre exemple.

Encore une fois, voici comment fonctionne le système générique dans .NET. La seule raison pour laquelle quelque chose comme ça fonctionne ...

Query.OrderBy(x => x.PublishedOn)

... est parce que le type TOrderBy peut être déduit du type de retour d'expression (DateTime).

+0

Merci pour vos explications. Bien que j'ai écrit le même code a travaillé, quand j'ai utilisé [db4o] (http://db4o.com) avec le même code. Des idées? – davehauser

+0

Avez-vous une bonne idée de la manière d'implémenter cette fonctionnalité d'une manière différente? – davehauser

+0

Vous pouvez le faire de plusieurs façons, mais je doute que vous serez en mesure de tirer le résultat final que vous espérez et c'est juste une limitation de .NET. –

Questions connexes