MS_EntityFrameworkResearch - NetDevInfraWGinOSSConsortium/NetDevInfraWiki GitHub Wiki
- æ»ãïŒEntity FrameworkïŒ
- Entity Framework ã®èª¿æ»
- Entity Framework ã®æžå¿µ
Entity Framework ã®æžå¿µã«å¯Ÿãã調æ»çµæã
- ãŠãŒã¶ãŒå®çŸ©ã®
DbContextãçæ -
SqlQueryã¡ãœããã§æå°éã®ããŒã¿ãååŸ -
DbContextãžæ ŒçŽ -
DbContextã®ã©ã€ãã¿ã€ã ã®ç®¡ç
äŸãã°ãProductContext ã¯ã©ã¹ã¯
-
DbContextã¯ã©ã¹ããæŽŸçããå¿ èŠãããã -
DbSetã®ããããã£ãå«ããå¿ èŠãããã -
DbSetããããã£ã¯ãã³ã³ããã¹ãã§æå®ããããšã³ãã£ãã£ã®ã³ã¬ã¯ã·ã§ã³ã衚ãã
public class ProductContext : DbContext
{
public DbSet<Category> Categories { get; set; }- Entity Framework Designer ã䜿çšããŠããå Žåã
ã³ã³ããã¹ãã¯ãVisual Studio ã®ãã³ãã¬ãŒãã«ãã£ãŠèªåçã«çæãããã - ã³ãŒããã¡ãŒã¹ã ãã¯ããã¯ã䜿çšããŠããå Žåã¯ãæåã§ã³ã³ããã¹ããäœæããã
ã¡ã¢ãªã®ããŒã¿ä¿æã¯ãDbContext ãªããžã§ã¯ã ã€ã³ã¹ã¿ã³ã¹ã®ã©ã€ãã¿ã€ã ãšåãã
以äžã®ããã«ãusing ã䜿ããšãã©ã€ãã¿ã€ã ã¯æç¢ºã«ãªãã
using (ProductContext context = new ProductContext())
{
// Perform data access using the context
}è£è¶³ïŒã©ã€ãã¿ã€ã ã¯çãä¿ã€ïŒ:
DbContextã¯
倿Žè¿œè·¡ã®ããã«èªã¿èŸŒãã ãšã³ãã£ãã£ããã¹ãŠä¿æãç¶ããããã
é·å¯¿åœã«ãããšã¡ã¢ãªãé£ãããã£ãã·ã¥ãå€ããªãã
ãŸããã¹ã¬ãã ã»ãŒãã§ã¯ãªããASP.NET Core ã§ã¯
AddDbContextã®æ¢å®ã ScopedïŒãªã¯ãšã¹ãåäœïŒã§ã
ãã®ååããã¬ãŒã ã¯ãŒã¯åŽã§æ ä¿ãããŠããã
ã·ã³ã°ã«ãã³ã«ãããããã¯ã°ã©ãŠã³ãåŠçã§äœ¿ãåãããããŠã¯ãªããªã
ïŒIDbContextFactory<T>ã䜿ã£ãŠéœåºŠçæããïŒã
using (ProductContext context = new ProductContext())
{
// Below code is enumerated using ToList() method.
// Stores all records in âmyCategoriesâ object (Memory)
IList<Category> myCategories =
context.Database.SqlQuery<Category>("Select * from Category").ToList();
}è£è¶³ïŒææ°åïŒEF Core ã§ã®ç SQLïŒ: EF Core ã§ã¯
Database.SqlQuery<T>ã®ä»£ããã«ä»¥äžã䜿ãã
çšé EF6 EF Core ãšã³ãã£ãã£åãè¿ã Set<T>().SqlQuery(...)Set<T>().FromSql($"...")ä»»æã®åã»ã¹ã«ã©ãŒãè¿ã Database.SqlQuery<T>(...)Database.SqlQuery<T>($"...")ïŒEF Core 8 以éïŒæŽæ°ç³» Database.ExecuteSqlCommand(...)Database.ExecuteSql($"...")éèŠ: EF Core ã®
FromSql/ExecuteSqlã¯
FormattableStringãåãåããè£éããå€ãèªåçã«ãã©ã¡ãŒã¿åããã// OK: @p0 ãšããŠãã©ã¡ãŒã¿åããã var rows = await context.Categories .FromSql($"SELECT * FROM Category WHERE Id = {id}") .ToListAsync();æååãèªåã§é£çµããŠæž¡ã
FromSqlRaw/ExecuteSqlRawã¯
SQL ã€ã³ãžã§ã¯ã·ã§ã³ã®å±éºããããããåå䜿ããªãã
- åãã©ã³ã¶ã¯ã·ã§ã³ã®ããã®æ°ããæ¥ç¶ãäœæããã
-
SaveChangesã¡ãœãããåŒã³åºããããšãå éšã§ãã©ã³ã¶ã¯ã·ã§ã³ãç¶æããã - äžåã®
SaveChangesã¡ãœããã§è€æ°ãšã³ãã£ãã£æŽæ°ã®ãã©ã³ã¶ã¯ã·ã§ã³ãç¶æããã
TransactionScopeã䜿çšããŠãã©ã³ã¶ã¯ã·ã§ã³ãåŠçããã
using (EntitiesContext context = new EntitiesContext())
{
using (TransactionScope scope = new TransactionScope())
{
//Code here
}
}è£è¶³: ãã®ã³ãŒãã¯
scope.Complete()ã®åŒã³åºããçç¥ãããŠããããã
ãã®ãŸãŸã§ã¯å¿ ãããŒã«ããã¯ãããïŒèª¬æçšã®éªšæ Œãšèªãã¹ãïŒã
ãŸããTransactionScopeã®æ¢å®ã®åé¢ã¬ãã«ã¯Serializableã§ããã
æç€ºæå®ãæšå¥šãããã詳现ã¯TransactionScopeãåç §ã
ASP.NET MVC ã§ DbContext ã®ãã©ã³ã¶ã¯ã·ã§ã³ãš
ç¬èª SQL åŠçã®ãã©ã³ã¶ã¯ã·ã§ã³ãåäžã®ã¹ã³ãŒãã«ãã
http://blog.makotoishida.com/2012/12/aspnet-mvcdbcontextsql.html
ãã©ã³ã¶ã¯ã·ã§ã³ãç¶æããããã«ã2 ã€ã®æ°ãã API ãå°å ¥ããŠããã
- ãã©ã³ã¶ã¯ã·ã§ã³ãéå§ããã
- ãã©ã³ã¶ã¯ã·ã§ã³ã®åé¢ã¬ãã«ãæå®ããããšãã§ããã
- ããã€ãã®æäœãçµã¿åãããŠãåããã©ã³ã¶ã¯ã·ã§ã³å ã§çµåããããšãã§ããã
- ãããã£ãŠãå šãŠã®ãã©ã³ã¶ã¯ã·ã§ã³ãã³ããããŸãã¯ããŒã«ããã¯ããããšãã§ããã
using (EntitiesContext context = new EntitiesContext())
{
using (var transaction = context.Database.BeginTransaction())
{
try
{
EmployeeMaster employee = new EmployeeMaster();
employee.Code = "A0001";
employee.Name = "Jignesh Trivedi";
employee.DepartmentId = 1;
context.Employees.Add(employee);
context.SaveChanges();
DepartmentMaster dept = new DepartmentMaster();
dept.Code = "DEP0001";
dept.Name = "Department 1";
context.Departments.Add(dept);
context.SaveChanges();
transaction.Commit();
}
catch (Exception ex)
{
transaction.Rollback();
}
}
}è£è¶³ïŒ
catchã§ã®Rollbackã¯äžèŠïŒ:usingãæããéã
ã³ããããããŠããªããã©ã³ã¶ã¯ã·ã§ã³ã¯Disposeã§èªåçã«
ããŒã«ããã¯ããããããcatchå ã®æç€ºçãªRollback()ã¯æ¬æ¥äžèŠã§ãã
ïŒDapperã®ç¯ã«ããææãšåãïŒããŸããäžèšã®ããã«äŸå€ãæ¡ãã€ã¶ã
catch (Exception ex)ã¯
åŒã³åºãå ããšã©ãŒãæ€ç¥ã§ããªããªãããã
å®åã§ã¯åã¹ããŒããããããããcatchãæžããªãã
- Entity Framework å€ã§æèšããããã©ã³ã¶ã¯ã·ã§ã³ã䜿çšãã
DbContextã€ã³ã¹ã¿ã³ã¹ãèš±å¯ããã - Entity Framework ã§ããã® API ã䜿çšãä»»æã®æ¢åãã©ã³ã¶ã¯ã·ã§ã³ã䜿çšããããšãã§ããã
using (SqlConnection con = new SqlConnection("connectionString"))
{
con.Open();
using (var transaction = con.BeginTransaction())
{
// Do something....
//Pass this transaction to Entity Framework....
using (EntitiesContext context = new EntitiesContext(con, false))
{
context.Database.UseTransaction(transaction);
EmployeeMaster employee = new EmployeeMaster();
employee.Code = "A0001";
employee.Name = "Jignesh Trivedi";
employee.DepartmentId = 1;
context.Employees.Add(employee);
context.SaveChanges();
}
}
}è£è¶³ïŒ
UseTransactionã®äŸ¡å€ïŒ: ããã¯
EF ãš Dapper / çã® ADO.NET ãåäžãã©ã³ã¶ã¯ã·ã§ã³ã§äœµçšãã
ããã® API ã§ããã
æ¥ç¶ãå ±æã§ãããããMS-DTCãžã®ææ Œã䌎ããã«æžã
ïŒTransactionScopeã®ææ Œã®è©±ãåç §ïŒãADO.NET vs ORM (Entity Framework, Dapper)ã§è¿°ã¹ã
ãEF ãš Dapper ã®ãã€ããªããæ§æããæç«ãããèŠã®æ©èœãšèšããã
ãªããã³ã³ã¹ãã©ã¯ã¿ã®ç¬¬ 2 åŒæ°falseã¯
ãæ¥ç¶ã®æææš©ãDbContextã«æž¡ããªããïŒ
DbContextã®ç Žæ£æã«æ¥ç¶ãéããªãããšããæå³ã§ããã
Entity Framework ã§æŽæ°åŠçãå®è¡ããå Žåã
åºæ¬çã«ã¯ãSaveChanges ã¡ãœããã䜿çšããã
ExecuteSqlCommand ã¡ãœããã¯ã
-
ã³ã³ããã¹ãå ã®ãšã³ãã£ãã£ã®å 容ã«é¢ä¿ãªãã
INSERTãUPDATEãDELETE ãªã©ã®ã¯ãšãªãå®è¡ã§ããã -
ãã®ãã
ExecuteSqlCommandã¡ãœããã®å®è¡åŸã¯ã
ãšã³ãã£ãã£ãš DB ã®å 容ã¯äžèŽããŠããªãã -
åŸã£ãŠããšã³ãã£ãã£ãš DB ã®å 容ãäžèŽãããå¿ èŠãããå Žåã
ã³ã³ããã¹ãå ã®ãšã³ãã£ãã£ããªãã¬ãã·ã¥ããå¿ èŠãããã
((IObjectContextAdapter)context).ObjectContext.Detach(myCategory);ObjectContext context = ((IObjectContextAdapter)myDbContext).ObjectContext;
// Refresh specific Entity object in the context
context.Refresh(System.Data.Objects.RefreshMode.StoreWins, myCategory);(OR)
// Refresh All Entities in the context.
var refreshableObjects = myDbContext.ChangeTracker.Entries().Select(c => c.Entity).ToList();
context.Refresh(System.Data.Objects.RefreshMode.StoreWins, refreshableObjects);è£è¶³ïŒææ°åïŒEF Core ã§ã®åæïŒ: EF Core ã«ã¯
ObjectContext/Refreshãååšããªãã代ããã«ã// åå¥ã®ãšã³ãã£ãã£ã DB ã®å€ã§äžæžã await context.Entry(myCategory).ReloadAsync(); // è¿œè·¡ç¶æ ããã¹ãŠç Žæ£ context.ChangeTracker.Clear(); // EF Core 5 以éã䜿ãã
ãªããEF Core 7 以éã®
ExecuteUpdate/ExecuteDeleteã
åãã倿Žè¿œè·¡ãçµç±ããªããããæ¬ç¯ãšåãäžäžèŽãèµ·ããã
ãäžæ¬æŽæ°ããåŸãåãDbContextã§èªã¿çŽããšå€ãå€ãè¿ãã
ãšããäºæ ã«ã€ãªããã®ã§ã
- äžæ¬æŽæ°ã¯å°çšã®çåœãª
DbContextã§è¡ã- ãããã¯å®è¡åŸã«
ChangeTracker.Clear()ããã®ãå®ç³ã§ããã
- EDM ãè€æ°ã®ãšã³ãã£ãã£ã«çµ±åããå Žåã
åäžã®SaveChangesã¡ãœããã®åŒã³åºãã§å®¹æã«è€æ°ã®ãšã³ãã£ãã£ã®æŽæ°ãå¯èœã - EDM ãè€æ°ã®ãšã³ãã£ãã£ã«åå²ããå Žåã
SaveChangesã¡ãœãããè€æ°ååŒã³åºãå¿ èŠãããã
æ¥ç¶ãšãã©ã³ã¶ã¯ã·ã§ã³ã®æç€ºçãªç®¡çãå¿ èŠã
DB ã«ã50ïœ100 ã®ããŒãã«ãå«ãŸããŠããå Žåã
ãã¹ãŠã®ãšã³ãã£ãã£ãå«ã 1 ã€ã®å€§ã㪠EDM ãæã€ããšã¯è¯ãæ¹æ³ã§ã¯ãªãã
è€æ°ãšã³ãã£ãã£ã 1 ã€ã®å€§ãã EDM ã«éçŽãããšã
äžèšã®ãããªããã€ãã®åé¡ãèµ·ããã
-
æ§èœã®åé¡
- ã¡ã¿ããŒã¿ ããŒãæéã®æ§èœ
- ãã¥ãŒçæã«ãããæ§èœ
-
éç¶ãšããã
- ãã¶ã€ããŒ
- ã€ã³ããªã»ã³ã¹
- CLR ããŒã ã¹ããŒã¹
äžèšãåé¿ããããã
ãã¹ãã»ãã©ã¯ãã£ã¹ã¯ä»»æã®åäœã« Entity Data ã¢ãã«ãåå²ããæ¹æ³ã§ããã
è£è¶³ïŒææ°åïŒEDMX ãç¡ããªã£ãŠãè«ç¹ã¯æ®ãïŒ: EF Core ã«ã¯ EDMX ãç¡ããã
ããã¥ãŒçæã®æ§èœããšããåé¡ã¯æ¶ãããã
DbContextã®ç²åºŠãšããè«ç¹ã¯æ®ãã
- 1 ã€ã®å·šå€§ãª
DbContextã¯ãååã®ã¢ãã«æ§ç¯ïŒèµ·åæïŒãé ããªã- æ¥åå¢çããšã«
DbContextãåãããšã
- ã¢ãã«æ§ç¯ã軜ããªãã責åãæç¢ºã«ãªã
- ãã ããã©ã³ã¶ã¯ã·ã§ã³ããŸããå Žåã¯æ¥ç¶ã®å ±æãå¿ èŠ
ïŒåè¿°ã®UseTransaction/ EF Core ã§ã¯UseTransaction+ åäžæ¥ç¶ïŒãã€ã¯ããµãŒãã¹çã«å¢çãåããªãåå²ã
åäž DB ã®ã¢ããªã¹ãªã 1 ã€ã«ããšããã®ãå®åçãªèœãšãæã§ããã
ãªããEF Core 6 以éã¯ã³ã³ãã€ã«æžã¿ã¢ãã«ïŒdotnet ef dbcontext optimizeïŒã§
èµ·åæã®ã¢ãã«æ§ç¯ã³ã¹ããå€§å¹ ã«åæžã§ããã
https://github.com/OpenTouryoProject/SampleProgram/issues/3
è£è¶³ïŒ3ã€ã®ææ®µã®äœ¿ãåãïŒ: èŠåºãã®ã¿ã ããèŠç¹ãè£è¶³ããã
ææ®µ å 容 åã System.Linq.DynamicïŒçŸåšã¯System.Linq.Dynamic.CoreïŒWhere("Name == @0", name)ã®ããã«æååã§ LINQ ãæžãæ€çŽ¢æ¡ä»¶ãå®è¡æã«æ±ºãŸãç»é¢ åŒæšïŒExpression TreeïŒ Expression<Func<T,bool>>ãçµã¿ç«ãŠãŠåæããåå®å šã«æ¡ä»¶ãç©ã¿äžãããå Žå Database.SqlQuery/FromSqlç SQL ãçµã¿ç«ãŠã SQL èªäœãåçã«ç·šéãããå Žå çŸå®çã«ã¯ãæ¡ä»¶ã®æç¡ã§
Whereãç©ã¿äžããã ãã§
倧åã®èŠä»¶ã¯æºãããïŒIQueryableã¯é å»¶è©äŸ¡ãªã®ã§ã
æåŸã«ToListAsync()ãããŸã§ SQL ã¯çºè¡ãããªãïŒãvar q = context.Employees.AsQueryable(); if (!string.IsNullOrEmpty(name)) q = q.Where(e => e.Name.Contains(name)); if (deptId is int d) q = q.Where(e => e.DepartmentId == d); var rows = await q.ToListAsync();ãããè¶ ããããã©ã¡ã¿ã»ããã«ãã£ãŠ SQL å®çŸ©ãã®ãã®ãç·šéãããèŠä»¶ã¯ã
ADO.NET vs ORM (Entity Framework, Dapper)ã§
è¿°ã¹ãããŠãããšãã ORM ã§ã¯è¡šçŸããããã
åçãã©ã¡ã¿ã©ã€ãºãã»ã¯ãšãªïŒOTR_DynamicParameterizedQuery.mdïŒã®ãããª
å°çšã®ä»çµã¿ãå¿ èŠã«ãªãã
- ef5 Entity Framework cache problems - Bruno Câmara
http://www.bfcamara.com/post/37112709703/ef5-entity-framework-cache-problems
è£è¶³ïŒEF ã®ããã£ãã·ã¥ã㯠2 çš®é¡ïŒ: æ··åãããããã®ã§æŽçããã
çš®é¡ å 容 第 1 ã¬ãã« ãã£ãã·ã¥ïŒå€æŽè¿œè·¡ïŒ DbContextãèªã¿èŸŒãã ãšã³ãã£ãã£ãä¿æãããFindã¯å ã«ãããèŠããç¡å¹åã§ããªãã¯ãšãª ãã©ã³ ãã£ãã·ã¥ LINQ åŒ â SQL ã®å€æçµæãã¢ããªå ã§ãã£ãã·ã¥ãã åèãªã³ã¯ã®ããã£ãã·ã¥ã®åé¡ãã¯åè ã®è©±ã§ã
ãå¥ã®åŠçã DB ãæŽæ°ããã®ã«ãDbContextã¯å€ãå€ãè¿ãããšããçŸè±¡ã
察çã¯**DbContextãé·çããããªã**ããšã«å°œãã
ïŒèªã¿åãå°çšãªãAsNoTracking()ãæå¹ïŒã
-
poco - Entity Framework 4 Does it make sense to create a single diagram for all entities - Stack Overflow
http://stackoverflow.com/questions/3867479/entity-framework-4-does-it-make-sense-to-create-a-single-diagram-for-all-entiti/3868075 -
Working With Large Models In Entity Framework â ADO.NET Blog
https://learn.microsoft.com/en-us/archive/blogs/adonet/
- Tips to improve Entity Framework Performance
http://www.dotnet-tricks.com/Tutorial/entityframework/J8bO140912-Tips-to-improve-Entity-Framework-Performance.html
è£è¶³ïŒEF Core ã®æ§èœãã§ãã¯ãªã¹ãïŒ: çŸåšæŒãããã¹ãé ç®ã
é ç® å 容 AsNoTracking()åç §å°çšã®ã¯ãšãªã§ã¯å¿ ãä»ãã å°åœ±ïŒ SelectïŒå¿ èŠãªåã ãåããDTO ãžçŽæ¥å°åœ±ãã Includeã®èšèšN+1 ãé¿ããããã ãéå°ãª Includeã¯è¡ã®éè€ïŒã«ã«ãã·ã¢ã³ççºïŒãæããEF Core 5 以éã¯AsSplitQuery()ã§åå²ã§ããäžæ¬åŠç ExecuteUpdate/ExecuteDeleteãå€§éæ¿å ¥ã¯SqlBulkCopyã³ã³ãã€ã«æžã¿ã¯ãšãª EF.CompileAsyncQueryã§ããã ãã¹ã®å€æã³ã¹ããåæžã³ã³ãã€ã«æžã¿ã¢ãã« dotnet ef dbcontext optimizeã§èµ·åæéãççž®ãã°ç¢ºèª çºè¡ SQL ãå¿ ãç®èŠããïŒSQL Server ã®ãã°ïŒ
Tags: ç§»è¡, .NETéçº, ããŒã¿ã¢ã¯ã»ã¹, ADO.NET, Entity Framework, æ§èœ