2013-01-15 4 views
11

Gibt es eine Möglichkeit, Cross-Datenbankabfragen in Entity Framework zu implementieren? Stellen wir uns vor, ich habe zwei Entitäten User und Post, User Entity ist in der Datenbank1 und Post ist in der Datenbank2, was bedeutet, dass diese Entitäten in separaten Datenbanken sind. Wie sollte ich Benutzerbeiträge in Entity Framework erhalten?Cross-Datenbankabfrage in EF

+0

mögliches Duplikat von [Entity Framework - Wie man Tabellen in verschiedenen Datenbanken, aber auf demselben Server verwaltet?] (Http://stackoverflow.com/questions/11544516/entity-framework-how-to-manage-tables-in) -Different-Datenbanken-aber-auf-der-same-s) – ken2k

+0

Ja, ich habe Posts in der Datenbank1, aber ich verstehe nicht, was meinst du ** durch SQL View oder Alias ​​**? – saber

Antwort

20

Der EF-Kontext unterstützt keine Cross-Datenbank-Abfragen. Sie müssen Beiträge in database1 über SQL View (or synonym) verfügbar machen und als Teil dieser Datenbank verwenden.

+0

+1 danke Ladislav, du hast meinen Tag gerettet. – saber

+0

Natürlich funktioniert das überhaupt nicht, wenn die Datenbank, der Sie beitreten möchten, nicht lokal ist. Link-Server-Joins funktionieren ebenfalls schlecht. Ich wünschte, dass der Kontext die Konfigurationsoption der Datenbankbesitzverkettung berücksichtigen würde, da dies wie ein grundlegendes Authentifizierungsproblem erscheint, das leicht überwunden werden könnte. – ewahner

4

Nein, das geht nicht. Sie müssen zu Kontexten schaffen und die Verbindung zu sich selbst herstellen. Siehe here.

Sie könnten zu Datenbanktricksen auflösen, indem Sie eine Ansicht in einer Datenbank erstellen, die eine Tabelle in der anderen widerspiegelt.

+0

Kann akzeptabel sein, wenn sich die Datenbank auf demselben Host befindet und die Datensätze klein sind, aber Client-seitige Joins funktionieren im Allgemeinen schlecht. – Andomar

+0

+1 danke für Ihre Antwort. – saber

9

Sie können ExecuteStoreQuery verwenden, wie:

var myOb = context.ExecuteStoreQuery<PlainOldClrObject>(
     @"select * 
      from db1.dbo.table1 t1 
      join db2.dbo.table2 t2 
      on  t2.t1_id = t1.id 
      where t1.id = {0}", 
     table1Id).FirstOrDefault(); 

Sie haben würde eine PlainOldClrObject Klasse mit den Spalten als Eigenschaften mit Getter/Setter definieren, wie:

class PlainOldClrObject 
{ 
    public int Id (get; set; } 
    public int Name (get; set; } 
    ... 
} 
+0

+1 guter Punkt. Die einfachste Lösung ist oft die beste. –

13

Ich weiß, das ist ein alter Faden, aber eigentlich. Das ist möglich. Wenn sich die Datenbanken auf demselben Server befinden, müssen Sie nur verwenden.

Als Beispiel, wenn ich eine an MyContext, anschließe, kann ich alle Befehlsausführungen abfangen und die angegebenen Tabelle (n) in der Abfrage durch meine vollständigen DB-Pfade ersetzen.

  public override void ReaderExecuting(DbCommand command, DbCommandInterceptionContext<DbDataReader> interceptionContext) 
    { 
     // Here, I can just replace the CommandText on the DbCommand - but remember I 
     // want to only do it on MyContext 
     var context = contexts.FirstOrDefault() as MyContext; 
     if (context != null) 
     { 
      command.CommandText = command.CommandText 
       .Replace("[dbo].[ReplaceMe1]", "[Database1].[dbo].[Customers]") 
       .Replace("[dbo].[ReplaceMe2]", "[Database2].[dbo].[Addresses]") 
       .Replace("[dbo].[ReplaceMe3]", "[Database3].[dbo].[Sales]"); 
     } 

     base.ReaderExecuting(command, interceptionContext); 
    } 

Die nette Sache auch an diesem Ansatz ist, dass die EF Modell Mapping funktioniert immer noch einwandfrei und respektiert Spalte Attribute, benötigt keine Ansichten und erfordert keine gespeicherte Procs.