2011-01-30 29 views
111

Tôi đã xem một số bản trình bày của EF Code First và chưa thấy cách EFCF hoạt động với các thủ tục được lưu trữ.Mã khung thực thể có hỗ trợ đầu tiên được lưu trữ thủ tục không?

Làm cách nào để khai báo phương thức sẽ sử dụng một số sp? Tôi có thể chuyển một thực thể đến một phương thức gọi sp mà không cần ánh xạ các thuộc tính thực thể theo cách thủ công đến các tham số sp không?

Ngoài ra, điều gì sẽ xảy ra nếu tôi thay đổi mô hình của mình? Nó sẽ thả sp của tôi trong khi tái tạo bảng từ mô hình? Và những gì về gây nên?

Nếu những điều này không được hỗ trợ, có bất kỳ kế hoạch hỗ trợ nào trong tương lai không?

+5

Điểm lộ trình EF mà EF 6 sẽ hỗ trợ các thủ tục và chức năng được lưu trữ cho Mã đầu tiên. http://entityframework.codeplex.com/wikipage?title=Roadmap – frennky

+0

Xem thêm: http://stackoverflow.com/questions/4873607/how-to-use-dbcontext-database-sqlquerytelementsql-params-with-stored-proced –

Trả lời

66

EDIT: Câu trả lời ban đầu của tôi cho EF4.1 (bên dưới) hiện đã lỗi thời. Vui lòng xem the answer below from Diego Vega (người làm việc cho nhóm EF tại Microsoft)!


@gsharp và Shawn Mclean: Bạn nhận thông tin này ở đâu? Bạn vẫn không có quyền truy cập vào ObjectContext cơ bản?

IEnumerable<Customer> customers = 
    ((IObjectContextAdapter)this) 
    .ObjectContext.ExecuteStoreQuery<Customer>("select * from customers"); 

Thay thế câu lệnh "chọn" bằng proc đã lưu và bạn sẽ làm như thế nào.

Đối với câu hỏi khác của bạn: Có, rất tiếc, s.p. của bạn sẽ bị ghi đè. Bạn có thể cần thêm câu lệnh "CREATE PROCEDURE" vào mã của bạn.

Đối với EF 4.2:

var customers = context.Database.SqlQuery<Customer>("select * from customers") 
+0

Cảm ơn. Bạn có thể chỉ cho tôi một số liên kết có thêm thông tin về chủ đề này không. – frennky

+1

Bạn sẽ muốn tra cứu ba hàm Thực thi trên đối tượng ObjectContext (ExecuteStoreQuery, ExecuteFunction và ExecuteStoreCommand). – anon

+0

Tôi hiểu nhầm câu hỏi. Tôi đã nghĩ rằng anh ấy muốn tạo ra một mã số đầu tiên của SP. – gsharp

50

Cập nhật: Từ EF6 trên, EF Mã đầu tiên không hỗ trợ lưu trữ bản đồ quy trình chèn, cập nhật và xóa dần. Bạn có thể chỉ định ánh xạ thủ tục đã lưu trữ trong quá trình tạo mô hình bằng phương thức MapToStoredProcedures. Chúng tôi cũng hỗ trợ giàn giáo tự động của các thủ tục lưu trữ cơ bản cho các hoạt động đó. Xem đặc điểm kỹ thuật của tính năng here.

Original câu trả lời: Chúng tôi sẽ không có hỗ trợ cho thủ tục lưu trữ bản đồ trong mô hình ở Mã-đầu tiên trong phiên bản đầu tiên, cũng không phải chúng ta sẽ có một cách để tự động tạo ra các thủ tục lưu trữ cho các hoạt động CRUD từ loại của bạn. Đây là những tính năng mà chúng tôi muốn thêm vào trong tương lai.

Như đã đề cập trong chủ đề này, có thể quay trở lại ObjectContext nhưng DbContext cũng cung cấp các API tốt để thực thi các truy vấn và lệnh SQL nguyên gốc (ví dụ: DbSet.SqlQuery, DbContext.Database.SqlQuery và DbContext.Database.ExecuteSqlCommand). Các phiên bản SqlQuery khác nhau có cùng chức năng vật chất cơ bản tồn tại trong EF4 (như ExecuteStoreQuery: http://msdn.microsoft.com/en-us/library/dd487208.aspx).

Hy vọng điều này sẽ hữu ích.

+6

BTW, tôi đã viết một bài đăng blog cách đây vài ngày để biết chi tiết cách sử dụng các phương thức này để gọi các thủ tục được lưu trữ, thậm chí các thủ tục đã lưu với các tham số đầu ra: http://blogs.msdn.com/b/diego/archive/2012/01 /10/how-to-execute-stored-procedures-sqlquery-in-the-dbcontext-api.aspx. – divega

+3

Cuối năm 2013, EF6 vẫn đang được phát triển. Chờ đợi ba năm chỉ để cải thiện hỗ trợ cho sprocs, thở dài. – DOK

+1

@divega Có hỗ trợ mạnh mẽ cho việc chỉ chọn các giá trị từ một thủ tục lưu sẵn - cách tiếp cận mã đầu tiên này có vẻ cụ thể để quản lý đối tượng thời gian sống? Cụ thể, đối với các tìm kiếm phức tạp, sử dụng thủ tục lưu sẵn spFooSearch với tham số đầu ra TotalRows. –

31
public IList<Product> GetProductsByCategoryId(int categoryId) 
    { 
     IList<Product> products; 

     using (var context = new NorthwindData()) 
     { 
      SqlParameter categoryParam = new SqlParameter("@categoryID", categoryId); 
      products = context.Database.SqlQuery<Product>("Products_GetByCategoryID @categoryID", categoryParam).ToList(); 
     } 

     return products; 
    } 

    public Product GetProductById(int productId) 
    { 
     Product product = null; 

     using (var context = new NorthwindData()) 
     { 
      SqlParameter idParameter = new SqlParameter("@productId", productId); 
      product = context.Database.SqlQuery<Product>("Product_GetByID @productId", idParameter).FirstOrDefault(); 
     } 

     return product; 
    } 
8

Một nhiều loại giải pháp an toàn sẽ là:

http://strugglesofacoder.blogspot.be/2012/03/calling-stored-procedure-with-entity.html

Việc sử dụng lớp này là:

var testProcedureStoredProcedure = new TestProcedureStoredProcedure() { Iets = 5, NogIets = true }; 

var result = DbContext.Database.ExecuteStoredProcedure(testProcedureStoredProcedure); 
+0

Liên kết không còn hoạt động nữa, nhưng đây là bản lưu trữ: http://web.archive.org/web/20150430090848/http://www.lucbos.net/2012/03/calling-stored-procedure-with-entity .html –

2

Đối với NET Core (EntityFrameworkCore), tôi đã được có thể khiến họ làm việc.

Có thể không phải là gọn gàng nhất, nhưng điều này chắc chắn hoạt động.

Việc chuyển để thêm các thủ tục lưu trữ trông giống như this:

using Microsoft.EntityFrameworkCore.Migrations; 
using System.Text; 

namespace EFGetStarted.AspNetCore.NewDb.Migrations 
{ 
    public partial class StoredProcedureTest : Migration 
    { 
     protected override void Up(MigrationBuilder migrationBuilder) 
     { 
      StringBuilder sb = new StringBuilder(); 
      sb.AppendLine("CREATE PROCEDURE GetBlogForAuthorName"); 
      sb.AppendLine("@authorSearch varchar(100)"); 
      sb.AppendLine("AS"); 
      sb.AppendLine("BEGIN"); 
      sb.AppendLine("-- SET NOCOUNT ON added to prevent extra result sets from interfering with SELECT statements."); 
      sb.AppendLine("SET NOCOUNT ON;"); 
      sb.AppendLine("SELECT Distinct Blogs.BlogId, Blogs.Url"); 
      sb.AppendLine("FROM Blogs INNER JOIN"); 
      sb.AppendLine("Posts ON Blogs.BlogId = Posts.BlogId INNER JOIN"); 
      sb.AppendLine("PostsAuthors ON Posts.PostId = PostsAuthors.PostId Inner JOIN"); 
      sb.AppendLine("Authors on PostsAuthors.AuthorId = Authors.AuthorId"); 
      sb.AppendLine("Where Authors.[Name] like '%' + @authorSearch + '%'"); 
      sb.AppendLine("END"); 

      migrationBuilder.Sql(sb.ToString()); 
     } 

     protected override void Down(MigrationBuilder migrationBuilder) 
     { 
      migrationBuilder.Sql("DROP PROCEDURE GetBlogForAuthorName"); 
     } 
    } 
} 

Sau đó tôi có thể gọi nó với mã following:

var blogs = _context.Blogs.FromSql("exec GetBlogForAuthorName @p0", "rod").Distinct(); 

Sau đó cố gắng nhận được một số dữ liệu liên quan (một đến nhiều dữ liệu quan hệ, ví dụ: Nội dung bài đăng) và blog đã trở lại với nội dung Đăng đầy như đã được xuất bản.

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