初學者常糾結:DAL 層查詢數據後,怎麼把 SqlDataReader 的結果「返回」給 BLL,再傳給 UI?是返回 DataTable、List<Dictionary> 還是自定義實體類?
定義實體類對應表結構,DAL 封裝 SqlDataReader 填充實體,返回 T 或 List<T>,上層調用極其清晰。
public class Nation
{
public int Id { get; set; }
public string NationName { get; set; }
}
public Nation GetByName(string name)
{
const string sql = "SELECT Id, NationName FROM TB_Nation WHERE NationName = @name";
Nation nation = null;
using (var conn = new SqlConnection(connString))
using (var cmd = new SqlCommand(sql, conn))
{
cmd.Parameters.AddWithValue("@name", name);
conn.Open();
using (var reader = cmd.ExecuteReader())
{
if (reader.Read())
{
nation = new Nation
{
Id = reader.GetInt32(0),
NationName = reader.GetString(1)
};
}
}
}
return nation; // 未找到返回 null
}
public List<Nation> GetAll()
{
var list = new List<Nation>();
const string sql = "SELECT Id, NationName FROM TB_Nation";
using (var conn = new SqlConnection(connString))
using (var cmd = new SqlCommand(sql, conn))
{
conn.Open();
using (var reader = cmd.ExecuteReader())
{
while (reader.Read())
{
list.Add(new Nation
{
Id = reader.GetInt32(0),
NationName = reader.GetString(1)
});
}
}
}
return list;
}
public NationService
{
private readonly NationDal _dal = new NationDal();
public Nation FindByName(string name)
{
if (string.IsNullOrWhiteSpace(name)) throw new ArgumentException("名稱不能為空");
return _dal.GetByName(name.Trim());
}
}
public ActionResult Detail(string name)
{
var service = new NationService();
var nation = service.FindByName(name);
if (nation == null) return HttpNotFound();
return View(nation); // 自動綁定到 ViewModel
}
using 確保連接/Reader 關閉PagedResult<T> 包裝類「返回實體類而非原始 DataReader」是從寫腳本走向工程化的關鍵一步。