【问题标题】:Cache mysql results c#缓存mysql结果c#
【发布时间】:2012-07-29 06:50:25
【问题描述】:

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

【问题讨论】:

  • winform? ASP.NET? MVC?什么? wpf? wcf?
  • 抱歉,我以为我已经标记了它,winform

标签: c# mysql winforms caching mysqldatareader


【解决方案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() 即可访问缓存列表。

【讨论】:

  • 所以你的解决方案是把datareader转换成一个对象,然后把这个对象存入一个列表中。是否有一种更简单的方法可以将数据从数据读取器转换为对象而无需定义代码,因为某些数据将有 20 列以上:(
  • 如果您愿意,可以将它们保存在 Dictionary&lt;string,object&gt; 而不是 List&lt;Priority&gt;。但是你需要一直转换这些值。从长远来看,我建议你走史蒂夫 B 的路。
【解决方案2】:

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

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

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

传统的方法是创建:

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

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

【讨论】:

    【解决方案3】:

    一种快速的方法是使用动态类型/匿名类 (.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 的值,则在加载缓存时必须覆盖这一点,但是这基本上就是您现在使用数据读取器的情况。

    【讨论】:

      【解决方案4】:

      您可以考虑一个小型应用程序工具包类 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() { }
      }
      

      【讨论】:

        猜你喜欢
        • 2016-04-17
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2013-12-24
        • 1970-01-01
        • 1970-01-01
        • 2011-01-06
        • 1970-01-01
        相关资源
        最近更新 更多