Question

J'ai une situation où je suis en train de filtrer un LINQ sélectionner à l'aide d'une sous-classe dérivée.

ctx.BaseEntity.OfType<SubClass>() -. Cela fonctionne bien

Cependant, je voudrais le faire en utilisant une valeur de chaîne à la place. Je suis venu à travers une barrière de performance quand j'ai beaucoup (> 20) Sous les classes et la sélection d'une entité sans utiliser OfType est tout simplement pas une option. J'ai une interface générique qui rend de la classe de base, donc je ne sais pas quel type de classe sera retourné au moment de la compilation.

Alors, ce que je voudrais faire est la suivante:

  1. Effectuer une projection de Sélectionnez où je juste retour le SubClassType de la base de données
  2. Effectuer une deuxième sélectionnez en utilisant cette valeur comme OfType à sélectionnez uniquement les pertinentes liées à entité de la base de données (masse Non unions généré)

        int id = 1;
        var classType = (from c in ctx.BaseClass.Include("ClassType")
                                   where c.id == id
                                   select new
                                              {
                                                  c.ClassType.TypeName
                                              }).First();
    
        BaseClass caseQuery = ctx.BaseClass.OfType<classType.TypeName>()
                        .Include("ClassType")
                        .Include("ChildEntity1")
                        .Include("ChildEntity2")
                        .Where(x => x.id== id);
    

Mais, évidemment, cela ne fonctionnera pas parce OfType nécessite un type et non une chaîne.

Toutes les idées sur la façon dont je peux y parvenir?

Mise à jour: Comme une note de côté à la question initiale, il se trouve que le moment vous projetez une requête qui utilise une propriété de navigation - il construit le monstre SQL, donc j'ai fini par utiliser une procédure stockée pour remplir mon entité ClassType des BaseClass Id.

Était-ce utile?

La solution

Je viens eu à travailler en utilisant eSQL, que je ne l'avais jamais utilisé auparavant. J'ai posté le code ici juste au cas où il aide quelqu'un. Est-ce que quelqu'un d'autre a obtenu une solution plus fortement typé qu'ils peuvent penser?

BaseClass caseQuery = ctx.BaseClass.CreateQuery<BaseClass>("SELECT VALUE c FROM OFTYPE(Entities.[BaseClass],namespace.[" + classType.TypeName + "])  as c")
                .Include("ClassType")
                .Include("ChildEntity1")
                .Include("ChildEntity2")
                .Where(x => x.id== id).FirstOrDefault();

Autres conseils

Pour répondre à la question de titre à appeler OfType avec un type chaîne / exécution, vous pouvez effectuer les opérations suivantes:

// Get the type, assuming the derived type is defined in the same assembly 
// as the base class and you have the type name as a string
var typeToFilter = typeof(BaseClass)
     .Assembly
     .GetType("Namespace." + derivedTypeName);

// The use reflection to get the OfType method and call it directly
MethodInfo ofType = typeof(Queryable).GetMethod("OfType");
MethodInfo ofTypeGeneric = method.MakeGenericMethod(new Type[] { typeToFilter });
var result = (IQueryable<Equipment>)generic.Invoke(null, new object[] { equipment });

Combinez cela avec votre procédure stockée pour obtenir le nom de la classe et vous (devrait?) Éviter le massif rejoindre -. Je n'ai pas la mise en œuvre de table par type pour jouer avec donc je ne peux pas tester

Licencié sous: CC-BY-SA avec attribution
Non affilié à StackOverflow
scroll top