2010-08-17 7 views
6

Grundsätzlich möchte ich zwei Iqueryable zu einem Iqueryable zusammenführen und dann den vollständigen Datensatz nach dem Ende meiner Schleife zurückgeben. Es läuft perfekt, aber am Ende haben meine Objret nichts, aber wenn ich debugge die Schleife obj einige Datensätze haben. wht im falschen BetreiberProblem beim Erstellen leer IQueryable <T> Objekt

IQueryable<MediaType> objret = Enumerable.Empty<MediaType>().AsQueryable(); 
var typ = _db.MediaTypes.Where(e => e.int_MediaTypeId != 1 && e.int_MediaTypeId_FK == null).ToList(); 
for (int i = 0; i < typ.Count; i++) 
{ 
    IQueryable<MediaType> obj = _db.MediaTypes.Where(e => e.bit_IsActive == true && e.int_MediaTypeId_FK == typ[i].int_MediaTypeId); 
    IQueryable<MediaType> obj1 = _db.MediaTypes.Where(e => e.int_OrganizationId == Authorization.OrganizationID && e.bit_IsActive == true && e.int_MediaTypeId_FK == typ[i].int_MediaTypeId); 

    if (obj1.Count() > 0) 
     obj.Concat(obj1); 
    if(obj.Count() > 0) 
     objret.Concat(obj); 
} 
return objret; 

Antwort

4

Genau wie die anderen Abfrage tun, Concat nicht die bestehende Reihenfolge ändern - es gibt eine neue Sequenz.

Also diese Zeilen:

if (obj1.Count() > 0) 
    obj.Concat(obj1); 
if(obj.Count() > 0) 
    objret.Concat(obj); 

sollte

if (obj1.Count() > 0) 
    objret = objret.Concat(obj1); 
if(obj.Count() > 0) 
    objret = objret.Concat(obj); 

Ich bin nicht sicher

sein, wie gut IQueryable dies gegeben zu handhaben wird, dass Sie LINQ to SQL abmischen (vielleicht Entities) mit Enumerable.AsQueryable, wohlgemerkt. Da Sie die Abfragen aufgrund der Aufrufe Count() bereits zu einem gewissen Grad ausführen, möchten Sie stattdessen eine List<T> erstellen?

(Sie brauchen nicht auf die Count() überhaupt auszuführen - rufen Sie einfach List<T>.AddRange(obj1) und dito für obj.)

Wie jeroenh erwähnt, im Idealfall wäre es schön, eine Lösung zu verwenden, die es alles, was das tun könnte Datenbank ohne Schleife in Ihrem C# -Code.

+0

ich es ändern, um eine Liste zu erstellen und es funktioniert Vielen Dank. –

+0

Dieser Ansatz generiert 4 Rundreisen zur Datenbank für jede Iteration in der For-Schleife ... Das ist ein mögliches Leistungsproblem, wenn Sie mich fragen (obwohl es natürlich von der tatsächlichen Größe der Tabelle abhängt). – jeroenh

+0

@jeroenh: Ja, ich habe impliziert, dass du 'Count()' überhaupt nicht benutzen musst. Ich werde das klarer machen. –

0

Ich denke, Sie sollten dies nicht mit einer for-Schleife tun. Der von Ihnen gepostete Code wird zweimal für jeden einzelnen aktiven Medientyp an die db gesendet, um Count() zu erhalten, und zusätzlich zweimal, um die tatsächlichen Ergebnisse zu erhalten.

Das Überprüfen der Count() - Eigenschaft ist nicht notwendig: Das Verketten leerer Ergebnismengen hat keinen zusätzlichen Effekt.

Darüber hinaus denke ich, was Sie versuchen, mit einer einzigen Abfrage durchgeführt werden, um zu erreichen, etwas entlang der Linien von (nicht getestet):

 // build up the query 

     var rootTypes = _db.MediaTypes.Where(e => e.int_MediaTypeId != 1 && e.int_MediaTypeId_FK == null); 
     var activeChildren = _db.MediaTypes 
           .Where(e => e.bit_IsActive); 
     var activeChildrenForOrganization = _db.MediaTypes 
           .Where(e => e.int_OrganizationId == Authorization.OrganizationID && e.bit_IsActive); 

     var q = from types in rootTypes 
       join e in activeChildren 
       on types.int_MediaTypeId equals e.int_MediaTypeId_FK into joined1 
       join e in activeChildrenForOrganization 
       on types.int_MediaTypeId equals e.int_MediaTypeId_FK into joined2 
       select new {types, joined1, joined2}; 


     // evaluate the query and concatenate the results. 
     // This will only go to the db once 
     return q.ToList().SelectMany(x => x.joined1.Concat(x.joined2)); 
Verwandte Themen