NHibernate - แนวปฏิบัติที่ดีที่สุดสำหรับเพียงเลือก

A มีการดำเนินการกับแอปพลิเคชัน MVC ของฉันที่มี id และส่งคืนชื่อของบุคคล

แนวทางปฏิบัติที่ดีที่สุดสำหรับสิ่งนั้นคืออะไร? ฉันกำลังทำตามคำแนะนำของ NHProf แต่โค้ดฟังดูแปลกนิดหน่อยหรืออะไรบางอย่างสำหรับฉัน

using (var session = Helper.SessionFactory.OpenStatelessSession())
{
    using (var tran = session.BeginTransaction(IsolationLevel.ReadCommitted))
    {
        return session.Query<Person>().Where(x => x.Id == id).Select(x => x.Name).SingleOrDefault();
        tran.Rollback();
    }
}

person Zote    schedule 10.05.2012    source แหล่งที่มา
comment
ฉันไม่เข้าใจว่าทำไมจึงแนะนำธุรกรรม...   -  person Felice Pollano    schedule 10.05.2012
comment
ฉันจะไม่ใช้ OpenStatelessSessionthe stateless session สำหรับสถานการณ์จำนวนมากและละเว้นแคช L1 แทนที่จะทำการสืบค้น linq ฉันเพียงแค่เรียก .Load<Person>(1) หรือ .Get<Person>(1) ซึ่งแสดงถึงความตั้งใจมากกว่าการสืบค้น linq   -  person Andreas    schedule 10.05.2012


คำตอบ (3)


หน้าการแจ้งเตือนของ NHProf อธิบายได้ค่อนข้างดี ฉันคิดว่า -

http://nhprof.com/Learn/Alerts/DoNotUseImplicitTransactions

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

ในตัวอย่างของคุณข้างต้น ปัญหาไม่ได้เป็นปัญหามากนัก เนื่องจากธุรกรรมของคุณจะดำเนินการในใบแจ้งยอดเพียงรายการเดียวเท่านั้น หากวิธีการของคุณใช้คำสั่งหลายรายการ อย่างไรก็ตาม แนวทางปฏิบัติที่ดีในการรวมคำสั่งเหล่านั้นไว้ในธุรกรรม

person richeym    schedule 10.05.2012
comment
ตกลง แต่สำหรับวิธีง่ายๆ ฉันควรติดตาม NHProf และสร้างธุรกรรมหรือไม่ - person Zote; 10.05.2012
comment
คำตอบนั้นเป็นจริงเพียงบางส่วนเท่านั้น คุณควร เสมอ บิดเบือนการสืบค้นฐานข้อมูลของคุณในธุรกรรม และแน่นอนว่ามันจะเป็นปัญหาแม้ว่าคุณจะดำเนินการคำสั่งเดียวก็ตาม การทำธุรกรรมโดยนัยมีราคาแพง! และ NH จะไม่ใช้แคช L2 โดยไม่มีธุรกรรม - person Andreas; 10.05.2012

ต่อไปนี้เป็นวิธีที่ฉันจะเข้าใกล้การเลือกนี้:

    using (var session = Helper.SessionFactory.OpenStatelessSession())
    using (var tran = session.BeginTransaction(IsolationLevel.ReadCommitted))
    {
        try
        {
            string personName = session.Query<Person>()
            .Where(x => x.Id == id)
            .Single(x => x.Name);

            tran.Commit();
            return personName;
        }
        catch(Exception ex)
        {
            // handle exception
            tran.Rollback();
        }
    }

คำตอบ SO นี้ให้คำแนะนำที่ดีในการจัดการกับการทำธุรกรรม:

NHibernate - ITransaction.Commit จำเป็นจริงๆ หรือไม่

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

http://compiledexperience.com/blog/posts/how-not-to-use-linq

person Peadar Doyle    schedule 10.05.2012
comment
-1 สำหรับการจับทุกอย่าง ทำงานซ้ำซ้อน (ใช้และลองจับ) - person Andreas; 10.05.2012
comment
@Andreas เท่าที่ฉันทราบการใช้ไม่มีวิธีในการประมวลผลข้อยกเว้นที่ส่งออกมาและทางเลือกคือใช้การลองซ้ำซ้อนหรือการกำจัดด้วยตนเอง คุณจะใช้การจัดการข้อผิดพลาดในกรณีนี้อย่างไรเนื่องจากมีหลายเลเยอร์ที่อาจทำให้เกิดข้อผิดพลาด (NHibernate, ADO.NET, LINQ) - person Peadar Doyle; 11.05.2012
comment
stackoverflow.com/questions/6418992/ และสำหรับข้อยกเว้น stackoverflow.com/ คำถาม/426346/ stackoverflow. com/questions/114658/ blogs.msdn.com/b/ericlippert/archive/2008/09/10/ และอย่าบอกฉันว่าคุณสามารถจัดการ stackoverflows ได้อย่างถูกต้อง หน่วยความจำไม่เพียงพอ exc ด้วย tran.Rollback(); ของคุณ - person Andreas; 11.05.2012
comment
ขอบคุณสำหรับลิงก์ ฉันไม่ทราบว่าธุรกรรมถูกย้อนกลับโดยปริยาย นอกจากนี้ ฉันควรจะใส่ //handle ข้อยกเว้นไว้หลัง Rollback() เนื่องจากฉันตั้งใจให้เป็นตัวยึดตำแหน่งสำหรับการจัดการข้อผิดพลาด ฉันขอขอบคุณสิ่งที่คุณพูดเกี่ยวกับการจัดการข้อยกเว้นทั้งหมด และอาจไม่ใช่สิ่งที่ดีที่สุดที่จะทำที่นี่ - person Peadar Doyle; 11.05.2012

อย่าสร้างหลายเซสชันในคำขอ HTTP เดียว โดยหลักการแล้วสิ่งที่คุณต้องทำคือเปิดเซสชันและธุรกรรมที่เกี่ยวข้องในขอบเขตคำขอ และใช้เซสชันนี้ตลอดการดำเนินการทั้งหมดของคุณ

นี่คือบล็อกโพสต์ที่อธิบายวิธีการบรรลุเป้าหมาย: http://hackingon.net/post/NHibernate-Session-Per-Request-with-ASPNET-MVC.aspx

ฉันขอแนะนำให้ใช้คอนเทนเนอร์ IOC และสร้างคลาสที่สร้างเซสชันให้กับคุณและกำหนดขอบเขตคลาสนี้ตามขอบเขตคำขอ

มีแหล่งข้อมูลมากมายบนเว็บเพื่อแก้ไขปัญหานี้ .. Google มัน ..

person Baz1nga    schedule 10.05.2012
comment
แม้ว่าหนึ่งเซสชันต่อคำขอจะเป็นคำแนะนำที่ดี แต่ก็ไม่ใช่กฎที่ยากและรวดเร็ว และการมีหนึ่งธุรกรรมต่อคำขอถือเป็นคำแนะนำที่ไม่ดี ธรรมดาและเรียบง่าย - person Spivonious; 22.07.2016