我们的生活 發表於 2025-5-17 08:54:46

ASP.NET Core EFCore 属性配置与DbContext的用法详解

<div id="navCategory"><h5 class="catalogue">目录</h5><ul class="first_class_ul"><li><a href="#_label0">一、属性配置</a></li><ul class="second_class_ul"><li><a href="#_lab2_0_0">1. 数据注解(Data Annotations)</a></li><li><a href="#_lab2_0_1">2. Fluent API</a></li></ul><li><a href="#_label1">二、DbContext 详解</a></li><ul class="second_class_ul"><li><a href="#_lab2_1_2">1.&nbsp;定义 DbContext</a></li><li><a href="#_lab2_1_3">2.&nbsp;生命周期与依赖注入</a></li><li><a href="#_lab2_1_4">3. 数据操作</a></li><li><a href="#_lab2_1_5">4. 性能优化</a></li></ul><li><a href="#_label2">三、高级配置</a></li><ul class="second_class_ul"><li><a href="#_lab2_2_6">1. 多对多关系</a></li><li><a href="#_lab2_2_7">2. 继承映射</a></li><li><a href="#_lab2_2_8">3. 全局过滤器</a></li></ul><li><a href="#_label3">四、最佳实践与常见问题</a></li><ul class="second_class_ul"></ul><li><a href="#_label4">结语</a></li><ul class="second_class_ul"></ul></ul></div><p>本文将深入探讨 ASP.NET Core 中 EFCore 的实体属性配置方法及&nbsp;<code>DbContext</code>&nbsp;的核心用法,帮助开发者高效管理数据模型与数据库交互。</p>
<p class="maodian"><a name="_label0"></a></p><h2>一、属性配置</h2>
<p>实体属性配置是定义模型与数据库映射的核心,EFCore 提供两种方式:<strong>数据注解</strong>和&nbsp;<strong>Fluent API</strong>。</p>
<p class="maodian"><a name="_lab2_0_0"></a></p><h3>1. 数据注解(Data Annotations)</h3>
<p>通过特性(Attributes)直接在实体类上声明配置,适合简单场景。</p>
<div class="jb51code"><pre class="brush:csharp;">public class Product{   
// 主键   
public int Id { get; set; }
// 非空且最大长度100   
public string Name { get; set; }
// 外键   
public int CategoryId { get; set; }   
public Category Category { get; set; }}</pre></div>
<p><strong>常用注解:</strong></p>
<ul><li><p><code></code>:主键</p></li><li><p><code></code>:非空约束</p></li><li><p><code></code>:最大长度</p></li><li><p><code></code>:外键关系</p></li><li><p><code></code>:自定义表名</p></li></ul>
<p class="maodian"><a name="_lab2_0_1"></a></p><h3>2. Fluent API</h3>
<p>在&nbsp;<code>DbContext</code>&nbsp;的&nbsp;<code>OnModelCreating</code>&nbsp;方法中配置,提供更灵活的方式。</p>
<p></p>
<div class="jb51code"><pre class="brush:csharp;">protected override void OnModelCreating(ModelBuilder modelBuilder){   
modelBuilder.Entity&lt;Product&gt;(entity =&gt;    {      
entity.HasKey(p =&gt; p.Id); // 主键   
   entity.Property(p =&gt; p.Name)         
   .IsRequired()         
    .HasMaxLength(100);
      entity.HasOne(p =&gt; p.Category) // 一对一/多关系      
      .WithMany(c =&gt; c.Products)         
    .HasForeignKey(p =&gt; p.CategoryId);
   });}</pre></div>
<p></p>
<p><strong>常用配置方法:</strong></p>
<ul><li><p><code>HasKey()</code>:定义主键</p></li><li><p><code>Property().IsRequired()</code>:非空约束</p></li><li><p><code>HasIndex()</code>:创建索引</p></li><li><p><code>HasOne().WithMany()</code>:配置导航关系</p></li></ul>
<p><strong>优势:</strong></p>
<ul><li><p>集中管理配置,避免污染实体类。</p></li><li><p>支持复杂配置(如复合主键、继承映射)。</p></li></ul>
<p class="maodian"><a name="_label1"></a></p><h2>二、DbContext 详解</h2>
<p><code>DbContext</code>&nbsp;是 EFCore 的核心,负责数据库连接、查询、事务管理等。</p>
<p class="maodian"><a name="_lab2_1_2"></a></p><h3>1.&nbsp;定义 DbContext</h3>
<p>派生类需继承&nbsp;<code>DbContext</code>,并暴露&nbsp;<code>DbSet&lt;T&gt;</code>&nbsp;属性。</p>
<p></p>
<div class="jb51code"><pre class="brush:csharp;">public class AppDbContext : DbContext{   
public DbSet&lt;Product&gt; Products { get; set; }   
public DbSet&lt;Category&gt; Categories { get; set; }
    protected override void OnConfiguring(DbContextOptionsBuilder options)      
=&gt; options.UseSqlServer("Your_Connection_String");
    protected override void OnModelCreating(ModelBuilder modelBuilder)   
  {      
  // Fluent API 配置   
  }
}</pre></div>
<p></p>
<p class="maodian"><a name="_lab2_1_3"></a></p><h3>2.&nbsp;生命周期与依赖注入</h3>
<p>在 ASP.NET Core 中,通过依赖注入管理上下文生命周期:</p>
<div class="jb51code"><pre class="brush:csharp;">// Startup.cs
services.AddDbContext&lt;AppDbContext&gt;(options =&gt;   
options.UseSqlServer(Configuration.GetConnectionString("Default")));</pre></div>
<ul><li><p><strong>作用域(Scoped)</strong>:默认选项,每个请求一个实例,确保线程安全。</p></li><li><p>避免长时间持有&nbsp;<code>DbContext</code>,以防内存泄漏。</p></li></ul>
<p class="maodian"><a name="_lab2_1_4"></a></p><h3>3. 数据操作</h3>
<ul><li><p><strong>查询</strong>:</p></li></ul>
<div class="jb51code"><pre class="brush:csharp;">var products = await _context.Products.Where(p =&gt; p.Price &gt; 50).ToListAsync();</pre></div>
<ul><li><p><strong>保存变更</strong>:</p></li></ul>
<div class="jb51code"><pre class="brush:csharp;">_context.Products.Add(newProduct);
await _context.SaveChangesAsync();</pre></div>
<p><strong>关键方法:</strong></p>
<ul><li><p><code>Add()</code>,&nbsp;<code>Remove()</code>:跟踪实体状态</p></li><li><p><code>SaveChangesAsync()</code>:提交事务</p></li></ul>
<p class="maodian"><a name="_lab2_1_5"></a></p><h3>4. 性能优化</h3>
<ul><li><p><strong>AsNoTracking()</strong>:禁用变更跟踪,提升查询速度。</p></li><li><p><strong>DbContext 池</strong>:复用上下文实例,减少开销。</p></li></ul>
<div class="jb51code"><pre class="brush:csharp;">services.AddDbContextPool&lt;AppDbContext&gt;(...);</pre></div>
<p class="maodian"><a name="_label2"></a></p><h2>三、高级配置</h2>
<p class="maodian"><a name="_lab2_2_6"></a></p><h3>1. 多对多关系</h3>
<p>使用 Fluent API 配置中间表:</p>
<div class="jb51code"><pre class="brush:plain;">modelBuilder.Entity&lt;Post&gt;()   
.HasMany(p =&gt; p.Tags)   
.WithMany(t =&gt; t.Posts)   
.UsingEntity(j =&gt; j.ToTable("PostTags"));</pre></div>
<p class="maodian"><a name="_lab2_2_7"></a></p><h3>2. 继承映射</h3>
<p>TPH(Table-Per-Hierarchy)模式:</p>
<div class="jb51code"><pre class="brush:plain;">modelBuilder.Entity&lt;Blog&gt;()   
.HasDiscriminator&lt;string&gt;("BlogType")   
.HasValue&lt;Blog&gt;("Standard")   
.HasValue&lt;RssBlog&gt;("RSS");</pre></div>
<p class="maodian"><a name="_lab2_2_8"></a></p><h3>3. 全局过滤器</h3>
<p>自动应用查询条件(如软删除):</p>
<div class="jb51code"><pre class="brush:plain;">modelBuilder.Entity&lt;Post&gt;().HasQueryFilter(p =&gt; !p.IsDeleted);</pre></div>
<p class="maodian"><a name="_label3"></a></p><h2>四、最佳实践与常见问题</h2>
<ul><li><p><strong>选择数据注解还是 Fluent API?</strong></p>
<ul><li><p>简单配置用数据注解,复杂需求用 Fluent API。</p></li></ul></li><li><p><strong>DbContext 线程安全</strong></p>
<ul><li><p>确保每个请求使用独立实例,避免并发问题。</p></li></ul></li><li><p><strong>迁移(Migrations)</strong></p>
<ul><li><p>通过&nbsp;<code>dotnet ef migrations add</code>&nbsp;生成数据库架构变更。</p></li></ul></li><li><p><strong>性能陷阱</strong></p>
<ul><li><p>避免在循环中频繁调用&nbsp;<code>SaveChanges()</code>。</p></li><li><p>使用&nbsp;<code>Include()</code>&nbsp;预加载关联数据,减少 N+1 查询。</p></li></ul></li></ul>
<p class="maodian"><a name="_label4"></a></p><h2>结语</h2>
<p>掌握 EFCore 的属性配置与&nbsp;<code>DbContext</code>&nbsp;管理,能够显著提升数据层开发效率。合理选择配置方式,结合依赖注入和性能优化技巧,可构建高效稳健的 ASP.NET Core 应用。</p>
頁: [1]
查看完整版本: ASP.NET Core EFCore 属性配置与DbContext的用法详解