0

有没有办法缓存 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);
                    }
                }
            }
        }
4

4 回答 4

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()访问缓存列表。

于 2012-07-31T13:35:15.170 回答
1

简短的回答:填充一个对象,然后重用它

更长的答案:设计您的应用程序以使用某种解耦。最简单的方法是使用双重 DataSet/DataAdapter 类 + 一些数据绑定。

不仅您的代码将更易于阅读(和编写),而且您将拥有更大的灵活性(例如仅在需要时触发请求)。

一种传统的方法是创建:

  • 一个数据抽象层 (DAL),它包装 DB 操作以返回 Dataset(或自定义类),保存更改(DataSet 具有内置的更改跟踪功能)
  • 封装逻辑的业务逻辑层 (BLL)。Bll 可以与 DAL 一起使用
  • UI 层,包含应用程序本身。Ui 应该只调用 BLL 的方法。

从阅读这篇文章开始:http: //www.codeproject.com/Articles/36847/Three-Layer-Architecture-in-C-NET

于 2012-07-31T13:36:39.713 回答
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 可能会导致您的运行时错误,如果 Priority 不包含值或不是 int 的值,则在加载缓存时您必须涵盖这一点,但这基本上是您现在使用数据读取器的情况。

于 2012-07-31T14:00:45.303 回答
0

您可能会考虑一个小型应用程序工具包类 PriorityCheckboxes,并将其设为单例。然后,当您需要这些复选框值时,应首先加载 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() { }
}
于 2012-07-31T13:57:30.987 回答