วิธีที่ดีที่สุดในการค้นหาข้อมูลจาก MS SQL Server ใน C #?


9

วิธีที่ดีที่สุดในการสืบค้นข้อมูลจาก MS SQL Server ใน C # คืออะไร

ฉันรู้ว่ามันไม่ใช่วิธีปฏิบัติที่ดีที่จะมีคิวรี่ SQL ในโค้ด

เป็นวิธีที่ดีที่สุดในการสร้างขั้นตอนการจัดเก็บและเรียกมันจาก C # ด้วยพารามิเตอร์หรือไม่

using (var conn = new SqlConnection(connStr))
using (var command = new SqlCommand("StoredProc", conn) { CommandType = CommandType.StoredProcedure }) {
   conn.Open();
   command.ExecuteNonQuery();
   conn.Close();
}

8
"ฉันรู้ว่าไม่ใช่วิธีปฏิบัติที่ดีที่จะมีคิวรี SQL ในโค้ด" - imo นั่นเป็นเรื่องไร้สาระ
GrandmasterB

4
คุณไม่จำเป็นต้องโทรหา conn.Close () ถ้าคุณสร้างมันในบล็อกที่ใช้ จุดรวมของการใช้บล็อกคือการเลียนแบบสไตล์ C ++ ของ destructor ล้างข้อมูล ทำความสะอาดอย่างสง่างามตั้งแต่ยุคที่มีอารยธรรมมากขึ้น ไม่สุ่มหรือเงอะงะตามสไตล์ลองจับ
ลอร์ด Tydus

2
FYI ขั้นตอนการจัดเก็บเป็น "รหัส" จุดรวมของ procs ที่เก็บไว้คือการอนุญาตให้ผสมรหัสขั้นตอนกับ SQL ตามสไตล์การตั้งค่า ดังนั้นคุณจะมีแบบสอบถามในรหัสโดยไม่คำนึงถึง สำหรับแอพที่มีปริมาณสูงมากบางครั้งการใช้ลอจิกนอกฐานข้อมูลเพื่อให้สามารถปรับขนาดแนวนอนได้โดยการเพิ่มเซิร์ฟเวอร์ หากคุณสามารถรักษาฐานข้อมูลเดียว แต่ muli-server สำหรับตรรกะแล้วการปรับขนาดจะกลายเป็นเรื่องง่ายมาก
ลอร์ด Tydus

@GrandmasterB เรามี SQL inline จำนวนมากใน C # (C # LOC ของเราใกล้ 2 ล้านแล้ว) และ 6 ปีต่อมามันกลับมากัดเราเพราะตอนนี้เราต้องตามล่า SQL แบบอินไลน์ (เราเพิ่งว่าจ้างผู้เชี่ยวชาญ SQL - ดังนั้นเรากำลังปรับแต่งการแสดง) เชื่อใจฉัน: คุณไม่มีทางรู้ว่าแอปของคุณจะใหญ่แค่ไหนและสิ่งต่าง ๆ จะเปลี่ยนไปในอนาคต เก็บภาษาต่าง ๆ ไว้ในไฟล์ที่แตกต่างกัน - แม้ว่าคุณเพิ่งจะมอบหมายให้กับรายการทรัพยากร คุณสามารถทำได้// SQLCODE- แต่คุณต้องจำไว้ว่าต้องทำเช่นนั้น
Jonathan Dickinson

1
@ JonathanDickinson ใช้ procs ที่เก็บไว้หากคุณต้องการ ฉันได้กล่าวว่าหลายครั้งมีประโยชน์เมื่อคุณมีรหัสฐานที่แตกต่างกันในการทำงานกับฐานข้อมูลเดียวกัน แต่เพียงเพราะพวกเขามีประโยชน์ในบางสถานการณ์ไม่ได้โดยอัตโนมัติทำให้ไม่ได้ใช้พวกเขา 'ปฏิบัติไม่ดี' ตลอดเวลา หากการใช้คำสั่ง SQL โดยตรงไม่ทำให้เกิดปัญหาแสดงว่าไม่ใช่ 'การปฏิบัติที่ไม่เหมาะสม' สำหรับแอปนั้น
GrandmasterB

คำตอบ:


10

การใช้โพรซีเดอร์ที่จัดเก็บเป็นวิธีหนึ่งและใช้กันอย่างแพร่หลายมานานหลายปี

วิธีที่ทันสมัยกว่าในการโต้ตอบกับฐานข้อมูล SQL Server จาก C # (หรือภาษา. NET ใด ๆ ) คือการใช้ Entity Framework ข้อดีของ Entity Framework ก็คือมันให้ระดับที่สูงกว่าของนามธรรม

อ้างจาก Microsoft ( https://msdn.microsoft.com/en-us/data/jj590134 ):

ADO.NET Entity Framework ช่วยให้นักพัฒนาสามารถสร้างแอปพลิเคชันการเข้าถึงข้อมูลโดยการเขียนโปรแกรมกับโมเดลแอปพลิเคชันเชิงแนวคิดแทนการเขียนโปรแกรมโดยตรงกับสคีมาหน่วยเก็บข้อมูลเชิงสัมพันธ์ เป้าหมายคือการลดจำนวนรหัสและการบำรุงรักษาที่จำเป็นสำหรับแอปพลิเคชันที่เน้นข้อมูล แอปพลิเคชัน Entity Framework ให้ประโยชน์ดังต่อไปนี้:

  • แอปพลิเคชันสามารถทำงานในรูปแบบของแนวคิดรวบยอดแอปพลิเคชันเป็นศูนย์กลางมากขึ้นรวมถึงประเภทที่มีการสืบทอดสมาชิกที่ซับซ้อนและความสัมพันธ์
  • แอปพลิเคชันนั้นเป็นอิสระจากการพึ่งพาฮาร์ดโค้ดในเอ็นจินข้อมูลหรือสกีมาหน่วยเก็บข้อมูลเฉพาะ
  • การแม็พระหว่างโมเดลแนวคิดและสกีมาเฉพาะหน่วยเก็บข้อมูลสามารถเปลี่ยนแปลงได้โดยไม่ต้องเปลี่ยนโค้ดแอ็พพลิเคชัน
  • นักพัฒนาสามารถทำงานกับโมเดลวัตถุของแอปพลิเคชันที่สอดคล้องกันซึ่งสามารถแมปเข้ากับสคีมาหน่วยเก็บข้อมูลต่างๆซึ่งอาจนำไปใช้ในระบบการจัดการฐานข้อมูลที่แตกต่างกัน
  • โมเดลโมเดลเชิงแนวคิดหลายโมเดลสามารถแม็พกับสกีมาหน่วยเก็บข้อมูลเดียว
  • ส่วนสนับสนุน Language-integrated query (LINQ) ให้การตรวจสอบความถูกต้องทางไวยากรณ์เวลาคอมไพล์สำหรับแบบสอบถามกับโมเดลแนวคิด

การใช้ ORM กับขั้นตอนการจัดเก็บเกี่ยวข้องกับการแลกเปลี่ยนโดยเฉพาะอย่างยิ่งในแง่ของการรักษาความปลอดภัยและที่ตั้งของตรรกะ

แนวทาง "คลาสสิค" เพื่อการพัฒนากับ SQL Server คือการให้ตรรกะของแอปพลิเคชันอยู่ในขั้นตอนการจัดเก็บและโปรแกรมที่ให้สิทธิ์ด้านความปลอดภัยในการดำเนินการขั้นตอนการจัดเก็บเท่านั้นไม่ใช่การอัพเดทตารางโดยตรง แนวคิดในที่นี้คือกระบวนงานที่เก็บไว้เป็นเลเยอร์ตรรกะทางธุรกิจสำหรับแอปพลิเคชัน ในขณะที่ทฤษฎีเสียงมันมีแนวโน้มที่จะหลุดพ้นจากความโปรดปรานด้วยเหตุผลต่าง ๆ ถูกแทนที่ด้วยการใช้ตรรกะทางธุรกิจในการเขียนโปรแกรมภาษาเช่น C # หรือ VB แอปพลิเคชันที่ดียังคงใช้งานด้วยวิธีการที่ทำเป็นชั้นรวมถึงการแยกข้อกังวล ฯลฯ แต่มีแนวโน้มที่จะทำตามรูปแบบเช่น MVC

ข้อเสียของการใช้ตรรกะใน ORM มากกว่าฐานข้อมูลคือความง่ายในการดีบักและทดสอบกฎความสมบูรณ์ของข้อมูลโดยผู้รับผิดชอบฐานข้อมูล (DA หรือ DBA) ยกตัวอย่างคลาสสิกของการโอนเงินจากการตรวจสอบของคุณไปยังบัญชีเงินฝากออมทรัพย์มันเป็นสิ่งสำคัญที่จะทำเช่นนี้เป็นหน่วยงานของอะตอมในคำอื่น ๆ แซนวิชในการทำธุรกรรม หากการถ่ายโอนประเภทนี้ได้รับอนุญาตให้ทำผ่านขั้นตอนการจัดเก็บเป็นเรื่องง่ายสำหรับ DA และผู้ตรวจสอบไปยัง QA ถึงขั้นตอนการจัดเก็บ

หากในอีกทางหนึ่งจะทำผ่าน ORM เช่น Entity Framework และในการผลิตพบว่าในบางครั้งเงินถูกนำมาจากการตรวจสอบ แต่ไม่ได้นำไปสู่การดีบักการออมอาจจะซับซ้อนมากขึ้นโดยเฉพาะอย่างยิ่งหากมีหลายโปรแกรมที่เกี่ยวข้อง นี่อาจเป็นกรณีที่เป็นไปได้มากที่สุดซึ่งอาจเกี่ยวข้องกับปัญหาฮาร์ดแวร์แปลก ๆ ที่ต้องเกิดขึ้นในลำดับเฉพาะ ฯลฯ การทดสอบนี้ทำได้อย่างไร?


หรือ ORM อื่น ๆ มีหลายคนมีข้อดีและข้อเสียต่าง ๆ เมื่อเปรียบเทียบกับ EF
svick

8
รายการข้อเสียของ ORMs จะทำให้คำตอบนี้มีประโยชน์มากขึ้น
Den

6

จริงๆแล้วการยืนยันขั้นพื้นฐานนั้นเป็นที่ถกเถียงกัน - มีการแลกเปลี่ยนกันระหว่างวิธีที่มี SQL ในรหัสหรือมีรหัสในฐานข้อมูล

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

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

สิ่งที่สำคัญกว่าคือการกังวลเกี่ยวกับสถาปัตยกรรมและแอปพลิเคชั่นของคุณ - กำหนดเลเยอร์การเข้าถึงข้อมูลที่เหมาะสมไม่ว่าจะใช้ ORM เช่น Entity Framework หรือ NHibernate หรือทำอะไรบางอย่างโดยตรงควรแยกแอปพลิเคชันส่วนใหญ่ออกจากการตัดสินใจนี้ หรือใช้วิธีการที่เก็บไว้


ฉันจะเป็นอิสระฉันมักจะทำงานในโครงการขนาดเล็กที่มีทีมเล็ก (1-3 devs) - การใช้โพรซีเดอร์ที่เก็บไว้สำหรับฉันมีปัญหามากกว่าความคุ้มค่าเพราะธรรมชาติของแอปพลิเคชันของเรา โดยทั่วไปรหัสนั้นง่ายกว่าการอัพเดต schema (แม้จะอนุญาตให้ฉันมีรหัสที่ทำให้การปรับปรุง schema ค่อนข้างตรงไปตรงมา) และฉันสามารถบังคับใช้กฎเกณฑ์ทางธุรกิจโดยใช้รหัสการเข้าถึงข้อมูลทั่วไป นี่เป็นตัวอย่างที่ชัดเจนของ "Your Mileage May Vary"


2
+1 สำหรับ "ไม่ดีที่สุดเดียว" -1 สำหรับการปรับใช้โค้ดนั้นง่ายกว่าการปรับใช้การเปลี่ยนแปลง proc ที่เก็บไว้ +1 สำหรับการเลือกวิธีการที่เหมาะสมสำหรับแอปของคุณและทำให้แน่ใจได้ว่าการแยก DAL - ดังนั้น +1
Joel Brown

ฉันมีคุณสมบัติบิตการปรับใช้กับ "สำหรับฉัน" เพราะนั่นสำหรับฉันอย่างต่อเนื่องเป็นกรณี (โดยเฉพาะอย่างยิ่งสำหรับการใช้งานเว็บ) - สำหรับทุกสิ่งที่มันอาจจะมีบิตของการเขียนใหม่ในพื้นที่นั้น
Murph

+1 อะไรที่ดีที่สุดขึ้นอยู่กับแอปพลิเคชัน & สถานการณ์
GrandmasterB

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

@ JoelBrown - แน่นอน - ฉันคิดว่าไม่ฉันแน่ใจว่าฉันได้ทำข้อสันนิษฐานทั้งหมดที่นั่น ประการแรกสคีมาของฉันคือการควบคุมเวอร์ชัน (ในแบบที่หยาบ แต่มีประสิทธิภาพ) ฉันไม่ใช่ dba แต่ฉันฉลาดพอที่จะรู้ว่าสคีมานั้นต้องสอดคล้องกัน ฉันทำงานบนเว็บแอปเป็นส่วนใหญ่และคุณไม่สามารถไปที่ฐานข้อมูลได้ยกเว้นโดยไปที่เซิร์ฟเวอร์ในขณะที่ฉันมี (เพียง) ลดการปรับใช้แอพลง (มากหรือน้อย) ด้วยการคลิกเพียงปุ่มเดียว ... การใช้งานอยู่ในรายการ แต่ฉันได้เสมอพบการปรับปรุงสคีเครียดมากกว่าการปรับปรุงรหัส (ความสะดวกในการย้อนกลับ?)
Murph

4

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


1
การกำหนดตัวแปรเพียงพอหรือไม่ คุณไม่จำเป็นต้องฆ่าเชื้อโรคด้วยเช่นกัน?
StuperUser

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

0

แนวปฏิบัติที่ดีที่สุดมีมากเกินไปที่นี่ - มีหลายวิธีที่ดีในการทำและวิธีที่คุณเลือกควรขึ้นอยู่กับว่าแอปของคุณคืออะไรและคุณต้องทำอะไร ที่กล่าวว่ามีเพียงสองสิ่งที่คุณสามารถทำผิดจริงๆ:

  • เมื่อ @Bill ชี้ให้เห็นคุณควรตั้งค่าพารามิเตอร์การสืบค้นของคุณเสมอ การสร้างสตริงเป็นเวกเตอร์ง่าย ๆ สำหรับการฉีด SQL รวมถึงลักษณะของการติดตามบั๊กทั้งหมด ผู้คนที่ฉลาดกว่านั้นต่างก็คิดหาวิธีที่จะเพิ่มและหลีกเลี่ยง sql ดังนั้นคุณไม่จำเป็นต้องคิดออกเอง

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

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

โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.