[C#] Entity Framework 6에서 저장 프로 시저를 호출하는 방법 (코드 우선)?

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;