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

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

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

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

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



답변

편집 : 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")


답변

업데이트 : 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 ).

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


답변

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


답변

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

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


답변

.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();

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


답변