2009-09-11 7 views
0

Je souhaite pouvoir passer un type de variable à une méthode, principalement pour pouvoir transmettre une requête de structure d'entité à une méthode qui appliquera des inclusions communes d'objets imbriqués.Transmettre le type de variable à une méthode sans énumérer

C'est ce que je veux faire ...

public Person GetPersonByID(int personID) 
{ 
    var query = from Perspn p in Context.Persons 
       where p.PersonID = personID 
       select p; 

    ObjectQuery<Person> personQuery = ApplyCommonIncludes<Person>(query); 

    return personQuery.FirstOrDefault(); 
} 


public ObjectQuery<T> ApplyCommonIncludes<T>(SomeType query) 
{ 
    return ((ObjectQuery<T>)query) 
      .Include("Orders") 
      .Include("LoginHistory"); 
} 

Répondre

0

J'ai fini par créer une approche différente. Mon référentiel contient maintenant une liste de chaînes utilisées pour Includes. Pour conserver la sécurité de type pour la création comprend, j'ai créé la classe suivante:

/// <summary> 
/// Builds Includes 
/// </summary> 
public class IncludeBuilder 
{ 
    /// <summary> 
    /// List of parts for the Include 
    /// </summary> 
    private List<string> Parts; 

    /// <summary> 
    /// Creates a new IncludeBuilder 
    /// </summary> 
    private IncludeBuilder() 
    { 
     this.Parts = new List<string>(); 
    } 


    /// <summary> 
    /// Creates a new IncludeBuilder 
    /// </summary> 
    public static IncludeBuilder Create() 
    { 
     return new IncludeBuilder(); 
    } 


    /// <summary> 
    /// Adds a property name to the builder 
    /// </summary> 
    public IncludeBuilder AddPart<TEntity, TProp>(Expression<Func<TEntity, TProp>> expression) 
    { 
     string propName = ExpressionHelper.GetPropertyNameFromExpression(expression); 
     this.Parts.Add(propName); 

     return this; 
    } 


    /// <summary> 
    /// Gets a value of the include parts separated by 
    /// a decimal 
    /// </summary> 
    public override string ToString() 
    { 
     return string.Join(".", this.Parts.ToArray()); 

    } 

Cela me permet de le faire ...

myPersonRepository.AppendInclude(
    IncludeBuilder.Create() 
      .AddPart((Person p) => p.Orders) 
      .AddPart((Order o) => o.Items)); 

La déclaration ci-dessus passe expressions à la classe IncludeBuilder qui se traduit alors la ci-dessus dans "Orders.Items".

J'ai ensuite créé des méthodes d'assistance dans mon RepositoryBase qui ont reçu une ObjectQuery, appliquent les includes, exécutent la requête et retournent le résultat. Pas tout à fait ce que je cherchais, mais ça marche bien.

3

Semble-vous voulez réellement SomeType être ObjectQuery<T>, non?

public ObjectQuery<T> ApplyCommonIncludes<T>(ObjectQuery<T> query) 
{ 
    return query 
      .Include("Orders") 
      .Include("LoginHistory"); 
} 

Cette syntaxe est valide. Y a-t-il un problème avec ça?

Cela devrait fonctionner et retarder l'exécution (je pense que c'est ce que vous voulez dire par "sans énumération") jusqu'à ce que FirstOrDefault() soit appelé.

Questions connexes