Question

Je suis VS2008 avec Entity Framework. J'accéder à des objets de la base de données en utilisant esql pour OÙ fonctionnalité. Je passe une tonne d'ID à l'instruction select donc je morceau vers le haut dans des ensembles de 800. Puis-je fusionner ensemble les résultats de chaque morceau. Mon but est d'obtenir des résultats pour chaque morceau en parallèle, plutôt que d'attendre de manière synchrone. Je l'ai installé et je suis cadre réactive assez sûr que je dois utiliser ForkJoin. Cependant, je ne peux pas comprendre comment convertir cette fonction pour l'utiliser. Voici mon code existant:

    public static IList<TElement> SelectWhereIn<TElement, TValue>(this ObjectContext context, string fieldName, IList<TValue> idList)
    {
        var chunkedIds = idList.Split(CHUNK_SIZE);
        string entitySetName = typeof(TElement).Name + "Set";
        var retList = new List<TElement>();
        foreach (var idChunk in chunkedIds)
        {
            string delimChunk = string.Join(",", idChunk.Select(x => x.ToString()).ToArray());
            ObjectQuery<TElement> query = context.CreateQuery<TElement>("SELECT VALUE x FROM " + entitySetName + " AS x");
            query = query.Where("it." + fieldName + " IN {" + delimChunk + "}");
            retList.AddRange(query);
        }
        return retList;
    }

Merci!

  
    
      

EDIT >>>       J'ai modifié le code à utiliser comme ci-dessous Poor Man:

    
  
    public static IList<TElement> SelectWhereIn<TElement, TValue>(this ObjectContext context, string fieldName, IList<TValue> idList)
    {
        var chunkedIds = idList.Split(CHUNK_SIZE);
        string entitySetName = typeof(TElement).Name + "Set";
        var chunkLists = new List<IEnumerable<TElement>>();
        Parallel.ForEach(chunkedIds, idChunk =>
        {
            string delimChunk = string.Join(",", idChunk.Select(x => x.ToString()).ToArray());
            ObjectQuery<TElement> query = context.CreateQuery<TElement>("SELECT VALUE x FROM " + entitySetName + " AS x");
            query = query.Where("it." + fieldName + " IN {" + delimChunk + "}");
            chunkLists.Add(query.ToList());
        });
        var retList = new List<TElement>();
        foreach (var chunkList in chunkLists)
        {
            retList.AddRange(chunkList);
        }
        return retList;
    }

Il fonctionnait très bien la première fois. Mais la deuxième fois que je l'ai couru, je me suis cette erreur:

La connexion n'a pas été fermée. l'état actuel de la connexion se connecte. Description: Une exception non gérée produite lors de l'exécution de la demande Web actuelle. S'il vous plaît examiner la trace de la pile pour plus d'informations sur l'erreur et son origine dans le code.

Détails de l'exception: System.InvalidOperationException: La connexion n'a pas été fermé. l'état actuel de la connexion se connecte.

Erreur source:

Ligne 49: foreach (var IAsyncResult dans de résultats) Ligne 50: { Ligne 51: del.EndInvoke (IAsyncResult); Ligne 52: iAsyncResult.AsyncWaitHandle.Close (); Ligne 53:}

Il est intéressant, b / c Emre (l'auteur de la bibliothèque) a modifié son message original à parler de la façon dont il a ajouté ces lignes de code pour plus de sécurité. Est-ce que je l'utilise pas? Ou était son v1 plus sûr après tout?

Était-ce utile?

La solution

VS2010 n'ont que avec PLINQ. Utilisation de la AsParallel().WithDegreeOfParallelism(nbProcessors) extensions ferait ce dont vous avez besoin.

Avec VS2008, je l'ai utilisé Pauvre Parallel.ForEach de l'homme Iterator par Emre Aydinceren dans le passé quand je tentais de travailler autour d'un goulot d'étranglement, essayez de donner un coup de feu.

EDIT: En réaction à l'erreur que vous avez ajouté, il est peut-être un coup de feu au hasard dans l'obscurité, mais séparés des contextes pour chaque thread? Comme ceci:

Parallel.ForEach(chunkedIds, idChunk =>
    {
        ObjectContext context = new MyContext(connStr);//depending what's your config
                                                       // like, with or w/o conn string

        string delimChunk = string.Join(",", idChunk.Select(x => x.ToString()).ToArray());
        ObjectQuery<TElement> query = context.CreateQuery<TElement>("SELECT VALUE x FROM " + entitySetName + " AS x");
        query = query.Where("it." + fieldName + " IN {" + delimChunk + "}");
        chunkLists.Add(query.ToList());
    });

Vous pourriez avoir à bidouiller autour de certaines choses (comme prendre la chaîne de connextion du contexte étendu à instancier nouvelles Contextes).

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