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