ในฐานะคนที่ไม่ได้ใช้เทคโนโลยีอย่างใดอย่างหนึ่งในโครงการในโลกแห่งความเป็นจริงฉันสงสัยว่ามีใครรู้บ้างว่าทั้งสองนี้เสริมกันอย่างไรและฟังก์ชันการทำงานของพวกเขาทับซ้อนกันมากแค่ไหน?
ในฐานะคนที่ไม่ได้ใช้เทคโนโลยีอย่างใดอย่างหนึ่งในโครงการในโลกแห่งความเป็นจริงฉันสงสัยว่ามีใครรู้บ้างว่าทั้งสองนี้เสริมกันอย่างไรและฟังก์ชันการทำงานของพวกเขาทับซ้อนกันมากแค่ไหน?
คำตอบ:
LINQ เป็น SQL บังคับให้คุณใช้รูปแบบตารางต่อคลาส ประโยชน์ของการใช้รูปแบบนี้คือใช้งานได้ง่ายและรวดเร็วและใช้ความพยายามเพียงเล็กน้อยในการทำให้โดเมนของคุณทำงานตามโครงสร้างฐานข้อมูลที่มีอยู่ สำหรับแอปพลิเคชันที่เรียบง่ายนี่เป็นสิ่งที่ยอมรับได้อย่างสมบูรณ์แบบ (และมักจะดีกว่า) แต่สำหรับแอปพลิเคชันที่ซับซ้อนมากขึ้น devs มักจะแนะนำให้ใช้การออกแบบที่ขับเคลื่อนด้วยโดเมนรูปแบบแทน (ซึ่งเป็นสิ่งที่ NHibernate อำนวยความสะดวก)
ปัญหาเกี่ยวกับรูปแบบตารางต่อคลาสคือโครงสร้างฐานข้อมูลของคุณมีอิทธิพลโดยตรงต่อการออกแบบโดเมนของคุณ ตัวอย่างเช่นสมมติว่าคุณมีตารางลูกค้าที่มีคอลัมน์ต่อไปนี้เพื่อเก็บข้อมูลที่อยู่หลักของลูกค้า:
สมมติว่าคุณต้องการเพิ่มคอลัมน์สำหรับที่อยู่ทางไปรษณีย์ของลูกค้าด้วยดังนั้นคุณจึงเพิ่มคอลัมน์ต่อไปนี้ในตารางลูกค้า:
เมื่อใช้ LINQ กับ SQL อ็อบเจ็กต์ Customer ในโดเมนของคุณจะมีคุณสมบัติสำหรับแต่ละคอลัมน์ทั้งแปดนี้ แต่ถ้าคุณทำตามรูปแบบการออกแบบที่ขับเคลื่อนด้วยโดเมนคุณอาจได้สร้างคลาสที่อยู่และให้คลาสลูกค้าของคุณมีคุณสมบัติที่อยู่สองคุณสมบัติหนึ่งสำหรับที่อยู่ทางไปรษณีย์และอีกหนึ่งรายการสำหรับที่อยู่ปัจจุบัน
นั่นเป็นตัวอย่างง่ายๆ แต่แสดงให้เห็นว่ารูปแบบตารางต่อคลาสสามารถนำไปสู่โดเมนที่ค่อนข้างเหม็นได้อย่างไร ในที่สุดก็ขึ้นอยู่กับคุณ อีกครั้งสำหรับแอปง่ายๆที่ต้องการฟังก์ชัน CRUD พื้นฐาน (สร้างอ่านอัปเดตลบ) LINQ เป็น SQL นั้นเหมาะอย่างยิ่งเนื่องจากความเรียบง่าย แต่โดยส่วนตัวแล้วฉันชอบใช้ NHibernate เพราะมันช่วยให้โดเมนสะอาดขึ้น
แก้ไข: @lomaxx - ใช่ตัวอย่างที่ฉันใช้นั้นเรียบง่ายและอาจได้รับการปรับให้ทำงานได้ดีกับ LINQ เป็น SQL ฉันต้องการให้มันเป็นพื้นฐานที่สุดเท่าที่จะทำได้เพื่อขับรถกลับบ้าน ประเด็นยังคงอยู่แม้ว่าจะมีหลายสถานการณ์ที่โครงสร้างฐานข้อมูลของคุณกำหนดโครงสร้างโดเมนของคุณอาจเป็นความคิดที่ไม่ดีหรืออย่างน้อยก็นำไปสู่การออกแบบ OO ที่ไม่เหมาะสม
สองจุดที่พลาดไป:
LINQ เป็น SQL ไม่ทำงานกับ Oracle หรือฐานข้อมูลใด ๆ นอกเหนือจาก SqlServer อย่างไรก็ตามบุคคลที่ 3 จะให้การสนับสนุนที่ดีสำหรับ Oracle เช่นdevart ของ dotConnect , DbLinq , Mindscape ของ LightSpeedและALinq (ฉันไม่มีประสบการณ์ส่วนตัวเกี่ยวกับสิ่งเหล่านี้)
Linq ถึง NHibernateช่วยให้คุณใช้ Linq กับ Nhiberate ได้ดังนั้นจึงอาจลบเหตุผลที่จะไม่ใช้ออกไป
นอกจากนี้อินเทอร์เฟซใหม่ที่ใช้งานง่ายของ Nhibernateดูเหมือนว่าจะทำให้การกำหนดค่าการทำแผนที่ของ Nhibernate เจ็บปวดน้อยลง (ลบจุดเจ็บปวดของ Nhibernate ออกหนึ่งจุด)
ปรับปรุง
Linq ถึง Nhiberate ดีกว่าใน Nhiberate v3 ที่ตอนนี้อยู่ในอัลฟ่าอัลฟาดูเหมือนว่า Nhiberate v3 อาจจัดส่งในช่วงปลายปีนี้
Entity กรอบการทำงานเป็นของสุทธิ 4 ยังเริ่มที่จะมีลักษณะเหมือนตัวจริง
@ เควิน: ฉันคิดว่าปัญหาของตัวอย่างที่คุณนำเสนอคือคุณใช้การออกแบบฐานข้อมูลที่ไม่ดี ฉันคิดว่าคุณจะสร้างตารางลูกค้าและตารางที่อยู่และทำให้ตารางเป็นปกติ หากคุณทำเช่นนั้นคุณสามารถใช้ Linq To SQL สำหรับสถานการณ์ที่คุณกำลังแนะนำได้ Scott Guthrie มีบทความมากมายเกี่ยวกับการใช้ Linq To SQLซึ่งฉันขอแนะนำให้คุณลองดู
ฉันไม่คิดว่าคุณสามารถพูดว่า Linq และ NHibernate เสริมซึ่งกันและกันได้เนื่องจากหมายความว่าสามารถใช้ร่วมกันได้และในขณะนี้เป็นไปได้คุณจะเลือกอย่างใดอย่างหนึ่งและยึดติดกับมันได้ดีกว่ามาก
NHibernate ช่วยให้คุณสามารถแมปตารางฐานข้อมูลกับอ็อบเจ็กต์โดเมนของคุณได้ด้วยวิธีที่ยืดหยุ่นสูง นอกจากนี้ยังอนุญาตให้คุณใช้ HBL เพื่อสืบค้นฐานข้อมูล
Linq เป็น SQL ยังช่วยให้คุณสามารถแมปวัตถุโดเมนของคุณกับฐานข้อมูลได้ แต่จะใช้ไวยากรณ์แบบสอบถาม Linq เพื่อสืบค้นฐานข้อมูล
ข้อแตกต่างหลักที่นี่คือไวยากรณ์แบบสอบถาม Linq ถูกตรวจสอบในเวลาคอมไพล์โดยคอมไพเลอร์เพื่อให้แน่ใจว่าการสืบค้นของคุณถูกต้อง
สิ่งที่ต้องระวังสำหรับ linq คือมันมีให้ใช้งานใน. net 3.x เท่านั้นและรองรับเฉพาะใน VS2008 เท่านั้น NHibernate มีให้ใน 2.0 และ 3.x เช่นเดียวกับ VS2005
สิ่งที่ต้องระวังในการใช้ NHibernate ก็คือมันไม่ได้สร้างอ็อบเจ็กต์โดเมนของคุณและไม่สร้างไฟล์การแมป คุณต้องดำเนินการนี้ด้วยตนเอง Linq สามารถ
ทำสิ่งนี้ให้คุณโดยอัตโนมัติ
NHibernate ที่คล่องแคล่วสามารถสร้างไฟล์การแมปของคุณตามหลักการง่ายๆ ไม่มีการเขียน XML และพิมพ์ผิด
ฉันเพิ่งทำงานในโครงการซึ่งเราจำเป็นต้องเปลี่ยนจาก Linq เป็น SQL เป็น NHibernate ด้วยเหตุผลด้านประสิทธิภาพ โดยเฉพาะอย่างยิ่งวิธีของ L2S ในการทำให้วัตถุเป็นจริงดูเหมือนช้ากว่า ditto ของ NHibernate และการจัดการการเปลี่ยนแปลงก็ค่อนข้างช้าเช่นกัน และอาจเป็นเรื่องยากที่จะปิดการจัดการการเปลี่ยนแปลงสำหรับสถานการณ์เฉพาะที่ไม่จำเป็น
หากคุณกำลังจะใช้เอนทิตีของคุณที่ตัดการเชื่อมต่อจาก DataContext - ในสถานการณ์ WCF เช่นคุณอาจมีปัญหามากมายในการเชื่อมต่อกับ DataContext อีกครั้งเพื่ออัปเดตการเปลี่ยนแปลง ฉันไม่มีปัญหากับ NHibernate
สิ่งที่ฉันจะพลาดจาก L2S ส่วนใหญ่คือการสร้างรหัสที่ช่วยให้ความสัมพันธ์เป็นปัจจุบันอยู่เสมอทั้งสองด้านของเอนทิตี แต่ฉันเดาว่ามีเครื่องมือบางอย่างสำหรับ NHibernate ที่จะทำเช่นนั้นด้วย ...
.ObjectTrackingEnabled = false
คุณDataContext
จะช่วยแก้ปัญหาการติดตามการเปลี่ยนแปลงของคุณได้ ตราบใดที่คุณซื้อเป็นรูปแบบหน่วยการทำงานและไม่ต้องการทำ DDD Linq-to-SQL ก็มอบให้
คุณช่วยอธิบายความหมายของ "LINQ" ได้หรือไม่?
LINQ ไม่ใช่เทคโนโลยีการเข้าถึงข้อมูล แต่เป็นเพียงคุณลักษณะภาษาที่รองรับการสืบค้นเป็นโครงสร้างดั้งเดิม สามารถค้นหาโมเดลวัตถุใด ๆ ที่รองรับอินเทอร์เฟซเฉพาะ (เช่น IQueryable)
หลายคนอ้างถึง LINQ To SQL ว่า LINQ แต่นั่นไม่ถูกต้องเลย Microsoft เพิ่งเปิดตัว LINQ To Entities ด้วย. NET 3.5 SP1 นอกจากนี้ NHibernate ยังมีอินเทอร์เฟซ LINQ ดังนั้นคุณสามารถใช้ LINQ และ NHibernate เพื่อรับข้อมูลของคุณ
โดย LINQ ฉันสมมติว่าคุณหมายถึง LINQ เป็น SQL เนื่องจาก LINQ โดยตัวมันเองไม่มีฐานข้อมูล "goings on" ที่เกี่ยวข้อง เป็นเพียงภาษาแบบสอบถามที่มี syntac sugar เป็นส่วนประกอบเพื่อให้มีลักษณะเป็น SQL-ish
ในตัวอย่างพื้นฐานทั่วไป NHibernate และ LINQ ถึง SQL ดูเหมือนว่าทั้งคู่กำลังแก้ปัญหาเดียวกัน เมื่อคุณผ่านพ้นไปคุณจะรู้ทันทีว่า NHibernate รองรับคุณสมบัติมากมายที่ช่วยให้คุณสร้างโมเดลโดเมนที่สมบูรณ์ได้อย่างแท้จริง นอกจากนี้ยังมีโครงการ LINQ ถึง NHibernate ที่ให้คุณใช้ LINQ เพื่อค้นหา NHibernate ในลักษณะเดียวกับที่คุณใช้ LINQ กับ SQL
ก่อนอื่นให้แยกสองสิ่งที่แตกต่างกัน: การสร้างแบบจำลองฐานข้อมูลเกี่ยวข้องกับข้อมูลในขณะที่การสร้างแบบจำลองวัตถุเกี่ยวข้องกับเอนทิตีและความสัมพันธ์
ข้อดีของ Linq-to-SQL คือการสร้างคลาสจากสคีมาฐานข้อมูลอย่างรวดเร็วเพื่อให้สามารถใช้เป็นอ็อบเจ็กต์เรกคอร์ดที่ใช้งานอยู่ (ดูนิยามรูปแบบการออกแบบเรกคอร์ดที่ใช้งานอยู่)
ข้อดีของ NHibernate คือให้ความยืดหยุ่นระหว่างการสร้างแบบจำลองวัตถุและการสร้างแบบจำลองฐานข้อมูล ฐานข้อมูลสามารถสร้างแบบจำลองเพื่อสะท้อนข้อมูลของคุณได้ดีที่สุดโดยคำนึงถึงประสิทธิภาพเช่น แม้ว่าการสร้างแบบจำลองออบเจ็กต์ของคุณจะสะท้อนให้เห็นถึงองค์ประกอบของกฎธุรกิจได้ดีที่สุดโดยใช้แนวทางเช่นการออกแบบโดเมนที่ขับเคลื่อนด้วย (ดูความคิดเห็นของ Kevin Pang)
ด้วยฐานข้อมูลเดิมที่มีการสร้างแบบจำลองและ / หรือรูปแบบการตั้งชื่อที่ไม่ดี Linq-to-SQL จะสะท้อนโครงสร้างและชื่อที่ไม่ต้องการนี้ไปยังคลาสของคุณ อย่างไรก็ตาม NHibernate สามารถซ่อนความยุ่งเหยิงนี้ได้ด้วยตัวทำแผนที่ข้อมูล
ในโครงการกรีนฟิลด์ที่ฐานข้อมูลมีการตั้งชื่อที่ดีและมีความซับซ้อนต่ำ Linq-to-SQL อาจเป็นทางเลือกที่ดี
อย่างไรก็ตามคุณสามารถใช้Fluent NHibernate กับการจับคู่อัตโนมัติได้เพื่อจุดประสงค์เดียวกันนี้ด้วยการทำแผนที่ตามแบบแผน ในกรณีนี้คุณไม่ต้องกังวลกับตัวแมปข้อมูลใด ๆ ที่มี XML หรือ C # และปล่อยให้ NHibernate สร้างสคีมาฐานข้อมูลจากเอนทิตีของคุณตามแบบแผนที่คุณกำหนดเองได้
ในทางกลับกันเส้นโค้งการเรียนรู้ของ Linq-to-SQL นั้นเล็กกว่า NHibernate
หรือคุณสามารถใช้โครงการ Castle ActiveRecords ฉันใช้มันเป็นเวลาสั้น ๆ เพื่อเพิ่มโค้ดใหม่สำหรับโครงการเดิม ใช้ NHibernate และทำงานกับรูปแบบการบันทึกที่ใช้งานอยู่ (น่าแปลกใจที่ฉันรู้จักชื่อนี้) ฉันยังไม่ได้ลองใช้ แต่ฉันคิดว่าเมื่อคุณใช้มันแล้วหากคุณรู้สึกว่าจำเป็นต้องเปลี่ยนไปใช้การสนับสนุนของ NHibernate โดยตรงก็จะไม่มากเกินไปที่จะทำเช่นนั้นสำหรับบางส่วนหรือทั้งหมดของโครงการของคุณ
ตามที่คุณเขียนไว้ "สำหรับผู้ที่ไม่ได้ใช้อย่างใดอย่างหนึ่ง" LINQ to SQL นั้นใช้งานง่ายเพื่อให้ทุกคนสามารถใช้งานได้อย่างง่ายดายนอกจากนี้ยังสนับสนุนขั้นตอนซึ่งช่วยได้เกือบตลอดเวลา สมมติว่าคุณต้องการรับข้อมูลจากตารางมากกว่าหนึ่งตารางจากนั้นเขียนโพรซีเดอร์และลากโพรซีเดอร์นั้นไปยังผู้ออกแบบและมันจะสร้างทุกอย่างให้คุณสมมติว่าชื่อโพรซีเดอร์ของคุณคือ "CUSTOMER_ORDER_LINEITEM" ซึ่งดึงข้อมูลจากตารางทั้งสามนี้จากนั้นจึงเขียน
MyDataContext db = new MyDataContext();
List<CUSTOMER_ORDER_LINEITEMResult> records = db.CUSTOMER_ORDER_LINEITEM(pram1, param2 ...).ToList<CUSTOMER_ORDER_LINEITEMResult>();
คุณสามารถใช้คุณบันทึกวัตถุใน foreach loop ได้เช่นกันซึ่ง NHibernate ไม่รองรับ