2013-01-15 35 views
11

Có cách nào để thực hiện truy vấn cơ sở dữ liệu chéo trong Khuôn khổ thực thể không? Hãy tưởng tượng tôi có hai Entities User và Post, thực thể người dùng nằm trong database1 và Post nằm trong database2, có nghĩa là các thực thể đó nằm trong các cơ sở dữ liệu riêng biệt. Làm cách nào để tôi nhận được bài đăng của người dùng trong Khung thực thể?Truy vấn cơ sở dữ liệu chéo trong EF

+0

bản sao có thể có của [Khuôn khổ thực thể - cách quản lý các bảng trong cơ sở dữ liệu khác nhau nhưng trên cùng một máy chủ?] (Http://stackoverflow.com/questions/11544516/entity-framework-how-to-manage-tables-in -different-databases-but-on-the-same-s) – ken2k

+0

Có, tôi đã tiếp xúc với Bài đăng trong cơ sở dữ liệu1, nhưng tôi không hiểu, ý của bạn là gì ** thông qua SQL View hoặc bí danh **? – saber

Trả lời

20

Ngữ cảnh EF không hỗ trợ truy vấn cơ sở dữ liệu chéo. Bạn cần hiển thị các bài viết trong database1 thông qua SQL View (or synonym) và sử dụng nó như một phần của cơ sở dữ liệu đó.

+0

+1 cảm ơn Ladislav, bạn đã cứu ngày của tôi. – saber

+0

Tất nhiên điều này sẽ không hoạt động chút nào nếu cơ sở dữ liệu bạn muốn tham gia không phải là cục bộ. Link server join cũng hoạt động kém. Tôi muốn rằng Bối cảnh sẽ tôn trọng tùy chọn cấu hình cơ sở dữ liệu sở hữu cơ sở dữ liệu vì điều này có vẻ giống như một vấn đề xác thực cơ bản có thể dễ dàng khắc phục. – ewahner

4

Không, bạn không thể. Bạn sẽ phải tạo ra các bối cảnh và tự mình tham gia. Xem here.

Bạn có thể giải quyết thủ thuật cơ sở dữ liệu, tạo chế độ xem trong một cơ sở dữ liệu phản ánh một bảng trong một cơ sở dữ liệu khác.

+0

Có thể chấp nhận được nếu db nằm trên cùng một máy chủ và các tập dữ liệu nhỏ, nhưng nhìn chung, các kết nối phía máy khách hoạt động kém. – Andomar

+0

+1 cảm ơn bạn đã trả lời. – saber

9

Bạn có thể sử dụng ExecuteStoreQuery, như:

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

Bạn sẽ phải xác định một lớp PlainOldClrObject với các cột như các thuộc tính với getters/setters, như:

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

+1 điểm tốt. Giải pháp đơn giản nhất là khá tốt nhất. –

13

Tôi biết đây là một chủ đề cũ, nhưng, thực sự. điều này là khả thi. Nếu các cơ sở dữ liệu trên cùng một máy chủ, thì tất cả những gì bạn cần làm là sử dụng DbCommandInterceptor.

Ví dụ: nếu tôi đính kèm DbCommandInterceptor đến MyContext, Tôi có thể chặn tất cả các lệnh thực hiện và thay thế (các) Bảng được chỉ định trong truy vấn bằng đường dẫn đầy đủ của tôi.

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

Điều tốt đẹp về phương pháp này là ánh xạ mô hình EF vẫn hoạt động đúng và tôn trọng Thuộc tính cột, không yêu cầu lượt xem và không yêu cầu lưu trữ procs.

Các vấn đề liên quan