cách sử dụng các chế độ xem trong khung thực thể mã đầu tiên [đã đóng]


87

Trước tiên, làm cách nào để sử dụng chế độ xem cơ sở dữ liệu trong mã khung thực thể,


2
Không có câu trả lời nào dưới đây giải thích cách tạo chế độ xem bằng cách sử dụng di chuyển EF. Xem câu trả lời này cho một câu hỏi tương tự.
Rudey

Đây là một chủ đề có cùng một câu hỏi. - stackoverflow.com/questions/13593845/…
Div Tiwari

Hãy thử giải pháp của tôi . Nó ngăn chặn việc tạo di chuyển cho các bảng được đánh dấu là chế độ xem
kogoia

Câu trả lời:


95

Nếu, giống như tôi, bạn chỉ quan tâm đến thực thể ánh xạ đến từ một cơ sở dữ liệu khác (trong trường hợp của tôi là một lỗi) để liên kết chúng với các thực thể cụ thể của ứng dụng của bạn, thì bạn có thể sử dụng các dạng xem khi bạn sử dụng bảng (ánh xạ chế độ xem trong cùng một cách!). Rõ ràng, nếu bạn cố gắng cập nhật các thực thể đó, bạn sẽ nhận được một ngoại lệ nếu chế độ xem không thể cập nhật. Quy trình giống như trong trường hợp của các thực thể bình thường (dựa trên bảng):

  1. Tạo một lớp POCO cho chế độ xem; ví dụ FooView
  2. Thêm thuộc tính DbSet trong lớp DbContext
  3. Sử dụng tệp FooViewConfiguration để đặt tên khác cho dạng xem (sử dụng ToTable ("Foo"); trong hàm tạo) hoặc để đặt các thuộc tính cụ thể

    public class FooViewConfiguration : EntityTypeConfiguration<FooView>      
    {
        public FooViewConfiguration()
        {
            this.HasKey(t => t.Id);
            this.ToTable("myView");
        }
    }
    
  4. Thêm tệp FooViewConfiguration vào modelBuilder, ví dụ: loại bỏ phương thức OnModelCreating của Context:

    protected override void OnModelCreating(DbModelBuilder modelBuilder)
    {
        modelBuilder.Configurations.Add(new FooViewConfiguration ());
    }
    

64
+1 vì không giả định rằng "Code First" == tự động tạo cơ sở dữ liệu
onetwopunch

3
@DaveJellison bạn có muốn giải thích hoặc cung cấp liên kết về việc thêm chế độ xem như một phần của IDatabaseInitializer
Ralph Shillington

18
Có phải chỉ tôi hay mọi người đang nhận được bảng trống do quá trình di chuyển tạo ra? Có cách nào để tránh điều đó không?
Kremena Lalova

4
Chỉ cần đảm bảo ở đây, giải pháp này có yêu cầu chúng ta tạo Chế độ xem trên cơ sở dữ liệu SQL trước bên ngoài không? Có thể xác định chế độ xem trong mã và đưa nó vào cơ sở dữ liệu thông qua lệnh Add-Migration / Update-Database không?
frostshoxx

6
Một vài thứ. 1. Câu trả lời này không đề cập đến việc bạn phải tạo chế độ xem theo cách thủ công bằng SQL, điều này có thể được thực hiện bằng cách sử dụng di chuyển. 2. Bạn không phải cấu hình tên dạng xem nếu tên lớp khớp với tên dạng xem. 3. Bạn có thể sử dụng DataAnnotations như vậy:, [Table("myView")]điều này được cho là đơn giản hơn so với việc sử dụng tạo a EntityTypeConfiguration.
Rudey

23

Đây có thể là một bản cập nhật nhưng để sử dụng các chế độ xem với Mã EF, trước tiên chỉ cần thêm [Bảng ("NameOfView")] vào đầu lớp và tất cả sẽ hoạt động bình thường mà không cần phải trải qua tất cả các vòng mà mọi người khác đang trải qua. Ngoài ra, bạn sẽ phải báo cáo một trong các cột dưới dạng cột [key]. Đây là mã mẫu của tôi dưới đây để triển khai nó.

using System.ComponentModel.DataAnnotations;
using System.ComponentModel.DataAnnotations.Schema;

namespace SomeProject.Data
{
    [Table("SomeView")]
    public class SomeView
    {
        [Key]
        public int NameID { get; set; }
        public string Name { get; set; }
    }
}

Và đây là bối cảnh trông như thế nào

using System.Data.Entity;

namespace SomeProject.Data
{
    public class DatabaseContext : DbContext
    {
        public DbSet<SomeView> SomeViews { get; set; }
    }
}

2
Câu trả lời này giống với câu trả lời được chấp nhận, ngoại trừ câu trả lời này sử dụng DataAnnotations trong khi câu trả lời được chấp nhận sử dụng EF Fluid API.
Rudey

4
Thực ra không, không phải vậy. Tôi đã thử nhưng không thành công với câu trả lời được chấp nhận và nó không hoạt động tốt đối với tôi. Nhưng sau đó tôi đang sử dụng Migrations nên điều này có thể ảnh hưởng đến mọi thứ. Tôi thấy rằng tôi phải thực hiện di chuyển của mình trước THÌ thêm lớp chế độ xem của tôi vì nó đã tồn tại trong cơ sở dữ liệu. Chúng tôi sẽ xử lý nó theo cùng một cách nếu chúng tôi đã có các bảng hiện có trong cơ sở dữ liệu. Vì một dạng xem là một "bảng ảo" nên cú pháp bảng trong Entity Framework vẫn hoạt động.
Charles Owen

11

Nếu tất cả những gì bạn muốn là một loạt các đối tượng không chuẩn hóa, thì bạn có thể chỉ cần tạo một thuộc tính chỉ nhận công khai IQueryable<TDenormolized>trongDbContext lớp .

Trong getbạn trả về một kết quả Linq để chiếu các giá trị đã khử chuẩn hóa vào các đối tượng được chuẩn hóa của bạn. Điều này có thể tốt hơn việc viết DB View vì bạn đang lập trình, bạn không bị giới hạn bởi chỉ sử dụng các selectcâu lệnh. Ngoài ra, nó là loại thời gian biên dịch an toàn.

Chỉ cần cẩn thận không kích hoạt liệt kê như ToList()cuộc gọi, điều đó sẽ phá vỡ truy vấn trì hoãn và bạn có thể kết thúc với việc lấy lại một triệu bản ghi từ cơ sở dữ liệu và lọc chúng trên máy chủ ứng dụng của bạn.

Tôi không biết liệu đây có phải là cách đúng không, nhưng tôi đã thử và nó phù hợp với tôi.


6
Một trong những lý do tôi muốn sử dụng các khung nhìn là SQL được tạo bởi EF không phải lúc nào cũng 'đẹp' - chúng tôi có một số cấu trúc phân cấp kế thừa trong mô hình của mình (phát hiện ra những cạm bẫy quá muộn ...) và việc sử dụng các khung nhìn cho phép chúng tôi để tạo SQL theo cách thủ công. Chỉ cần một đối trọng là tại sao một cái nhìn sẽ thích hợp hơn
Carl

2
Lý do khác để không làm điều này có thể là việc sử dụng các biểu thức bảng phổ biến đệ quy, không có sẵn trong LINQ. Nhưng nếu không thì đây là một lời khuyên tốt cho các tình huống đơn giản hơn.
Tom Pažourek

1
Sử dụng thuộc tính thay vì dạng xem không phải là một tùy chọn nếu bạn muốn tận dụng các lợi ích của dạng xem được lập chỉ mục .
Rudey

"bạn không bị giới hạn bởi chỉ sử dụng các câu lệnh được chọn". Ý bạn là gì? Bất cứ điều gì bạn có thể làm với LINQ đều có thể được thực hiện bằng cách sử dụng câu lệnh SELECT, điều tương tự không thể nói ngược lại.
Rudey

3

Tôi biết đây là một câu hỏi cũ và có nhiều câu trả lời ở đây, nhưng tôi buộc phải gặp sự cố khi sử dụng câu trả lời này và đã xảy ra lỗi khi tôi sử dụng lệnh update-database trong Package Manager Console:

Đã có một đối tượng tên là '...' trong cơ sở dữ liệu.

và tôi sử dụng các bước sau để giải quyết vấn đề này:

  1. chạy lệnh này trong Bảng điều khiển Trình quản lý Gói: Thêm-di chuyển intial
  2. Trong thư mục Migrations, bạn có thể tìm thấy ..._ intial.cs tệp, mở nó và nhận xét hoặc xóa bất kỳ lệnh nào liên quan đến lớp của bạn mà bạn muốn ánh xạ
  3. bây giờ bạn có thể bình thường sử dụng lệnh update-database cho bất kỳ thay đổi nào khác đối với mô hình của bạn

hy vọng nó giúp.


1
Cảm ơn! Điều này thực sự hữu ích! Ngoài ra, thay vì chỉ xóa mã được tạo bằng EF Migrations, bạn có thể thêm vào đó migrationBuilder.Sql("CREATE OR REPLACE VIEW ...); Vì vậy, các đồng nghiệp cũng có thể sử dụng nó để nâng cấp cơ sở dữ liệu của họ.
Rich_Rich
Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.