0

MySQLクエリ、特にデータリーダーの結果をキャッシュする方法はありますか?

アプリケーションのロード時に 1 回だけ実行する必要があるありふれたクエリがいくつかあり、リモート サーバーにクエリを実行する代わりに、各フォームでキャッシュ値を使用できます。

現在、私の方法は、 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 クラス + いくつかのデータバインディングを使用することです。

コードの読み取り (および書き込み) が簡単になるだけでなく、柔軟性が大幅に向上します (必要な場合にのみリクエストを発行するなど)。

従来のアプローチは、次のものを作成することです。

  • DB操作をラップしてDataset(またはカスタムクラス)を返し、変更を保存するData Abstraction Layer(DAL)(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)
            {

            }
        }

得られないのは型の安全性です。つまり、優先度に値またはintではない値が含まれていない場合、item.Priorityがランタイムエラーを引き起こす可能性があります。キャッシュをロードするときにこれをカバーする必要がありますが、基本的にはあなたが現在データリーダーを使用している状況。

于 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 に答える