C # MS SQL Server'dan veri sorgulamak için en iyi yöntem?


9

C # MS SQL Server'dan veri sorgulamak için en iyi yolu nedir?

Kodda bir SQL sorgusu olması iyi bir uygulama olmadığını biliyorum.

Saklı yordam oluşturmak ve parametreleri C # ile parametreleri çağırmak için en iyi yoldur?

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

8
"Kodda bir SQL sorgusu olması iyi bir uygulama olmadığını biliyorum." - imo, bu saçmalık.
GrandmasterB

4
Kullanarak bir blokta oluşturduysanız conn.Close () öğesini çağırmanız gerekmez. Kullanım bloğunun bütün amacı, yıkıcı temizlemenin C ++ stilini taklit etmektir. Daha medeni bir çağdan kalma zarif bir temizlik. Try-catch tarzı kadar rastgele veya sakar değil.
Lord Tydus

2
Bilginize. Saklı yordamlar da "kod" dur. Depolanan proc'ların bütününde prosedürel kodun set tabanlı stil SQL ile karıştırılmasına izin vermekti. Böylece, kodda ne olursa olsun bir sorgulama olur. Son derece yüksek hacimli uygulamalar için, bazen sunucu ekleyerek yatay ölçeklendirmeye izin vermek için mantık dışında veritabanının gerçekleştirilmesi daha iyidir. Tek bir DB koruyabiliyorsanız, ancak mantık için muli-sunucusu varsa, ölçekleme çok daha kolay hale gelir.
Lord Tydus

@GrandmasterB C # 'da önemli miktarda SQL satır içi var (C # LOC şimdi 2 milyona yakın) - ve 6 yıl sonra bizi ısırmaya geri dönüyor çünkü şimdi bu satır içi SQL'i avlamamız gerekiyor (son zamanlarda bir SQL uzmanı tuttuk - bu yüzden performans ayarları yapıyoruz). Güven bana: Uygulamanızın ne kadar büyük olacağını ve gelecekte işlerin nasıl değişeceğini asla bilemezsiniz. Farklı dilleri farklı dosyalarda saklayın - sadece kaynakları tezahür ettirmek için delege verseniz bile. Bunu da yapabilirsiniz // SQLCODE- ama bunu yapmayı hatırlamanız gerekir.
Jonathan Dickinson

1
@JonathanDickinson, İsterseniz saklanan procs kullanın. Aynı veritabanına karşı çalışan farklı kod tabanları olduğunda birçok kez yararlı dedim. Ancak, bazı durumlarda yararlı olmaları, onları her zaman otomatik olarak 'kötü uygulama' kullanmamak anlamına gelmez . SQL ifadeleri doğrudan bir soruna neden olmazsa, bu uygulama için bir 'kötü uygulama' değildir.
GrandmasterB

Yanıtlar:


10

Saklı yordamları kullanmak bir yoludur ve yıllardır yaygın olarak kullanılmaktadır.

C # (veya herhangi bir .NET dili) SQL Server veritabanlarıyla etkileşim kurmanın daha modern bir yolu Entity Framework kullanmaktır. Entity Framework'ün avantajı, daha yüksek bir soyutlama düzeyi sağlamasıdır.

Microsoft'tan alıntı yapmak için ( https://msdn.microsoft.com/en-us/data/jj590134 ):

ADO.NET Entity Framework, geliştiricilerin doğrudan ilişkisel bir depolama şemasına karşı programlama yapmak yerine kavramsal bir uygulama modeline göre programlama yaparak veri erişim uygulamaları oluşturmalarını sağlar. Amaç, veri odaklı uygulamalar için gereken kod ve bakım miktarını azaltmaktır. Entity Framework uygulamaları aşağıdaki avantajları sağlar:

  • Uygulamalar, mirasa sahip türler, karmaşık üyeler ve ilişkiler dahil olmak üzere daha uygulama merkezli bir kavramsal model açısından çalışabilir.
  • Uygulamalar, belirli bir veri motoruna veya depolama şemasına sabit kodlanmış bağımlılıklardan kurtarılır.
  • Kavramsal model ile depolamaya özgü şema arasındaki eşlemeler, uygulama kodunu değiştirmeden değişebilir.
  • Geliştiriciler, muhtemelen farklı veritabanı yönetim sistemlerinde uygulanan çeşitli depolama şemalarıyla eşleştirilebilen tutarlı bir uygulama nesne modeliyle çalışabilir.
  • Birden fazla kavramsal model, tek bir depolama şemasına eşlenebilir.
  • Dille tümleşik sorgu (LINQ) desteği, kavramsal bir modele karşı sorgular için derleme zamanı sözdizimi doğrulaması sağlar.

Bir ORM'ye Karşı Saklı Yordamların kullanımı, özellikle güvenlik ve mantığın bulunduğu yerlerde dengesizlikleri içerir.

SQL Server ile geliştirmeye yönelik "klasik" yaklaşım, uygulama mantığının depolanan yordamlarda ve programların doğrudan güncelleştirilen depolanmış yordamları yürütmek için güvenlik hakları verdiği programlarda kalmasını sağlamaktır. Buradaki konsept, saklı prosedürlerin uygulama (lar) için iş mantığı katmanı olduğudur. Teori sağlam olsa da, çeşitli nedenlerle lehine düşme eğilimi vardı, bunun yerine iş mantığını C # veya VB gibi bir programlama dilinde uygulamak. İyi uygulamalar, endişelerin ayrılması vb. Dahil olmak üzere kademeli bir yaklaşımla uygulanmaktadır, ancak MVC gibi bir modeli takip etme olasılığı daha yüksektir.

Veritabanı yerine ORM'de mantık uygulamasının bir dezavantajı, veritabanından sorumlu olanların (DA veya DBA) veri bütünlüğü kurallarında hata ayıklama ve test etme kolaylığıdır. Çekten tasarruf hesabınıza para aktarmanın klasik örneğini ele alalım, bunun atomik bir iş birimi, yani bir işlemde sandviç haline getirilmesi önemlidir. Bu tür bir aktarımın sadece saklı bir prosedürle yapılmasına izin verilirse, DA ve denetçilerin saklı prosedürü KG için nispeten kolaydır.

Öte yandan, bu, Varlık Çerçevesi gibi bir ORM yoluyla yapılırsa ve üretimde, nadiren de olsa, paranın kontrol edilmesinden alındığı ancak tasarruflara konulmadığı, özellikle de birden fazla programın potansiyel olarak dahil olduğu durumlarda, hata ayıklamanın çok daha karmaşık olabileceği keşfedilir. Bu, büyük olasılıkla, belirli bir dizide vb. Meydana gelmesi gereken tuhaf donanım sorunlarını içeren bir uç durum olacaktır.


Veya diğer ORM. EF ile karşılaştırıldığında çeşitli avantajları ve dezavantajları olan birçoğu vardır.
Ocak'ta svick

8
ORM'lerin dezavantajlarını listelemek bu cevabı daha kullanışlı hale getirecektir.
Den

6

Aslında temel iddia tartışmalıdır - ya kodda SQL olması ya da veritabanında kod bulunması (saklı yordamlarla gittiğiniz yer) arasında değiş tokuşlar vardır.

Bunun sonucu, tek bir "en iyi" olmadığıdır, bu genelleştirebileceğiniz bir şey değildir, çünkü hangi yöne giderseniz gidin bir taviz veriyorsunuz (fayda elde edersiniz, ancak kısıtlamalar da getirersiniz).

Uygulamanız ve veritabanınız arasında bire bir yazışma varsa, o zaman gerçekten önemli değil. Öte yandan, bu uygulamalar arasında veritabanı içinde tutarlılığı zorunlu kılan önemli sayıda uygulama tarafından paylaşılan büyük bir çekirdek veritabanınız varsa çok daha önemli hale gelir.

Daha da önemlisi, uygulamanızın mimarisi ve katmanı hakkında endişelenmektir - Entity Framework veya NHibernate gibi bir ORM kullanmanın veya daha doğrudan bir şey yapmanın, sorgu oluşturmanıza bakılmaksızın uygulamanızın çoğunu bu karardan ayırması gerekip gerekmediği uygun bir veri erişim katmanı verildiğinde veya saklı yordamları kullanın.


Serbestçe, küçük ekiplerle (1-3 devs) nispeten küçük projeler üzerinde çalışmaya eğilimliyim - saklı prosedürleri kullanmak benim için, uygulamalarımızın doğası (ve beceri setim?) kod genellikle şemayı güncellemekten çok daha kolaydır (hatta şemayı güncellemeyi nispeten kolaylaştıran bir kodum olmasına izin verir) ve ortak veri erişim kodunu kullanarak iş kurallarını uygulayabiliyorum. Bu açıkça "Kilometre Değişebilir" klasik bir örneğidir.


2
"Tek bir en iyi" için +1, kod dağıtmak için -1, saklı proc değişikliklerini dağıtmaktan daha kolaydır, uygulamanız için anlamlı ve DAL yalıtımı sağlayan bir yaklaşım seçmek için +1 - So +1.
Joel Brown

Konuşlandırma bitini "benim için" nitelendirdim, çünkü bu benim için tutarlı bir şekilde oldu (özellikle web uygulamaları için) - her şey için o bölgede biraz yeniden yazma yapabilir.
Murph

+1, en iyisi uygulama ve duruma bağlıdır.
GrandmasterB

1
Sanırım içinde çalıştığınız koşullara bağlı. Sizi üretimden kilitleyen DBA'larınız yoksa, veritabanında depolanan bir yedek proc'u bırakmak korkutucu derecede kolay olabilir. Bu nedenle, üretim kontrolleri olmadan yeni biçimlendirme, komut dosyası ve hatta yeni derlenmiş kodu merkezi bir uygulamaya bırakarak da çok kolay olabilir.
Joel Brown

@JoelBrown - Kesinlikle - Sanırım, hayır, orada bir sürü varsayım yaptığımdan eminim. Öncelikle şemam sürüm kontrollüdür (kaba ama etkili bir şekilde), dba değilim ama şemanın tutarlı olması gerektiğini bilecek kadar zekiyim. Çoğunlukla web uygulamalarında çalışıyorum ve sunucuyu ziyaret etmek dışında veritabanlarına ulaşamıyorum, oysa uygulamaların dağıtımını (az ya da çok) tek bir düğmeyle tıkladım ... şema güncellemelerini ... dağıtım listede, ancak her zaman şema güncellemelerini kod güncellemelerinden daha stresli buldum (geri alma kolaylığı?)
Murph

4

Girdilerinizi parametrelendirdiğiniz sürece herhangi bir yaklaşım geçerlidir. Kod argümanlarında sorguların çoğu, kitaplıkların birçoğu sizi ifadelerinizi bir araya getirmeye zorladığı ve sql enjeksiyon saldırılarının geldiği kötü eski günlerden geldi.


1
Parametreleme yeterli mi? Dezenfekte etmeniz de gerekmez mi?
StuperUser

bu sizin kaynağınıza ve amacınıza bağlıdır. Sorusunu tam anlamıyla soruyordum, bazı parametrelerle salt okunur. Yaygın olarak, uygun şekilde parametrelenmiş bir tip istisnası veya kötü giriş ile sonuç alınmaması durumunda kirli girişle yapacağınız en kötü şey. Ekleme farklıdır ve kaynağı yetkili olarak değerlendirmedikçe genellikle doğrulanması gerekir.
Bill

0

En iyi uygulama burada gerçekten abartılı - bunu yapmanın birçok iyi yolu var ve seçtiğiniz uygulama uygulamanızın ne olduğuna ve ne yapmanız gerektiğine bağlı olmalıdır. Bununla birlikte, gerçekten yanlış yapabileceğiniz sadece iki şey var:

  • @ Fatura'nın işaret ettiği gibi, sorgularınızı her zaman parametrelendirmelisiniz. Dize oluşturma, SQL enjeksiyonu için kolay bir vektör ve ayrıca izlemesi zor olan her türlü yöntemdir. Çok daha akıllı insanlar, sql'i nasıl tupelize edip kaçacaklarını anladılar, böylece kendiniz anlamanıza gerek yok.

  • Bağlantılarınızı kapatın. En iyi yol her şeyi kullanarak bir ifadeyi sarmaktır, ancak denemek / yakalamak / nihayet teknenizi yüzerse de serindir. Ancak her zaman ucuz bir araba gibi bir bağlantı kullandığınızdan emin olun - sert ve hızlı sürün ve hızlı bir şekilde kurtulun.

Vehamently tartışacağım diğer bir uygulama, veri erişim kodunuzu mümkün olduğunca az yerde yoğunlaştırdığınızdan emin olmanızdır. Ön uç web uygulamalarının, bu uyarıyı uygulamaya yardımcı olması için System.Data.SqlClient'e doğrudan başvurmasına izin vermiyoruz.

Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.