wake-up-neo.com

Fehler: "Der angegebene LINQ-Ausdruck enthält Verweise auf Abfragen, die verschiedenen Kontexten zugeordnet sind."

Ich erhalte den im Titel angezeigten Fehler von einer LINQ-Abfrage, die zwei Tabellen aus zwei verschiedenen edmx-Dateien enthält. Hier ist die Abfrage:

var query = (from a in db1.Table1
           join b in db1.Table2 on a.Id equals b.Id
           orderby a.Status
           where b.Id == 1 && a.Status == "new"
           select new
           {
               Id = a.Id,
               CompanyId = (from c in db2.Company
                            where s.Id == a.Id
                            select
                            new { c.CompanyId })
           });

db1 und db2 sind Kontexte, die zwei verschiedenen edmx-Dateien zugeordnet sind. Wie kann ich diesen Fehler überwinden?

55
Ashiq A N

Sie müssen zwei Datenbankabfragen ausführen:

var IDs =  (from a in db1.Table1 
            join b in db1.Table2 on a.Id equals b.Id 
            orderby a.Status 
            where b.Id == 1 && a.Status == "new" 
            select new a.Id).ToArray();

var query = from c in db2.Company
            join a in IDs on c.Id equals a.Id
            select new { Id = a.Id, CompanyId = c.CompanyId };

Die .ToArray() ist entscheidend. Es verhindert, dass EF versucht, die kombinierte Abfrage auszuführen (die fehlschlägt, da zwei verschiedene Kontexte verwendet werden). Sie können .AsEnumerable() verwenden, wenn Sie lieber faul laden möchten.


Und deine Anschlussfrage:

Gibt es eine andere Möglichkeit, die LINQ-Abfrage weiter zu optimieren? Das ist, die Aktion in einer einzelnen LINQ-Abfrage selbst ausführen?

Damit Ihre ursprüngliche Abfrage erfolgreich ausgeführt werden kann, muss sie nur einen einzigen Datenkontext verwenden. Das bedeutet, dass alle Daten in einem einzigen EDMX verfügbar sein müssen, was wiederum eine einzelne Verbindungszeichenfolge bedeutet. Es gibt mehrere Möglichkeiten, dies zu erreichen:

  • Wenn sich beide Tabellen in derselben Datenbank befinden, fügen Sie beide zu einem einzigen EDMX hinzu.
  • Wenn sie sich in verschiedenen Datenbanken befinden, jedoch in derselben Instanz, erstellen Sie eine Ansicht in einer der Datenbanken, die aus der Tabelle in der anderen Datenbank ausgewählt wird, und fügen Sie dann die lokale Tabelle und Ansicht zu einem einzigen EDMX hinzu.
  • Wenn sie sich auf verschiedenen Instanzen/Servern befinden, einen Verbindungsserver erstellt haben, dann eine Ansicht der Tabelle auf dem Verbindungsserver erstellen, dann die lokale Tabelle und Sicht zu einem einzelnen EDMX hinzufügen.
104
Allon Guralnek

Sie müssen entweder die zweite Tabelle zum Modell des ersten Kontexts hinzufügen. Wenn sich dies in mehreren Datenbanken befindet, müssen Sie die sekundäre Suche auf der Clientseite mit einem Linq-zu-Objekt-Join durchführen.

2
Jim Wooley

Sie müssen EntityConnection manuell erstellen, das mit Ressourcen aus allen gewünschten .EDMXs gefüllt ist . Sie können dies tun, indem Sie entweder Verbindung zu app.config oder programmaticaly ..__ hinzufügen. Anschließend können Sie DBContext mithilfe der vorbereiteten EntityConnection erstellen.

methode a) 

<add name="MyConnection"
connectionString="metadata=res://*/Entities.ModuleA.csdl|res://*/Entities.ModuleA.ssdl|res://*/Entities.ModuleA.msl|res://*/Entities.ModuleB.csdl|res://*/Entities.ModuleB.ssdl|res://*/Entities.ModuleB.msl;
provider=System.Data.SqlClient;provider connection string=&quot;MyConnectionString&quot;"
providerName="System.Data.EntityClient" />

using (EntityConnection oEntityConnection =
    new EntityConnection("name=MyConnection"))
{
    using(DbContext oDBContext = new DbContext(oEntityConnection))
    {
        //your code - available are entities declared in Entities.ModuleA and Entities.ModuleB
    }
}

methode b)

 using (EntityConnection oEntityConnection =
        new EntityConnection(new MetadataWorkspace(
        new string [] { 
"res://Entities.ModuleA/", 
"res://Entities.ModuleB/" 
},
        new Assembly[] { 
Assembly.GetAssembly(typeof(Entities.ModuleA.AnyType)),
Assembly.GetAssembly(typeof(Entities.ModuleB.AnyType)) 
}
        )))
    {
        using(DbContext oDBContext = new DbContext(oEntityConnection))
        {
            //your code - available are entities declared in Entities.ModuleA and Entities.ModuleB
        }
    }
0