Entity Framework 6을 처음 접했고 프로젝트에서 저장 프로 시저를 구현하고 싶습니다. 다음과 같은 저장 프로 시저가 있습니다.
ALTER PROCEDURE [dbo].[insert_department]
@Name [varchar](100)
AS
BEGIN
INSERT [dbo].[Departments]([Name])
VALUES (@Name)
DECLARE @DeptId int
SELECT @DeptId = [DeptId]
FROM [dbo].[Departments]
WHERE @@ROWCOUNT > 0 AND [DeptId] = SCOPE_IDENTITY()
SELECT t0.[DeptId]
FROM [dbo].[Departments] AS t0
WHERE @@ROWCOUNT > 0 AND t0.[DeptId] = @DeptId
END
Department
수업:
public class Department
{
public int DepartmentId { get; set; }
public string Name { get; set; }
}
modelBuilder
.Entity<Department>()
.MapToStoredProcedures(s =>
s.Update(u => u.HasName("modify_department")
.Parameter(b => b.Department, "department_id")
.Parameter(b => b.Name, "department_name"))
.Delete(d => d.HasName("delete_department")
.Parameter(b => b.DepartmentId, "department_id"))
.Insert(i => i.HasName("insert_department")
.Parameter(b => b.Name, "department_name")));
protected void btnSave_Click(object sender, EventArgs e)
{
string department = txtDepartment.text.trim();
// here I want to call the stored procedure to insert values
}
내 문제는 : 저장 프로 시저를 호출하고 매개 변수를 전달하는 방법은 무엇입니까?
답변
DbContext
다음과 같이 클래스 에서 저장 프로 시저를 호출 할 수 있습니다 .
this.Database.SqlQuery<YourEntityType>("storedProcedureName",params);
그러나 저장 프로 시저가 여러 결과 집합을 샘플 코드로 반환하면 MSDN에서이 유용한 기사를 볼 수 있습니다.
답변
스토어드 프로 시저가 리턴 한 결과와 동일한 특성 이름을 가진 오브젝트를 작성하기 만하면됩니다. 다음 저장 프로 시저의 경우 :
CREATE PROCEDURE [dbo].[GetResultsForCampaign]
@ClientId int
AS
BEGIN
SET NOCOUNT ON;
SELECT AgeGroup, Gender, Payout
FROM IntegrationResult
WHERE ClientId = @ClientId
END
다음과 같은 클래스를 만듭니다.
public class ResultForCampaign
{
public string AgeGroup { get; set; }
public string Gender { get; set; }
public decimal Payout { get; set; }
}
다음을 수행하여 절차를 호출하십시오.
using(var context = new DatabaseContext())
{
var clientIdParameter = new SqlParameter("@ClientId", 4);
var result = context.Database
.SqlQuery<ResultForCampaign>("GetResultsForCampaign @ClientId", clientIdParameter)
.ToList();
}
결과에는 ResultForCampaign
개체 목록이 포함 됩니다. SqlQuery
필요한만큼 많은 매개 변수를 사용하여 호출 할 수 있습니다 .
답변
나는 그것을 해결했다 ExecuteSqlCommand
내 자신의 메소드를 DbContext에 자신의 인스턴스로 넣으십시오.
public void addmessage(<yourEntity> _msg)
{
var date = new SqlParameter("@date", _msg.MDate);
var subject = new SqlParameter("@subject", _msg.MSubject);
var body = new SqlParameter("@body", _msg.MBody);
var fid = new SqlParameter("@fid", _msg.FID);
this.Database.ExecuteSqlCommand("exec messageinsert @Date , @Subject , @Body , @Fid", date,subject,body,fid);
}
그래서 당신은 다음과 같이 코드 뒤에 메소드를 가질 수 있습니다 :
[WebMethod] //this method is static and i use web method because i call this method from client side
public static void AddMessage(string Date, string Subject, string Body, string Follower, string Department)
{
try
{
using (DBContext reposit = new DBContext())
{
msge <yourEntity> Newmsg = new msge();
Newmsg.MDate = Date;
Newmsg.MSubject = Subject.Trim();
Newmsg.MBody = Body.Trim();
Newmsg.FID= 5;
reposit.addmessage(Newmsg);
}
}
catch (Exception)
{
throw;
}
}
이것은 내 SP입니다.
Create PROCEDURE dbo.MessageInsert
@Date nchar["size"],
@Subject nchar["size"],
@Body nchar["size"],
@Fid int
AS
insert into Msg (MDate,MSubject,MBody,FID) values (@Date,@Subject,@Body,@Fid)
RETURN
희망이 당신을 도왔습니다
답변
예제를 사용하여 다음을 수행하는 두 가지 방법이 있습니다.
1-스토어드 프로 시저 맵핑 사용
이 코드는 매핑 유무에 관계없이 작동합니다. 엔터티에서 매핑을 해제하면 EF가 insert + select 문을 생성합니다.
protected void btnSave_Click(object sender, EventArgs e)
{
using (var db = DepartmentContext() )
{
var department = new Department();
department.Name = txtDepartment.text.trim();
db.Departments.add(department);
db.SaveChanges();
// EF will populate department.DepartmentId
int departmentID = department.DepartmentId;
}
}
2-저장 프로 시저를 직접 호출
protected void btnSave_Click(object sender, EventArgs e)
{
using (var db = DepartmentContext() )
{
var name = new SqlParameter("@name", txtDepartment.text.trim());
//to get this to work, you will need to change your select inside dbo.insert_department to include name in the resultset
var department = db.Database.SqlQuery<Department>("dbo.insert_department @name", name).SingleOrDefault();
//alternately, you can invoke SqlQuery on the DbSet itself:
//var department = db.Departments.SqlQuery("dbo.insert_department @name", name).SingleOrDefault();
int departmentID = department.DepartmentId;
}
}
부서 개체를 직접 사용하여 많은 SqlParameter 개체를 만들 필요가 없으므로 첫 번째 방법을 사용하는 것이 좋습니다.
답변
사용 MapToStoredProcedures()
하는 엔터티는 저장 프로 시저에 엔터티를 매핑하고 있음을 나타내며,이 작업을 수행 할 때는 저장 프로 시저가 있다는 사실을 없애고이를 그대로 사용해야합니다 context
. 이와 같은 것 ( 브라우저에 작성되었으므로 테스트되지 않음 )
using(MyContext context = new MyContext())
{
Department department = new Department()
{
Name = txtDepartment.text.trim()
};
context.Set<Department>().Add(department);
}
실제로 저장 프로 시저를 직접 호출하기 만하면됩니다. SqlQuery
답변
또한 기본적으로 EF에서 저장 프로 시저 (여러 결과 집합을 반환하는 저장 프로 시저 포함), TVF 및 스칼라 UDF를 호출 할 수 있도록 만든 규칙을 사용할 수 있습니다.
Entity Framework 6.1이 릴리스 될 때까지 데이터베이스 기능을 수행 할 때만 스토어 함수 (예 : 테이블 값 함수 및 스토어드 프로 시저)를 EF에서 사용할 수있었습니다. Code First 앱에서 스토어 기능을 호출 할 수있는 해결 방법이 있었지만 Linq 쿼리에서 TVF를 여전히 사용할 수 없었습니다. EF 6.1에서는 맵핑 API가 공개되었으며 (일부 추가 조정과 함께) Code First 앱에서 상점 기능을 사용할 수있었습니다.
필자는 지난 2 주 동안 매우 열심히 노력했으며 코드 우선 접근 방식 및 Entity Framework 6.1.1 ( 이상). 이 릴리스에 포함 된 수정 사항 및 새로운 기능에 만족합니다.
더 읽어보십시오 .
답변
object[] xparams = {
new SqlParameter("@ParametterWithNummvalue", DBNull.Value),
new SqlParameter("@In_Parameter", "Value"),
new SqlParameter("@Out_Parameter", SqlDbType.Int) {Direction = ParameterDirection.Output}};
YourDbContext.Database.ExecuteSqlCommand("exec StoreProcedure_Name @ParametterWithNummvalue, @In_Parameter, @Out_Parameter", xparams);
var ReturnValue = ((SqlParameter)params[2]).Value;