有没有办法缓存MySQL查询的结果,特别是数据读取器?
我有一些普通的查询,只需要在加载应用程序时执行一次,然后每个表单都可以使用缓存值而不是查询远程服务器。
目前我的方法是使用MySqlDataReader来检索数据并将其存储在另一个MySqlDataReader中,以便我可以在以后检索它(例如下面的例子)
if (parentfrm.prioritylist != null)
{
if (parentfrm.prioritylist.HasRows)
{
using (var rows = parentfrm.prioritylist)
{
while (rows.Read())
{
cboxitem cbi = new cboxitem(int.Parse(rows["priorityid"].ToString()), rows["label"].ToString());
cb.Items.Add(cbi);
}
}
}
else
{
query = @"SELECT priorityid, label FROM prioritylist WHERE active = 'Y' ORDER BY theorder ASC";
parentfrm.prioritylist = db.localfetchrows(query);
if (cb != null)
{
using (var rows = db.localfetchrows(query))
{
while (rows.Read())
{
cboxitem cbi = new cboxitem(int.Parse(rows["priorityid"].ToString()), rows["label"].ToString());
cb.Items.Add(cbi);
}
}
}
}
}
else
{
query = @"SELECT priorityid, label FROM prioritylist WHERE active = 'Y' ORDER BY theorder ASC";
parentfrm.prioritylist = db.localfetchrows(query);
if (cb != null)
{
using (var rows = db.localfetchrows(query))
{
while (rows.Read())
{
cboxitem cbi = new cboxitem(int.Parse(rows["priorityid"].ToString()), rows["label"].ToString());
cb.Items.Add(cbi);
}
}
}
}
答案 0 :(得分:1)
public class Priority{
public int PriorityId {get;set;}
public string Label {get;set;}
}
public class CachedItems {
private static List<Priority> _priorityList=new List<Priority>();
public static List<Priority> GetPriorityList() {
if (_priorityList==null){
// Load DB Items to the _priorityList,
// if the app is multithreaded, you might wanna add some locks here
}
}
}
然后在代码中的任何位置,只需使用CachedItems.GetPriorityList()
来访问缓存列表。
答案 1 :(得分:1)
简短回答:填充对象并重复使用
更长的答案:设计您的应用程序以使用某种解耦。最简单的方法是使用双DataSet / DataAdapter类+一些数据绑定。
不仅您的代码更易于阅读(和写入),而且您将具有更大的灵活性(例如仅在需要时触发请求)。
传统方法是创建:
首先阅读本文:http://www.codeproject.com/Articles/36847/Three-Layer-Architecture-in-C-NET
答案 2 :(得分:1)
一种快速的方法是使用动态的类型/匿名类(.NET 4),这与您已经在做的事情相同(基于Mennans代码构建)
public class CachedItems
{
private static List<dynamic> _priorityList = new List<dynamic>();
public static List<dynamic> GetPriorityList()
{
if (_priorityList == null)
{
// Load DB Items to the _priorityList,
// if the app is multithreaded, you might wanna add some locks here
query = @"SELECT priorityid, label FROM prioritylist WHERE active = 'Y' ORDER BY theorder ASC";
parentfrm.prioritylist = db.localfetchrows(query);
if (cb != null)
{
using (var rows = db.localfetchrows(query))
{
while (rows.Read())
{
_priorityList.Add(new {
PriorityId = int.Parse(rows["priorityid"].ToString()),
Label = rows["label"].ToString()
});
}
}
}
}
return _priorityList;
}
}
使用缓存的值:
foreach (var item in CachedItems.GetPriorityList())
{
if (item.Priority == 1)
{
}
}
你没有得到的是类型安全,即item.Priority migth会导致运行时错误,如果Priority不包含值或不是int的值,则在加载缓存时必须覆盖此值,但是这基本上就是你现在使用datareader的情况。
答案 3 :(得分:0)
您可以考虑使用一个小型应用程序工具包类PriorityCheckbox,并使其成为单例。然后,当您需要这些复选框值时,首先在PriorityCheckboxes上引用GetInstance()方法,应该加载它。如果你有竞争条件,那么加载逻辑可以进入静态初始化器。
public class PriorityCheckboxes {
private static CheckBox _CBItems = null;
private static PriorityCheckboxes _instance - null;
public CheckBox CheckBoxes {
get() { return _CBItems; }
}
private PriorytyCheckboxes() {
this.LoadCBItems();
_instance = new PriorityCheckboxes();
}
public static PriorityCheckboxes GetInstance() {
if(_instance == null ) _instance = new PriorityCheckboxes();
return _instance;
}
private void LoadCBItems() { }
}