ç§ã¯æè¿ãEFã䜿çšãããã¹ãŠã®äººãEFã®èª¿çæ¹æ³ãç¥ã£ãŠããããã§ã¯ãªãããšãçºèŠããŸãããããã«ã圌ãã¯çè§£ããããšã«ç±å¿ã§ã¯ãããŸãããéåžžã«æ©ã段éã§åé¡ã«çŽé¢ããŠãã-ã»ããã¢ããã
æ§æãæåããåŸã§ããããŒã¿èŠæ±ã«åé¡ããããŸãã人ã ãLINQãç¥ããªãããã§ã¯ãªãããã¹ãŠããªããžã§ã¯ããããªã¬ãŒã·ã§ãã«ã¢ãã«ã«ãããã³ã°ã§ããããã§ã¯ãªãããã§ãããªã³ã¯ãæäœãããšãã人ã ã¯ããŒãã«ã§èããããã§ããSQLã¯ãšãªãæç»ããããããLINQã«å€æããŠã¿ãŸãã
ãããšããããããç§ãèšäºã§è©±ãããä»ã®äœãã
ã»ããã¢ãã
ãã人ããããžã§ã¯ãã«æ¥ãŠãããã§åããŠEFãèŠãŠããã®ãããªå¥è·¡ã«é©ããŠãããã䜿ãããšãåŠã³ãå人çãªç®çã«äœ¿ãããšã«æ±ºããŸãããæ°ãããããžã§ã¯ããäœæããŸãã...ãããŠäœãããŸããïŒ
ããªãã¯ã°ãŒã°ã«ã詊è¡ããšã©ãŒãéå§ããŸãã EFããããžã§ã¯ãã«åçŽã«æ¥ç¶ããããã«ãéçºè ã¯çè§£ã§ããªãçš®é¡ã®åé¡ã«çŽé¢ããŸãã
1.å¿ èŠãªDBMSã§åäœããããã«æ§æããã«ã¯ã©ãããã°ããã§ããïŒ
2.ç§»è¡ã®äœæ¥ãæ§æããã«ã¯ã©ãããã°ããã§ããïŒ
ãã£ãšåé¡ããããšæããŸãããããããããããæãé »ç¹ãªåé¡ã§ãããã¹ãŠãé çªã«è©±ããŸãããã
1.ããŠãããã¯ã°ãŒã°ã«ã§ãã :)ããªãã®ä»äºã¯ãDBMSçšã®EntityFrameworkã³ã¢ãããã€ããŒãèŠã€ããããšã§ãã
ãŸãããããã€ããŒã®èª¬æã«ã¯ãã»ããã¢ããã®æé ãèšèŒãããŠããŸãã
ããšãã°ãPostgreSQLã®å ŽåãNugetããã±ãŒãžNpgsql.EntityFrameworkCore.PostgreSQLãã€ã³ã¹ããŒã«ããå¿ èŠããããŸãã
DbContextOptionsãåãå ¥ããç¬èªã®ã³ã³ããã¹ããäœæããæ¬¡ã®ããã«å šäœãäœæããŸã
var opts = new DbContextOptionsBuilder<MyDbContext>()
.UseNpgsql(constring);
var ctx = new MyDbContext(opts.Options);
ASP .NET Coreã¢ããªã±ãŒã·ã§ã³ã䜿çšããŠããå Žåãã³ã³ããã¹ãã¯ã³ã³ãããŒã«ç°ãªãæ¹æ³ã§ç»é²ãããŸããããããããªãã¯ãã§ã«ããªãã®äœæ¥ãããžã§ã¯ãã§ãããèŠãããšãã§ããŸãããŸãã¯ã°ãŒã°ã«ã
2.äŒç€Ÿã«ä¹³æ¯ãããªãå Žåã¯ãç§»è¡ãæäœããããã«å¿ èŠãªããŒã«ãã€ã³ã¹ããŒã«ããæ¹æ³ãç¥ã£ãŠããå¯èœæ§ããããŸããããã±ãŒãžãããŒãžã£ãŒçšãNETCoreCLIçšãã
ãã ããæ°ä»ããŠããªããããããŸããããéžæããã¹ã¿ãŒãã¢ãããããžã§ã¯ãïŒ--startup-projectïŒã¯ãç§»è¡ãæäœãããšãã«éå§ãããŸããã€ãŸããç§»è¡ã®éå§ãããžã§ã¯ããã¢ããªã±ãŒã·ã§ã³ãèµ·åãããããžã§ã¯ããšåãã§ãããäœããã®çç±ã§éå§ãããšãã«ctx.Database.MigrateïŒïŒã䜿çšããŠç§»è¡ãããŒã«ããäœæããããšãããšã以åã«äœæããç§»è¡ãåé€ããããå¥ã®ç§»è¡ãäœæããŸããæåŸã«äœæãããç§»è¡ãããŒã¹ã«ããŒã«ãããŸããé©ãïŒ
ãããããããããæåã®ç§»è¡ãäœæããããšãããšã次ã®ãããªãã®ãèŠã€ãããŸã
ãã®DbContextã«ã¯ããŒã¿ããŒã¹ãããã€ããŒãæ§æãããŠããŸããããããã€ããŒã¯ãDbContext.OnConfigureã¡ãœããããªãŒããŒã©ã€ãããããã¢ããªã±ãŒã·ã§ã³ãµãŒãã¹ãããã€ããŒã§AddDbContextã䜿çšããŠæ§æã§ããŸããAddDbContextã䜿çšããå Žåã¯ãDbContextã¿ã€ããã³ã³ã¹ãã©ã¯ã¿ãŒã§DbContextOptions <TContext>ãªããžã§ã¯ããåãå ¥ãããããDbContextã®åºæ¬ã³ã³ã¹ãã©ã¯ã¿ãŒã«æž¡ãããšã確èªããŠãã ããã
ããã¯ãç§»è¡ãåŠçããããŒã«ãã³ã³ããã¹ãã«åºã¥ããŠç§»è¡ãäœæããããã§ããããã®ããã«ã¯ã€ã³ã¹ã¿ã³ã¹ãå¿ èŠã§ãããããæäŸããã«ã¯ãã¹ã¿ãŒã¿ãŒãããžã§ã¯ãã«IDesignTimeDbContextFactoryã€ã³ã¿ãŒãã§ã€ã¹ãå®è£ ããå¿ èŠããããŸããããã¯é£ãããããŸãããã³ã³ããã¹ãã®ã€ã³ã¹ã¿ã³ã¹ãè¿ãå¿ èŠãããã¡ãœããã¯1ã€ã ãã§ãã
ã¢ãã«ã®èšå®
æåã®ç§»è¡ã¯ãã§ã«äœæãããŠããŸãããäœããã®çç±ã§ç©ºã§ããã¢ãã«ã¯ãããŸããã
éèŠãªã®ã¯ãã¢ãã«ãããŒã¿ããŒã¹ã«å€æããããã®ã³ã³ããã¹ããæããŠããªããšããããšã§ãã
EFãç§»è¡ãäœæããŠããŒã¿ããŒã¹ã«ã¢ãã«ã®ããŒãã«ãäœæããã«ã¯ãå°ãªããšãã³ã³ããã¹ãã«DbSet <MyEntity>ã¿ã€ãã®ããããã£ãäœæããå¿ èŠããããŸãã
ããšãã°ããã®ããããã£ã«ãã£ãŠ
public DbSet <MyEntity> MyEntities {get;ã»ãããã; }
MyEntitiesããŒãã«ã¯MyEntityãšã³ãã£ãã£ã®ããããã£ã«å¯Ÿå¿ãããã£ãŒã«ãã䜿çšããŠäœæãããŸãã
DbSetã䜿çšããããªãå ŽåããŸãã¯ãšã³ãã£ãã£ã®ããã©ã«ãã®ããŒãã«äœæã«ãŒã«ã«åœ±é¿ãäžãããå Žåã¯
protected override void OnModelCreating(ModelBuilder modelBuilder)
ãã³ã³ããã¹ãã®ã¡ãœããããªãŒããŒã©ã€ãããå¿ èŠããããŸãã
ãããè¡ãæ¹æ³ãããªãã¯ããããç¥ã£ãŠããŸããããã«ããããã³ã°ã«ãŒã«ãå¶åŸ¡ã§ãã屿§ã«ã€ããŠã¯ãããããåç¥ã§ããããããããããã«ãããŸãã屿§ã§ã¯ãããã³ã°ãå®å šã«å¶åŸ¡ã§ããŸãããã€ãŸããOnModelCreatingãæ¹è¯ããå¿ èŠããããŸããã€ãŸããæ³šéã®åœ¢åŒã𿵿¢ãªapiã®åœ¢åŒã®äž¡æ¹ã§ãšã³ãã£ãã£ããããã³ã°ããããã®ã«ãŒã«ããããŸããæ¬¡ã«ããã£ãŒã«ãã®ååãééã£ãŠããçç±ãäºæ³ã©ããã®ååããŸãã¯ééã£ãå¶éãæ¢ããŸãã
-ããã§ã¯ããã¹ãŠãåçŽã§ã-ããªããèšã-OnModelCreatingãä»ããŠãã¹ãŠãæ§æããŸã
ãããŠã10åã®ãã£ãŒã«ããã20çªç®ã®ãšã³ãã£ãã£ãèšå®ããåŸãããªãã®ç®ã¯æ³¢æã€ããã«ãªããŸãããããšã³ãã£ãã£ã®ãã£ãŒã«ãèšå®ãèŠã€ããããšããŠããŸããã200ã500è¡ã®é·ãã®åäžãªãããã¯ãããã¹ãŠãç®ã®åã«æµ®ããã§ããŸãã
ã¯ãããã®ãããã¯ã20ã®ã¡ãœããã«åå²ã§ããå°ãç°¡åã«ãªããŸãããã ããIEntityTypeConfiguration <TEntity>ã€ã³ã¿ãŒãã§ã€ã¹ãããããšãç¥ã£ãŠãããšäŸ¿å©ã§ãããããå®è£ ããããšã§ãç¹å®ã®ãšã³ãã£ãã£ã«å¯ŸããŠããã®å®è£ ã§ç¹å®ã®ãšã³ãã£ãã£ã®ãããã³ã°ã«ãŒã«ãèšè¿°ã§ããŸããã³ã³ããã¹ãããããååŸããã«ã¯ã
OnModelCreatingã§modelBuilder.ApplyConfigurationsFromAssemblyïŒassemblyWithConfigurationsïŒ;ãèšè¿°ããå¿ èŠããããŸãã
ãããŠãã¡ãããäžè¬çãªåäœãåãOnModelCreatingã«è»¢éããããšãã§ããŸããããšãã°ããã¹ãŠãŸãã¯å€æ°ã®ãšã³ãã£ãã£ã®èå¥åã«é¢ããäžè¬çãªã«ãŒã«ãããå Žåã¯ã次ã®ããã«æ§æã§ããŸãã
foreach (var idEntity in modelBuilder.Model.GetEntityTypes()
.Where(x => typeof(BaseIdEntity).IsAssignableFrom(x.ClrType))
.Select(x => modelBuilder.Entity(x.ClrType)))
{
idEntity.HasKey(nameof(BaseIdEntity.Id));
}
ã¯ãšãªã®äœæ
ããŠãæŽçæŽé ããŠãããå°ãæ°æã¡ãããªããŸããã
çŸåšãããŒã ãããžã§ã¯ãã®ã¯ãšãªãSQLããLinqã«ããçŽãå¿ èŠããããŸããç§ã¯ãã§ã«ä»äºã§ãªã¯ãšã¹ããæžããŠããŸããããã¯
梚ãç ²æããã®ãšåããããç°¡åã§ãctx.MyEntities.WhereïŒæ¡ä»¶ïŒ.SelectïŒãããïŒ.GroupByïŒåŒïŒ.OrderByïŒåŒïŒâŠè»œãã
ããã§ãç§ãã¡ã®èŠæ±ã¯äœã§ããïŒ
SELECT bla bla bla FROM table
RIGHT JOIN.......
ãã
ctx.LeftEntities.RightJoin(.... f@#$
ç§ã¯EFãç¥ããã£ãšåãããLinqãšãã®æ¡åŒµã¡ãœããã䜿çšããŠããŸãããäžåºŠã質åã¯ãããŸããã§ããããRIGHT JOINãLEFT JOINã¯
ã©ãã«ãããŸãã...ãªããžã§ã¯ãã®èгç¹ããLEFTJOINãšã¯äœã§ããïŒ
ãã
class LeftEntity
{
public List<RightEntity> RightEntities { get; set; }
}
ãããéæ³ã§ã¯ãããŸãããä»ã®ãšã³ãã£ãã£ã®ãªã¹ããåç §ããç¹å®ã®ãšã³ãã£ãã£ããããŸããããªãå ŽåããããŸãã
ã€ãŸãããã
ctx.LeftEntities.Include(x => x.RightEntities)
RIGHT JOINãšã¯äœã§ããïŒããã¯éLEFTJOINã§ããã€ãŸããå¥ã®ãšã³ãã£ãã£ããå§ããŸãã
ãã ãããã¹ãŠãçºçããŸããå·ŠåŽã®ãšã³ãã£ãã£ãåäžã®å³åŽã®ãšã³ãã£ãã£ã«é¢é£ä»ããããŠããªãå ŽåïŒå³åŽã®ãšã³ãã£ãã£ãNULLã®å ŽåïŒã§ããåãã³ãã«ãåå¥ã®ãšã³ãã£ãã£ãšããŠå¶åŸ¡ããå¿ èŠãããå ŽåããããŸãããããã£ãŠãæç€ºçã«LEFTJOINã¯æ¬¡ã®ããã«å®è¡ã§ããŸãã
ctx.LeftEntities.SelectMany(x => x.RightEntities.DefaultIfEmpty(), (l, r) => new { Left = l, Right = r })
ããã«ããããªã¬ãŒã·ã§ãã«ã¢ãã«ã®å Žåãšåæ§ã«ããã€ã³ãã£ã³ã°ãå¶åŸ¡ã§ããŸãããªãããªãã¯ãããå¿ èŠãšããã®ã§ããããïŒé¡§å®¢ãããŒã¿ãããŒãã«ã®åœ¢åŒã§è¡šç€ºããå¿ èŠããããäžŠã¹æ¿ããããŒãžä»ããå¿ èŠã§ãããšããŸãã
ç§ããã®ã¢ã€ãã¢ã¯å¥œãã§ã¯ãããŸããããExcelã«ã¯èª°ããç¬èªã®çãšç¡éã®æãæã£ãŠããŸããããã§ãããããå³ã§èŠãããã¶ãã«åªãããããä»äºãç¶ããŸããæ¬¡ã¯äœã§ããïŒ
FULL JOIN
ã ããããŸããç§ã¯ãã§ã«çè§£ããŸãããç§ãã¡ã¯SQLã§èããŠããŸãããç§ãã¡ã¯ãã®ãããªãªããžã§ã¯ãã§èããŠããŸãããããŠä»ãã®ããã«...ãããŒããããã©ã®ããã«è¡šçŸããŸããïŒ
ã¿ãã«ãªãã§ã¯ãã©ãã«ãã
äžè¬ã«ãã¿ãã«ã䜿çšããå¿ èŠãããå Žåãæ¥ç¶ã®ã¿ã€ãïŒ1-1ã1-nãnnïŒã«ã€ããŠã®çè§£ã倱ãããäžè¬ã«ãçè«çã«ã¯ãããšãšè±¡ã亀差ãããããšãã§ããŸããããã¯é»ãéæ³ã§ãã
ãã£ãŠã¿ãŸãããïŒ
åºç€ãšããŠå€å¯Ÿå€ãåããŸãããã
ãããã£ãŠã3çš®é¡ã®ãšã³ãã£ãã£
LeftEntity
RightEntity
LeftRightïŒæ¥ç¶ãæŽçããããïŒ
LeftRightãåæããŒã§äœæããŸãããã®ãšã³ãã£ãã£ã«çŽæ¥ã¢ã¯ã»ã¹ããå¿ èŠã¯ãããŸãããå€éšããåç §ããå¿ èŠããªããããäžèŠãªãã£ãŒã«ããã€ã³ããã¯ã¹ãäœæããŸããã
ã¯ãšãªã®çµæãšããŠãå·ŠåŽã®ãšã³ãã£ãã£ãšå³åŽã®ãšã³ãã£ãã£ãå«ãã¿ãã«ã®ã»ãããååŸããããšæããŸããããã«ãããŒãžã³ãšã³ãã£ãã£ãæ£ãããšã³ãã£ãã£ãšã¯äœã®é¢ä¿ããªãå Žåãæ£ãããªããžã§ã¯ãã¯nullã«ãªããŸããåãããšãå³åŽã®ãšã³ãã£ãã£ã«ãåœãŠã¯ãŸããŸãã
LeftRightã¯åºåãšããŠã¯é©ããŠããªãããšã倿ããŸããããã®å¶éã«ããããšã³ãã£ãã£ã®1ã€ããªããšãã³ãã«ãäœæã§ããŸããã DDDãç·Žç¿ãããšãççŸãçºçããŸãã
ç·Žç¿ããªããŠããç·Žç¿ãã¹ãã§ã¯ãããŸããã
LeftRightFullåºåã®æ°ããã¿ã€ããäœæããŸããããããã«ã¯ãå·Šå³ã®ãšã³ãã£ãã£ãžã®ãªã³ã¯ãå«ãŸããŠããŸãã
ã ãããæã ã¯
å·Š
L1
L2
å³
R1
R2
LeftRight
L2 R2ã
ç§ãã¡ã¯ãåºåã§æ¬²ãã
L1 N
L2 R2
nR1
å·ŠåŽã®æ¥ç¶ããå§ããŸããã
var query = ctx.LeftEntities
.SelectMany(x => x.RightLinks.DefaultIfEmpty(), (l, lr) => new LeftRightFull
{
LeftEntity = l,
RightEntity = lr.RightEntity
})
ä»ãç§ãã¡ã¯ãã§ã«
L1 n
L2 R2ãæã£ãŠããŸã
次ã¯äœã§ããïŒ SelectManyãä»ããŠRightEntityãã¹ãã£ãã¯ããŸããïŒããŠã
L1 n R1 n
L1 n R2 L2
L2 R2 R1 n
L2 R2 R2 L2ãååŸ
ããŸããæ¡ä»¶ã«ãã£ãŠäžèŠãªãã®ïŒL2 R2 R1nããã³L1n R2 L2ïŒãé€å€ã§ããŸãããL1 n R1nã倿ããæ¹æ³ã¯äžæã§ãã in
L1 n
n R1
ãããããçºæã«ãã£ãŠç§ãã¡ã¯ééã£ãéæ®µã«é£ããŠè¡ãããŸããããããã®åæ§ã®ã¯ãšãªããUnionãä»ããŠå·Šå³ã®ãšã³ãã£ãã£ã®å·Šçµåã«æ¥ç¶ããŠã¿ãŸãããã
L1 n
L2 R2
UNION
L2 R2
nR1
ããã§ããã©ãŒãã³ã¹ã«ã€ããŠè³ªåããããããããŸããããã¹ãŠãç¹å®ã®DBMSãšãã®ãªããã£ãã€ã¶ã®çްå¿ãã«äŸåãããããç§ã¯ãããã«çããŸããã
ãŸãã¯ãç®çã®ã¯ãšãªã䜿çšããŠãã¥ãŒãäœæããããšãã§ããŸããUnionã¯EFCore 2ã§åäœããªãããããã¥ãŒãäœæããå¿ èŠããããŸããããã ããå¿ããªãããšããå§ãããŸããçªç¶ãIsDeletedãã©ã°ã䜿çšããŠãšã³ãã£ãã£ã®ãœããåé€ãå®è£ ããããšã«ããŸããããã¥ãŒã§ã¯ãããããµããŒãããå¿ èŠããããŸããå¿ããŠããŸã£ãå Žåããã€ãã°ã¬ããŒããåãåããã¯ããããŸããã
ã¡ãªã¿ã«ãã³ãŒãå šäœãæžãçŽããã«ãœããåé€ãå®è£ ããã«ã¯ã©ãããã°ããã§ããïŒæ¬¡åã¯ããã«ã€ããŠã話ããŸããå€åäœãä»ã®ãã®ã
ã¿ãªãããããããªãã