|
Entity Framework (EF) Core 是轻量化、可扩展、开源和跨平台版的常用 Entity Framework 数据访问技术。EF Core 可用作对象关系映射程序 (O/RM)
创建DbContext 对象
DbContext的生存期
DbContext 的生存期从创建实例时开始,并在释放实例时结束。DbContext生成
为每个请求创建一个 ApplicationDbContext 实例,并传递给控制器,以在请求结束后释放前执行工作单元- public void ConfigureServices(IServiceCollection services)
- {
- services.AddControllers();
- services.AddDbContext<ApplicationDbContext>(
- options => options.UseSqlServer("name=ConnectionStrings:DefaultConnection"));
- }
- public class ApplicationDbContext : DbContext
- {
- public ApplicationDbContext(DbContextOptions<ApplicationDbContext> options)
- : base(options)
- {
- }
- }
- public class MyController
- {
- private readonly ApplicationDbContext _context;
- public MyController(ApplicationDbContext context)
- {
- _context = context;
- }
- }
复制代码- public class ApplicationDbContext : DbContext
- {
- private readonly string _connectionString;
- public ApplicationDbContext(string connectionString)
- {
- _connectionString = connectionString;
- }
- protected override void OnConfiguring(DbContextOptionsBuilder optionsBuilder)
- {
- optionsBuilder.UseSqlServer(_connectionString);
- }
- }
- //或者
- public class ApplicationDbContext : DbContext
- {
- public ApplicationDbContext(DbContextOptions<ApplicationDbContext> options)
- : base(options)
- {
- }
- }
- var contextOptions = new DbContextOptionsBuilder<ApplicationDbContext>()
- .UseSqlServer(@"Server=(localdb)\mssqllocaldb;Database=Test")
- .Options;
- using var context = new ApplicationDbContext(contextOptions);
复制代码
DBContext的属性
DbContextOptionsBuilder
所有DBContext配置的起始点都是 DbContextOptionsBuilder。 可以通过三种方式获取此生成器:
- 在 AddDbContext 和相关方法中
- 在 OnConfiguring 中
- 使用 new 显式构造
DbContextOptions
允许多个具体子类使用其不同的泛型 DbContextOptions 的实例初始化DBContext- public sealed class ApplicationDbContext1 : ApplicationDbContextBase
- {
- public ApplicationDbContext1(DbContextOptions<ApplicationDbContext1> contextOptions)
- : base(contextOptions)
- {
- }
- }
- public sealed class ApplicationDbContext2 : ApplicationDbContextBase
- {
- public ApplicationDbContext2(DbContextOptions<ApplicationDbContext2> contextOptions)
- : base(contextOptions)
- {
- }
- }
- protected ApplicationDbContext(DbContextOptions contextOptions)
- : base(contextOptions)
- {
- }
复制代码
DBContext的两个关键方法
OnConfiguring配置方法
DBContext的配置入口 - protected override void OnConfiguring(DbContextOptionsBuilder optionsBuilder)
- {
- //配置数据库提供程序,还有其他数据库配置如下图:
- optionsBuilder.UseSqlServer(@"Server=(localdb)\mssqllocaldb;Database=Test");
- //日志记录配置,通过在控制台输出
- optionsBuilder.LogTo(Console.WriteLine, LogLevel.Information).EnableSensitiveDataLogging();
- //关于其他DBContext配置,参看下图
- }
- protected override void OnModelCreating(ModelBuilder modelBuilder)
- {
- base.OnModelCreating(modelBuilder, typeof(BaseEntity));
- }
复制代码 关于其他数据库提供程序
关于DbContextOptionsBuilder 的更多配置
OnModelCreating配置方法
实体的配置入口方法 -
- protected override void OnModelCreating(ModelBuilder modelBuilder)
- {
- modelBuilder.Entity<AuditEntry>();
- }
复制代码
使用 fluent API 配置模型替代OnModelCreating
关于实体的配置,还可使用Fluent api 可在上下文中替代 OnModelCreating 方法,并使用 Fluent API 来配置模型。 此配置方法最为有效,并可在不修改实体类的情况下指定配置。 Fluent API 配置具有最高优先级,并将替代约定和数据注释。 配置按调用方法的顺序应用,如果存在任何冲突,最新调用将替代以前指定的配置。查看代码- modelBuilder.Entity<Blog>()
- .Property(b => b.Url)
- .IsRequired(); //代替修改实体
- 还有这种等等
- [NotMapped]
- public class BlogMetadata
- protected override void OnModelCreating(ModelBuilder modelBuilder)
- {
- modelBuilder.Ignore<BlogMetadata>();
- }
复制代码
DBContext的结构
模型
模型由实体类和表示数据库会话的上下文对象构成。 上下文对象允许查询并保存数据- public class BloggingContext : DbContext
- {
- public DbSet<Blog> Blogs { get; set; }
- public DbSet<Post> Posts { get; set; }
- protected override void OnConfiguring(DbContextOptionsBuilder optionsBuilder)
- {
- optionsBuilder.UseSqlServer(
- @"Server=(localdb)\mssqllocaldb;Database=Blogging;Trusted_Connection=True");
- }
- }
- public class Blog
- {
- public int BlogId { get; set; }
- public string Url { get; set; }
- public int Rating { get; set; }
- public List<Post> Posts { get; set; }
- }
复制代码
实体
在上下文中包含一种类型的 DbSet 意味着它包含在 EF Core 的模型中,或者在OnModelCreating 指定的;我们通常将此类类型称为实体加入实体的三种方式
- 在上下文的 DbSet 属性中公开。
- 通过实体 Blog.Posts 的导航属性发现的。
- 在 OnModelCreating 中指定的。
- internal class MyContext : DbContext
- {
- public DbSet<Blog> Blogs { get; set; }
- protected override void OnModelCreating(ModelBuilder modelBuilder)
- {
- modelBuilder.Entity<AuditEntry>();
- }
- }
- public class Blog
- {
- public string Url { get; set; }
- public List<Post> Posts { get; set; }
- }
- public class Post
- {
- public string Content { get; set; }
- }
复制代码
实体的属性约束
关于属性的约束,查看一下链接 实体属性 - EF Core | Microsoft Learn以下列出常用等等 | | [NotMapped] | | [Column("blog_id")] | 指定数据库列映射,数据库列与实体列不一致 | [Column(TypeName = "varchar(200)")] | | [MaxLength(500)] | | [Required] | | [Comment("The URL of the blog")] | 描述 | [Column(Order = 2)] | |
实体状态变化规则
DBContext上下文为跟踪状态时,实体变化如下;
EntityState的5个状态解释:
成员名称 | 说明 | Detached | 对象存在,但没有被跟踪。 在创建实体之后、但将其添加到对象上下文之前,该实体处于此状态。 An entity is also in this state after it has been removed from the context by calling the Detach method or if it is loaded by using a NoTrackingMergeOption. 没有 ObjectStateEntry 实例与状态为 Detached 的对象关联。 | Unchanged | 自对象附加到上下文中后,或自上次调用 SaveChanges 方法后,此对象尚未经过修改。 | Added | 对象为新对象,并且已添加到对象上下文,但尚未调用 SaveChanges 方法。 在保存更改后,对象状态将更改为 Unchanged。 状态为 Added 的对象在 ObjectStateEntry 中没有原始值。 | Modified | 对象上的一个标量属性已更改,但尚未调用 SaveChanges 方法。 在不带更改跟踪代理的 POCO 实体中,调用 DetectChanges 方法时,已修改属性的状态将更改为 Modified。 在保存更改后,对象状态将更改为 Unchanged。 | Deleted | 删除状态 |
手动设置实体状态
- _mIPODataDBContext.Entry(t_TaskOrderFiles).Property(x => x.Url).IsModified = true;
- _mIPODataDBContext.SaveChanges();
复制代码
DBContext的查询方式
跟踪和不跟踪查询(AsNoTracking)
- //跟踪
- var blog = context.Blogs.SingleOrDefault(b => b.BlogId == 1);
- blog.Rating = 5;
- context.SaveChanges();
- //不跟踪
- var blogs = context.Blogs
- .AsNoTracking()
- .ToList();
- //在上下文实例级别取消跟踪
- context.ChangeTracker.QueryTrackingBehavior = QueryTrackingBehavior.NoTracking;
复制代码
导航查询(Include,ThenInclude)
- //同级Include,子级,更深级别的关联 ThenInclude
- var blogs = context.Blogs
- .Include(blog => blog.Posts)
- .ThenInclude(post => post.Author)
- .ToList();
复制代码
Inner Join查询
通过linq表达式
- var query = from photo in context.Set<PersonPhoto>()
- join person in context.Set<Person>()
- on new { Id = (int?)photo.PersonPhotoId, photo.Caption }
- equals new { Id = person.PhotoId, Caption = "SN" }
- where b.ProjectOrderId == Guid.Parse(proIdParam.Value) && p.IsDel == false
- select new { person, photo };
-
- SELECT [p].[PersonId], [p].[Name], [p].[PhotoId], [p0].[PersonPhotoId], [p0].[Caption], [p0].[Photo]
- FROM [PersonPhoto] AS [p0]
- INNER JOIN [Person] AS [p] ON ([p0].[PersonPhotoId] = [p].[PhotoId] AND ([p0].[Caption] = N'SN'))
复制代码
通过lamada表达式
- var query = from b in context.Set<Blog>()
- from p in context.Set<Post>().Where(p => b.BlogId == p.BlogId)
- select new { b, p };
-
- SELECT [b].[BlogId], [b].[OwnerId], [b].[Rating], [b].[Url], [p].[PostId], [p].[AuthorId], [p].[BlogId], [p].[Content], [p].[Rating], [p].[Title]
- FROM [Blogs] AS [b]
- INNER JOIN [Posts] AS [p] ON [b].[BlogId] = [p].[BlogId]
复制代码
Left Join查询
lamada表达式
- var query = from b in context.Set<Blog>()
- join p in context.Set<Post>()
- on b.BlogId equals p.BlogId into grouping
- from p in grouping.DefaultIfEmpty()
- select new { b, p };
复制代码
linq表达式
- var query2 = from b in context.Set<Blog>()
- from p in context.Set<Post>().Where(p => b.BlogId == p.BlogId).DefaultIfEmpty()
- select new { b, p };
- SELECT [b].[BlogId], [b].[OwnerId], [b].[Rating], [b].[Url], [p].[PostId], [p].[AuthorId], [p].[BlogId], [p].[Content], [p].[Rating], [p].[Title]
- FROM [Blogs] AS [b]
- LEFT JOIN [Posts] AS [p] ON [b].[BlogId] = [p].[BlogId]
复制代码
GroupJoin查询
- var query = from b in context.Set<Blog>()
- join p in context.Set<Post>()
- on b.BlogId equals p.BlogId into grouping
- select new { b, Posts = grouping.Where(p => p.Content.Contains("EF")).ToList() };
复制代码
GroupBy查询
- var query = from p in context.Set<Post>()
- group p by p.AuthorId
- into g
- where g.Count() > 0
- orderby g.Key
- select new { g.Key, Count = g.Count() };
-
- SELECT [p].[AuthorId] AS [Key], COUNT(*) AS [Count]
- FROM [Posts] AS [p]
- GROUP BY [p].[AuthorId]
- HAVING COUNT(*) > 0
- ORDER BY [p].[AuthorId]
复制代码 支持的其他聚合运算符.NET | SQL | Average(x => x.Property) | AVG(Property) | Count() | COUNT(*) | LongCount() | COUNT(*) | Max(x => x.Property) | MAX(Property) | Min(x => x.Property) | MIN(Property) | Sum(x => x.Property) | SUM(Property) |
纯SQL查询
- var rowsModified = context.Database.ExecuteSql($"UPDATE [Blogs] SET [Url] = NULL");
-
- var overAverageIds = context.Database
- .SqlQuery<int>($"SELECT [BlogId] AS [Value] FROM [Blogs]")
- .Include(b => b.Posts)
- .Where(id => id > context.Blogs.Average(b => b.BlogId))
- .ToList();
复制代码
来源:https://www.cnblogs.com/workcn/archive/2023/05/24/17427415.html
免责声明:由于采集信息均来自互联网,如果侵犯了您的权益,请联系我们【E-Mail:cb@itdo.tech】 我们会及时删除侵权内容,谢谢合作! |
本帖子中包含更多资源
您需要 登录 才可以下载或查看,没有账号?立即注册
x
|