Entity Framework Code First는 저장 프로 시저를 지원합니까?


112

저는 EF Code First의 여러 프레젠테이션을 보았지만 EFCF가 저장 프로 시저와 어떻게 작동하는지 보지 못했습니다.

일부 sp를 사용할 메서드를 어떻게 선언 할 수 있습니까? 엔티티 속성을 sp 매개 변수에 수동으로 매핑하지 않고 sp를 호출하는 메서드에 엔티티를 전달할 수 있습니까?

또한 모델을 변경하면 어떻게됩니까? 모델에서 테이블을 다시 만드는 동안 내 sp를 삭제합니까? 그리고 트리거는 어떻습니까?

이러한 것들이 지원되지 않는다면 향후 지원할 계획이 있습니까?


5
EF 로드맵은 EF 6이 Code First에 대한 저장 프로 시저 및 함수를 지원할 것이라는 점을 지적합니다. entityframework.codeplex.com/wikipage?title=Roadmap
frennky

답변:


66

편집 : EF4.1 (아래)에 대한 원래 답변은 이제 구식입니다. 아래의 Diego Vega (Microsoft의 EF 팀에서 일하고 있는)의 답변을 참조하십시오 !


@gsharp 및 Shawn Mclean :이 정보는 어디서 얻습니까? 여전히 기본 ObjectContext에 액세스 할 수 없습니까?

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

"select"문을 저장된 proc으로 바꾸면됩니다.

다른 질문에 관해서는 : 예, 불행히도 귀하의 sp가 방해받을 것입니다. 코드에 "CREATE PROCEDURE"문을 추가해야 할 수도 있습니다.

EF 4.2의 경우 :

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

감사. 이 주제에 대한 자세한 정보가있는 링크를 알려 주시겠습니까?
frennky 2011 년

1
ObjectContext 개체 (ExecuteStoreQuery, ExecuteFunction 및 ExecuteStoreCommand)에서 세 가지 Execute 함수를 조회 할 수 있습니다.
anon

나는 질문을 오해했다. 나는 그가 먼저 코드를 기반으로 SP를 만들고 싶다고 생각했다.
gsharp 2011 년

Context.OnModelCreating을 재정의하고 사용자 지정 논리를 추가하여 코드를 통해 저장된 procs와 같은 데이터베이스 항목을 상당히 쉽게 만들 수 있습니다. 이상적이지는 않지만 꼬집어서 트릭을 할 것입니다.
Rick Strahl 2011 년

IObjectContextAdapter 캐스트가 필요하지 않습니다. DbContext는 내장 된 데이터베이스 오브젝트를 사용하여 sp 또는 사용자 정의 SQL 문을 처리 할 수 ​​있습니다. context.Database.SqlQuery <Dummy> ( "sp_GetDummy");
Steven K.

50

업데이트 : EF6부터 EF Code First는 삽입, 업데이트 및 삭제에 대한 저장 프로 시저 매핑을 지원합니다. MapToStoredProcedures 메서드를 사용하여 모델 생성 중에 저장 프로 시저 매핑을 지정할 수 있습니다. 또한 이러한 작업에 대한 기본 저장 프로 시저의 자동 스캐 폴딩을 지원합니다. 여기 에서 기능 사양을 참조 하십시오 .

원래 답변 : 첫 번째 릴리스에서는 Code-First에서 모델의 저장 프로 시저 매핑을 지원하지 않으며, 사용자 유형에서 CRUD 작업을위한 저장 프로 시저를 자동으로 생성하는 방법도 없습니다. 앞으로 추가하고 싶은 기능입니다.

이 스레드에서 언급했듯이 ObjectContext로 폴백 할 수 있지만 DbContext는 네이티브 SQL 쿼리 및 명령 (예 : DbSet.SqlQuery, DbContext.Database.SqlQuery 및 DbContext.Database.ExecuteSqlCommand)을 실행하기위한 멋진 API도 제공합니다. 다른 SqlQuery 버전은 EF4에 존재하는 동일한 기본 구체화 기능을 가지고 있습니다 (예 : ExecuteStoreQuery : http://msdn.microsoft.com/en-us/library/dd487208.aspx ).

도움이 되었기를 바랍니다.


6
BTW, 저는 며칠 전에 이러한 메서드를 사용하여 저장 프로 시저를 호출하는 방법을 자세히 설명하는 블로그 게시물을 작성했습니다 . 출력 매개 변수가있는 저장 프로시 저도 포함 됩니다. blogs.msdn.com/b/diego/archive/2012/01/10/… .
divega

3
2013 년 말 EF6는 아직 개발 중입니다. sprocs에 대한 지원을 개선하기 위해 3 년을 기다립니다.
DOK 2013 년

1
@divega 저장 프로 시저에서 값을 선택하기위한 강력한 형식의 지원이 있습니까?이 코드 우선 접근 방식은 개체 수명 관리에 특화되어 있습니까? 특히 복잡한 검색의 경우 TotalRows 출력 매개 변수와 함께 spFooSearch 저장 프로 시저를 사용합니다.
John Zabroski

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

더 많은 유형의 안전한 솔루션은 다음과 같습니다.

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

이 클래스의 사용법은 다음과 같습니다.

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

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

링크는 더 이상 활성화되지 않지만 아카이브는 다음과 같습니다. web.archive.org/web/20150430090848/http://www.lucbos.net/2012/…
Arturo Torres Sánchez

2

.NET Core (EntityFrameworkCore)의 경우 작동하게 할 수있었습니다.

가장 깔끔하지 않을 수도 있지만 이것은 확실히 작동합니다.

저장 프로 시저를 추가하기위한 마이그레이션은 다음과 같습니다 .

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

그런 다음 다음 코드 로 호출 할 수 있습니다.

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

나중에 관련 데이터 (일대 다 관계 데이터, 예 : 게시물 콘텐츠)를 가져 오려고 시도했고 블로그는 예상대로 채워진 게시물 콘텐츠로 돌아 왔습니다.

당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.