0

プロジェクトに Identity マップ パターンと DataMapper パターンを実装しています。しかし、私にはいくつかの問題があります。

ゲートウェイによってデータベースからデータを取得するとき、オブジェクトの新しいインスタンスを作成してリストを返します...

Identy Map に関してデータベースからデータを取得するための最良の方法は何ですか? データベースから患者を取得し、これらのデータをユーザーに表示したい..

Identity map のオブジェクトの ID はどうですか? 私の解決策(私の考えでは):1)デフォルトIDで新しいオブジェクトを作成する2)オブジェクトをデータベースに保存する3)データベース内の最後のオブジェクトのIDを取得する4)オブジェクトの新しいIDを設定する5)新しいIDでキャッシュに保存する... .

それは良い解決策ですか?

ご協力いただきありがとうございます!

私のアイデンティティマップオブジェクト(シングルトン):

public class PacientMap
{

    //Cache obsahující jednotlivé instance entiti

    private static PacientMap _instance;
    private Dictionary<int, Pacient> _cache; // Slouží k ukládání objektů pacient

    //Privátní konstruktor, (zaručí mi, že nedojde k vytvoření další instance) => metoda PacientGetInstance ho zavolá jen jednou
    private PacientMap()
    {
            _cache = new Dictionary<int, Pacient>();
    }

    //Metoda pro vytvoreni objektu jedinacek
    public static PacientMap PacientGetInstance()
    {   
        //Je-li promenna instance null, tak se vytvori objekt
        if (_instance == null)
        {
            _instance = new PacientMap();
        }

       //Vratime jedinacka
        return _instance;
    }



    /***********************************
     Vrátí jedinečnou instanci pro zadaný klíč. Pokud instance neexistuje, bude
     vytvořena a uložena do cache.
    ***************************************/
    public Pacient GetPacient(int klic)
    {
        // Pokud je v cache objekt s daným klicem
        if (_cache.ContainsKey(klic))
        {
            //Vrátím objekt
            return _cache[klic];
        }
        // Pokud jsem ho v cache nenasel
        // Zkusím ho najít v databázi
        if (SerachInDb(klic))
        {
            // Pokud byl nalezen v DB, byl automaticky uložen do cahe a jen si ho pod jeho id v cahe nejdu
            return _cache[klic];
        }

        // Pokud nebyl nikde nalezen, vyhodíme chybu
        throw new Exception();
    }

    /// <summary>
    /// Najde Pacienta v databází a pokud ho najde ulozí ho do cache a vrací TRUE
    /// Pokud ho nenejde vrací FALSE
    /// </summary>
    /// <param name="klic"></param>
    /// <returns></returns>
    private bool SerachInDb(int klic)
    {

        Pacient pac = PacientDataGateway.GetInstance().SelectByPacientId(klic);

        if (pac == null)
        {
            return false;
        }

        _cache.Add(klic, pac);

        return true;
    }

    /// <summary>
    /// Vytvoření nového pacienta
    /// </summary>
    /// <param name="klic"></param>
    /// <param name="pacient"></param>
    /// <returns></returns>
    public bool Add(int IdPacienta, string jmeno, string prijmeni, DateTime datumNarozeni, string cisloPojisteni, string telefon, int zubarId)
    {
        if(SerachInDb(zubarId))
        {
            return true;
        }

        Pacient pacient = new Pacient(0, jmeno, prijmeni, datumNarozeni, cisloPojisteni, telefon, zubarId);

        if(PacientDataGateway.GetInstance().insert(pacient))
        {
            // TODO: Selectnu si púoslední záznam z DB a zjistím so jeho id
        }

        return true;
    }

}

Pacient Mapper があります。

      public List<Pacient> SelectPacient()
    {
        Database db = new Database();
        db.Connect();

        SqlCommand command = db.CreateCommand("SELECT ID,jmeno,prijmeni,datumNarozeni,cisloPojisteni,telefon,Zubarid FROM pacient");

        SqlDataReader reader = db.Select(command);

        List<Pacient> pacienti = new List<Pacient>();

        Pacient pacient = null;
        while (reader.Read())
        {
            pacient = new Pacient();

            pacient.Id = reader.GetInt32(0);
            pacient.Jmeno = reader.GetString(1);
            pacient.Prijmeni = reader.GetString(2);
            pacient.DatumNarozeni = reader.GetDateTime(3);
            pacient.CisloPojisteni = reader.GetString(4);
            pacient.Telefon = reader.GetString(5);
            pacient.idZubare = reader.GetInt32(6);

            pacienti.Add(pacient);
        }
        reader.Close();
        db.Close();

        return pacienti;
    }
4

1 に答える 1

0

データベースからオブジェクトを取得する前に、IdentityMap でオブジェクトの存在を確認する必要があります。これにより、同じオブジェクトの複数のコピーを取得して、その後の更新の競合を防ぐことができます。Id で単一のオブジェクトを要求する場合、最初にオブジェクトの IdentityMap を確認してから、オブジェクトがまだない場合にのみデータベースを呼び出すことができます。複数のオブジェクトの場合、結果が非​​決定論的であるため、これを行うことはできません。データベースにクエリを実行してからマップを確認し、ギャップを埋める必要があります。

最終的に、IdentityMap の仕事は、特定のスコープに対してオブジェクトのメモリ内コピーが常に 1 つだけ存在するようにすることです。あなたがこれを達成している場合、それは仕事です。

マップが Id でキー設定されている場合、マップに追加する前に Id が必要になります。これは、クライアント上で、または挿入クエリを介して実行できます。Id を取得するために往復する必要がないため、クライアント側でのキーの割り当てを好みます。ただし、提案されたアプローチは問題ないようです。

IdentityMap の私自身の実装は、Type によってキー設定され、次にネストされた Dictionaries を使用して Id によってキー設定されます。これは、キーがテーブル スコープの場合に便利です。

于 2012-11-28T16:58:03.703 に答える