Evet, kodlama SQL dizeleri uygulama koduna genellikle bir anti-kalıptır.
Bunu üretim kodunda görerek yıllarca geliştirdiğimiz toleransı bir kenara koymaya çalışalım. Tamamen farklı dilleri aynı dosyada farklı bir sözdizimi ile karıştırmak genellikle arzu edilen bir geliştirme tekniği değildir. Bu, Razor gibi çoklu dillere bağlamsal anlam vermek için tasarlanmış şablon dillerinden farklıdır. As Sava B. altında bir yorumda bahseder, C # veya diğer uygulama dili (Python, C ++, vs.) SQL diğerleri gibi bir dizedir ve anlamsal olarak anlamsızdır. Aynısı, çoğu durumda birden fazla dili karıştırırken de geçerlidir, ancak C'nin satır içi montajı, HTML'de CSS'nin küçük ve anlaşılır snippet'leri (CSS'nin HTML ile karıştırılmak üzere tasarlandığına dikkat çeken) gibi, bunun kabul edilebilir olduğu durumlar olduğu açıktır. ), ve diğerleri.
(Robert C. Martin karıştırma dilleri, Temiz Kod , Bölüm 17, "Kod Kokuları ve Sezgisel", sayfa 288)
Bu yanıt için SQL'e odaklanacağım (soruda sorulduğu gibi). SQL'i alakart olmayan bir dize kümesi olarak saklarken aşağıdaki sorunlar ortaya çıkabilir:
- Veritabanı mantığını bulmak zor. Tüm SQL ifadelerinizi bulmak için ne ararsınız? "SELECT", "UPDATE", "MERGE" vb.
- Aynı veya benzer SQL'nin yeniden kullanım kullanımları zorlaşır.
- Diğer veritabanlarına destek eklemek zordur. Kişi bunu nasıl başarır? Her veritabanı için if..then ifadelerini ekleyin ve tüm sorguları yöntemde dizge olarak saklayın?
- Geliştiriciler, başka bir dilde bir ifade okur ve odağın, yöntemin amacından yöntemin uygulama detaylarına (verinin nereden ve nereden alındığı) geçmesine odaklanır.
- Tek gömlekler çok fazla sorun olmasa da, satır içi SQL dizeleri ifadeler daha karmaşık hale geldikçe dağılmaya başlar. 113 satırlı bir ifade ile ne yaparsınız? 113 çizginin hepsini metodunuza eklediniz mi?
- Geliştirici, sorguları SQL editörleri (SSMS, SQL Developer, vb.) Ve kaynak kodları arasında ileri geri nasıl etkili bir şekilde taşır? C # 'nin
@
öneki bunu kolaylaştırıyor, ancak her SQL satırından alıntı yapan ve yeni satırlardan kaçan bir sürü kod gördüm.
"SELECT col1, col2...colN"\
"FROM painfulExample"\
"WHERE maintainability IS NULL"\
"AND modification.effort > @necessary"\
- SQL'i çevreleyen uygulama koduyla hizalamak için kullanılan girinti karakterleri, her yürütme sırasında ağ üzerinden iletilir. Bu muhtemelen küçük ölçekli uygulamalar için önemsizdir, ancak yazılımın kullanımı arttıkça eklenebilir.
Tam ORM'ler (Entity Framework veya Hibernate gibi Nesne İlişkisel eşleştiriciler) uygulama kodunda rastgele karabiber SQL'i ortadan kaldırabilir. SQL ve kaynak dosyalarını kullanmam bir örnek. ORM'ler, yardımcı sınıflar vb. Hepsi temiz kodun hedefine ulaşmada yardımcı olabilir.
Kevin'ın daha önceki bir cevabında dediği gibi, koddaki SQL küçük projelerde kabul edilebilir, ancak büyük projeler küçük projeler olarak başlar ve çoğu takımın geri dönme ve bunu doğru yapma olasılığı genellikle kod boyutuyla ters orantılıdır.
SQL'i bir projede tutmanın birçok basit yolu vardır. Sık kullandığım yöntemlerden biri, her SQL ifadesini genellikle "sql" adlı bir Visual Studio kaynak dosyasına koymaktır. Araçlarınıza bağlı olarak bir metin dosyası, JSON belgesi veya başka bir veri kaynağı makul olabilir. Bazı durumlarda, SQL dizelerini birleştirmeye adanmış ayrı bir sınıf en iyi seçenek olabilir, ancak yukarıda açıklanan sorunlardan bazılarına sahip olabilir.
SQL Örnek: Hangisi daha zarif görünüyor ?:
using(DbConnection connection = Database.SystemConnection()) {
var eyesoreSql = @"
SELECT
Viewable.ViewId,
Viewable.HelpText,
PageSize.Width,
PageSize.Height,
Layout.CSSClass,
PaginationType.GroupingText
FROM Viewable
LEFT JOIN PageSize
ON PageSize.Id = Viewable.PageSizeId
LEFT JOIN Layout
ON Layout.Id = Viewable.LayoutId
LEFT JOIN Theme
ON Theme.Id = Viewable.ThemeId
LEFT JOIN PaginationType
ON PaginationType.Id = Viewable.PaginationTypeId
LEFT JOIN PaginationMenu
ON PaginationMenu.Id = Viewable.PaginationMenuId
WHERE Viewable.Id = @Id
";
var results = connection.Query<int>(eyesoreSql, new { Id });
}
Oluyor
using(DbConnection connection = Database.SystemConnection()) {
var results = connection.Query<int>(sql.GetViewable, new { Id });
}
SQL, her zaman uygulama kodunun akışını kesmeyecek bir yorum için alan içeren, her biri nasıl yapıldığını açıklayan bir açıklayıcı ada sahip, kolayca bulunabilen bir dosyada veya gruplanmış dosya grubundadır :
Bu basit yöntem yalnız bir sorgu yürütür. Tecrübelerime göre, fayda "yabancı dil" in kullanımı olarak daha da artmaktadır.
Bir kaynak dosyasını kullanmam sadece bir örnek. Dil (bu durumda SQL) ve platforma bağlı olarak farklı yöntemler daha uygun olabilir.
Bu ve diğer yöntemler yukarıdaki listeyi şu şekilde çözer:
- Veritabanı kodu zaten merkezileştiği için bulunması kolaydır. Daha büyük projelerde, like-SQL'i ayrı dosyalar halinde, belki de bir klasör altında toplayın
SQL
.
- İkinci, üçüncü vb. Veritabanları için destek kolaydır. Her veritabanının benzersiz ifadelerini döndüren bir arayüz (veya başka bir dil soyutlama) yapın. Her veritabanı için uygulama, aşağıdakine benzer ifadelerden biraz daha fazlası olur:
return SqlResource.DoTheThing;
Doğru, bu uygulamalar kaynağı atlayabilir ve SQL'i bir dizgide içerebilir, ancak yukarıdaki bazı sorunların tümü yüzeye çıkacaktır.
- Yeniden düzenleme basit - aynı kaynağı tekrar kullanmanız yeterli. Aynı kaynak girişini, çoğu zaman birkaç format ifadesiyle farklı DBMS sistemleri için de kullanabilirsiniz. Bunu sık sık yapıyorum.
- İkincil dilin kullanımı açıklayıcı isimler kullanabilir, örneğin
sql.GetOrdersForAccount
daha genişSELECT ... FROM ... WHERE...
- SQL ifadeleri, boyutlarına ve karmaşıklıklarına bakılmaksızın tek bir satırla toplanır.
- SQL, SSMS ve SQL Developer gibi veritabanı araçları arasında değişiklik yapılmadan veya dikkatli bir şekilde kopyalanmadan kopyalanıp yapıştırılabilir. Tırnak işareti yok. Sonunda ters eğik çizgi yok. Özellikle Visual Studio kaynak editörü durumunda, tek bir tıklama SQL deyimini vurgular. CTRL + C tuşlarına basıp ardından SQL editörüne yapıştırın.
Bir kaynakta SQL oluşturulması hızlıdır, bu nedenle kaynak kullanımını kod koduyla karıştırmak için çok az ivme vardır.
Seçilen yönteme bakılmaksızın, karıştırma dillerinin genellikle kod kalitesini düşürdüğünü buldum. Burada açıklanan bazı sorunların ve çözümlerin, geliştiricilerin uygun olduğunda bu kod kokusunu gidermelerine yardımcı olacağını umuyorum.