2014-10-19 22 views
8

Tôi đang làm việc trên một ứng dụng web ASP.NET MVC 4. Tôi đang sử dụng Entity Framework làm lớp truy cập dữ liệu, sử dụng phương pháp tiếp cận cơ sở dữ liệu đầu tiên (.edmx tệp).Nối các bảng từ hai cơ sở dữ liệu bằng cách sử dụng khung thực thể

Hiện tại tôi gặp sự cố khi tham gia các bảng được xác định bên trong hai cơ sở dữ liệu khác nhau (ví dụ: tôi có hai tệp .edmx).

Ví dụ nếu tôi muốn tham gia bàn tôi đang thực hiện các truy vấn sau đây: -

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

tôi sẽ có hai cuộc gọi riêng biệt để các cơ sở dữ liệu, và tham gia vào bên trong máy chủ ứng dụng, mà không phải là tốt nhất giải pháp định hướng hiệu suất. Lý tưởng nhất là sự tham gia sẽ xảy ra hoàn toàn bên trong cơ sở dữ liệu.

Tôi biết rằng thủ tục được lưu trữ sẽ cho phép tôi tham gia các bảng từ cơ sở dữ liệu khác nhau hoàn toàn trên máy chủ, nhưng tôi không muốn sử dụng SP vì nó sẽ làm cho mã của tôi ít bảo trì hơn và ít kiểm tra hơn.

Vì vậy, tôi đang tìm kiếm giải pháp mà tôi có thể thực hiện việc tham gia bằng cách sử dụng khung thực thể và kết quả trong một cơ sở dữ liệu tham gia?

+0

Ý tưởng chính, là chúng ta đã chọn để làm việc với Entity Framework như lớp truy cập dữ liệu của chúng tôi là nó cung cấp các tính năng chính sau: - 1. mã truy cập dữ liệu được tuân thủ và thử nghiệm như là một phần của toàn bộ ứng dụng. dễ kiểm tra hơn và cung cấp thời gian phát triển nhanh so với các thủ tục được lưu trữ.2, EF cung cấp một lớp trên cơ sở dữ liệu và sản phẩm của chúng tôi có thể hoạt động trên các nhà cung cấp cơ sở dữ liệu khác nhau. và như tôi đã đề cập rằng chức năng duy nhất chúng tôi hiện có phụ thuộc trực tiếp vào cơ sở dữ liệu là thủ tục lưu trữ để thực hiện tìm kiếm trước –

+0

nhưng nếu tôi muốn bắt đầu tạo chế độ xem cho các chức năng khác nhau, thì tôi sẽ mất đi những ưu điểm mà EF cung cấp. vì vậy hãy để tôi xây dựng lại câu hỏi ban đầu là cách tiếp cận hiện tại của tôi để lấy dữ liệu liên quan từ hai cơ sở dữ liệu bằng cách sử dụng hai câu lệnh sql riêng biệt và sau đó kết hợp dữ liệu trên máy chủ ứng dụng được coi là thiết kế rất xấu? Mặc dù tôi sẽ có hai truy vấn riêng biệt nhưng chúng rẻ hơn so với câu lệnh sql tham gia duy nhất ... –

+0

Tôi có thể có một giải pháp cho bạn, nhưng tôi có một câu hỏi: Bạn đang chọn gì trong biến 'query'? Bạn có đang lấy dữ liệu từ cả hai ngữ cảnh hay chỉ từ một trong số chúng (tức là chỉ lấy các mục trong 'công nghệ' tồn tại trong' tài nguyên')? – IronMan84

Trả lời

0

Tôi có thể đề xuất bạn xem xét sử dụng một số synonym trong cơ sở dữ liệu của mình. Ví dụ, bạn có thể tạo một từ đồng nghĩa với bảng tài nguyên trong cơ sở dữ liệu mà bảng công nghệ của bạn nằm. Điều này sẽ đảm bảo rằng bạn sẽ không cần phải duy trì 2 tệp EDMX. Thay vào đó bạn có thể có một tệp EDMX duy nhất và bạn có thể chỉ cần tham gia bảng công nghệ của mình vào từ đồng nghĩa của bảng tài nguyên và thì đấy - bạn đang trên đường đi.

CẬP NHẬT: Xin lưu ý rằng nếu bạn đang sử dụng các từ đồng nghĩa, bạn sẽ cần thêm một chút công việc để thực hiện tệp EDMX để làm cho nó hoạt động trong Khuôn khổ thực thể. Đây là một blog post đã được đưa ra bởi một lập trình viên đã làm cho nó hoạt động. Đây là câu hỏi stackoverflow gốc cô ấy hỏi.

HẠNH PHÚC MỪNG !!! :)

+0

những gì tôi đã tìm kiếm là một cách tiếp cận out-of-the-box để hỗ trợ tham gia các bảng bên trong DB, từ hai cơ sở dữ liệu khác nhau bằng cách sử dụng khung thực thể .. –

+0

@johnG - Bạn không thể tham gia hai bảng cơ sở dữ liệu trên hai ngữ cảnh khác nhau làm những gì bạn đang làm hiện đang chọn mỗi người trong số họ và tham gia các kết quả. Chỉ có cách bạn có thể làm điều đó là nếu cả hai bảng đang được chọn theo cùng một ngữ cảnh trong cách khác nhau - đó là nơi sử dụng Từ đồng nghĩa. – Gjohn

+0

như vậy sẽ thực hiện phép nối trong máy chủ ứng dụng của tôi và chuyển hai truy vấn cơ sở dữ liệu đến từng cơ sở dữ liệu được xem xét một thiết kế rất xấu? tôi có nghĩa là có những tình huống thực sự mà các loại giới hạn được giải quyết bằng cách làm cách giải quyết tương tự? –

3

Nếu bạn muốn thực hiện nó với một cuộc gọi cơ sở dữ liệu duy nhất, bạn sẽ phải tạo Chế độ xem trong cơ sở dữ liệu tham gia 2 bảng từ db riêng biệt. Khi chế độ xem được tạo, bạn có thể thêm nó vào EF dưới dạng một đối tượng duy nhất mà bạn có thể thao tác thêm và truy vấn. Quan điểm về cơ bản sẽ là một bảng và nó sẽ dễ dàng duy trì và dễ ràng buộc với kiểu được đánh máy mạnh

Cách khác, tương tự như bạn đã đăng, bạn có thể truy vấn các tệp .edmx riêng biệt và sau đó tham gia. Có, có 2 cuộc gọi đến cơ sở dữ liệu nhưng nó không phải là đắt tiền và có lẽ sẽ không nhận thấy một sự khác biệt.

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 

} 
+3

Nhưng để ngăn chặn ngoại lệ EF nói rằng bạn không thể sử dụng hai ngữ cảnh trong một truy vấn, bạn nên thực hiện 'db.Table1.AsEnumerable()' và 'db2.Table2.AsEnumerable()'. –

+4

Ý kiến ​​rất tồi trong quan điểm của tôi: mỗi khi bạn gọi 'AsEnumerable()' trên một bảng, EF sẽ lấy toàn bộ nội dung của bảng và tải nó vào RAM. –

1

@ CSharper's answer is closed. Như @Oliver đã đề cập trong các nhận xét, IEnumerable tải bảng vào bộ nhớ ứng dụng, dẫn đến sự cố nếu bạn có cơ sở dữ liệu lớn.

Giải pháp là sử dụng IQueryable, có thể được gọi với LINQ - điều này tạo ra SQL nhanh hơn nhiều.

// 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); 
} 
Các vấn đề liên quan