เช‘เชฌเซเชœเซ‡เช•เซเชŸเชฐเซ‡เชชเซ‹เชเชฟเชŸเชฐเซ€ - เชคเชฎเชพเชฐเชพ เชนเซ‹เชฎ เชชเซเชฐเซ‹เชœเซ‡เช•เซเชŸเซเชธ เชฎเชพเชŸเซ‡ .NET เช‡เชจ-เชฎเซ‡เชฎเชฐเซ€ เชฐเชฟเชชเซ‹เชเซ€เชŸเชฐเซ€ เชชเซ‡เชŸเชฐเซเชจ

เชฎเซ‡เชฎเชฐเซ€เชฎเชพเช‚ เชฌเชงเซ‹ เชกเซ‡เชŸเชพ เชถเชพ เชฎเชพเชŸเซ‡ เชธเช‚เช—เซเชฐเชนเชฟเชค เช•เชฐเชตเซ‹?

เชตเซ‡เชฌเชธเชพเช‡เชŸ เช…เชฅเชตเชพ เชฌเซ‡เช•เชเชจเซเชก เชกเซ‡เชŸเชพ เชธเซเชŸเซ‹เชฐ เช•เชฐเชตเชพ เชฎเชพเชŸเซ‡, เชฎเซ‹เชŸเชพเชญเชพเช—เชจเชพ เชธเชฎเชœเชฆเชพเชฐ เชฒเซ‹เช•เซ‹เชจเซ€ เชชเซเชฐเชฅเชฎ เช‡เชšเซเช›เชพ SQL เชกเซ‡เชŸเชพเชฌเซ‡เช เชชเชธเช‚เชฆ เช•เชฐเชตเชพเชจเซ€ เชนเชถเซ‡. 

เชชเชฐเช‚เชคเซ เช•เซ‡เชŸเชฒเซ€เช•เชตเชพเชฐ เชฎเชจเชฎเชพเช‚ เชตเชฟเชšเชพเชฐ เช†เชตเซ‡ เช›เซ‡ เช•เซ‡ เชกเซ‡เชŸเชพ เชฎเซ‹เชกเซ‡เชฒ SQL เชฎเชพเชŸเซ‡ เชฏเซ‹เช—เซเชฏ เชจเชฅเซ€: เช‰เชฆเชพเชนเชฐเชฃ เชคเชฐเซ€เช•เซ‡, เชถเซ‹เชง เช…เชฅเชตเชพ เชธเชพเชฎเชพเชœเชฟเช• เช—เซเชฐเชพเชซ เชฌเชจเชพเชตเชคเซ€ เชตเช–เชคเซ‡, เชคเชฎเชพเชฐเซ‡ เช‘เชฌเซเชœเซ‡เช•เซเชŸเซเชธ เชตเชšเซเชšเซ‡เชจเชพ เชœเชŸเชฟเชฒ เชธเช‚เชฌเช‚เชงเซ‹ เชถเซ‹เชงเชตเชพเชจเซ€ เชœเชฐเซ‚เชฐ เช›เซ‡. 

เชธเซŒเชฅเซ€ เช–เชฐเชพเชฌ เชชเชฐเชฟเชธเซเชฅเชฟเชคเชฟ เช เช›เซ‡ เช•เซ‡ เชœเซเชฏเชพเชฐเซ‡ เชคเชฎเซ‡ เชŸเซ€เชฎเชฎเชพเช‚ เช•เชพเชฎ เช•เชฐเซ‹ เช›เซ‹ เช…เชจเซ‡ เชธเชพเชฅเซ€เชฆเชพเชฐเชจเซ‡ เช–เชฌเชฐ เชจเชฅเซ€ เชนเซ‹เชคเซ€ เช•เซ‡ เชเชกเชชเซ€ เชชเซเชฐเชถเซเชจเซ‹ เช•เซ‡เชตเซ€ เชฐเซ€เชคเซ‡ เชฌเชจเชพเชตเชตเซเช‚. เชคเชฎเซ‡ N+1 เชธเชฎเชธเซเชฏเชพเช“ เช‰เช•เซ‡เชฒเชตเชพเชฎเชพเช‚ เช…เชจเซ‡ เชตเชงเชพเชฐเชพเชจเชพ เช…เชจเซเช•เซเชฐเชฎเชฃเชฟเช•เชพเช“ เชฌเชจเชพเชตเชตเชพเชฎเชพเช‚ เช•เซ‡เชŸเชฒเซ‹ เชธเชฎเชฏ เชชเชธเชพเชฐ เช•เชฐเซเชฏเซ‹ เชนเชคเซ‹ เชœเซ‡เชฅเซ€ เชฎเซเช–เซเชฏ เชชเซƒเชทเซเช  เชชเชฐเชจเซเช‚ SELECT เชฏเซ‹เช—เซเชฏ เชธเชฎเชฏเชฎเชพเช‚ เชชเซ‚เชฐเซเชฃ เชฅเชพเชฏ?

เช…เชจเซเชฏ เชฒเซ‹เช•เชชเซเชฐเชฟเชฏ เช…เชญเชฟเช—เชฎ NoSQL เช›เซ‡. เช•เซ‡เชŸเชฒเชพเช‚เช• เชตเชฐเซเชทเซ‹ เชชเชนเซ‡เชฒเชพ เช† เชตเชฟเชทเชฏเชจเซ€ เช†เชธเชชเชพเชธ เช˜เชฃเซ‹ เชนเชพเช‡เชช เชนเชคเซ‹ - เช•เซ‹เชˆเชชเชฃ เช…เชจเซเช•เซ‚เชณ เชชเซเชฐเชธเช‚เช— เชฎเชพเชŸเซ‡ เชคเซ‡เช“เช เชฎเซ‹เช‚เช—เซ‹เชกเซ€เชฌเซ€เชจเซ‹ เช‰เชชเชฏเซ‹เช— เช•เชฐเซเชฏเซ‹ เชนเชคเซ‹ เช…เชจเซ‡ เชœเซ‡เชธเชจ เชฆเชธเซเชคเชพเชตเซ‡เชœเซ‹เชจเชพ เชฐเซ‚เชชเชฎเชพเช‚ เชœเชตเชพเชฌเซ‹เชฅเซ€ เช–เซเชถ เชนเชคเชพ. (เชฌเชพเชฏ เชง เชตเซ‡, เชกเซ‹เช•เซเชฏเซเชฎเซ‡เชจเซเชŸเซเชธเชฎเชพเช‚ เช—เซ‹เชณเชพเช•เชพเชฐ เชฒเชฟเช‚เช•เซเชธเชจเซ‡ เช•เชพเชฐเชฃเซ‡ เชคเชฎเชพเชฐเซ‡ เช•เซ‡เชŸเชฒเซ€ เช•เซเชฐเซ‰เชš เชฆเชพเช–เชฒ เช•เชฐเชตเซ€ เชชเชกเซ€?).

เชนเซเช‚ เชฌเซ€เชœเซ€, เชตเซˆเช•เชฒเซเชชเชฟเช• เชชเชฆเซเชงเชคเชฟ เช…เชœเชฎเชพเชตเชตเชพเชจเซเช‚ เชธเซ‚เชšเชจ เช•เชฐเซเช‚ เช›เซเช‚ - เชถเชพ เชฎเชพเชŸเซ‡ เชเชชเซเชฒเชฟเช•เซ‡เชถเชจ เชฎเซ‡เชฎเชฐเซ€เชฎเชพเช‚ เชคเชฎเชพเชฎ เชกเซ‡เชŸเชพเชจเซ‡ เชธเช‚เช—เซเชฐเชนเชฟเชค เช•เชฐเชตเชพเชจเซ‹ เชชเซเชฐเชฏเชพเชธ เชจ เช•เชฐเซ‹, เชธเชฎเชฏเชพเช‚เชคเชฐเซ‡ เชคเซ‡เชจเซ‡ เชฐเซ‡เชจเซเชกเชฎ เชธเซเชŸเซ‹เชฐเซ‡เชœ (เชซเชพเช‡เชฒ, เชฐเชฟเชฎเซ‹เชŸ เชกเซ‡เชŸเชพเชฌเซ‡เช) เชชเชฐ เชธเชพเชšเชตเซ‹? 

เชฎเซ‡เชฎเชฐเซ€ เชธเชธเซเชคเซ€ เชฅเชˆ เช—เชˆ เช›เซ‡, เช…เชจเซ‡ เชฎเซ‹เชŸเชพเชญเชพเช—เชจเชพ เชจเชพเชจเชพ เช…เชจเซ‡ เชฎเชงเซเชฏเชฎ เช•เชฆเชจเชพ เชชเซเชฐเซ‹เชœเซ‡เช•เซเชŸเซเชธ เชฎเชพเชŸเซ‡ เช•เซ‹เชˆเชชเชฃ เชธเช‚เชญเชตเชฟเชค เชกเซ‡เชŸเชพ 1 GB เชฎเซ‡เชฎเชฐเซ€เชฎเชพเช‚ เชซเชฟเชŸ เชฅเชถเซ‡. (เช‰เชฆเชพเชนเชฐเชฃ เชคเชฐเซ€เช•เซ‡, เชฎเชพเชฐเซ‹ เชชเซเชฐเชฟเชฏ เชนเซ‹เชฎ เชชเซเชฐเซ‹เชœเซ‡เช•เซเชŸ เช›เซ‡ เชจเชพเชฃเชพเช•เซ€เชฏ เชŸเซเชฐเซ‡เช•เชฐ, เชœเซ‡ เชฆเซ‹เชข เชตเชฐเซเชท เชธเซเชงเซ€ เชฎเชพเชฐเชพ เช–เชฐเซเชšเชพเช“, เชฌเซ‡เชฒเซ‡เชจเซเชธ เช…เชจเซ‡ เชตเซเชฏเชตเชนเชพเชฐเซ‹เชจเชพ เชฆเซˆเชจเชฟเช• เช†เช‚เช•เชกเชพ เช…เชจเซ‡ เช‡เชคเชฟเชนเชพเชธ เชฐเชพเช–เซ‡ เช›เซ‡, เชคเซ‡ เชฎเชพเชคเซเชฐ 45 MB เชฎเซ‡เชฎเชฐเซ€ เชตเชพเชชเชฐเซ‡ เช›เซ‡.)

เช—เซเชฃ:

  • เชกเซ‡เชŸเชพเชจเซ€ เชเช•เซเชธเซ‡เชธ เชธเชฐเชณ เชฌเชจเซ‡ เช›เซ‡ - เชคเชฎเชพเชฐเซ‡ เชชเซเชฐเชถเซเชจเซ‹, เช†เชณเชธเซ เชฒเซ‹เชกเชฟเช‚เช—, ORM เชธเซเชตเชฟเชงเชพเช“ เชตเชฟเชถเซ‡ เชšเชฟเช‚เชคเชพ เช•เชฐเชตเชพเชจเซ€ เชœเชฐเซ‚เชฐ เชจเชฅเซ€, เชคเชฎเซ‡ เชธเชพเชฎเชพเชจเซเชฏ C# เช‘เชฌเซเชœเซ‡เช•เซเชŸเซเชธ เชธเชพเชฅเซ‡ เช•เชพเชฎ เช•เชฐเซ‹ เช›เซ‹;
  • เชตเชฟเชตเชฟเชง เชฅเซเชฐเซ‡เชกเซ‹เชจเซ€ เชเช•เซเชธเซ‡เชธ เชธเชพเชฅเซ‡ เชธเช‚เช•เชณเชพเชฏเซ‡เชฒเซ€ เช•เซ‹เชˆ เชธเชฎเชธเซเชฏเชพ เชจเชฅเซ€;
  • เช–เซ‚เชฌ เชœ เชเชกเชชเซ€ - เช•เซ‹เชˆ เชจเซ‡เชŸเชตเชฐเซเช• เชตเชฟเชจเช‚เชคเซ€เช“ เชจเชนเซ€เช‚, เช•เซเชตเซ‡เชฐเซ€ เชญเชพเชทเชพเชฎเชพเช‚ เช•เซ‹เชกเชจเซเช‚ เช•เซ‹เชˆ เชญเชพเชทเชพเช‚เชคเชฐ เชจเชนเซ€เช‚, เช‘เชฌเซเชœเซ‡เช•เซเชŸเชจเชพ (de)เช•เซเชฐเชฎเซ€เช•เชฐเชฃเชจเซ€ เชœเชฐเซ‚เชฐ เชจเชฅเซ€;
  • เชคเซ‡ เช•เซ‹เชˆเชชเชฃ เชธเซเชตเชฐเซ‚เชชเชฎเชพเช‚ เชกเซ‡เชŸเชพ เชธเช‚เช—เซเชฐเชนเชฟเชค เช•เชฐเชตเชพ เชฎเชพเชŸเซ‡ เชธเซเชตเซ€เช•เชพเชฐเซเชฏ เช›เซ‡ - เชคเซ‡ เชกเชฟเชธเซเช• เชชเชฐ XMLเชฎเชพเช‚ เชนเซ‹เชฏ, เช…เชฅเชตเชพ SQL เชธเชฐเซเชตเชฐเชฎเชพเช‚ เชนเซ‹เชฏ, เช…เชฅเชตเชพ Azure เชŸเซ‡เชฌเชฒ เชธเซเชŸเซ‹เชฐเซ‡เชœเชฎเชพเช‚ เชนเซ‹เชฏ.

เชตเชฟเชชเช•เซเชท:

  • เช†เชกเซเช‚ เชธเซเช•เซ‡เชฒเชฟเช‚เช— เช–เซ‹เชตเชพเชˆ เช—เชฏเซเช‚ เช›เซ‡, เช…เชจเซ‡ เชชเชฐเชฟเชฃเชพเชฎเซ‡, เชถเซ‚เชจเซเชฏ เชกเชพเช‰เชจเชŸเชพเช‡เชฎ เชœเชฎเชพเชตเชŸ เช•เชฐเซ€ เชถเช•เชพเชคเซ€ เชจเชฅเซ€;
  • เชœเซ‹ เชเชชเซเชฒเชฟเช•เซ‡เชถเชจ เช•เซเชฐเซ‡เชถ เชฅเชพเชฏ เช›เซ‡, เชคเซ‹ เชคเชฎเซ‡ เช†เช‚เชถเชฟเช• เชฐเซ€เชคเซ‡ เชกเซ‡เชŸเชพ เช—เซเชฎเชพเชตเซ€ เชถเช•เซ‹ เช›เซ‹. (เชชเชฐเช‚เชคเซ เช…เชฎเชพเชฐเซ€ เชเชชเซเชฒเชฟเช•เซ‡เชถเชจ เช•เซเชฏเชพเชฐเซ‡เชฏ เช•เซเชฐเซ‡เชถ เชฅเชคเซ€ เชจเชฅเซ€, เชฌเชฐเชพเชฌเชฐ?)

เชคเซ‡ เช•เซ‡เชตเซ€ เชฐเซ€เชคเซ‡ เช•เชพเชฎ เช•เชฐเซ‡ เช›เซ‡?

เช…เชฒเซเช—เซ‹เชฐเชฟเชงเชฎ เชจเซ€เชšเซ‡ เชฎเซเชœเชฌ เช›เซ‡:

  • เชถเชฐเซ‚เช†เชคเชฎเชพเช‚, เชกเซ‡เชŸเชพ เชธเซเชŸเซ‹เชฐเซ‡เชœ เชธเชพเชฅเซ‡ เช•เชจเซ‡เช•เซเชถเชจ เชธเซเชฅเชพเชชเชฟเชค เชฅเชพเชฏ เช›เซ‡, เช…เชจเซ‡ เชกเซ‡เชŸเชพ เชฒเซ‹เชก เชฅเชพเชฏ เช›เซ‡;
  • เช‘เชฌเซเชœเซ‡เช•เซเชŸ เชฎเซ‰เชกเชฒ, เชชเซเชฐเชพเชฅเชฎเชฟเช• เช…เชจเซเช•เซเชฐเชฎเชฃเชฟเช•เชพเช“ เช…เชจเซ‡ เชฐเชฟเชฒเซ‡เชถเชจเชฒ เช‡เชจเซเชกเซ‡เช•เซเชธ (1:1, 1:เช˜เชฃเชพ) เชฌเชจเซ‡เชฒ เช›เซ‡;
  • เช‘เชฌเซเชœเซ‡เช•เซเชŸ เชชเซเชฐเซ‹เชชเชฐเซเชŸเซ€เช (INotifyPropertyChanged) เชฎเชพเช‚ เชซเซ‡เชฐเชซเชพเชฐเซ‹ เชฎเชพเชŸเซ‡ เช…เชจเซ‡ เชธเช‚เช—เซเชฐเชน (INotifyCollectionChanged) เชฎเชพเช‚ เช˜เชŸเช•เซ‹ เช‰เชฎเซ‡เชฐเชตเชพ เช…เชฅเชตเชพ เชฆเซ‚เชฐ เช•เชฐเชตเชพ เชฎเชพเชŸเซ‡ เชธเชฌเชธเซเช•เซเชฐเชฟเชชเซเชถเชจ เชฌเชจเชพเชตเชตเชพเชฎเชพเช‚ เช†เชตเซ‡ เช›เซ‡;
  • เชœเซเชฏเชพเชฐเซ‡ เชธเชฌเซเชธเซเช•เซเชฐเชฟเชชเซเชถเชจ เชŸเซเชฐเชฟเช—เชฐ เชฅเชพเชฏ เช›เซ‡, เชคเซเชฏเชพเชฐเซ‡ เชกเซ‡เชŸเชพ เชธเซเชŸเซ‹เชฐเซ‡เชœ เชชเชฐ เชฒเช–เชตเชพ เชฎเชพเชŸเซ‡ เชฌเชฆเชฒเชพเชฏเซ‡เชฒ เช‘เชฌเซเชœเซ‡เช•เซเชŸ เช•เชคเชพเชฐเชฎเชพเช‚ เช‰เชฎเซ‡เชฐเชตเชพเชฎเชพเช‚ เช†เชตเซ‡ เช›เซ‡;
  • เชธเซเชŸเซ‹เชฐเซ‡เชœเชฎเชพเช‚ เชซเซ‡เชฐเชซเชพเชฐเซ‹ เชธเชฎเชฏเชพเช‚เชคเชฐเซ‡ (เชŸเชพเชˆเชฎเชฐ เชชเชฐ) เชชเซƒเชทเซเช เชญเซ‚เชฎเชฟ เชฅเซเชฐเซ‡เชกเชฎเชพเช‚ เชธเชพเชšเชตเชตเชพเชฎเชพเช‚ เช†เชตเซ‡ เช›เซ‡;
  • เชœเซเชฏเชพเชฐเซ‡ เชคเชฎเซ‡ เชเชชเซเชฒเชฟเช•เซ‡เชถเชจเชฎเชพเช‚เชฅเซ€ เชฌเชนเชพเชฐ เชจเซ€เช•เชณเซ‹ เช›เซ‹, เชคเซเชฏเชพเชฐเซ‡ เชซเซ‡เชฐเชซเชพเชฐเซ‹ เชธเซเชŸเซ‹เชฐเซ‡เชœเชฎเชพเช‚ เชชเชฃ เชธเชพเชšเชตเชตเชพเชฎเชพเช‚ เช†เชตเซ‡ เช›เซ‡.

เช•เซ‹เชก เช‰เชฆเชพเชนเชฐเชฃ

เชœเชฐเซ‚เชฐเซ€ เชจเชฟเชฐเซเชญเชฐเชคเชพ เช‰เชฎเซ‡เชฐเซ€ เชฐเชนเซเชฏเชพ เช›เซ‡

// ะžัะฝะพะฒะฝะฐั ะฑะธะฑะปะธะพั‚ะตะบะฐ
Install-Package OutCode.EscapeTeams.ObjectRepository
    
// ะฅั€ะฐะฝะธะปะธั‰ะต ะดะฐะฝะฝั‹ั…, ะฒ ะบะพั‚ะพั€ะพะผ ะฑัƒะดัƒั‚ ัะพั…ั€ะฐะฝัั‚ัŒัั ะธะทะผะตะฝะตะฝะธั
// ะ˜ัะฟะพะปัŒะทัƒะนั‚ะต ั‚ะพ, ะบะพั‚ะพั€ั‹ะผ ะฑัƒะดะตั‚ะต ะฟะพะปัŒะทะพะฒะฐั‚ัŒัั.
Install-Package OutCode.EscapeTeams.ObjectRepository.File
Install-Package OutCode.EscapeTeams.ObjectRepository.LiteDb
Install-Package OutCode.EscapeTeams.ObjectRepository.AzureTableStorage
    
// ะžะฟั†ะธะพะฝะฐะปัŒะฝะพ - ะตัะปะธ ะฝัƒะถะฝะพ ั…ั€ะฐะฝะธั‚ัŒ ะผะพะดะตะปัŒ ะดะฐะฝะฝั‹ั… ะดะปั Hangfire
// Install-Package OutCode.EscapeTeams.ObjectRepository.Hangfire

เช…เชฎเซ‡ เชกเซ‡เชŸเชพ เชฎเซ‹เชกเซ‡เชฒเชจเซเช‚ เชตเชฐเซเชฃเชจ เช•เชฐเซ€เช เช›เซ€เช เชœเซ‡ เชธเซเชŸเซ‹เชฐเซ‡เชœเชฎเชพเช‚ เชธเช‚เช—เซเชฐเชนเชฟเชค เชฅเชถเซ‡

public class ParentEntity : BaseEntity
{
    public ParentEntity(Guid id) => Id = id;
}
    
public class ChildEntity : BaseEntity
{
    public ChildEntity(Guid id) => Id = id;
    public Guid ParentId { get; set; }
    public string Value { get; set; }
}

เชชเช›เซ€ เช‘เชฌเซเชœเซ‡เช•เซเชŸ เชฎเซ‹เชกเซ‡เชฒ:

public class ParentModel : ModelBase
{
    public ParentModel(ParentEntity entity)
    {
        Entity = entity;
    }
    
    public ParentModel()
    {
        Entity = new ParentEntity(Guid.NewGuid());
    }
    
    public Guid? NullableId => null;
    
    // ะŸั€ะธะผะตั€ ัะฒัะทะธ 1:Many
    public IEnumerable<ChildModel> Children => Multiple<ChildModel>(x => x.ParentId);
    
    protected override BaseEntity Entity { get; }
}
    
public class ChildModel : ModelBase
{
    private ChildEntity _childEntity;
    
    public ChildModel(ChildEntity entity)
    {
        _childEntity = entity;
    }
    
    public ChildModel() 
    {
        _childEntity = new ChildEntity(Guid.NewGuid());
    }
    
    public Guid ParentId
    {
        get => _childEntity.ParentId;
        set => UpdateProperty(() => _childEntity.ParentId, value);
    }
    
    public string Value
    {
        get => _childEntity.Value;
        set => UpdateProperty(() => _childEntity.Value, value
    }
    
    // ะ”ะพัั‚ัƒะฟ ั ะฟะพะธัะบะพะผ ะฟะพ ะธะฝะดะตะบััƒ
    public ParentModel Parent => Single<ParentModel>(ParentId);
    
    protected override BaseEntity Entity => _childEntity;
}

เช…เชจเซ‡ เช›เซ‡เชฒเซเชฒเซ‡, เชกเซ‡เชŸเชพ เชเช•เซเชธเซ‡เชธ เช•เชฐเชตเชพ เชฎเชพเชŸเซ‡ เชฐเซ€เชชเซ‹เชเซ€เชŸเชฐเซ€ เช•เซเชฒเชพเชธ เชชเซ‹เชคเซ‡:

public class MyObjectRepository : ObjectRepositoryBase
{
    public MyObjectRepository(IStorage storage) : base(storage, NullLogger.Instance)
    {
        IsReadOnly = true; // ะ”ะปั ั‚ะตัั‚ะพะฒ, ะฟะพะทะฒะพะปัะตั‚ ะฝะต ัะพั…ั€ะฐะฝัั‚ัŒ ะธะทะผะตะฝะตะฝะธั ะฒ ะฑะฐะทัƒ
    
        AddType((ParentEntity x) => new ParentModel(x));
        AddType((ChildEntity x) => new ChildModel(x));
    
        // ะ•ัะปะธ ะธัะฟะพะปัŒะทัƒะตั‚ัั Hangfire ะธ ะฝะตะพะฑั…ะพะดะธะผะพ ั…ั€ะฐะฝะธั‚ัŒ ะผะพะดะตะปัŒ ะดะฐะฝะฝั‹ั… ะดะปั Hangfire ะฒ ObjectRepository
        // this.RegisterHangfireScheme(); 
    
        Initialize();
    }
}

เชเช• ObjectRepository เช‰เชฆเชพเชนเชฐเชฃ เชฌเชจเชพเชตเซ‹:

var memory = new MemoryStream();
var db = new LiteDatabase(memory);
var dbStorage = new LiteDbStorage(db);
    
var repository = new MyObjectRepository(dbStorage);
await repository.WaitForInitialize();

เชœเซ‹ เชชเซเชฐเซ‹เชœเซ‡เช•เซเชŸ เชนเซ‡เช‚เช—เชซเชพเชฏเชฐเชจเซ‹ เช‰เชชเชฏเซ‹เช— เช•เชฐเชถเซ‡

public void ConfigureServices(IServiceCollection services, ObjectRepository objectRepository)
{
    services.AddHangfire(s => s.UseHangfireStorage(objectRepository));
}

เชจเชตเซ‹ เช‘เชฌเซเชœเซ‡เช•เซเชŸ เชฆเชพเช–เชฒ เช•เชฐเชตเซเช‚:

var newParent = new ParentModel()
repository.Add(newParent);

เช† เช•เซ‹เชฒ เชธเชพเชฅเซ‡, เชชเชฆเชพเชฐเซเชฅ เชชเซ‡เชฐเชจเซเชŸ เชฎเซ‹เชกเชฒ เชกเซ‡เชŸเชพเชฌเซ‡เชเชฎเชพเช‚ เชฒเช–เชตเชพ เชฎเชพเชŸเซ‡ เชธเซเชฅเชพเชจเชฟเช• เช•เซ‡เชถ เช…เชจเซ‡ เช•เชคเชพเชฐ เชฌเช‚เชจเซ‡เชฎเชพเช‚ เช‰เชฎเซ‡เชฐเชตเชพเชฎเชพเช‚ เช†เชตเซ‡ เช›เซ‡. เชคเซ‡เชฅเซ€, เช† เช‘เชชเชฐเซ‡เชถเชจ O(1) เชฒเซ‡ เช›เซ‡, เช…เชจเซ‡ เช† เช‘เชฌเซเชœเซ‡เช•เซเชŸ เชธเชพเชฅเซ‡ เชคเชฐเชค เชœ เช•เชพเชฎ เช•เชฐเซ€ เชถเช•เชพเชฏ เช›เซ‡.

เช‰เชฆเชพเชนเชฐเชฃ เชคเชฐเซ€เช•เซ‡, เชฐเซ€เชชเซ‹เชเซ€เชŸเชฐเซ€เชฎเชพเช‚ เช† เช‘เชฌเซเชœเซ‡เช•เซเชŸ เชถเซ‹เชงเชตเชพ เช…เชจเซ‡ เชšเช•เชพเชธเชตเชพ เชฎเชพเชŸเซ‡ เช•เซ‡ เชชเชฐเชค เช•เชฐเซ‡เชฒ เช‘เชฌเซเชœเซ‡เช•เซเชŸ เช เชœ เช‰เชฆเชพเชนเชฐเชฃ เช›เซ‡:

var parents = repository.Set<ParentModel>();
var myParent = parents.Find(newParent.Id);
Assert.IsTrue(ReferenceEquals(myParent, newParent));

เชถเซเช‚ เชฅเชฏเซเช‚? เชธเซ‡เชŸ () เชชเชฐเชค เช•เชฐเซ‡ เช›เซ‡ เช•เซ‹เชทเซเชŸเช• เชถเชฌเซเชฆเช•เซ‹เชถ, เชœเซ‡เชฎเชพเช‚ เชธเชฎเชพเชตเซ‡ เช›เซ‡ เชธเชฎเชตเชฐเซเชคเซ€ เชถเชฌเซเชฆเช•เซ‹เชถ เช…เชจเซ‡ เชชเซเชฐเชพเชฅเชฎเชฟเช• เช…เชจเซ‡ เช—เซŒเชฃ เช…เชจเซเช•เซเชฐเชฎเชฃเชฟเช•เชพเช“เชจเซ€ เชตเชงเชพเชฐเชพเชจเซ€ เช•เชพเชฐเซเชฏเช•เซเชทเชฎเชคเชพ เชชเซเชฐเชฆเชพเชจ เช•เชฐเซ‡ เช›เซ‡. เช† เชคเชฎเชจเซ‡ เชคเชฎเชพเชฎ เช‘เชฌเซเชœเซ‡เช•เซเชŸเซเชธ เชชเชฐ เชธเช‚เชชเซ‚เชฐเซเชฃเชชเชฃเซ‡ เชชเซเชจเชฐเชพเชตเชฐเซเชคเชจ เช•เชฐเซเชฏเชพ เชตเชฟเชจเชพ Id (เช…เชฅเชตเชพ เช…เชจเซเชฏ เชฎเชจเชธเซเชตเซ€ เชตเชชเชฐเชพเชถเช•เชฐเซเชคเชพ เช…เชจเซเช•เซเชฐเชฎเชฃเชฟเช•เชพเช“) เชฆเซเชตเชพเชฐเชพ เชถเซ‹เชงเชตเชพ เชฎเชพเชŸเซ‡เชจเซ€ เชชเชฆเซเชงเชคเชฟเช“เชจเซ€ เชฎเช‚เชœเซ‚เชฐเซ€ เช†เชชเซ‡ เช›เซ‡.

เชœเซเชฏเชพเชฐเซ‡ เชตเชธเซเชคเซเช“ เช‰เชฎเซ‡เชฐเซ€ เชฐเชนเซเชฏเชพ เชนเซ‹เชฏ ObjectRepository เชคเซ‡เชฎเชจเซ€ เชชเซเชฐเซ‹เชชเชฐเซเชŸเซ€เช เชฌเชฆเชฒเชตเชพ เชฎเชพเชŸเซ‡ เชธเชฌเชธเซเช•เซเชฐเชฟเชชเซเชถเชจ เช‰เชฎเซ‡เชฐเชตเชพเชฎเชพเช‚ เช†เชตเซ‡ เช›เซ‡, เชคเซ‡เชฅเซ€ เชชเซเชฐเซ‹เชชเชฐเซเชŸเซ€เชฎเชพเช‚ เช•เซ‹เชˆเชชเชฃ เชซเซ‡เชฐเชซเชพเชฐ เชชเชฃ เช† เช‘เชฌเซเชœเซ‡เช•เซเชŸเชจเซ‡ เชฐเชพเชˆเชŸ เช•เชคเชพเชฐเชฎเชพเช‚ เช‰เชฎเซ‡เชฐเชตเชพเชฎเชพเช‚ เชชเชฐเชฟเชฃเชฎเซ‡ เช›เซ‡. 
เชฌเชนเชพเชฐเชฅเซ€ เชชเซเชฐเซ‹เชชเชฐเซเชŸเซ€เช เช…เชชเชกเซ‡เชŸ เช•เชฐเชตเซ€ เช POCO เช‘เชฌเซเชœเซ‡เช•เซเชŸ เชธเชพเชฅเซ‡ เช•เชพเชฎ เช•เชฐเชตเชพ เชœเซ‡เชตเซเช‚ เชœ เชฒเชพเช—เซ‡ เช›เซ‡:

myParent.Children.First().Property = "Updated value";

เชคเชฎเซ‡ เชจเซ€เชšเซ‡เชจเซ€ เชฐเซ€เชคเซ‡ เช‘เชฌเซเชœเซ‡เช•เซเชŸ เช•เชพเชขเซ€ เชถเช•เซ‹ เช›เซ‹:

repository.Remove(myParent);
repository.RemoveRange(otherParents);
repository.Remove<ParentModel>(x => !x.Children.Any());

เช† เช‘เชฌเซเชœเซ‡เช•เซเชŸเชจเซ‡ เช•เชพเชขเซ€ เชจเชพเช–เชตเชพเชจเซ€ เช•เชคเชพเชฐเชฎเชพเช‚ เชชเชฃ เช‰เชฎเซ‡เชฐเซ‡ เช›เซ‡.

เชฌเชšเชค เช•เซ‡เชตเซ€ เชฐเซ€เชคเซ‡ เช•เชพเชฎ เช•เชฐเซ‡ เช›เซ‡?

ObjectRepository เชœเซเชฏเชพเชฐเซ‡ เชฎเซ‹เชจเชฟเชŸเชฐ เช•เชฐเซ‡เชฒ เช‘เชฌเซเชœเซ‡เช•เซเชŸเซเชธ เชฌเชฆเชฒเชพเชฏ เช›เซ‡ (เช•เซเชฏเชพเช‚ เชคเซ‹ เช‰เชฎเซ‡เชฐเชตเซเช‚ เช…เชฅเชตเชพ เช•เชพเชขเซ€ เชจเชพเช–เชตเซเช‚, เช…เชฅเชตเชพ เช—เซเชฃเชงเชฐเซเชฎเซ‹ เชฌเชฆเชฒเชตเซเช‚), เช˜เชŸเชจเชพ เชŠเชญเซ€ เช•เชฐเซ‡ เช›เซ‡ เชฎเซ‹เชกเชฒ เชฌเชฆเชฒเชพเชฏเซ‡เชฒเชชเชฐ เชธเชฌเซเชธเซเช•เซเชฐเชพเช‡เชฌ เช•เชฐเซเชฏเซเช‚ ISstorage. เช…เชฎเชฒเซ€เช•เชฐเชฃเซ‹ ISstorage เชœเซเชฏเชพเชฐเซ‡ เช•เซ‹เชˆ เช˜เชŸเชจเชพ เชฌเชจเซ‡ เช›เซ‡ เชฎเซ‹เชกเชฒ เชฌเชฆเชฒเชพเชฏเซ‡เชฒ เชซเซ‡เชฐเชซเชพเชฐเซ‹เชจเซ‡ 3 เช•เชคเชพเชฐเซ‹เชฎเชพเช‚ เชฎเซ‚เช•เชตเชพเชฎเชพเช‚ เช†เชตเซ‡ เช›เซ‡ - เช‰เชฎเซ‡เชฐเชตเชพ เชฎเชพเชŸเซ‡, เช…เชชเชกเซ‡เชŸ เช•เชฐเชตเชพ เชฎเชพเชŸเซ‡ เช…เชจเซ‡ เช•เชพเชขเซ€ เชจเชพเช–เชตเชพ เชฎเชพเชŸเซ‡.

เช…เชฎเชฒเซ€เช•เชฐเชฃเซ‹ เชชเชฃ ISstorage เช†เชฐเช‚เชญ เชชเชฐ, เชคเซ‡เช“ เชเช• เชŸเชพเชˆเชฎเชฐ เชฌเชจเชพเชตเซ‡ เช›เซ‡ เชœเซ‡เชจเชพ เช•เชพเชฐเชฃเซ‡ เชฆเชฐ 5 เชธเซ‡เช•เชจเซเชกเซ‡ เชซเซ‡เชฐเชซเชพเชฐเซ‹ เชธเชพเชšเชตเชตเชพเชฎเชพเช‚ เช†เชตเซ‡ เช›เซ‡. 

เชตเชงเซเชฎเชพเช‚, เชธเซ‡เชต เช•เซ‰เชฒเชจเซ‡ เชฆเชฌเชพเชฃ เช•เชฐเชตเชพ เชฎเชพเชŸเซ‡ เชเช• API เช›เซ‡: ObjectRepository.Save().

เชฆเชฐเซ‡เช• เชธเซ‡เชต เชชเชนเซ‡เชฒเชพเช‚, เช…เชฐเซเชฅเชนเซ€เชจ เช‘เชชเชฐเซ‡เชถเชจเซเชธ เช•เชคเชพเชฐเชฎเชพเช‚เชฅเซ€ เชชเซเชฐเชฅเชฎ เชฆเซ‚เชฐ เช•เชฐเชตเชพเชฎเชพเช‚ เช†เชตเซ‡ เช›เซ‡ (เช‰เชฆเชพเชนเชฐเชฃ เชคเชฐเซ€เช•เซ‡, เชกเซเชชเซเชฒเชฟเช•เซ‡เชŸ เช‡เชตเซ‡เชจเซเชŸเซเชธ - เชœเซเชฏเชพเชฐเซ‡ เช‘เชฌเซเชœเซ‡เช•เซเชŸ เชฌเซ‡ เชตเชพเชฐ เชฌเชฆเชฒเชตเชพเชฎเชพเช‚ เช†เชตเซเชฏเซ‹ เชนเชคเซ‹ เช…เชฅเชตเชพ เช‘เชฌเซเชœเซ‡เช•เซเชŸเชจเซ‡ เชเชกเชชเชฅเซ€ เช‰เชฎเซ‡เชฐเชตเชพ/เชฆเซ‚เชฐ เช•เชฐเชตเชพเชฎเชพเช‚ เช†เชตเซเชฏเซ‹ เชนเชคเซ‹), เช…เชจเซ‡ เชฎเชพเชคเซเชฐ เชคเซเชฏเชพเชฐเซ‡ เชœ เชธเชพเชšเชตเซ‹. 

เชคเชฎเชพเชฎ เช•เซ‡เชธเซ‹เชฎเชพเช‚, เชธเชฎเช—เซเชฐ เชตเชฐเซเชคเชฎเชพเชจ เช‘เชฌเซเชœเซ‡เช•เซเชŸ เชธเชพเชšเชตเชตเชพเชฎเชพเช‚ เช†เชตเซ‡ เช›เซ‡, เชคเซ‡เชฅเซ€ เชถเช•เซเชฏ เช›เซ‡ เช•เซ‡ เช‘เชฌเซเชœเซ‡เช•เซเชŸเชจเซ‡ เช•เชคเชพเชฐเชฎเชพเช‚ เช‰เชฎเซ‡เชฐเชตเชพเชฎเชพเช‚ เช†เชตเซเชฏเชพ เชนเชคเชพ เชคเซ‡เชจเชพ เช•เชฐเชคเชพเช‚ เช‘เชฌเซเชœเซ‡เช•เซเชŸเชจเชพ เชจเชตเชพ เชธเช‚เชธเซเช•เชฐเชฃเซ‹ เชธเชนเชฟเชค, เชคเซ‡เช“ เชฌเชฆเชฒเชพเชฏเชพ เชนเชคเชพ เชคเซ‡เชจเชพ เช•เชฐเชคเชพเช‚ เช…เชฒเช— เช•เซเชฐเชฎเชฎเชพเช‚ เชธเชพเชšเชตเชตเชพเชฎเชพเช‚ เช†เชตเซ‡ เช›เซ‡.

เชฌเซ€เชœเซเช‚ เชถเซเช‚ เช›เซ‡?

  • เชคเชฎเชพเชฎ เชชเซเชธเซเชคเช•เชพเชฒเชฏเซ‹ .NET เชงเซ‹เชฐเชฃ 2.0 เชชเชฐ เช†เชงเชพเชฐเชฟเชค เช›เซ‡. เช•เซ‹เชˆเชชเชฃ เช†เชงเซเชจเชฟเช• .NET เชชเซเชฐเซ‹เชœเซ‡เช•เซเชŸเชฎเชพเช‚ เช‰เชชเชฏเซ‹เช— เช•เชฐเซ€ เชถเช•เชพเชฏ เช›เซ‡.
  • API เชฅเซเชฐเซ‡เชก เชธเชฒเชพเชฎเชค เช›เซ‡. เช†เช‚เชคเชฐเชฟเช• เชธเช‚เช—เซเชฐเชนเซ‹ เชชเชฐ เช†เชงเชพเชฐเชฟเชค เช…เชฎเชฒ เช•เชฐเชตเชพเชฎเชพเช‚ เช†เชตเซ‡ เช›เซ‡ เชธเชฎเชตเชฐเซเชคเซ€ เชถเชฌเซเชฆเช•เซ‹เชถ, เช‡เชตเซ‡เชจเซเชŸ เชนเซ‡เชจเซเชกเชฒเชฐ เชชเชพเชธเซ‡ เช•เชพเช‚ เชคเซ‹ เชคเชพเชณเชพเช“ เชนเซ‹เชฏ เช›เซ‡ เช…เชฅเชตเชพ เชคเซ‡เชฎเชจเซ€ เชœเชฐเซ‚เชฐ เชนเซ‹เชคเซ€ เชจเชฅเซ€. 
    เชฏเชพเชฆ เชฐเชพเช–เชตเชพ เชœเซ‡เชตเซ€ เชตเชธเซเชคเซ เชฎเชพเชคเซเชฐ เช•เซ‰เชฒ เช•เชฐเชตเชพเชจเซ€ เช›เซ‡ ObjectRepository.Save();
  • เชฎเชจเชธเซเชตเซ€ เช…เชจเซเช•เซเชฐเชฎเชฃเชฟเช•เชพเช“ (เชตเชฟเชถเชฟเชทเซเชŸเชคเชพเชจเซ€ เชœเชฐเซ‚เชฐ เช›เซ‡):

repository.Set<ChildModel>().AddIndex(x => x.Value);
repository.Set<ChildModel>().Find(x => x.Value, "myValue");

เชคเซ‡เชจเซ‹ เช‰เชชเชฏเซ‹เช— เช•เซ‹เชฃ เช•เชฐเซ‡ เช›เซ‡?

เชตเซเชฏเช•เซเชคเชฟเช—เชค เชฐเซ€เชคเซ‡, เชฎเซ‡เช‚ เชคเชฎเชพเชฎ เชนเซ‹เชฌเซ€ เชชเซเชฐเซ‹เชœเซ‡เช•เซเชŸเซเชธเชฎเชพเช‚ เช† เช…เชญเชฟเช—เชฎเชจเซ‹ เช‰เชชเชฏเซ‹เช— เช•เชฐเชตเชพเชจเซเช‚ เชถเชฐเซ‚ เช•เชฐเซเชฏเซเช‚ เช•เชพเชฐเชฃ เช•เซ‡ เชคเซ‡ เช…เชจเซเช•เซ‚เชณ เช›เซ‡ เช…เชจเซ‡ เชกเซ‡เชŸเชพ เชเช•เซเชธเซ‡เชธ เชฒเซ‡เชฏเชฐ เชฒเช–เชตเชพ เช…เชฅเชตเชพ เชญเชพเชฐเซ‡ เชˆเชจเซเชซเซเชฐเชพเชธเซเชŸเซเชฐเช•เซเชšเชฐ เชœเชฎเชพเชตเชตเชพ เชฎเชพเชŸเซ‡ เชฎเซ‹เชŸเชพ เช–เชฐเซเชšเชจเซ€ เชœเชฐเซ‚เชฐ เชจเชฅเซ€. เชตเซเชฏเช•เซเชคเชฟเช—เชค เชฐเซ€เชคเซ‡, litedb เช…เชฅเชตเชพ เชซเชพเช‡เชฒเชฎเชพเช‚ เชกเซ‡เชŸเชพ เชธเซเชŸเซ‹เชฐ เช•เชฐเชตเซ‹ เชธเชพเชฎเชพเชจเซเชฏ เชฐเซ€เชคเซ‡ เชฎเชพเชฐเชพ เชฎเชพเชŸเซ‡ เชชเซ‚เชฐเชคเซ‹ เช›เซ‡. 

เชชเชฐเช‚เชคเซ เชญเซ‚เชคเช•เชพเชณเชฎเชพเช‚, เชœเซเชฏเชพเชฐเซ‡ เชนเชตเซ‡ เชจเชฟเชทเซเช•เซเชฐเชฟเชฏ เชธเซเชŸเชพเชฐเซเชŸเช…เชช EscapeTeems (เชฎเซ‡เช‚ เชตเชฟเชšเชพเชฐเซเชฏเซเช‚ เช•เซ‡ เชคเซ‡ เช…เชนเซ€เช‚ เช›เซ‡, เชชเซˆเชธเชพ - เชชเชฃ เชจเชพ, เชซเชฐเซ€เชฅเซ€ เช…เชจเซเชญเชต เช•เชฐเซ‹) - Azure เชŸเซ‡เชฌเชฒ เชธเซเชŸเซ‹เชฐเซ‡เชœเชฎเชพเช‚ เชกเซ‡เชŸเชพ เชธเซเชŸเซ‹เชฐ เช•เชฐเชตเชพ เชฎเชพเชŸเซ‡ เชตเชชเชฐเชพเชฏ เช›เซ‡.

เชญเชตเชฟเชทเซเชฏเชจเซ€ เชฏเซ‹เชœเชจเชพเช“

เชนเซเช‚ เช† เช…เชญเชฟเช—เชฎเชจเชพ เชฎเซเช–เซเชฏ เช—เซ‡เชฐเชซเชพเชฏเชฆเชพเชฎเชพเช‚เชจเชพ เชเช•เชจเซ‡ เช เซ€เช• เช•เชฐเชตเชพ เชฎเชพเช‚เช—เซ เช›เซเช‚ - เช†เชกเซ€ เชธเซเช•เซ‡เชฒเชฟเช‚เช—. เช† เช•เชฐเชตเชพ เชฎเชพเชŸเซ‡, เชคเชฎเชพเชฐเซ‡ เช•เชพเช‚ เชคเซ‹ เชตเชฟเชคเชฐเชฟเชค เชตเซเชฏเชตเชนเชพเชฐเซ‹เชจเซ€ เชœเชฐเซ‚เชฐ เช›เซ‡ (sic!), เช…เชฅเชตเชพ เชฎเชœเชฌเซ‚เชค-เช‡เชšเซเช›เชพเชฅเซ€ เชจเชฟเชฐเซเชฃเชฏ เชฒเซ‡เชตเซ‹ เชœเซ‹เชˆเช เช•เซ‡ เชœเซเชฆเชพ เชœเซเชฆเชพ เชฆเชพเช–เชฒเชพเช“เชฎเชพเช‚เชฅเซ€ เชธเชฎเชพเชจ เชกเซ‡เชŸเชพ เชฌเชฆเชฒเชตเซ‹ เชœเซ‹เชˆเช เชจเชนเซ€เช‚, เช…เชฅเชตเชพ "เช›เซ‡เชฒเซเชฒเซเช‚ เช•เซ‹เชฃ เชธเชพเชšเซเช‚ เช›เซ‡" เชจเชพ เชธเชฟเชฆเซเชงเชพเช‚เชค เช…เชจเซเชธเชพเชฐ เชคเซ‡เชจเซ‡ เชฌเชฆเชฒเชตเชพ เชฆเซ‹.

เชคเช•เชจเซ€เช•เซ€ เชฆเซƒเชทเซเชŸเชฟเช•เซ‹เชฃเชฅเซ€, เชนเซเช‚ เชจเซ€เชšเซ‡เชจเซ€ เชฏเซ‹เชœเชจเชพเชจเซ‡ เชถเช•เซเชฏ เชœเซ‹เช‰เช‚ เช›เซเช‚:

  • เช‘เชฌเซเชœเซ‡เช•เซเชŸ เชฎเซ‰เชกเชฒเชจเซ‡ เชฌเชฆเชฒเซ‡ เช‡เชตเซ‡เชจเซเชŸเชฒเซ‰เช— เช…เชจเซ‡ เชธเซเชจเซ‡เชชเชถเซ‹เชŸ เชธเซเชŸเซ‹เชฐ เช•เชฐเซ‹
  • เช…เชจเซเชฏ เช‰เชฆเชพเชนเชฐเชฃเซ‹ เชถเซ‹เชงเซ‹ (เชธเซ‡เชŸเชฟเช‚เช—เซเชธเชฎเชพเช‚ เชคเชฎเชพเชฎ เช‰เชฆเชพเชนเชฐเชฃเซ‹เชจเชพ เช…เช‚เชคเชฟเชฎ เชฌเชฟเช‚เชฆเซเช“ เช‰เชฎเซ‡เชฐเซ‹? udp เชถเซ‹เชง? เชฎเชพเชธเซเชŸเชฐ/เชธเซเชฒเซ‡เชต?)
  • เช•เซ‹เชˆเชชเชฃ เชธเชฐเซเชตเชธเช‚เชฎเชคเชฟ เช…เชฒเซเช—เซ‹เชฐเชฟเชงเชฎ, เชœเซ‡เชฎ เช•เซ‡ RAFT เชฆเซเชตเชพเชฐเชพ EventLog เช‰เชฆเชพเชนเชฐเชฃเซ‹ เชตเชšเซเชšเซ‡ เชจเช•เชฒ เช•เชฐเซ‹.

เชคเซเชฏเชพเช‚ เชฌเซ€เชœเซ€ เชธเชฎเชธเซเชฏเชพ เชชเชฃ เช›เซ‡ เชœเซ‡ เชฎเชจเซ‡ เชšเชฟเช‚เชคเชพ เช•เชฐเซ‡ เช›เซ‡ - เช•เชพเชธเซเช•เซ‡เชก เช•เชพเชขเซ€ เชจเชพเช–เชตเซเช‚, เช…เชฅเชตเชพ เช…เชจเซเชฏ เช‘เชฌเซเชœเซ‡เช•เซเชŸเซเชธเชฎเชพเช‚เชฅเซ€ เชฒเชฟเช‚เช•เซเชธ เชงเชฐเชพเชตเชคเชพ เช‘เชฌเซเชœเซ‡เช•เซเชŸเซเชธเชจเซ‡ เช•เชพเชขเซ€ เชจเชพเช–เชตเชพเชจเชพ เช•เซ‡เชธเซ‹เชจเซ€ เชถเซ‹เชง. 

เชธเซเชฐเซ‹เชค

เชœเซ‹ เชคเชฎเซ‡ เช…เชนเซ€เช‚ เชธเซเชงเซ€ เช†เช–เซ€ เชฐเซ€เชคเซ‡ เชตเชพเช‚เชšเซ€ เชฒเซ€เชงเซเช‚ เชนเซ‹เชฏ, เชคเซ‹ เชœเซ‡ เชฌเชพเช•เซ€ เช›เซ‡ เชคเซ‡ เช•เซ‹เชก เชตเชพเช‚เชšเชตเชพเชจเซเช‚ เช›เซ‡; เชคเซ‡ GitHub เชชเชฐ เชฎเชณเซ€ เชถเช•เซ‡ เช›เซ‡:
https://github.com/DiverOfDark/ObjectRepository

เชธเซ‹เชฐเซเชธ: www.habr.com

เชเช• เชŸเชฟเชชเซเชชเชฃเซ€ เช‰เชฎเซ‡เชฐเซ‹