Frage

Ich bin in VS2008 mit Entity Framework. Ich bin der Zugriff auf Objekte aus der Datenbank esql für WHERE IN-Funktion verwenden. Ich bin vorbei eine Tonne IDs die select-Anweisung, damit ich chunk es in Sätze von 800 bis Dann habe ich die Ergebnisse zusammen aus jedem Klumpen verschmelzen. Mein Ziel ist es, Ergebnisse für jeden Block parallel zu erhalten, anstatt synchron warten. Ich installierte Reactive Framework und bin ziemlich sicher, dass ich den Einsatz von ForkJoin machen müssen. Aber ich kann nicht herausfinden, wie diese Funktion konvertieren, es zu benutzen. Hier ist mein vorhandener Code:

    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;
    }

Danke!

  
    
      

EDIT >>>       Ich änderte den Code des armen Mannes zu verwenden, wie unten:

    
  
    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;
    }

Es hat super funktioniert das erste Mal. Aber das zweite Mal, dass ich es lief, habe ich diesen Fehler:

Die Verbindung wurde nicht geschlossen. Die Verbindung der aktuelle Zustand verbindet. Beschreibung: Eine nicht behandelte Ausnahme trat während der Ausführung der aktuellen Webanforderung. Überprüfen Sie die Stapelüberwachung, um weitere Informationen über den Fehler und wo es im Code verursacht.

Ausnahmedetails: System.InvalidOperationException: Die Verbindung wurde nicht geschlossen. Die Verbindung der aktuelle Zustand verbindet.

Quellfehler:

Zeile 49: foreach (var IAsyncResult in Ergebnisliste) Zeile 50: { Zeile 51: del.EndInvoke (IAsyncResult); Linie 52: iAsyncResult.AsyncWaitHandle.Close (); Zeile 53:}

Es ist interessant, b / c Emre (der Autor der Bibliothek) bearbeitet, um seine ursprünglichen Post hat darüber reden, wie er diese Zeilen Code für zusätzliche Sicherheit gegeben. Verwende ich es richtig? Oder war sein v1 sicherer doch?

War es hilfreich?

Lösung

VS2010 hat das mit PLINQ. die Erweiterungen AsParallel().WithDegreeOfParallelism(nbProcessors) Mit tun würde, was Sie brauchen.

Mit VS2008 habe ich armen Mannes Parallel.ForEach Iterator von Emre Aydinceren verwendet in der Vergangenheit, als ich versuche, wurde um eine Performance-Engpass zu umgehen, versuchen sie ihm eine Chance zu geben.

EDIT: In Reaktion auf den Fehler, den Sie hinzugefügt, es könnte einen zufälligen Schuss im Dunkel, aber separate Kontexte für jeden Thread? Wie so:

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());
    });

Sie können sich um einige Dinge zu zwicken haben (wie die Connextion String nehmen Sie aus dem Kontext neue Contexts instanziiert erweitert).

Lizenziert unter: CC-BY-SA mit Zuschreibung
Nicht verbunden mit StackOverflow
scroll top