c# - stored - entity framework 저장 프로 시저




Entity Framework 6(코드 우선)에서 저장 프로 시저를 호출하는 방법 (11)

필자는 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

학급 :

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
}

내 문제는 : 어떻게 저장 프로 시저를 호출하고 매개 변수를 전달할 수 있습니까?


EDMX가 테이블 선택 옵션에 저장된 프로 시저를 선택한 경우이 시간을 만들면 프로 시저 이름을 사용하여 프로 시저 저장소를 호출합니다.

var num1 = 1; 
var num2 = 2; 

var result = context.proc_name(num1,num2).tolist();// list or single you get here.. using same thing you can call insert,update or delete procedured.

그것은 나를 먼저 코드에서 작동합니다. 뷰 모델 (StudentChapterCompletionViewModel)의 속성과 일치하는 목록을 반환합니다.

var studentIdParameter = new SqlParameter
{
     ParameterName = "studentId",
     Direction = ParameterDirection.Input,
     SqlDbType = SqlDbType.BigInt,
     Value = studentId
 };

 var results = Context.Database.SqlQuery<StudentChapterCompletionViewModel>(
                "exec dbo.sp_StudentComplettion @studentId",
                 studentIdParameter
                ).ToList();

컨텍스트에 맞게 업데이트 됨

Context는 아래처럼 DbContext를 상속받는 클래스의 인스턴스입니다.

public class ApplicationDbContext : DbContext
{
    public DbSet<City> City { get; set; }
}

var Context = new  ApplicationDbContext();

삽입, 업데이트 및 삭제를 위해 EF 6과 저장 프로 시저의 매핑이 어떻게 작동하는지 보여주는이 링크를 살펴보십시오. http://msdn.microsoft.com/en-us/data/dn468673

부가

다음은 코드 첫 번째에서 저장 프로 시저를 호출하는 좋은 예입니다.

하나의 매개 변수로 저장 프로 시저를 실행해야하며 저장 프로 시저가 Entity States와 일치하는 데이터 집합을 반환하므로 다음과 같이 처리합니다.

var countryIso = "AR"; //Argentina

var statesFromArgentina = context.Countries.SqlQuery(
                                      "dbo.GetStatesFromCountry @p0", countryIso
                                                    );

이제 두 개의 매개 변수를 사용하여 다른 저장 프로 시저를 실행하고 싶다고합시다.

var countryIso = "AR"; //Argentina
var stateIso = "RN"; //Río Negro

var citiesFromRioNegro = context.States.SqlQuery(
                            "dbo.GetCitiesFromState @p0, @p1", countryIso, stateIso
                          );

우리는 매개 변수에 대해 색인 기반 이름 지정을 사용하고 있습니다. 이는 Entity Framework가 SQL 삽입 문제를 피하기 위해 DbParameter 개체로 이러한 매개 변수를 래핑하기 때문입니다.

희망이 예제는 도움이!


엔티티를 저장 프로 시저에 매핑한다는 것을 나타내는 MapToStoredProcedures() 를 사용하고 있습니다. 이렇게하면 저장 프로 시저가 있다는 사실을 놓고 평소와 같이 context 를 사용해야합니다. 이와 비슷한 것 ( 테스트되지 않은 브라우저에 쓰여짐 )

using(MyContext context = new MyContext())
{
    Department department = new Department()
    {
        Name = txtDepartment.text.trim()
    };
    context.Set<Department>().Add(department);
}

정말로하려고하면 저장 프로 시저를 직접 호출 한 다음 SqlQuery 를 사용 SqlQuery


이 나를 위해 매개 변수를 전달하는 동안 저장된 프로 시저에서 데이터를 끌어서 작동합니다.

var param = new SqlParameter("@datetime", combinedTime);
var result = 
        _db.Database.SqlQuery<QAList>("dbo.GetQAListByDateTime @datetime", param).ToList();

_db 는 dbContext입니다.


이것은 EF (DB first)가 DbContext 클래스에서 생성하는 것입니다.

public ObjectResult<int> Insert_Department(string department)
{
    var departmentParameter = new ObjectParameter("department", department);

    return ((IObjectContextAdapter)this).ObjectContext.ExecuteFunction<int>("insert_department", departmentParameter);
}

저장 프로 시저에서 반환 한 결과와 동일한 속성 이름을 가진 개체를 만드는 것뿐입니다. 다음 저장 프로 시저의 경우 :

    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 를 호출 할 수 있습니다.


코드 첫 번째 접근 방식에서 저장 프로 시저 호출이 편리하지 않음을 발견했습니다. 대신 Dapper 를 사용하는 것을 선호합니다.

다음 코드는 Entity Framework 로 작성되었습니다.

var clientIdParameter = new SqlParameter("@ClientId", 4);

var result = context.Database
.SqlQuery<ResultForCampaign>("GetResultsForCampaign @ClientId", clientIdParameter)
.ToList();

다음 코드는 Dapper 로 작성되었습니다.

return Database.Connection.Query<ResultForCampaign>(
            "GetResultsForCampaign ",
            new
            {
                ClientId = 4
            },
            commandType: CommandType.StoredProcedure);

두 번째 코드는 이해하기가 더 쉽다고 생각합니다.


친절한 승객 은 엔티티 프레임 워크를 사용하여 저장된 결과에서 여러 결과 집합을 반환 할 수있는 프로젝트를 보유하고 있습니다. 아래에 그의 예 중 하나가 ....

using (testentities te = new testentities())
{
    //-------------------------------------------------------------
    // Simple stored proc
    //-------------------------------------------------------------
    var parms1 = new testone() { inparm = "abcd" };
    var results1 = te.CallStoredProc<testone>(te.testoneproc, parms1);
    var r1 = results1.ToList<TestOneResultSet>();
}

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)
{
    int resault;
    try
    {
        using (DBContex reposit = new DBContex())
        {
            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

희망이 당신을 도왔다.


public IList<Models.StandardRecipeDetail> GetRequisitionDetailBySearchCriteria(Guid subGroupItemId, Guid groupItemId)
{
    var query = this.UnitOfWork.Context.Database.SqlQuery<Models.StandardRecipeDetail>("SP_GetRequisitionDetailBySearchCriteria @SubGroupItemId,@GroupItemId",
    new System.Data.SqlClient.SqlParameter("@SubGroupItemId", subGroupItemId),
    new System.Data.SqlClient.SqlParameter("@GroupItemId", groupItemId));
    return query.ToList();
}




entity-framework