- Microsoft.EntityFrameworkCore
- Microsoft.EntityFrameworkCore.SqlServer - Only if MS SQL Server is used
- Microsoft.EntityFrameworkCore.Design
- Microsoft.EntityFrameworkCore.Tools
-
Create models
public class Blog { public int BlogId { get; set; } public string Url { get; set; } public ICollection<Post> Posts { get; } = new List<Post>(); } public class Post { public int PostId { get; set; } public JObject Content { get; set; } public int BlogId { get; set; } public Blog Blog { get; set; } }
-
Add configuration to the entity type [Not Required]
//example for handling JObject properties public class PostConfiguration : IEntityTypeConfiguration<Post> { public void Configure(EntityTypeBuilder<Post> builder) { var jsonSerializerSettings = new JsonSerializerSettings { NullValueHandling = NullValueHandling.Ignore }; builder .Property(auditLog => auditLog.Request) .HasConversion( SerializeObject(jsonSerializerSettings), DeserializeObject(jsonSerializerSettings)); builder .Property(auditLog => auditLog.Response) .HasConversion( SerializeObject(jsonSerializerSettings), DeserializeObject(jsonSerializerSettings)); } private static Expression<Func<JObject, string>> SerializeObject( JsonSerializerSettings serializerSettings) { return jsonObject => JsonConvert.SerializeObject(jsonObject, serializerSettings); } private static Expression<Func<string, JObject>> DeserializeObject( JsonSerializerSettings serializerSettings) { return stringValue => JsonConvert.DeserializeObject<JObject>( stringValue, serializerSettings); } }
-
Create a context
public class BloggingContext : DbContext { public DbSet<Blog> Blogs { get; set; } public DbSet<Post> Posts { get; set; } public BloggingContext(DbContextOptions<AuditLogContext> options) : base(options) { } protected override void OnModelCreating(ModelBuilder modelBuilder) { modelBuilder.Entity<Blog>().ToTable("Blog"); modelBuilder.Entity<Post>().ToTable("Posts"); modelBuilder.ApplyConfiguration(new PostConfiguration()); } }
-
Register the context in
IServiceCollection
services.AddDbContext<AuditLogContext>(options => options.UseSqlServer( Configuration.GetConnectionString(nameof(AuditLogContext))));
Note: if the migrations are in a different project
services.AddDbContext<AuditLogContext>(options => options.UseSqlServer( Configuration.GetConnectionString(nameof(AuditLogContext)), dbContextOptionsBuilder => dbContextOptionsBuilder.MigrationsAssembly("Blog.Web")));
-
Create a migration
Add-Migration InitialCreate
Note - After running the command, check the generated code to see if it is correct
-
Update the database
Update-Database
Note: Use
-Verbose
flag to see the generated sql queries
-
Stop tracking when not writing data to the database using
AsNoTracking
. For more info goto Microsoft Docs - Tracking vs. No-Tracking Queriesvar blogs = context.Blogs .AsNoTracking() .ToList();
-
Pick the best pattern to load related entities using the navigation properties in your model. For more info regarding tracking goto Microsoft Docs - Loading Related Data
-
Entity Framework Core allows you to drop down to raw SQL queries when working with a relational database with
FromSqlRaw
andFromSqlInterpolated
. For more info goto Microsoft Docs - Raw SQL Queries/* * FromSqlInterpolated */ var searchTerm = "Lorem ipsum"; var blogs = context.Blogs .FromSqlInterpolated($"SELECT * FROM dbo.SearchBlogs({searchTerm})") .Include(b => b.Posts) .ToList(); /* * FromSqlRaw */ var user = "johndoe"; var blogs = context.Blogs .FromSqlRaw("EXECUTE dbo.GetMostPopularBlogsForUser {0}", user) .ToList();
-
Because Entity framework core uses in-memory snapshots to track changes to our entities, if we happen to have an entity cachedin memory, we can save ourselves a trip to the database by looking it up with the
Find
andFindAsync
methods. For more info goto Microsoft Docs - DbContext.Find Method or Microsoft Docs - DbContext.FindAsync Method -
AddDbContextPool
enables pooling ofDbContext
instances. Context pooling can increase throughput in high-scale scenarios such as web servers by reusing context instances, rather than creating new instances for each request. For more info goto Microsoft Docs - DbContext poolingservices.AddDbContextPool<BloggingContext>( options => options.UseSqlServer(connectionString));