2016-11-09 18 views
6

Có cách nào kết hợp mã đầu tiên và cơ sở dữ liệu đầu tiên trong cùng một ngữ cảnh không? Chúng tôi đang chạy vào các vấn đề hiệu suất thời gian phát triển lớn khi chỉnh sửa tệp EDMX (mất 1,5 phút để lưu). Tôi đã chuyển không chèn/cập nhật/xóa UDF/procs được lưu trữ của mình thành một số mẫu T4 tùy chỉnh tự động tạo mã đầu tiên, nhưng tôi dường như không nhận được OnModelCreating để gọi khi EDMX tham gia.Kết hợp mã First & Database First In Single Model?

Những điều khác chúng tôi đã xem xét, nhưng sẽ không làm việc vì một lý do này hay cách khác:

  1. Chúng ta có thể không (hợp lý) tách mã của chúng tôi với nhiều bối cảnh là có rất nhiều chồng chéo trong mối quan hệ thực thể của chúng tôi. Nó cũng có vẻ như khá một người đã đi con đường này hối tiếc.

  2. Chúng tôi đã thử có 2 ngữ cảnh khác nhau, nhưng có khá nhiều sự tham gia giữa các đối tượng & UDF. Đây có thể là hy vọng cuối cùng của chúng tôi, nhưng tôi thực sự muốn tránh nó.

  3. Chúng tôi không thể chuyển sang Dapper vì chúng tôi không may đã sử dụng quá nhiều IQueryable.

  4. Chúng tôi đã cố gắng hoàn thành Mã-Thứ nhất, nhưng có các tính năng mà chúng tôi đang sử dụng trong EDMX không được hỗ trợ (chủ yếu liên quan đến chèn/cập nhật/xóa bản đồ quy trình được lưu trữ).

+0

Tệp EDMX không tạo một lớp học một phần cho ngữ cảnh không? Được một thời gian kể từ khi tôi sử dụng một ... – DavidG

+0

Nó có, nhưng OnModelCreating không nhận được gọi là nếu bạn đang sử dụng EDMX như xa như tôi có thể nói. – randomsolutions

+0

Tôi không nghĩ rằng đây là trường hợp? – DavidG

Trả lời

0

Cảm ơn mọi người vì những câu trả lời kỹ lưỡng và được suy nghĩ kỹ lưỡng.

Nhiều câu trả lời khác giả định rằng ánh xạ thủ tục được lưu trữ trong Mã EF-Đầu tiên hoạt động giống nhau, nhưng chúng không giống nhau. Tôi hơi mờ về điều này vì nó đã được khoảng 6 tháng kể từ khi tôi nhìn vào nó, nhưng tôi tin rằng về thủ tục lưu trữ đầu tiên EF 6.3 mã yêu cầu bạn phải vượt qua mọi cột từ thực thể của bạn để chèn/cập nhật thủ tục lưu trữ của bạn và bạn chỉ chuyển (các) cột chính cho thủ tục xóa của bạn. Không có tùy chọn để chọn và chọn cột nào bạn có thể vượt qua. Chúng tôi có yêu cầu duy trì người đã xóa hồ sơ để chúng tôi phải chuyển một số thông tin bổ sung bên cạnh chỉ một khóa đơn giản.

Điều đó đang được nói, những gì tôi đã làm là sử dụng mẫu T4 để tự động tạo các tệp EDMX/Context/Model của tôi từ cơ sở dữ liệu (với một số siêu dữ liệu bổ sung). Điều này làm cho trải nghiệm thời gian của nhà phát triển của chúng tôi giảm từ 1,5 phút xuống còn khoảng 5 giây.

Tôi hy vọng bản đồ hóa thủ tục lưu trữ EF sẽ được cải thiện để đạt được parody với EDMX và sau đó tôi có thể tạo mã ánh xạ Code-First và loại bỏ hoàn toàn thế hệ EDMX.

+1

Bạn có thể ánh xạ một thủ tục lưu trữ cho các loại phi thực thể và nguyên thủy và sử dụng Database.SqlQuery . Mô hình tùy chỉnh phải khớp với các cột được trả về bởi quy trình được lưu trữ "Chọn". Ý tưởng tương tự này áp dụng cho Chèn, Cập nhật và Xóa. Một số thủ tục được lưu trữ được ánh xạ trong các ứng dụng của chúng tôi bằng cách sử dụng phương pháp này. Xem các liên kết sau: Sử dụng Database.SqlQuery: http://stackoverflow.com/questions/4873607/how-to-use-dbcontext-database-sqlquerytelementsql-params-with-stored-proced Tài liệu MSDN: https : //msdn.microsoft.com/en-us/library/dn468673 (v = vs.113) .aspx – Charles

1

Tôi đến đây từ một liên kết trong xét của bạn về khác nhau question, nơi bạn hỏi:

bạn nói rằng mã đầu tiên & cơ sở dữ liệu đầu tiên là "kỹ thuật có thể" bạn có thể giải thích như thế nào để đạt được điều đó?

Đầu tiên, ngữ cảnh của câu hỏi khác hoàn toàn khác. OP đã hỏi liệu có thể sử dụng cả hai phương pháp cơ sở dữ liệu-đầu tiên và mã-đầu tiên trong cùng một dự án, nhưng quan trọng, không nhất thiết phải cùng bối cảnh. Tôi nói rằng đó là "kỹ thuật có thể" áp dụng cho các cựu, không phải sau này. Hoàn toàn không có cách nào để sử dụng cả hai mã đầu tiên và cơ sở dữ liệu đầu tiên trong cùng một ngữ cảnh. Trên thực tế, để cụ thể hơn một chút, giả sử không có cách nào để sử dụng cơ sở dữ liệu hiện có và cũng di chuyển cùng cơ sở dữ liệu đó với các thực thể mới.

Thuật ngữ bị nhầm lẫn một chút ở đây do một số tên không may của Microsoft khi EF được phát triển. Ban đầu, bạn chỉ có Model-first và Database-first. Cả hai đều sử dụng EDMX. Sự khác biệt duy nhất là Model-first sẽ cho phép bạn thiết kế các thực thể của bạn và tạo ra một cơ sở dữ liệu từ đó, trong khi Database-first lấy một cơ sở dữ liệu hiện có và tạo các thực thể từ đó.

Với EF 4.1, Mã đầu tiên được giới thiệu, loại bỏ hoàn toàn EDMX và cho phép bạn làm việc với POCO (đối tượng lớp cũ đồng bằng). Tuy nhiên, mặc dù tên, Code-first có thể và luôn có thể làm việc với một cơ sở dữ liệu hiện có hoặc tạo một cơ sở dữ liệu mới. Code-first, sau đó thực sự là Model-first và Database-first, kết hợp, trừ đi EDMX khủng khiếp. Gần đây, nhóm EF cuối cùng đã tiến một bước xa hơn và không dùng EDMX hoàn toàn, bao gồm cả phương pháp Model-first và Database-first. Đó là không được khuyến nghị để tiếp tục sử dụng một trong hai điểm này và bạn có thể mong đợi hỗ trợ EDMX được giảm hoàn toàn trong các phiên bản tương lai của Visual Studio.

Với tất cả những gì đã nói, hãy tìm hiểu sự thật.Bạn không thể vừa có cơ sở dữ liệu hiện có vừa là một cơ sở dữ liệu được quản lý bởi EF trong một ngữ cảnh duy nhất. Bạn sẽ ít nhất cần hai: một cho các bảng hiện có của bạn và một cho những người được quản lý bởi EF. Thêm vào vấn đề này, hai bối cảnh này phải tham chiếu đến các cơ sở dữ liệu khác nhau. Nếu có bất kỳ bảng hiện có nào trong cơ sở dữ liệu được quản lý bởi EF, EF sẽ cố gắng loại bỏ chúng. Dài và ngắn, bạn phải tách riêng công cụ quản lý EF khỏi công cụ được quản lý bên ngoài của bạn, có nghĩa là bạn không thể tạo khóa ngoài giữa các thực thể trong một ngữ cảnh và một thực thể khác.

Tùy chọn thực sự duy nhất của bạn ở đây là chỉ cần thực hiện mọi thứ "cơ sở dữ liệu đầu tiên". Nói cách khác, bạn sẽ phải xử lý cơ sở dữ liệu của bạn như hiện tại và tự tạo các bảng mới, thay đổi các cột, vv mà không cần phải di chuyển EF. Về vấn đề này, bạn cũng nên đi trước và đổ EDMX. Tạo tất cả các thực thể của bạn dưới dạng POCO và chỉ cần vô hiệu hóa bộ khởi tạo cơ sở dữ liệu trong ngữ cảnh của bạn. Nói cách khác, Code-đầu tiên với một cơ sở dữ liệu hiện có. Tôi có additional information, nếu bạn cần.

4

Hãy xem liên kết sau. Tôi trả lời một câu hỏi khác trong một thời trang tương tự:
How to use Repository pattern using Database first approach in entity framework

Như tôi đã đề cập trong bài đó, tôi sẽ đích thân cố gắng để chuyển sang một cách tiếp cận Mã Đầu tiên và thoát khỏi các tập tin EDMX vì nó đã bị phản đối và quan trọng nhất, các nỗ lực bảo trì là đáng kể và phức tạp hơn nhiều so với cách tiếp cận Code First.

Nó không phải là khó chuyển đổi sang mã đầu tiên từ một phương pháp tiếp cận mô hình đầu tiên. Một số bước và hình ảnh xuống dưới đây:

  1. Hiển thị tất cả các tệp ở cấp dự án và mở rộng tệp EDMX. Bạn sẽ nhận thấy rằng tệp EDMX có tệp .TT sẽ có nhiều tệp lồng nhau, Mô hình ngữ cảnh và POCO nối giữa chúng dưới dạng .cs hoặc .vb (tùy thuộc vào ngôn ngữ bạn đang sử dụng). Xem hình ảnh bên dưới:
    enter image description here
  2. Dỡ bỏ dự án, nhấp chuột phải và sau đó chỉnh sửa.
  3. Xem hình dưới đây, nhận thấy sự phụ thuộc giữa bối cảnh và tập tin TT
    enter image description here
  4. Hủy bỏ sự phụ thuộc, yếu tố xml sẽ giống như hình dưới đây:
    enter image description here
  5. Lặp lại thủ tục cho Model các lớp học (Những người có định nghĩa mô hình)
  6. Tải lại dự án của bạn, xóa (các) tệp EDMX
  7. Có thể bạn sẽ cần làm một số tweek và cập nhật tên/tham chiếu.

Tôi đã làm điều này một vài lần trong quá khứ và nó hoạt động hoàn hảo trên sản xuất. Bạn cũng có thể tìm kiếm các công cụ thực hiện chuyển đổi này cho bạn.

Đây có thể là cơ hội tốt để bạn suy nghĩ lại về kiến ​​trúc.

BTW: Điểm dấu 4 không phải là nút hiển thị cho bạn. Bạn có thể lập bản đồ/sử dụng các thủ tục lưu trữ thông qua EF. Nhìn vào liên kết sau:
How to call Stored Procedure in Entity Framework 6 (Code-First)?

+0

Bạn cũng có thể muốn xem lại mẫu Repository và mẫu CQRS. Cả hai đều có lợi ích khác nhau và có thể hữu ích để đáp ứng nhu cầu của bạn. – Charles

2

Nó cũng có vẻ như khá một dân tộc đã đi tuyến đường này [nhiều ngữ cảnh] hối tiếc.

Tôi không phải một trong số đó.

Vấn đề cốt lõi của bạn là ngữ cảnh quá lớn. Vì vậy, phá vỡ nó lên. Tôi biết rằng chắc chắn sẽ có các thực thể cần được chia sẻ trong một số ngữ cảnh, điều này có thể làm phát sinh tên lớp trùng lặp. Một cách dễ dàng để giải quyết vấn đề này là đổi tên các lớp thành các tên cụ thể theo ngữ cảnh của chúng.

Ví dụ, tôi có một ApplicationUser bảng (những người không có) mà các bản đồ đến một lớp học có cùng tên trong bối cảnh chính, nhưng để một lớp AuthorizationUser trong AuthorizationContext của tôi, hoặc ReportingUser trong một ReportingContext. Đây không phải là vấn đề ở tất cả. Tuy nhiên, hầu hết các trường hợp sử dụng xoay quanh một loại ngữ cảnh, vì vậy không thể nhầm lẫn được.

Tôi thậm chí còn có ngữ cảnh chuyên biệt hoạt động trên cùng một dữ liệu như các bối cảnh khác, nhưng theo cách kinh tế hơn. Ví dụ, một ngữ cảnh không ánh xạ tới các cột được tính toán trong cơ sở dữ liệu, do đó không có lần đọc sau khi chèn và cập nhật (ngoài các giá trị nhận dạng).

Vì vậy, tôi khuyên bạn nên đi cho nó, bởi vì ...

Có cách nào để kết hợp mã đầu tiên và cơ sở dữ liệu đầu tiên trong bối cảnh tương tự?

Không, không có. Cả hai cách tiếp cận có các cách khác nhau để xây dựng DbModel (chứa mô hình cửa hàng, mô hình lớp và ánh xạ giữa cả hai). Trong một số được tạo ra DbContext, bạn thậm chí thấy rằng một số UnintentionalCodeFirstException được ném, để lái xe về nhà mà bạn không được phép sử dụng phương pháp đó.

chủ yếu liên quan đến chèn/cập nhật/xóa bản đồ stored procedure

Như đã nói trong câu trả lời khác, lập bản đồ hành động CUD thủ tục lưu trữ là supported in EF6 code-first.

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