วิธีการเรียกกระบวนงานที่เก็บไว้ใน Entity Framework 6 (รหัสแรก)?


259

ฉันใหม่มากสำหรับ 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
}

ปัญหาของฉันคือฉันจะเรียกขั้นตอนการจัดเก็บและส่งพารามิเตอร์เข้าไปได้อย่างไร?


ฉันสนใจที่จะรู้เช่นกัน เป็นการดีที่ฉันจะข้าม EF ไปเลยและทำงานทุกอย่างไม่ได้ทำอะไรนอกจากกระบวนการเก็บไว้ ฉันเป็นผู้เชี่ยวชาญเรื่อง SQL แต่พบว่า EF ผิดหวังอย่างมากที่จะนำไปใช้
David Britz

คำตอบ:


247

คุณสามารถเรียกขั้นตอนที่เก็บไว้ในDbContextชั้นเรียนของคุณดังนี้

this.Database.SqlQuery<YourEntityType>("storedProcedureName",params);

แต่ถ้ากระบวนงานที่เก็บไว้ของคุณส่งคืนชุดผลลัพธ์หลายชุดเป็นโค้ดตัวอย่างคุณสามารถดูบทความที่เป็นประโยชน์นี้ใน MSDN

ขั้นตอนการจัดเก็บด้วยชุดผลลัพธ์หลายชุด


2
ขอบคุณ @Alborz คุณช่วยให้ฉันเชื่อมโยงบางอย่างเกี่ยวกับการใช้งานที่หลากหลายของ Stored Procedure ใน Entity Framework 6 Code First ได้ไหม ฉันค้นหาทุกที่บนเว็บ แต่ไม่ได้รับบทความใด ๆ ที่ฉันสามารถเรียกขั้นตอนการจัดเก็บสำหรับพารามิเตอร์เข้าและออกได้โดยตรง ขอบคุณสำหรับเวลาอันมีค่าของคุณ
Jaan

2
บทความนี้อาจเป็นประโยชน์บล็อก.msdn.com/b/diego/archive/2012/01/10/…
Alborz

8
สิ่งนี้ดูเหมือนจะไม่ทำงานกับพารามิเตอร์ ดูเหมือนว่าจะต้องแสดงรายการพารามิเตอร์อย่างชัดเจนว่าเป็นส่วนหนึ่งของแบบสอบถาม
ทำเครื่องหมาย

6
ใช่คุณจะต้องระบุ params เป็นส่วนหนึ่งของการค้นหา "storedProcedureName @param1, @param2"- นอกจากนี้ยังมีประเภทของการเป็นparams System.Data.SqlClient.SqlParameter[]
สไตล์ Oppa Gingham

6
this.Database.SqlQuery<YourEntityType>("storedProcedureName @param1", new System.Data.SqlClient.SqlParameter("@param1", YourParam));
Ppp

152

สิ่งที่คุณต้องทำคือสร้างวัตถุที่มีชื่อคุณสมบัติเดียวกันกับผลลัพธ์ที่ส่งคืนโดยกระบวนงานที่เก็บไว้ สำหรับกระบวนงานที่เก็บไว้ต่อไปนี้:

    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โดยใช้พารามิเตอร์ได้มากเท่าที่ต้องการ


2
สำหรับสถานการณ์ที่ปิดเพียงครั้งเดียวสิ่งนี้จะใช้งานได้ดี ฉันพบว่าคำจำกัดความ SProc ควรคู่กับคลาสที่สืบทอดมาจาก DBContext อย่างแน่นหนาแทนที่จะออกมาใน "ทุ่งข้าวสาลี" ของผลิตภัณฑ์
GoldBishop

50

ฉันแก้ไขมันด้วย 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

หวังว่าจะช่วยคุณ


2
คุณต้องระบุความยาวของพารามิเตอร์ nchar ให้กับกระบวนงานที่เก็บไว้ของคุณมิฉะนั้นจะมีความยาวเพียงหนึ่งตัวอักษรตามที่คุณพบ
Dave W

@ Mahdighafoorian นี่คือคำตอบที่มีประโยชน์มากขอบคุณมาก! :)
Komengem

ไวยากรณ์นี้ไม่ต้องการการแก้ไขคำสั่งของพารามิเตอร์ SProc ในคำอื่น ๆ การจัดตำแหน่งตามลำดับ
GoldBishop

21

ใช้ตัวอย่างของคุณต่อไปนี้เป็นสองวิธีในการทำให้สิ่งนี้สำเร็จ:

1 - ใช้การแมปกระบวนงานที่เก็บไว้

โปรดทราบว่ารหัสนี้จะทำงานโดยมีหรือไม่มีการแมป หากคุณปิดการแมปในเอนทิตี EF จะสร้างคำสั่งแทรก + เลือก

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 จำนวนมาก


3
ระวังเป็นตัวอย่างที่สองที่การเปลี่ยนแปลงไม่ได้ถูกติดตามโดย dbContext
edtruant

แก้ไขใช้ System.Data.Entity.DbSet <TEntity> .SqlQuery (String, Object []) แทน
edtruant

@edtruant dbContext ดูเหมือนจะติดตามการเปลี่ยนแปลง ในการทดสอบฉันดู db. <DbSet> .Count () ก่อนและหลังคำสั่ง insert ในทั้งสองวิธีการนับเพิ่มขึ้นหนึ่ง เพื่อความสมบูรณ์ฉันเพิ่มเมธอดสำรองลงในตัวอย่าง
Brian Vander Plaats

1
ฉันไม่เห็นการอ้างอิงถึงโพรซีเดอร์ที่เก็บไว้ในตัวอย่างแรก
xr280xr

2
@ xr280xr insert_department ถูกอ้างอิงในนิพจน์ modelBuilder ในคำถามของ OP นั่นเป็นข้อได้เปรียบในการทำแผนที่สิ่งต่าง ๆ ในลักษณะนี้เพราะมันทำหน้าที่ได้อย่างมีประสิทธิภาพเช่นเดียวกับถ้าคุณปล่อยให้ EF สร้างคำสั่งแทรก / อัพเดต / ลบ
Brian Vander Plaats

15

คุณกำลังใช้MapToStoredProcedures()ซึ่งบ่งชี้ว่าคุณกำลังแมปเอนทิตีของคุณไปยังขั้นตอนการจัดเก็บเมื่อทำเช่นนี้คุณจะต้องปล่อยให้ไปตามความจริงที่ว่ามีขั้นตอนการจัดเก็บและใช้งานได้contextตามปกติ บางอย่างเช่นนี้ ( เขียนลงในเบราว์เซอร์จึงไม่ได้ทดสอบ )

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

หากสิ่งที่คุณพยายามทำจริงๆคือการเรียกขั้นตอนการจัดเก็บโดยตรงจากนั้นใช้ SqlQuery


2
ขอบคุณ qujck แต่ฉันต้องการใช้กระบวนงานที่เก็บไว้ ฉันได้รับโค้ดตัวอย่างเพื่อความสะดวกในการเข้าใจ
Jaan

4
@Jaan - รหัสด้านบนจะใช้กระบวนการที่เก็บไว้ คุณหมายถึงคุณต้องการเรียกขั้นตอนการจัดเก็บโดยตรงหรือไม่
qujck

ใช่. คุณช่วยบอกฉันได้ไหมว่าวิธีไหนดีกว่ากัน โทรหาขั้นตอนการจัดเก็บโดยตรงหรือรหัสข้างต้นที่คุณได้รับ
Jaan

6
@Jaan ใช้รหัสที่ฉันแสดง - ORM นั้นหมายถึงการซ่อนการใช้งานพื้นฐาน - การใช้รหัสด้านบนทำให้แน่ใจได้ว่ามันไม่สำคัญกับส่วนที่เหลือของรหัสของคุณว่ามีขั้นตอนการจัดเก็บหรือไม่ คุณสามารถเปลี่ยนการแม็พโมเดลเป็นโพรซีเดอร์ที่เก็บอื่นหรือเป็นโพรซีเดอร์ที่เก็บไว้โดยไม่เปลี่ยนแปลงอะไรเลย
qujck

4
@ Chazt3n .MapToStoredProcedures(s => คำถามที่แสดงให้เห็นถึงวิธีการจัดเก็บที่ถูกกำหนดค่าจากบรรทัด โทรไปที่Addควรแก้ไขเพื่อ.Insert(i => i.HasName("insert_department")
qujck

12

ตอนนี้คุณสามารถใช้การประชุมที่ฉันสร้างขึ้นซึ่งเปิดใช้งานการเรียกใช้โพรซีเดอร์ที่เก็บไว้ (รวมถึงโพรซีเดอร์ที่เก็บไว้ที่ส่งคืนชุดผลลัพธ์หลายชุด) TVF และสเกลาร์ UDF โดยกำเนิดจาก EF

จนกว่าเอนทิตี Entity Framework 6.1 จะถูกปล่อยออกมาฟังก์ชั่นการจัดเก็บ (เช่นฟังก์ชั่นการประเมินมูลค่าของตารางและขั้นตอนการจัดเก็บ) สามารถใช้ได้ใน EF เท่านั้นเมื่อทำฐานข้อมูลก่อน มีวิธีแก้ไขปัญหาบางประการที่ทำให้สามารถเรียกใช้ฟังก์ชันการจัดเก็บในแอพ Code First ได้ แต่คุณยังไม่สามารถใช้ TVF ในการค้นหา Linq ซึ่งเป็นข้อ จำกัด ที่ใหญ่ที่สุดข้อหนึ่ง ใน EF 6.1 API การแมปถูกทำให้เป็นสาธารณะซึ่ง (รวมถึงการปรับแต่งเพิ่มเติม) ทำให้สามารถใช้ฟังก์ชั่นร้านค้าในแอพ Code First ของคุณได้

อ่านเพิ่มเติม

ฉันผลักดันอย่างหนักในช่วงสองสัปดาห์ที่ผ่านมาและนี่คือ - รุ่นเบต้าของการประชุมที่ช่วยให้การใช้ฟังก์ชั่นร้านค้า (เช่นขั้นตอนการจัดเก็บฟังก์ชันมูลค่าตาราง ฯลฯ ) ในแอปพลิเคชันที่ใช้วิธีการแรก หรือใหม่กว่า) ฉันมีความสุขมากกว่าด้วยการแก้ไขและคุณสมบัติใหม่ที่รวมอยู่ในรุ่นนี้

อ่านเพิ่มเติม


ที่จริงแล้วตั้งแต่ 4.0 คุณสามารถรัน SProcs โดยไม่มี Model คุณจำเป็นต้องดำเนินการคำสั่ง Raw SQL แทนคุณสมบัติของวัตถุ แม้จะใช้ 6.1.x คุณต้องใช้ SqlQuery <T> หรือ ExecuteSqlCommand เพื่อให้ได้เอฟเฟกต์ที่คล้ายกัน
GoldBishop

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

1
params เป็นตัวระบุใช้ชื่ออื่น
yogihosting

2
ไม่จำเป็นต้องบันทึก SaveChanges () ที่นี่ การเปลี่ยนแปลงเกิดขึ้นที่การเรียก ExecuteSqlCommand ()
Xavier Poinas

10

สิ่งนี้ใช้ได้กับฉันโดยดึงข้อมูลกลับมาจากกระบวนงานที่เก็บไว้ในขณะที่ส่งผ่านพารามิเตอร์

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

_db คือ dbContext


9

ดูลิงค์นี้ที่แสดงวิธีการทำแผนที่ของ EF 6 ด้วยวิธีการจัดเก็บเพื่อทำการแทรกปรับปรุงและลบ: http://msdn.microsoft.com/en-us/data/dn468673

ส่วนที่เพิ่มเข้าไป

นี่เป็นตัวอย่างที่ดีในการเรียกขั้นตอนการจัดเก็บจาก Code First:

สมมติว่าคุณต้องดำเนินการ Stored Procedure ด้วยพารามิเตอร์เดียวและ Stored Procedure ส่งคืนชุดข้อมูลที่ตรงกับ 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
                          );

ขอให้สังเกตว่าเรากำลังใช้การตั้งชื่อตามดัชนีสำหรับพารามิเตอร์ นี่เป็นเพราะเอนทิตีกรอบจะตัดพารามิเตอร์เหล่านี้ขึ้นเป็นวัตถุ DbParameter ไปๆมาๆคุณเพื่อหลีกเลี่ยงปัญหาการฉีด SQL

หวังว่าตัวอย่างนี้จะช่วย!


6
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();
}

4

มันทำงานให้ฉันที่รหัสแรก มันส่งคืนรายการที่มีคุณสมบัติการจับคู่ของรูปแบบมุมมอง (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();

อัปเดตสำหรับบริบท

บริบทเป็นตัวอย่างของคลาสที่รับ DbContext เหมือนด้านล่าง

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

var Context = new  ApplicationDbContext();

สวัสดีฉันไม่พบ Context.Database.SqlQuery <Model> นี้ซึ่งฉันสามารถใช้ Context.TableName.SqlQuery (ProcName) ได้ ซึ่งทำให้ฉันมีปัญหา
มาร์แชลล์

@Marshall, บางทีคุณกำลังใช้การออกแบบฐานข้อมูลเป็นครั้งแรก โปรดตรวจสอบลิงค์นี้stackoverflow.com/questions/11792018/…
reza.cse08

1

ผู้โดยสารที่ไม่มีเหตุผล มีโครงการที่อนุญาตให้ส่งคืนผลลัพธ์จำนวนมากจาก proc ที่จัดเก็บโดยใช้เฟรมเวิร์กเอนทิตี หนึ่งในตัวอย่างของเขาด้านล่าง ....

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

1

คุณสามารถส่งพารามิเตอร์ไปที่sp_GetByIdและดึงผลลัพธ์ทั้งในToList()หรือFirstOrDefault();

var param  = new SqlParameter("@id", 106);
var result = dbContext
               .Database
               .SqlQuery<Category>("dbo.sp_GetById @id", param)
               .FirstOrDefault();

0

หากคุณต้องการส่งผ่าน params ตารางลงในกระบวนงานที่เก็บไว้คุณต้องตั้งค่าคุณสมบัติ TypeName สำหรับ params ตารางของคุณ

SqlParameter codesParam = new SqlParameter(CODES_PARAM, SqlDbType.Structured);
            SqlParameter factoriesParam = new SqlParameter(FACTORIES_PARAM, SqlDbType.Structured);

            codesParam.Value = tbCodes;
            codesParam.TypeName = "[dbo].[MES_CodesType]";
            factoriesParam.Value = tbfactories;
            factoriesParam.TypeName = "[dbo].[MES_FactoriesType]";


            var list = _context.Database.SqlQuery<MESGoodsRemain>($"{SP_NAME} {CODES_PARAM}, {FACTORIES_PARAM}"
                , new SqlParameter[] {
                   codesParam,
                   factoriesParam
                }
                ).ToList();

0

นี่คือสิ่งที่ EF (DB แรก) สร้างในคลาส DbContext:

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

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

0

เมื่อ 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.

0

ฉันพบว่าการโทรของขั้นตอนการจัดเก็บในแนวทางแรกไม่สะดวก ฉันชอบที่จะใช้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);

ฉันเชื่อว่าโค้ดที่สองนั้นง่ายต่อการเข้าใจ


0
public static string ToSqlParamsString(this IDictionary<string, string> dict)
        {
            string result = string.Empty;
            foreach (var kvp in dict)
            {
                result += $"@{kvp.Key}='{kvp.Value}',";
            }
            return result.Trim(',', ' ');
        }

public static List<T> RunSproc<T>(string sprocName, IDictionary<string, string> parameters)
        {
            string command = $"exec {sprocName} {parameters.ToSqlParamsString()}";
            return Context.Database.SqlQuery<T>(command).ToList();
        }

0

ไม่มีอะไรต้องทำ ... เมื่อคุณสร้าง dbcontext สำหรับโค้ดวิธีแรกเริ่มต้น namespace ด้านล่างพื้นที่ API ได้อย่างคล่องแคล่วทำรายการของ sp และใช้ที่อื่นที่คุณต้องการ

public partial class JobScheduleSmsEntities : DbContext
{
    public JobScheduleSmsEntities()
        : base("name=JobScheduleSmsEntities")
    {
        Database.SetInitializer<JobScheduleSmsEntities>(new CreateDatabaseIfNotExists<JobScheduleSmsEntities>());
    }

    public virtual DbSet<Customer> Customers { get; set; }
    public virtual DbSet<ReachargeDetail> ReachargeDetails { get; set; }
    public virtual DbSet<RoleMaster> RoleMasters { get; set; }

    protected override void OnModelCreating(DbModelBuilder modelBuilder)
    {
        //modelBuilder.Types().Configure(t => t.MapToStoredProcedures());

        //modelBuilder.Entity<RoleMaster>()
        //     .HasMany(e => e.Customers)
        //     .WithRequired(e => e.RoleMaster)
        //     .HasForeignKey(e => e.RoleID)
        //     .WillCascadeOnDelete(false);
    }
    public virtual List<Sp_CustomerDetails02> Sp_CustomerDetails()
    {
        //return ((IObjectContextAdapter)this).ObjectContext.ExecuteFunction<Sp_CustomerDetails02>("Sp_CustomerDetails");
        //  this.Database.SqlQuery<Sp_CustomerDetails02>("Sp_CustomerDetails");
        using (JobScheduleSmsEntities db = new JobScheduleSmsEntities())
        {
           return db.Database.SqlQuery<Sp_CustomerDetails02>("Sp_CustomerDetails").ToList();

        }

    }

}

}

public partial class Sp_CustomerDetails02
{
    public long? ID { get; set; }
    public string Name { get; set; }
    public string CustomerID { get; set; }
    public long? CustID { get; set; }
    public long? Customer_ID { get; set; }
    public decimal? Amount { get; set; }
    public DateTime? StartDate { get; set; }
    public DateTime? EndDate { get; set; }
    public int? CountDay { get; set; }
    public int? EndDateCountDay { get; set; }
    public DateTime? RenewDate { get; set; }
    public bool? IsSMS { get; set; }
    public bool? IsActive { get; set; }
    public string Contact { get; set; }
}

0

การใช้ MySql และรหัสเฟรมเวิร์ก Entity ก่อนวิธีการ:

public class Vw_EMIcount
{
    public int EmiCount { get; set; }
    public string Satus { get; set; }
}

var result = context.Database.SqlQuery<Vw_EMIcount>("call EMIStatus('2018-3-01' ,'2019-05-30')").ToList();

0

สร้างขั้นตอนใน MYsql

delimiter //
create procedure SP_Dasboarddata(fromdate date, todate date)
begin
select count(Id) as count,date,status,sum(amount) as amount from 
details
where (Emidate between fromdate and todate)
group by date ,status;
END;
//

สร้างคลาสที่มีกระบวนงานที่เก็บไว้ส่งคืนค่าชุดผลลัพธ์

[Table("SP_reslutclass")]
public  class SP_reslutclass
{
    [Key]
    public int emicount { get; set; }
    public DateTime Emidate { get; set; }
    public int ? Emistatus { get; set; }
    public int emiamount { get; set; }

}

เพิ่มคลาสใน Dbcontext

  public  class ABCDbContext:DbContext
{
    public ABCDbContext(DbContextOptions<ABCDbContext> options)
       : base(options)
    {

    }

 public DbSet<SP_reslutclass> SP_reslutclass { get; set; }
}

โทรเอนทิตีในพื้นที่เก็บข้อมูล

   var counts = _Dbcontext.SP_reslutclass.FromSql("call SP_Dasboarddata 
                    ('2019-12-03','2019-12-31')").ToList();
โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.