我有这个用来从SQL中获取东西的小方法。我要么用varSearch = ""
或varSearch = "something"
来称呼它。我想知道如果以这种方式编写的方法是最好的还是将它分成两个方法(通过重载)更好,或者我可能以某种方式参数化整个WHERE
clausule?
private void sqlPobierzKontrahentDaneKlienta(ListView varListView, string varSearch) {
varListView.BeginUpdate();
varListView.Items.Clear();
string preparedCommand;
if (varSearch == "") {
preparedCommand = @"
SELECT t1.[KlienciID],
CASE WHEN t2.[PodmiotRodzaj] = 'Firma' THEN
t2.[PodmiotFirmaNazwa] ELSE
t2.[PodmiotOsobaNazwisko] + ' ' + t2.[PodmiotOsobaImie] END AS 'Nazwa'
FROM [BazaZarzadzanie].[dbo].[Klienci] t1
INNER JOIN [BazaZarzadzanie].[dbo].[Podmioty] t2
ON t1.[PodmiotID] = t2.[PodmiotID]
ORDER BY t1.[KlienciID]";
} else {
preparedCommand = @"
SELECT t1.[KlienciID],
CASE WHEN t2.[PodmiotRodzaj] = 'Firma' THEN
t2.[PodmiotFirmaNazwa] ELSE
t2.[PodmiotOsobaNazwisko] + ' ' + t2.[PodmiotOsobaImie] END AS 'Nazwa'
FROM [BazaZarzadzanie].[dbo].[Klienci] t1
INNER JOIN [BazaZarzadzanie].[dbo].[Podmioty] t2
ON t1.[PodmiotID] = t2.[PodmiotID]
WHERE t2.[PodmiotOsobaNazwisko] LIKE @searchValue OR t2.[PodmiotFirmaNazwa] LIKE @searchValue OR t2.[PodmiotOsobaImie] LIKE @searchValue
ORDER BY t1.[KlienciID]";
}
using (var varConnection = Locale.sqlConnectOneTime(Locale.sqlDataConnectionDetails))
using (SqlCommand sqlQuery = new SqlCommand(preparedCommand, varConnection)) {
sqlQuery.Parameters.AddWithValue("@searchValue", "%" + varSearch + "%");
using (SqlDataReader sqlQueryResult = sqlQuery.ExecuteReader())
if (sqlQueryResult != null) {
while (sqlQueryResult.Read()) {
string varKontrahenciID = sqlQueryResult["KlienciID"].ToString();
string varKontrahent = sqlQueryResult["Nazwa"].ToString();
ListViewItem item = new ListViewItem(varKontrahenciID, 0);
item.SubItems.Add(varKontrahent);
varListView.Items.AddRange(new[] {item});
}
}
}
varListView.EndUpdate();
}
答案 0 :(得分:6)
更好的方法实际上是使用存储过程而不是将SQL硬编码到应用程序中。您可以将where子句参数传递给存储过程并处理数据库端的逻辑。
这种方法还提供了这样的优势:如果您需要在另一个应用程序(例如JAVA应用程序)中使用此逻辑,则逻辑将集中在数据库中,因此您无需再次重写它。
答案 1 :(得分:3)
在多个级别上糟透了:
根本没有DAL - 这意味着您的SQL代码将覆盖所有表单。糟糕的维护 - 至少将所有SQL处理放在一个类中。
这是很多手动编写代码,因此性能不佳(如:程序员性能)。看看BLToolkit如何在RUNTIME上生成所有代码(来自使用SQL和抽象方法的属性 - 使用真实方法生成字节码的子类)。
那就是说,除非我能说服你使用真正的数据访问层/像NHibernate这样的ORM。
FOr 1我会以程序员的身份解雇你(欢迎回来当实习生)。在表单中使用SQL并不是我在重新编写数据库时花费时间的想法 - 因此,它不可测试且难以维护。这是顺便说一句。 ,而不是“.net specific” - 隔离SQL是我20年前(几乎)用smalltalk和C ++做过的事情;)
对于2,我会 - 好吧 - 由于指导原则不会发生;)
答案 2 :(得分:0)
我确信有更好的方法,比如使用存储过程,但如果你真的需要这样做,你需要:
string preparedCommandTemplate = @"
SELECT t1.[KlienciID],
CASE WHEN t2.[PodmiotRodzaj] = 'Firma' THEN
t2.[PodmiotFirmaNazwa] ELSE
t2.[PodmiotOsobaNazwisko] + ' ' + t2.[PodmiotOsobaImie] END AS 'Nazwa'
FROM [BazaZarzadzanie].[dbo].[Klienci] t1
INNER JOIN [BazaZarzadzanie].[dbo].[Podmioty] t2
ON t1.[PodmiotID] = t2.[PodmiotID] {0}
ORDER BY t1.[KlienciID]";
string whereClause="WHERE t2.[PodmiotOsobaNazwisko] LIKE @searchValue OR t2.[PodmiotFirmaNazwa] LIKE @searchValue OR t2.[PodmiotOsobaImie] LIKE @searchValue"
if (string.Emtpy.Equals(varSearch )) {
preparedCommand = string.Format(preparedCommandTemplate,string.Empty)
} else {
preparedCommand = string.Format(preparedCommandTemplate,whereCaluse)
}
答案 3 :(得分:0)
如果您不想使用存储过程,请至少参数化where子句。这种代码很快就会失控。我还会考虑使用自由文本索引或Lucene.NET之类的东西在多个字段中实现这种“喜欢”的搜索。
答案 4 :(得分:0)
鉴于您希望在代码中继续使用硬编码的SQL语句(而不是切换到LINQ2SQL或Entity Framework或其他ORM工具),您肯定做的一件事不想做将where子句作为参数添加到您的方法中(如果这是'参数化where子句'的意思)。这使得使用此方法的客户端依赖于您的数据访问技术(在本例中为SQL数据库)。
比较以下两个电话:
sqlPobierzKontrahentDaneKlienta(lv, "something");
和
sqlPobierzKontrahentDaneKlienta(lv,
"WHERE t2.[PodmiotOsobaNazwisko] LIKE '%something%' OR " +
" t2.[PodmiotFirmaNazwa] LIKE '%something%' OR " +
" t2.[PodmiotOsobaImie] LIKE '%something%'")
哪一个看起来更好?