ãã®èšäºã§ã¯ã次ã®åé¡ã«ã€ããŠèª¬æããŸãã
- ãµãŒãã¹ã¢ãã«ãžã®åãæ¿ãæã®ã¢ããªã±ãŒã·ã§ã³ã¢ãŒããã¯ãã£ã®éžæã ããæ£ç¢ºã«ã¯ããŠãŒã¶ãŒéã®WebãµãŒããŒãšããŒã¿ããŒã¹ã®ã·ã£ãŒãã£ã³ã°ã
- åçã³ãŒãã®æé©åãããå®è¡ã ã€ãŸã ããã察åŠãããã®ãç¥ããªããã®ã³ãŒãã ã¡ã¿ããŒã¿ã䜿çšããŠæ©èœããã³ãŒãã
- ãŠãŒã¶ãŒã®æš©å©ãåºåããå®å šãªãã¢ãŒããã¯ãã£ïŒãã¡ããããã®ãããã¯ã«é¢é£ãããã¹ãŠã®ãã®ãšåæ§ã«ïŒã
- ãŠãŒã¶ãŒããŒã¿ã®ä¿åã
ã³ã³ã¹ãã©ã¯ã¿ãŒã®æ¬è³ªã¯ãã·ã¹ãã 管çè ãäžé£ã®ãšã³ãã£ãã£ãå®çŸ©ããåãšã³ãã£ãã£ã«äžé£ã®ãã£ãŒã«ãïŒå±æ§ïŒãèšå®ããããšã§ãã ããŒã¿ããŒã¹ã¬ãã«ã§ãšã³ãã£ãã£ããšã«ããŒãã«ãçæãããŸãã ãŸããå€ãã®èŠå ã«å¿ããŠãåå¥ã«ã¢ã¯ã»ã¹æš©ãèšå®ããŸãã ãã®çµæãã·ã¹ãã ã¯ã¢ã¯ã»ã¹æš©ã«åºã¥ããŠãã¹ãŠã®ãŠãŒã¶ãŒã®CRUDã€ã³ã¿ãŒãã§ã€ã¹ãçæããŸãã 管çè ã¯ããšã³ãã£ãã£ã®èš±å®¹ç¶æ ïŒã¹ããŒã¿ã¹ïŒãšç¶æ éã®é·ç§»ã®ã°ã©ããæ§æããããšãã§ããŸãã ãã®ãããªã°ã©ãã¯ããšã³ãã£ãã£ã®ç§»åã®ããžãã¹ããã»ã¹ãæ¬è³ªçã«èª¬æããŸãã ããžãã¹ããã»ã¹ãå®è¡ããããã®ãã¹ãŠã®ã€ã³ã¿ãŒãã§ã€ã¹ãèªåçã«çæãããŸãã
åºæ¬çãªã·ã¹ãã ã€ã³ã¿ãŒãã§ã€ã¹ã®ç»å
ããšãã°ãåºèã®å Žåã補åã®æ¬è³ªã«ã¯ãééãäŸ¡æ Œãæå¹æéã補é æ¥ãªã©ã®å±æ§ããããŸãã補åã«ã¯ãå庫ãåºèãè³Œå ¥ããç¶æ ããããŸãã åºé·ã¯èªåã®åºã§ååãèŠãŸãã ã¡ã€ã³ã®èå±ã¯ããããã¯ãŒã¯ã®ãã¹ãŠã®è補åãèŠãŠããŸãã ãã¡ãããããã¯ãã¹ãŠéåžžã«åçŽã§ãã
æåããã®ã³ã³ã¹ãã©ã¯ã¿ã¯ãèªåçšã«ãäœæãããŸããã 次ã®é¡§å®¢ãäœçŸãã®ããŒãã«ãCRUDããŒãžãå€æ°ã®ç°ãªãã¬ããŒããããŒã¿ïŒè¡ãšåïŒãåé¢ããæ©èœãäœæããããšãæ¬åœã«æãã§ããŸããã§ããã åæã«ãåãããžã§ã¯ããå®å šã«ç®¡çããããšèããŠããŸããã ã»ãšãã©äœã§ãããããã«é ŒãŸãããããããããããšãã§ããŸãã èšèšè ã¯ãéçºã®ã¹ããŒããšãã®å®ãïŒã«ãŒãã«éçºè ãã·ã¹ãã ã¯ã»ãšãã©ããžãã¹ããã»ã¹ãæãäžããªãã£ãïŒãæäŸããŠãããã¢ããªã¹ãã¯å¿çšããžãã¯ãè¡ããŸããã ãã¶ã€ããŒã圌èªèº«ã§ãããšããäºå®ã¯ãéã ããæããã¹ãŠãããããšãå¯èœã«ããŸããã åæã«ãã·ã¹ãã ã®äžæ žãéçºãããŸããã
以åã¯ãæ°ããæœåšé¡§å®¢ããšã«ããããžã§ã¯ãã®ã³ããŒãå±éããŸããã ãã®ã³ããŒã圌ãŸãã¯ç§ãã¡ã®ãµãŒããŒã«ã€ã³ã¹ããŒã«ããŸããã 顧客åãã«ãã¶ã€ããŒã§ã¢ããªã±ãŒã·ã§ã³ãã«ã¹ã¿ãã€ãºããŸããã ããäžåºŠããããŒãžã£ãŒãïŒç°ãªãURLã䜿çšããŠïŒã¢ããªã±ãŒã·ã§ã³ã®ã€ã³ã¹ã¿ã³ã¹ãããã«10åäœæããŠãç°ãªãã¯ã©ã€ã¢ã³ãã«è¡šç€ºããããã«èŠæ±ãããšãIISã¯ãµãŒããŒã®ãã¹ãŠã®RAMã䜿çšããŸããã ãã¹ãŠã®ã¢ããªã±ãŒã·ã§ã³ã®é床ãå€§å¹ ã«äœäžããŸããã IISãé©åã«ç®¡çãããã¶ã€ããŒã¢ãŒããã¯ãã£ãå®æããããšãããçšåºŠã®ïŒå Žåã«ãã£ãŠã¯å€§éã®ïŒãªãœãŒã¹ãç²åŸã§ããããšã¯æããã§ããã ããããééã£ãæ¹åã«é²ãã§ããããšã«æ°ã¥ããŸããã
ã¢ãŒããã¯ãã£ã®éžæ
åé¡ã«ã€ããŠè©³çŽ°ã«èããŠã3ã€ã®äž»ãªåé¡ãç¹å®ããŸããã
- ãããŒãžã£ãŒã¯ãããã°ã©ããŒã«é Œããã«ã¢ããªã±ãŒã·ã§ã³ãäœæããããšèããŠããŸããã ããã«è¯ãããšã«ãã¯ã©ã€ã¢ã³ãèªèº«ããããŒãžã£ãŒã«é£çµ¡ããã«ã¢ããªã±ãŒã·ã§ã³ãäœæããŸãã
- ãµãŒããŒã¯ãåããªãœãŒã¹ã§1æ¡ã®å€§ããªè² è·ã«èããå¿ èŠããããŸããã
- ã·ã¹ãã ã®æŽæ°ã¯ãããã»ã©èŠçãªãè¡ãå¿ èŠããããŸãã åå¥ã«ä¿å®ããã³æŽæ°ããªããã°ãªããªãé¢é£ã®ãªããããžã§ã¯ãããããããããŸããã
次ã«ããã¬ãŒã³ã¹ããŒãã³ã°ã»ãã·ã§ã³ããããŸããã å®è£ ã®3ã€ã®äž»ãªãªãã·ã§ã³ã«ã€ããŠèª¬æããŸããã
ãªãã·ã§ã³1ïŒ
ãã¹ãŠã1ã€ã®ã¹ãŒããŒã¢ããªã±ãŒã·ã§ã³ã§è¡ãããŸãã è¿œå ã®ApplicationEntityãšã³ãã£ãã£ãååŸããã«ã¯ããã¹ãŠã®ã·ã¹ãã ãšã³ãã£ãã£ïŒããŒã¿ããŒã¹å ã®ã¡ã¿ããŒã¿ããŒãã«ïŒãäœããã®æ¹æ³ã§ApplicationEntityãåç §ããå¿ èŠããããŸãã WebãµãŒããŒã§ãæš©éãå¶éããåŠçãè¡ããŸãïŒèª°ãäœãèŠããã誰ãäœãæ¯é ããããªã©ïŒã
ãªãã·ã§ã³1ã®ãã©ã¹ïŒ
- ã€ããªãã®ãŒçã«ãéåžžã«åçŽãªå®è£ ã ãããäœã§ãã£ããããããã®ãããªã¢ãŒããã¯ãã£ã®å®è£ ãæãåçŽã«ããããšã ãããè¡ãã«ã¯ããããžã§ã¯ãå šäœã§æ°çŸã®ifã䜿çšããŸãã
- æ°ããã·ã¹ãã ã®ç°¡åãªå±éã ã·ã¹ãã ãäœæãããšããã¡ã¿ããŒã¿ããŒãã«ã®è€æ°ã®è¡ããã°ããç°¡åã«æ¿å ¥ãããŸãã
- ã·ã¹ãã ã®æŽæ°ã¯éåžžã«ç°¡åã§ãã 1ã€ã®WebãµãŒããŒã1ã€ã®ããŒã¹ãå®æçãªå±éã
ãªãã·ã§ã³1ã®çæïŒ
- ãœãªã¥ãŒã·ã§ã³ã¯éåžžã«äžå®å®ã«èŠããŸãïŒã»ãã¥ãªãã£ã®èŠ³ç¹ããïŒã ã¢ããªã±ãŒã·ã§ã³éã§ãã®æš©å©ã®åé¢ããã¹ãŠæ£ããæ£ããå®è£ ãããšããŠããã³ãŒããå€æŽãããšãæ°ãããã§ãã¯ãäžæ£ç¢ºã«ãªããªã¹ã¯ããããŸãã ãã®çµæã1人ã®ãŠãŒã¶ãŒãå€éšã·ã¹ãã ã®ç®¡çããã«ã®äžéšã«ã¢ã¯ã»ã¹ã§ããŸãã
- çµæãšããŠçããã¹ãŒããŒããŒã¹ã¯ãéåžžã«è²§åŒ±ã«ã¹ã±ãŒãªã³ã°ãããŸãã å€æ°ã®ã¯ã©ã€ã¢ã³ããããå ŽåãDBMSã®ã·ã£ãŒãã£ã³ã°/ã¬ããªã±ãŒã·ã§ã³ã«ãã£ãŠã®ã¿ãããŒã¿ããŒã¹ã2+ãµãŒããŒã«åå²ã§ããŸãã éåžžã«éå®çã§ãäžéæã§ãã ã¯ã©ã€ã¢ã³ãããšã«ç°ãªãããŒã¹ãæã€æ¹ãã¯ããã«å¿«é©ã§ãã
ãªãã·ã§ã³2ïŒ
åã®æ®µèœã®æåŸã®ãã€ãã¹ããã次ã®è§£æ±ºçãçãŸããŸããã WebãµãŒããŒã1ã€ã®ã¢ããªã±ãŒã·ã§ã³ãšããŠäœæããå€æ°ã®ããŒã¿ããŒã¹ãäœæããïŒã¯ã©ã€ã¢ã³ãããšã«1ã€ïŒã WebãµãŒããŒã¯ã* .getreport.proãšãã圢åŒã®ãã¹ãŠã®ãªã¯ãšã¹ãããã£ããããŸããããããŒã¿ããŒã¹ã®ç¬¬3ã¬ãã«ãã¡ã€ã³ã«ãã£ãŠãããããŒã¯ç®çã®ã¯ã©ã€ã¢ã³ãããŒã¿ããŒã¹ãžã®æ¥ç¶æååãæ¢ããŸãã ããã«ãã·ã¹ãã ã¯ä»¥åã®ããã«æ©èœããŸãã ããŒã¿ããŒã¹ã§ã¯ãæ¥ç¶å ã¯ã¯ã©ã€ã¢ã³ãã·ã¹ãã äžã®ããŒã¿ã®ã¿ã§ãã
ãªãã·ã§ã³2ã®ãã©ã¹ïŒ
- 顧客ããšã«ç°ãªãåºç€ã å®å šã§ãã WebãµãŒããŒã¯ããã®åã®æ¥ç¶æååãç¥ããªãå Žåãå€éšããŒã¹ã§äœãã§ããŸããã ãããŠã圌ãç¥ã£ãŠããã°ããã¶ã€ããŒã®éåžžã®ã¡ã«ããºã ã§ãããŒã¿ããŒã¹å ã®ãŠãŒã¶ãŒæš©éã®ãã§ãã¯ããããŸãïŒããã¯ãã·ã¹ãã ã«ãŒãã«ã®åºç€ã§ããããããããã°ãããããŒã«ã§ãïŒã
- 顧客ããšã«ç°ãªãåºç€ã ã¹ã±ãŒã©ãã«ã§ãã å¿ èŠã«å¿ããŠã倧ããªé çãªãã«ç°ãªããã·ã³ã«åå²ã§ããŸãã WebãµãŒããŒã¯IISã«ãã£ãŠã¹ã±ãŒãªã³ã°ãããŸãã
- ã·ã¹ãã ã¯ç°¡åã«æŽæ°ã§ããŸãã 1ã€ã®WebãµãŒããŒãéåžžã®å±éã èªå移è¡ãæå¹ã«ããã³ãŒããã¡ãŒã¹ãã¯ããã¹ãŠã®ããŒã¿ããŒã¹ãææ°ããŒãžã§ã³ã«æŽæ°ããŸãã ãã ããããã¯1ããŒã¹ããŒãžã§ã³ãããééæ§ã®äœãããŒãžã§ã³ã§ãã
- ç¹å®ã®ã¯ã©ã€ã¢ã³ãã«ããŒã¿ããŒã¹ãžã®æ¥ç¶æååãäžããŠãã¯ã©ã€ã¢ã³ããèªåã®ããŒã¹ãèªåã®ã³ã³ãããŒã«äžã«ãããšæããããã䜿ã£ãŠäœã§ãã§ããããã«ããæ©èœã
ãªãã·ã§ã³2ã®çæïŒ
- å€æ°ã®ããŒã¿ããŒã¹ãç£èŠããã®ã¯ããå°é£ã§ãã ãã¹ãŠã®ããŒã¹ãžã®ãã¹ãŠã®ç§»è¡ãããŒã«ãããããšã確èªããå¿ èŠããããŸãã
- ã³ãŒããšãæ°ããã¢ããªã±ãŒã·ã§ã³ã®é·æçãªå±éãéåžžã«å·§åŠã§ãã å®å šã«æ°ããããŒã¿ããŒã¹ïŒæåã®ã³ãŒããŸãã¯åç §ããŒã¿ããŒã¹ã®åŸ©å ïŒãæ°ããDBMSãŠãŒã¶ãŒãäœæããæ°ããããŒã¿ããŒã¹ã«æ°ãããŠãŒã¶ãŒã«æš©éãäžããå¿ èŠããããŸãã
ãªãã·ã§ã³3ïŒ
ãµãŒãã¹ããã¯ã¹ãªãã·ã§ã³ã å€ãã®ä»®æ³ãã·ã³ããµãŒããŒã«ãããã€ãããŸãã åä»®æ³ãã·ã³ã«ã¯ãç¬èªã®ããŒã¿ããŒã¹ãæã€1ã€ã®åå¥ã®Webã¢ããªã±ãŒã·ã§ã³ããããŸãã ã¡ã€ã³ãµãŒããŒã¯ãªã¯ãšã¹ãã®è»¢éã®ã¿ãåŠçããŸãã
ãªãã·ã§ã³3ã®ãã©ã¹ïŒ
- å®å šãªã¢ããªã±ãŒã·ã§ã³åé¢ã æ倧ã®å®å šæ§ã åã¢ããªã±ãŒã·ã§ã³ã¯ãç¬èªã®ãµã³ãããã¯ã¹ã§å®è¡ãããŸãã
- å¿ èŠã«å¿ããŠããã¹ãŠã®ããŒã¿ãå«ãäœæ¥ããã¯ã¹ãã¯ã©ã€ã¢ã³ãã«è»¢éã§ããŸãã ä»®æ³ãã¡ã€ã«ãæå®ããã ãã§ãã
- ã¢ããªã±ãŒã·ã§ã³ãã¹ã±ãŒãªã³ã°ããæ©èœã¯ãã»ãŒç¡éã«ç·åœ¢ã§ãã ã€ãŸã 2åã®ãµãŒããŒ-2åã®ããã©ãŒãã³ã¹ã
- æ°ããã¢ããªã±ãŒã·ã§ã³ã®ç°¡åãªå±éã¯ãä»®æ³ãã·ã³ã®ã¯ããŒã³ãäœæããããã§ãªã¯ãšã¹ãã®éä¿¡ãéå§ããããšã§ãã
- ç¹å®ã®ã¯ã©ã€ã¢ã³ãã«ããŒã¿ããŒã¹ãžã®æ¥ç¶æååãäžããŠãã¯ã©ã€ã¢ã³ããèªåã®ããŒã¹ãèªåã®ã³ã³ãããŒã«äžã«ãããšæããããã§äœã§ãã§ããããã«ããæ©èœã
ãªãã·ã§ã³3ã®çæïŒ
- äž»ãªæ¬ ç¹ã¯ããã©ãŒãã³ã¹ã§ãã 以åã¯ããããžã§ã¯ãçšã«å¥ã®Webã¢ããªã±ãŒã·ã§ã³ãäœæããŸããããä»ã§ã¯ç¬èªã®OSãšDBMSã䜿çšããŠä»®æ³ãã·ã³å šäœãäœæããå¿ èŠããããŸãã CPUã¯ååãšããŠãµã°ããã¹ãã§ã¯ãããŸããããRAMã¯æ¬åœã«å€ããå¿ èŠãšããŸãã éåžžãäŸ¡æ Œãèšç®ããéã®äž»ãªãã©ã¡ãŒã¿ãŒã¯ãµãŒããŒäžã®RAMã§ãã
- æ°ããããŒãžã§ã³ã®å±éã¯éåžžã«å°é£ã§ãã å¥ã®ã¹ã¯ãªãããã¢ããããŒã¿ãŒããäœæããå¿ èŠããããŸãã ã«ãŒãã§ä»®æ³ãã·ã³ãå®è¡ããWebãµãŒããŒãåæ¢ããããŒã¿ããŒã¹ãšãã³ãæŽæ°ããŸãã ãŸãã¯ãåä»®æ³ãã·ã³ã§ãã®ãããªãæŽæ°ããµãŒãã¹ãäœæããããèªäœãããŒãžã§ã³ãç£èŠããFTPïŒãŸãã¯ãã®ãããªãã®ïŒçµç±ã§ããŒã¿ãååŸããŠWebãµãŒããŒãæŽæ°ããŸãã ãããã«ããããã®ãããªã¢ãŒããã¯ãã£ã§ã·ã¹ãã ã®ããŒãžã§ã³ãæŽæ°ããããšã¯éåžžã«æ¥œããã§ãã
é·ãäŒè°ã®åŸã2çªç®ã®ãªãã·ã§ã³ãéžæãããŸãã ã 以äžã«ã説æãããŠãããã©ââã¹ãããçç±ãšããã®çæãã©ã®ããã«è©äŸ¡ãããã説æããŸãã
ãªãã·ã§ã³ã®ã¢ãŒããã¯ãã£
ãã¹ãŠã®ã¯ã©ã€ã¢ã³ãããã®ãã¹ãŠã®ãªã¯ãšã¹ããééããåäžã®Webã¢ããªã±ãŒã·ã§ã³ããããŸãã æéãçµã€ãšãå¿ èŠã«å¿ããŠWebãã¡ãŒã ã«å€ããããšã¯æããã§ãã ãã®ããã®ã³ãŒãã®å€æŽã¯æå°éã«ãªããŸãã
ã¯ã©ã€ã¢ã³ãã¯URLã¢ãã¬ã¹myapplication.getreport.proã䜿çšããŠãµãŒããŒã«èŠæ±ãè¡ããWebãµãŒããŒã¯èŠæ±URLãšã¯ã©ã€ã¢ã³ãããŒã¹ãžã®æ¥ç¶æååéã®ãããã³ã°ãå«ãããŒã¿ããŒã¹ã«ã¢ã¯ã»ã¹ããŸãã åæ¥ç¶æååã¯ãããŒã¿ããŒã¹ã«å¯ŸããŠã®ã¿æš©éãæã€äžæã®DBMSãŠãŒã¶ãŒã«åºã¥ããŠããŸãã
ããŒã¿ããŒã¹ã¯ãšãªãæå°éã«æããããã«ããã®ãããã³ã°ã¯ãããŒãšå€ã®ã¿ã€ãïŒCïŒã®èŸæžïŒã®æ§é ã§WebãµãŒããŒã®ãã£ãã·ã¥ã«é 眮ãããŸãã ãã£ãã·ã¥ã¯æ°ç§ããšã«çµ¶ããæŽæ°ãããŸãã
ã¢ããªã±ãŒã·ã§ã³ã³ãŒããšèšå®ã«ã¯ä»ã®æ¥ç¶æååã¯ãããŸããã ããŒã¿ããŒã¹ãžã®æ°ããæ¥ç¶ãäœæãããšããã¢ããªã±ãŒã·ã§ã³ã¯ããã®ãã£ãã·ã¥ãããé€ããŠãæ¥ç¶ã®ããŒã¿ãååŸããå ŽæããããŸããã ãã®ããã«ããŠãå¥ã®ã¯ã©ã€ã¢ã³ãã®å€éšããŒã¿ããŒã¹ãžã®SQLã¯ãšãªã®æ¬ èœã®å¯èœæ§ãæé€ããŸãã
EntityFrameworkã³ã³ããã¹ãã®ããã©ã«ãã³ã³ã¹ãã©ã¯ã¿ãŒã¯privateã§ãã ãã®çµæãããŒã¿ããŒã¹ãžã®ã¢ã¯ã»ã¹ã«ã€ããŠã¯ãã©ã®ããŒã¿ããŒã¹ã«å¯ŸããŠãªã¯ãšã¹ããè¡ã£ãŠããããæ瀺çã«ç€ºãå¿ èŠããããŸãã ãŸããã©ã®ã³ã³ããã¹ãã§ãïŒGetClientConnectionStringã¡ãœããããïŒäœ¿çšã§ããæ¥ç¶æååã¯1ã€ã ããªã®ã§ãèŠéãå Žæã¯ãããŸããã 以äžã¯ãGetClientConnectionStringã¡ãœããã®å®è£ ã§ãã
GetClientConnectionStringã®å®è£
public static string GetClientConnectionString(this HttpContext context) { #if DEBUG if (Debugger.IsAttached && ConfigurationManager.ConnectionStrings[SERVICE_CONNECTION_STRING_NAME] == null) { /* ( URL connectionstring), . , */ return ConfigurationManager.AppSettings["DeveloperConnection-" + Environment.MachineName]; } #endif /* . , , .. Task, HttpContext, URL , . connectionstring, . .*/ if(context == null && TaskContext.Current != null) { // , ! return TaskContext.Current.ConnectionString; } /* , connectionstring */ if (context != null && ConfigurationManager.ConnectionStrings[SERVICE_CONNECTION_STRING_NAME] != null) { ServiceAccount account = context.GetServiceAccount(); if (account == null) { /* , , - connectionstring , */ return null; } if (account.GetCurrentPurchases().Any() == false) { /* ( ), connectionstring , */ return null; } return account.ConnectionString; } else if (ConfigurationManager.ConnectionStrings[DEFAULT_CONNECTION_STRING_NAME] != null) { /* , connectionstring */ return ConfigurationManager.ConnectionStrings[DEFAULT_CONNECTION_STRING_NAME].ConnectionString; } else { return null; } }
GetClientConnectionStringã®ãã«ãã¹ã¬ããå®è£
ïŒåžžã«HttpContextãšã¯éããŸããïŒ
/* http://stackoverflow.com/a/32459724*/ public sealed class TaskContext { private static readonly string contextKey = Guid.NewGuid().ToString(); public TaskContext(string connectionString) { this.ConnectionString = connectionString; } public string ConnectionString { get; private set; } public static TaskContext Current { get { return (TaskContext)CallContext.LogicalGetData(contextKey); } internal set { if (value == null) { CallContext.FreeNamedDataSlot(contextKey); } else { CallContext.LogicalSetData(contextKey, value); } } } } public static class TaskFactoryExtensions { public static Task<T> StartNewWithContext<T>(this TaskFactory factory, Func<T> action, string connectionString) { Task<T> task = new Task<T>(() => { T result; TaskContext.Current = new TaskContext(connectionString); try { result = action(); } finally { TaskContext.Current = null; } return result; }); task.Start(); return task; } public static Task StartNewWithContext(this TaskFactory factory, Action action, string connectionString) { Task task = new Task(() => { TaskContext.Current = new TaskContext(connectionString); try { action(); } finally { TaskContext.Current = null; } }); task.Start(); return task; } }
ãŠãŒã¶ãŒããã°ã€ã³ãããšãã¯ã©ã€ã¢ã³ããã©ãŠã¶ãŒã«accessTokenãçºè¡ããŸãã ãã°ã€ã³èŠæ±ãé€ããã·ã¹ãã ãžã®ãã¹ãŠã®èŠæ±ã¯ããã®accessTokenã䜿çšããŠçºçããŸãã ãããã®ããŒã¯ã³ã¯ããããã¯ã©ã€ã¢ã³ãããŒã¿ããŒã¹ã«æ ŒçŽãããããã¯ã©ã€ã¢ã³ãããã®ããŒã¯ã³ã¯å¥ã®ã¯ã©ã€ã¢ã³ãã«é©åããŸããã ããŒã¯ã³ã¯ããã°ã€ã³ããšã«å床çæãããGUIDã§ãã ãããã£ãŠãããŒã¯ã³ãéžæããããšã¯ã§ããŸããã ç°ãªãããŒã¿ããŒã¹ã®ã¬ãã«ã§ã®ããŒã¯ã³ã®åé¢ãšãèŠæ±ããã®æ¥ç¶æååã®å®çŸ©ãããã®ã¢ãŒããã¯ãã£ãªãã·ã§ã³ãåäžã®ã¹ãŒããŒããŒã¿ããŒã¹ã®ãªãã·ã§ã³ãããå®å šã«ããŸãã
ã¯ã©ã€ã¢ã³ããããµãŒããŒã«èŠæ±ãããšããæ¥ç¶æååãå®çŸ©ãããåŸãã»ãã¥ãªãã£ãã§ãã¯ã®ããã€ãã®ã¬ãã«ããããŸãã æåã®ã¬ãã«ã§ã¯ãAuthHandlerïŒDelegatingHandlerã¯ã©ã¹ãå®çŸ©ããŸãã APIã¡ãœãããåŒã³åºããããã³ã«åŒã³åºãããSendAsyncã¡ãœããããããŸãã åæã«ããªã¯ãšã¹ãããããŒã«accessTokenãã£ãŒã«ãããªãå ŽåããŸãã¯ãã®ãããªaccessTokenãæã€ãŠãŒã¶ãŒãèŠã€ãããªãã£ãå Žåãã·ã¹ãã ã¯ã³ã³ãããŒã©ãŒAPIã¡ãœãããåŒã³åºããªããŠããšã©ãŒãè¿ããŸãã
AuthHandlerã®å®è£
public class AuthHandler : DelegatingHandler { protected async override Task<HttpResponseMessage> SendAsync( HttpRequestMessage request, CancellationToken cancellationToken) { if (request.Method.Method == "OPTIONS") { var res = base.SendAsync(request, cancellationToken).Result; return res; } // API string classSuffix = "Controller"; var inheritors = Assembly.GetAssembly(typeof(BaseApiController)).GetTypes().Where(t => t.IsSubclassOf(typeof(ApiController))) .Where(inheritor => inheritor.Name.EndsWith(classSuffix)); // UnautorizedMethod. " " ( GUID ) var methods = inheritors.SelectMany(inheritor => inheritor.GetMethods().Select(methodInfo => new { Inheritor = inheritor, MethodInfo = methodInfo, Attribute = methodInfo.GetCustomAttribute(typeof(System.Web.Http.ActionNameAttribute)) as System.Web.Http.ActionNameAttribute })).Where(method => method.MethodInfo.GetCustomAttribute(typeof(UnautorizedMethodAttribute)) != null); // ConnectionString string connection = System.Web.HttpContext.Current.GetClientConnectionString(); if (string.IsNullOrEmpty(connection)) { var res = new HttpResponseMessage(System.Net.HttpStatusCode.NotFound); return res; } // , if (!request.RequestUri.LocalPath.EndsWith("/api/login/login") && methods.All(method => !request.RequestUri.LocalPath.ToLower().EndsWith($"/api/{method.Inheritor.Name.Substring(0, method.Inheritor.Name.Length - classSuffix.Length)}/{method.Attribute?.Name ?? method.MethodInfo.Name}".ToLower()))) { // login UnautorizedMethod // , .. , UnautorizedMethod - . // var accessToken = request.GetAccessToken(); var accountDbWorker = new AccountDbWorker(connection, null, DbWorkerCacheManager.GetCacheProvider(connection)); var checkAccountExists = accountDbWorker.CheckAccountExists(accessToken); if (checkAccountExists == false) { var res = new HttpResponseMessage(System.Net.HttpStatusCode.Unauthorized); return res; } else { // . AuthTokenManager.Instance.Refresh(request.GetTokenHeader()); } } else { //methods without any auth } // var response = await base.SendAsync(request, cancellationToken); return response; } }
次ã«ãç®çã®ã³ã³ãããŒã©ãŒã®ã³ãŒããåŒã³åºããã察å¿ããDALã«ãŒãã«ã¡ãœãããåŒã³åºãããŸãã 圌ã®accessTokenã«ãããŠãŒã¶ãŒã®ãªã¹ãå ã®ãŠãŒã¶ãŒã®ãã¹ãŠã®æ€çŽ¢ã®æåã«ãéåžžã«éèŠãªã«ãŒãã«ã¡ãœããïŒããŒã¿ãå€æŽãŸãã¯ã¹ãã£ã³ïŒã 次ã«ãç¹å®ã®ãŠãŒã¶ãŒã®æš©éã確èªããã¡ã€ã³ã¡ãœããã³ãŒããå®è¡ããŸãã ããã§ã¯ãã¹ãŠãæšæºã§ãã
æŽæ°ããŒãžã§ã³
ãªããªã ã¢ããªã±ãŒã·ã§ã³ã¯åäžã®Webã¢ããªã±ãŒã·ã§ã³ã§æ§æããããããWebããŒãã®æŽæ°ã¯è¿ éãã€ç°¡åã§ãã ããã«èå³æ·±ãã®ã¯ãããŒã¿ããŒã¹ã®ç¶æ³ã§ãã Code Firstã¢ãããŒãã䜿çšããŠããããããŠãŒã¶ãŒã®ãªã¯ãšã¹ãã«å¿ããŠããã¹ãŠã®ç§»è¡ãããŒã¿ããŒã¹ã«éãããŸãã
å®éããã¹ãŠã®ããŒã¿ããŒã¹ãžã®ç§»è¡ã¯ãããã«æ©ã段éïŒã¢ããªã±ãŒã·ã§ã³ã®èµ·åäžïŒã§è¡ãããŸãã å®éã«ã¯ãã¡ãŒã«ã§ãŠãŒã¶ãŒã«éç¥ãéä¿¡ããã¡ã«ããºã ããããŸãã éç¥ã¯ãããŒã¿ã«å¿ããŠã·ã¹ãã ã®ãŠãŒã¶ãŒã«éä¿¡ã§ããéåžžã®æçŽã§ãã ãã®ããã«ãµãŒããŒåŽã®ã¹ã¯ãªããããã°ã©ãã³ã°èšèªã䜿çšããŸãã ã¢ããªã±ãŒã·ã§ã³ãèµ·åãããšããã®ãµãŒãã¹ãèµ·åãããã¹ãŠã®ãŠãŒã¶ãŒããŒã¿ããŒã¹ãåç §ããŠãéä¿¡ããæåããããã©ããã確èªããŸãã çŸæç¹ã§ã¯ããã¹ãŠã®ãŠãŒã¶ãŒããŒã¿ããŒã¹ãžã®ããŒãªã³ã°ãã€ã°ã¬ãŒã·ã§ã³ããããŸãã
äœæ¥é床
ãã®ãã¹ãŠã®äœæ¥ã®çµæãIISã§ãã¹ãŠã®ã¢ããªã±ãŒã·ã§ã³ãæäœããããã«å¿ èŠãªã¡ã¢ãªã®éãå€§å¹ ã«åæžãããŸããã æ£ç¢ºãªæ°åã瀺ãããšã¯ã§ããŸããããæ°çŸã®ãŠãŒã¶ãŒã®ããžãã¹ã¢ããªã±ãŒã·ã§ã³ïŒããŒã¿ããŒã¹ãªã©ïŒã4 GBã®RAMãæèŒãããµãŒããŒã«ç°¡åã«åãŸããããã«å€ãã®ãŠãŒã¶ãŒãåãŸããŸãã ã·ã¹ãã ã¯ã¡ã¢ãªããã®ã·ã³ã¯ãåæ¢ããŸããã
ãã ããCPUã®ããã©ãŒãã³ã¹ã¯ããã»ã©åäžããŠããŸããã ãããã¡ã€ãªã³ã°ã¯å€§ããªåé¡ãæããã«ããŸããã ã·ã¹ãã ã¯ããŠãŒã¶ãŒãã¯ãšãªãå®è¡ããããŒãã«ã«ã€ããŠïŒã³ã³ãã€ã«æ®µéã§ïŒäºåã«äœãç¥ããŸããã ä»»æã®ããŒãã«ã®ããŒã¿ã«å¯ŸããæãåçŽãªã¯ãšãªã§ãã£ãŠããã¡ã¿ããŒã¿ããŒã¿ããŒã¹ã«å¯ŸããŠéåžžã«å€ãã®ã¯ãšãªãå®è¡ããå¿ èŠããããŸãã ãããã®ã¯ãšãªã®çµæã«åºã¥ããŠãsqlãçæãããŸãã çµæã®SQLã¯ãã§ã«å®éã®ããŒã¿ãè¿ããéåžžã«é«éã«å®è¡ãããŸãã
ãããããã¡ã¿ããŒã¿ã¹ããŒããžã®ã¯ãšãªã®æ°ãã©ãã«ãããŠæžããããšãã§ãããã©ããçåã«æããŸããã åŠå®çãªåçãåãåããŸããã ã¯ãšãªãäœæããã«ã¯ãããŒã¿ããŒã¹å ã®ããŒãã«ã®ååãããŒãã«ã®ãã¹ãŠã®åã®ååãçŸåšã®ãŠãŒã¶ãŒã®ããŒã«ãç¥ãå¿ èŠããããŸãã åããŒã«ã«ã€ããŠã衚瀺ãèš±å¯ãããŠããåãç¥ãå¿ èŠããããŸãã 圌女ãèŠãããšãèš±å¯ãããŠããè¡ã決å®ããããã®å€ãã®è¿œå ããŒã¿ã«ã€ããŠã¯ã詳现ã«ã¯è§ŠããŸããããå®éã«ã¯ããŸããŸãªã¡ã¿ããŒã¿ããŒãã«ã«å¯ŸããããŸããŸãªã¯ãšãªããããŸãã ãããŠããã®ãã¹ãŠã®ã¡ã¿ããŒã¿ãå¿ èŠã§ãã ã¡ã¿ããŒã¿ã®ååŸã¯ããªã¯ãšã¹ãèªäœã®å®è¡ãããã»ãŒ2æ¡é·ãã£ãã
ãã®ãããªå Žæã¯ãããããããŸããã æš©å©ã確èªããã«ã¯ãããããã®ã¡ã¿ããŒã¿ãå¿ èŠã§ããã èããåŸããã®ã¡ã¿ããŒã¿ããã¹ãŠãµãŒããŒã«ãã£ãã·ã¥ããããšã«ããŸããã ãããããã®æ±ºå®ã¯ãäžèŠãããšæããããããã€ããªãã®ãŒçã«è€éã§ãã 説æãã以åã®ãã£ãã·ã¥ã«ã¯ãã€ã³ã³ããŒã¬ã³ãããŒã¿ã®éåžžã«å°ããªã»ãããå«ãŸããŠããŸãã å®éãã·ã³ãã«ãªããããå«ãŸããŠããŸãïŒURL-> connectionstringãaccessToken-> account + DateïŒã ãŸãããã®ãã£ãã·ã¥ã¯ã倧ãããæ¥ç¶æ§ãé«ããé·ã調æŽå¯èœãªè€éãªæ§é ã§ãã
ãã£ãã·ã³ã°ã·ã¹ãã ãçæ£é¢ããå®è£ ãããšãcãªæ§é ïŒããŒã«ãããã£ã¯ã·ã§ããªãä»ããããŒã¿ãžã®è¿ éãªã¢ã¯ã»ã¹ãå¯èœïŒãšããããåããããã®è€éãªã³ãŒããåŸãããŸãã ã¡ã¿ããŒã¿ãå€æŽãããã¹ãŠã®ã¡ãœããã§ã¯ãRefreshCacheã¡ãœãããåŒã³åºãå¿ èŠãããããã®ãããªã¡ãœããã¯å€æ°ãããŸãã ãã®ãããªã¡ãœãããåŒã³åºãã®ãå¿ããããšã¯éåžžã«äžæå¿«ã§ãã é¡ãå®è£ ããRefreshCacheã³ãŒãèªäœãéåžžã«å€§ãããèŠèŠããã§ãã ããã¯ã巚倧ãªã€ã³ã¯ã«ãŒãã«å ¥ãããæ§é å šäœãèšè¿°ããŠãããããŒã¿ããŒã¹ã«ãã¹ãŠã®ããŒã¿ãèŠæ±ããããšãã§ããªãããã§ãã éçŸå®çã«ãã£ããåäœããŸãã ãã®çµæããªã¯ãšã¹ããå°ããªãªã¯ãšã¹ãã®æã«åå²ããã³ãŒãã«NavigationPropãæ¥çããå¿ èŠããããŸããããã¯ãã§ã«é«éã«æ©èœããŠããŸãã ãã®çµæãæ°ããã¡ã¿ããŒã¿ãšã³ãã£ãã£ãã·ã¹ãã ã«è¿œå ãããšãé çã®çš®ãçºçããŸãããã¹ãŠã®CRUDã¡ãœããã«ã€ããŠãRefreshCacheãåŒã³åºãããã®ã¡ãœããã«æ°ãããšã³ãã£ãã£ããã¡ã€ã«ãããã¹ãŠã®ãšã³ãã£ãã£ã®ãã¹ãŠã®NavigationPropã«å ¥ããŸãã äžè¬çã«èšãã°ãããã¯ãã¹ãŠç§ãã¡ãåã°ããŸããã§ããããå©ãã«ãªãã§ãããã è¯ãåããèŠã€ããããããè¯ãåããæ¢ããŠãã ãã ã
2ã€ã®äžè²«æ§ã®ãªãåé¡ãç¹å®ããŸããã
- ã¡ã¿ãšã³ãã£ãã£ãå€æŽãããšãã«RefreshCacheã³ãŒããæåã§åŒã³åºãã
- RefreshCacheã§ãã£ãã·ã¥ãæ§ç¯ããããã®ãããã°ããäžååãªãµããŒããéåžžã«ãŸãšãŸãã®ããã³ãŒãã
æåã®åé¡ã¯ãEntityFrameworkãè žã«å°å ¥ããããšã§è§£æ±ºããŸããã EntityFrameworkã§SaveChangesã¡ãœãããåå®çŸ©ããŸããã ãã®äžã§ãé¢å¿ã®ãããšã³ãã£ãã£ãå€æŽãããã©ããã確èªããŸãã å€æŽãããå Žåããã£ãã·ã¥ãåæ§ç¯ããŸãã
EntityFramework EntityFrameworkèªåå€æŽè¿œè·¡ã³ãŒã
/* , . String[] - , ( , )*/ static readonly Dictionary<Type, string[]> _trackedTypes = new Dictionary<Type, string[]>() { { typeof(Account), new string[] { GetPropertyName((Account a) => a.Settings) } }, //.. { typeof(Table), new string[0] }, }; // , static string GetPropertyName<T, P>(Expression<Func<T, P>> action) { var expression = (MemberExpression)action.Body; string name = expression.Member.Name; return name; } /*, */ string[] GetChangedValues(DbEntityEntry entry) { return entry.CurrentValues .PropertyNames .Where(n => entry.Property(n).IsModified) .ToArray(); } /* */ bool IsInterestingChange(DbEntityEntry entry) { Type entityType = ObjectContext.GetObjectType(entry.Entity.GetType()); if (_trackedTypes.Keys.Contains(entityType)) { switch (entry.State) { case System.Data.Entity.EntityState.Added: case System.Data.Entity.EntityState.Deleted: return true; case System.Data.Entity.EntityState.Detached: case System.Data.Entity.EntityState.Unchanged: return false; case System.Data.Entity.EntityState.Modified: return GetChangedValues(entry).Any(v => !_trackedTypes[entityType].Contains(v)); default: throw new NotImplementedException(); } } else return false; } public override int SaveChanges() { bool needRefreshCache = ChangeTracker .Entries() .Any(e => IsInterestingChange(e)); int answer = base.SaveChanges(); if (needRefreshCache) { if (Transaction.Current == null) { RefreshCache(null, null); } else { Transaction.Current.TransactionCompleted -= RefreshCache; Transaction.Current.TransactionCompleted += RefreshCache; } } return answer; }
2çªç®ã®åé¡ã¯2段éã§è§£æ±ºãããŸããã æåã®æ®µéã§ãéåžžã«æªãã³ãŒããæžããŸããã ãŸããé床ãå®éã«åçã«å¢å ããããšã確èªãããã£ãã 第äºã«ãç§ãã¡ã¯äœããããå¿ èŠãããã³ãŒããèŠãããšæããŸããã å¿ èŠãªãã¹ãŠã®ã¡ã¿ããŒã¿ãååŸããããã®æéã®ã³ãŒãã§ããããã¹ãŠãå«ããããšãªãã¡ã¿ããŒã¿ãšã³ãã£ãã£ã®ãªã¹ããååŸããããšã«ãªããŸããã 次ã«ããã¹ãŠã®NavigationPropãæåã§æ¥çããŸããã
ãæªãããã£ãã·ã³ã°ã³ãŒãã®äŸ
// var taskColumns = Task.Factory.StartNewWithContext(() => { /* , isReadOnly , ..*/ using (var entities = new Context(connectionString, isReadOnly: true)) { return entities.Columns.ToList(); } }, connectionString); var taskTables = Task.Factory.StartNewWithContext(() => { using (var entities = new Context(connectionString, isReadOnly: true )) { return entities.Tables.ToList(); } }, connectionString); var columns = taskColumns.Result; var tables = taskTables.Result; /* Dictionary, ( )*/ var columnsDictByTableId = columns .GroupBy(c => c.TableId) .ToDictionary(c => c.Key, c => c.ToList()); foreach(var table in tables) { table.Columns = columnsDictByTableId[table.Id]; }
ãã¹ãŠã®ã¡ã¿ããŒã¿ãšã³ãã£ãã£ã®å®å šãªãªã¹ããååŸããããã®ã³ãŒãã¯ãã¹ã¬ããã«åå²ãããŸãã ããã¯ã倧ããªãªã¹ãã2ã3ãããªããåžžã«ããŒã¿ãåä¿¡ããŠââããã®ãæ¬è³ªçã«ãã®äžã«ãããšããäºå®ã«ãããã®ã§ãã ãã®å®è£ ã¯ãåã«PingãæžãããŸãã ãã®ã³ãŒãã®åé¡ã¯ãååšãããšã³ãã£ãã£ãå€ãã»ã©ããšã³ãã£ãã£éã®æ¥ç¶ãå€ããªãããšã§ãã æé·ã¯éç·åœ¢ã§ãã äžè¬ã«ãã³ãŒãã¯ããŸãæ©èœããŸãããç§ã¯ãããæžããããããŸããã§ããã ãã®çµæããã¹ãŠããªãã¬ã¯ã·ã§ã³ã§è¡ãããšã«ããŸããïŒäžèšãšåãã¢ã«ãŽãªãºã ãå®è£ ããŸããããã¹ãŠã®ããããã£ãšãšã³ãã£ãã£ã®ãµã€ã¯ã«ã§ïŒã
æ±çšãã£ãã·ã¥
// private Task<List<T>> GetEntitiesAsync<T>(string connectionString, Func<SokolDWEntities, List<T>> getter) { var task = Task.Factory.StartNewWithContext(() => { using (var entities = new SokolDWEntities(connectionString, isReadOnly: true)) { return getter(entities); } }, connectionString); return task; } /// <summary> /// , /// NavigationProp /// . , Include EF, . /// , , , . /// . , , BaseEntity. /// BaseEntity [Required][Key][DatabaseGenerated(DatabaseGeneratedOption.Identity)] public long Id { get; set; } /// Dictionary ( ) /// </summary> /// <param name="entities"> , </param> private void SetProperties(params object[] entities) { // -> #entitiesByTypes[typeof(Account)] -> var entitiesByTypes = new Dictionary<Type, object>(); //dictsById[typeof(Account)][1] -> 1 var dictsById = new Dictionary<Type, Dictionary<long, BaseEntity>>(); //dictsByCustomAttr[typeof(Column)]["TableId"][1] -> , 1 var dictsByCustomAttr = new Dictionary<Type, Dictionary<string, Dictionary<long, object>>>(); //pluralFksMetadata[typeof(Table)] Table var pluralFksMetadata = new Dictionary<Type, Dictionary<PropertyInfo, ForeignKeyAttribute>>(); //needGroupByPropList[typeof(Column)] , Dictionary ( ) var needGroupByPropList = new Dictionary<Type, List<string>>(); // entitiesByTypes dictsById foreach (var entitySetObject in entities) { var listType = entitySetObject.GetType(); if (listType.IsGenericType && (listType.GetGenericTypeDefinition() == typeof(List<>))) { Type entityType = listType.GetGenericArguments().Single(); entitiesByTypes.Add(entityType, entitySetObject); if (typeof(BaseEntity).IsAssignableFrom(entityType)) { //dictsById BaseEntity ( ) var entitySetList = entitySetObject as IEnumerable<BaseEntity>; var dictById = entitySetList.ToDictionary(o => o.Id); dictsById.Add(entityType, dictById); } } else { throw new ArgumentException(); } } // pluralFksMetadata needGroupByPropList foreach (var entitySet in entitiesByTypes) { Type entityType = entitySet.Key; var virtualProps = entityType .GetProperties() .Where(p => p.GetCustomAttributes(true).Any(attr => attr.GetType() == typeof(ForeignKeyAttribute))) .Where(p => p.GetGetMethod().IsVirtual) .ToList(); // NavigationProp var pluralFKs = virtualProps .Where(p => typeof(IEnumerable).IsAssignableFrom(p.PropertyType)) .Where(p => entitiesByTypes.Keys.Contains(p.PropertyType.GetGenericArguments().Single())) .ToDictionary(p => p, p => (p.GetCustomAttributes(true).Single(attr => attr.GetType() == typeof(ForeignKeyAttribute)) as ForeignKeyAttribute)); pluralFksMetadata.Add(entityType, pluralFKs); foreach (var pluralFK in pluralFKs) { Type pluralPropertyType = pluralFK.Key.PropertyType.GetGenericArguments().Single(); if (!needGroupByPropList.ContainsKey(pluralPropertyType)) { needGroupByPropList.Add(pluralPropertyType, new List<string>()); } if (!needGroupByPropList[pluralPropertyType].Contains(pluralFK.Value.Name)) { needGroupByPropList[pluralPropertyType].Add(pluralFK.Value.Name); } } // NavigationProp var singularFKsDictWithAttribute = virtualProps .Where(p => entitiesByTypes.Keys.Contains(p.PropertyType)) .ToDictionary(p => p, p => entityType.GetProperty((p.GetCustomAttributes(true).Single(attr => attr.GetType() == typeof(ForeignKeyAttribute)) as ForeignKeyAttribute).Name)); var entitySetList = entitySet.Value as IEnumerable<object>; // (NavigationProp) foreach (var entity in entitySetList) { foreach (var singularFK in singularFKsDictWithAttribute) { var dictById = dictsById[singularFK.Key.PropertyType]; long? value = (long?)singularFK.Value.GetValue(entity); if (value.HasValue && dictById.ContainsKey(value.Value)) { singularFK.Key.SetValue(entity, dictById[value.Value]); } } } } MethodInfo castMethod = typeof(Enumerable).GetMethod("Cast"); MethodInfo toListMethod = typeof(Enumerable).GetMethod("ToList"); // dictsByCustomAttr foreach (var needGroupByPropType in needGroupByPropList) { var entityList = entitiesByTypes[needGroupByPropType.Key] as IEnumerable<object>; foreach (var propName in needGroupByPropType.Value) { var prop = needGroupByPropType.Key.GetProperty(propName); var groupPropValues = entityList .ToDictionary(e => e, e => (long?)prop.GetValue(e)); var castMethodSpecific = castMethod.MakeGenericMethod(new Type[] { needGroupByPropType.Key }); var toListMethodSpecific = toListMethod.MakeGenericMethod(new Type[] { needGroupByPropType.Key }); var groupByValues = entityList .GroupBy(e => groupPropValues[e], e => e) .Where(e => e.Key != null) .ToDictionary(e => e.Key.Value, e => toListMethodSpecific.Invoke(null, new object[] { castMethodSpecific.Invoke(null, new object[] { e }) })); if (!dictsByCustomAttr.ContainsKey(needGroupByPropType.Key)) { dictsByCustomAttr.Add(needGroupByPropType.Key, new Dictionary<string, Dictionary<long, object>>()); } dictsByCustomAttr[needGroupByPropType.Key].Add(propName, groupByValues); } } // (NavigationProp) foreach (var pluralFkMetadata in pluralFksMetadata) { if (!dictsById.ContainsKey(pluralFkMetadata.Key)) continue; var entityList = entitiesByTypes[pluralFkMetadata.Key] as IEnumerable<object>; foreach (var entity in entityList) { var baseEntity = (BaseEntity)entity; foreach (var fkProp in pluralFkMetadata.Value) { var dictByCustomAttr = dictsByCustomAttr[fkProp.Key.PropertyType.GetGenericArguments().Single()]; if (dictByCustomAttr.ContainsKey(fkProp.Value.Name)) { if(dictByCustomAttr[fkProp.Value.Name].ContainsKey(baseEntity.Id)) fkProp.Key.SetValue(entity, dictByCustomAttr[fkProp.Value.Name][baseEntity.Id]); } } } } } //Without locking private DbWorkerCacheData RefreshNotSafe(string connectionString) { GlobalHost.ConnectionManager.GetHubContext<AdminHub>().Clients.All.cacheRefreshStart(); //get data parallel var accountsTask = GetEntitiesAsync(connectionString, e => e.Accounts.ToList()); //.. var tablesTask = GetEntitiesAsync(connectionString, e => e.Tables.ToList()); //wait data var accounts = accountsTask.Result; //.. var tables = tablesTask.Result; DAL.DbWorkers.Code.Extensions.SetProperties ( accounts, /*..*/ tables ); /* " ", O(1) */ }
ãã®æè»ãªãã£ãã·ã³ã°ã¡ãœãããäœæããåã«ãä¿æããŠããæ倧ã®ããŒã¿ããŒã¹ïŒ600以äžã®ãŠãŒã¶ãŒããŒãã«ã100以äžã®ããŒã«ïŒã§ã®RefreshCacheã®å®è¡æéã¯çŽ10ç§ã§ããã ãã®ã¡ãœããã®å®è£ åŸ-11.5ç§ã å®éããªãã¬ã¯ã·ã§ã³ãä»ããŠãã£ãŒã«ãã«ã¢ã¯ã»ã¹ããããã«äœåãªæéãè²»ããããŸãããã¿ã€ã ã©ã°ã¯ãããã§ãã ããããæéã®äžéšã¯ãä»ã§ã¯ãã¹ãŠã®ãšã³ãã£ãã£ã®ãã¹ãŠã®NavigationPropãéå§ããããšããäºå®ã«ãã£ãŠåãäžããããŸãããã以åã¯ãã¹ãŠã§ã¯ãããŸããã§ããã ãã®ã¢ãããŒãã®å©ç¹ã¯ãtable.Columns.FirstïŒïŒãTable.Columns ... I.e. ãã®äžé£ã®ãšã³ãã£ãã£å ã®ãã¹ãŠã®ãªã³ã¯ãåæãããçªç¶ã®NullReferenceExceptionãæããããšãªãã³ãŒããèšè¿°ã§ããŸãã
äžèšã®ãã£ãã·ã¥ã®å®è£ ã«ãããã·ã¹ãã ã®é床ãå€§å¹ ã«åäžããŸããã CPUã®è² è·ã¯æå°éã«ãªããŸããã ã·ã³ã°ã«ã³ã¢ãã·ã³äžã§ããCPUè² è·ãæå°éã«æããªãããäœçŸäººãã®ãŠãŒã¶ãŒã«ãšã£ãŠãã¹ãŠãè¿ éã«æ©èœããŸãã
ããŒã¿ã»ãã¥ãªãã£
顧客ããµãŒãã¹ã«ç§»è¡ããéãããŒã¿ã®å®å šæ§ã®åé¡ãããæ¥æ¿ã«çºçããŸããã ããã¯ã¹åããããœãªã¥ãŒã·ã§ã³ãæäŸããïŒãã³ãæšãŠãïŒãšããããŒã¿ã®å®å šæ§ã«é¢ãã質åã¯ãããŸããã§ããã ã¯ã©ã€ã¢ã³ãã«ã¯ãç¬èªã®ãµãŒããŒã管çè ãããã¯ã¢ããããããŸããã
ã¯ã©ãŠãããŒãžã§ã³ã§ã¯ãéåžžã«ç°¡åã«å®è¡ã§ããŸãã ã¯ã©ã€ã¢ã³ãã倱ãããšãæããŠãããšã³ãã£ãã£ã¯2çš®é¡ã®ã¿ã§ãã ããã¯ããŠãŒã¶ãŒãå ¥åããããŒã¿ããŒã¹å ã®ããŒã¿ãšãæ·»ä»ãããã¡ã€ã«ã§ãã ã©ã¡ããAmazon S3ã«ä¿åãããŸãã ååãšããŠããã¡ã€ã«ã¯ããã«ããã«ä¿åãããããŒã«ã«ãã£ã¹ã¯ã«ä¿åãããã®ã§ã¯ãªããWebãµãŒããŒçµç±ã§ã¢ããããŒããããŸãã ãŠãŒã¶ãŒããã¡ã€ã«ãããŠã³ããŒããããšããŠã§ããµãŒããŒèªäœããã®ãã¡ã€ã«ãAmazonããããŠã³ããŒãããã¯ã©ã€ã¢ã³ãã«æäŸããŸãã æ¯æ©ããã¹ãŠã®ææããŒã¿ããŒã¹ã®ããã¯ã¢ãããAmazonã«ã¢ããããŒããããŸãã æã«äžåºŠãç§èªèº«ãããŒã¿ããŒã¹ã®ãã¹ãŠã®ããã¯ã¢ãããããŒã«ã«ãã·ã³ã«ããŠã³ããŒãããŸãã
ãã¡ã€ã«ã«é¢ããŠã¯ãAmazon S3ã§ããŒã¿ã倱ããããšããŒã¿ã倱ãããå¯èœæ§ããããŸãã ããŒã¿ããŒã¹ã®ããŒã¿ã¯ãAmazon S3ããŠã§ããµãŒããŒãããŒã«ã«ãã·ã³ããæ¶ããŸãã
çµè«
ãããã£ãŠãäžèšã®ããã¹ãã¯ãã¢ãŒããã¯ãã£ã®çç£æ§ãæ¡åŒµæ§ãå®å šæ§ãã©ã®ããã«å®çŸãããã瀺ããŠããŸãã ãã®ã¢ãããŒãã«ããããããŒãžã£ãŒã¯ããã°ã©ããŒãªãã§ã¢ããªã±ãŒã·ã§ã³ã®ãããã¿ã€ãïŒã»ãšãã©æ¢è£œã®ã¢ããªã±ãŒã·ã§ã³ã§ãã£ãŠãïŒãäœæã§ããŸããã ãããžã§ã¯ãå šäœã®ã¡ã³ããã³ã¹ã«ãããæéãå€§å¹ ã«ççž®ãããŸããã ã·ã¹ãã ã®é床ãå€§å¹ ã«åäžããããµãŒããŒã®ã³ã¹ããåæžããããšãã§ããŸããã
ãªããã®ããã¹ããæžããã®ã§ãã
ããã¯ç§ãå人çã«è¡ã£ãäžã§æãè€éã§èå³æ·±ãã·ã¹ãã ã§ããããã§ã¯ãå°ãããªãããéèŠãªåŽé¢ã®ã¿ã説æããŸãïŒãŠãŒã¶ãŒã¢ããªã±ãŒã·ã§ã³éã®ãªãœãŒã¹å ±æïŒãå®éãã·ã¹ãã ã¯éåžžã«å€§ããå€æ©èœã§ãããã®æçš¿ã®å·çã¯ãç§ãã¡ãæ£ç¢ºã«äœãããã®ãããããŠãã®çç±ãäœç³»åããŠå®çŸããã®ã«åœ¹ç«ã¡ãŸããããã®ããã¹ãã¯ããã®ææããµãŒãã¹ã®ã¬ãã«ã«èŠçŽããããšãèããŠãã人ã«ãšã£ãŠèå³æ·±ããã®ã«ãªããšæããŸããç§ãã¡ã®åé¡ãšè§£æ±ºçã¯ãŠããŒã¯ã§ã¯ãªããšæããŸãããããã誰ãããœãªã¥ãŒã·ã§ã³ã®äžéšãæ¹å€ããããæ£ç¢º/è¿ é/æè»ãªäœããæäŸããã§ããããæçµçã«ãããã¯ç§ãã¡ã匷ãããããšãã§ããŸãããŸãããããŠãã¡ãããç§ãã¡ã¯ç§ãã¡ã«ã€ããŠèãããããšæããŸãããçªç¶ããã®æçš¿ãèªãã åŸãç§ãã¡ã®ã·ã¹ãã ã«ãã°ã€ã³ããŠãããèŠãããšæãã§ããããçŸåšãéçºè ãšITã€ã³ãã°ã¬ãŒã¿ãŒåãã®ã¢ãã£ãªãšã€ãããã°ã©ã ãéå§ããŠããŸãïŒç§ã®äŒç€Ÿã®ãŠã§ããµã€ãã¯ç§ã®ãããã£ãŒã«ã«èšèŒãããŠããŸãïŒãäŒèšã·ã¹ãã ã®èšèšè ãä»ã®äººã«åœ¹ç«ã€ããšãæãã§ããŸãã
UPD 1.ã¢ã³ã±ãŒããè¿œå ããŸããïŒãµã³ãããã¯ã¹ã«ã¯ãã®ãããªãªãã·ã§ã³ã¯ãããŸããã§ããïŒã