web-dev-qa-db-de.com

Verknüpfen von Tabellen aus zwei Datenbanken mithilfe des Entity-Frameworks

Ich arbeite an einer ASP.NET MVC 4-Webanwendung. Ich verwende Entity Framework als Datenzugriffsschicht, wobei die Datenbank zuerst verwendet wird (.edmx-Datei).

Derzeit habe ich ein Problem in Join-Tabellen, die in zwei verschiedenen Datenbanken definiert sind (d. H. Ich habe zwei .edmx-Dateien).

Wenn ich beispielsweise Tabellen verknüpfen möchte, führe ich die folgende Abfrage aus: -

public ActionResult AutoComplete(string term)
{
   var tech = repository.AllFindTechnolog(term).Take(100);//Call to the first database
   var resources = repository.GetResources(tech.Select(a => a.IT360ID.Value).ToArray(), false);//call to the second database

   var query = from techItems in tech
         join resourcesItems in resources
         on techItems.IT360ID.Value equals resourcesItems.RESOURCEID // join based on db2ID
         orderby techItems.PartialTag
         select new //code goes here

   return Json(query, JsonRequestBehavior.AllowGet);
}

Ich habe zwei getrennte Aufrufe der Datenbank und eine Verknüpfung innerhalb des Anwendungsservers, was nicht die beste leistungsorientierte Lösung ist. Idealerweise werden die Joins vollständig in der Datenbank-Engine ausgeführt.

Ich weiß, dass eine gespeicherte Prozedur mir erlaubt, Tabellen aus verschiedenen Datenbanken rein auf dem Server zu verknüpfen, aber ich möchte nicht SP verwenden, da dadurch mein Code weniger wartbar und weniger testbar ist. 

Ich suche also nach einer Lösung, bei der ich den Join mithilfe des Entity-Frameworks ausführen kann, um einen einzigen Datenbank-Join zu erhalten?

11
john Gu

Wenn Sie dies mit einem einzigen Datenbankaufruf tun möchten, müssen Sie in der Datenbank eine View erstellen, die die beiden Tabellen aus separaten Datenbanken verbindet. Nachdem die Ansicht erstellt wurde, können Sie sie als einzelnes Objekt zu EF hinzufügen, das Sie dann weiter bearbeiten und die Abfrage deaktivieren können. Die Ansicht wird im Grunde eine Tabelle sein, die leicht zu warten ist und an ein stark typisiertes Modell gebunden werden kann

Auf eine andere Art und Weise, wie Sie sie geschrieben haben, können Sie separate .edmx-Dateien abfragen und sie dann verbinden. Ja, es gibt zwei Aufrufe der Datenbank, aber es sollte nicht so teuer sein und dürfte keinen Unterschied bemerken .

using(var db = new MyEntities())
using (var db2 = new MyEntities2())
{
   var one = db.Table1.AsEnumerable();
   var two = db2.Table2.AsEnumerable(); 

   var result = from o in one
                join t in two on o.Id equals t.Id
                // blah blah

}
4
CSharper

@CSharper's Antwort ist nahe. Wie in den Kommentaren von @Oliver erwähnt, lädt IEnumerable die Tabelle in den Anwendungsspeicher, was zu Abstürzen führt, wenn Sie eine große Datenbank haben. 

Die Lösung ist die Verwendung von IQueryable, das mit LINQ aufgerufen werden kann. Dadurch wird SQL erzeugt, das viel schneller ist. 

// This is a generic method, modify to your needs
public ActionResult Details(int? id)
   var one = db.Table1.AsQueryable();
   var two = db2.Table2.AsQueryable(); 

   // since you're using MVC EF, I assume you want to put this in a viewmodel 
   // (in this case ObjectCombined)
   // assume "id" is passed as parameter 
   Object1 result1 = (from o in one where one.id == id select o).Single();
   Object2 result2 = (from t in two where t.id == o.id select t).Single();
   ObjectCombined result = new ObjectCombined(result1, result2);
   return View(result);
}
2
chakeda

sie können eine Ansicht oder eine gespeicherte Prozedur erstellen. Ihre SQL-Anweisung kann dann eine Cross-DB-Abfrage durchführen. Stellen Sie dabei sicher, dass Ihre Anmeldeinformationen DML oder DDL für beide DBs enthalten. Ansonsten versuchen Sie die verschachtelten using-Entitäten, um sicherzustellen, dass Sie den linq-Fehler nicht erhalten, wenn Sie die db-Entität nicht innerhalb einer using-Anweisung deklarieren.

0
CyberNinja

Dürfte ich vorschlagen, dass Sie ein synonym in Ihrer Datenbank verwenden? Sie können beispielsweise ein Synonym für die Ressourcentabelle in der Datenbank erstellen, in der sich Ihre Tech-Tabelle befindet. Dadurch wird sichergestellt, dass Sie keine 2 EDMX-Dateien verwalten müssen. Stattdessen können Sie eine einzelne EDMX-Datei haben und Ihre Tech-Tabelle einfach mit dem Synonym von Ressourcentabelle und voila verknüpfen - Sie sind auf dem Weg.

UPDATE: Wenn Sie Synonyme verwenden, müssen Sie die EDMX-Datei mit etwas mehr Arbeit erledigen, damit sie in Entity Framework funktioniert. Hier ist ein Blogbeitrag , der von einem Programmierer ausgegeben wurde, der ihn zum Laufen brachte. Hier ist die ursprüngliche stackoverflow frage, die sie gestellt hat.

HAPPY CODING !!! :)

0
Gjohn