簡體   English   中英

如何在 EntityFramework Core 中使用部分類和部分 OnModelCreating 方法擴展 DbContext

[英]How to extend DbContext with partial class and partial OnModelCreating method in EntityFramework Core

我正在使用 EF Core 和 DatabaseFirst 方法。 我的 dbContext 是由Scaffold-DbContext命令自動創建的。

我需要將一些新的 DbSet 添加到 dbContext 中,並將一些額外的代碼添加到OnModelCreating方法中,但是在每個腳手架之后,添加的代碼都被刪除了,我每次都必須再次添加它。

我想要做的是創建另一個部分 dbContext 類並將protected override void OnModelCreating(ModelBuilder modelBuilder)方法標記為部分

但得到錯誤:

部分方法不能有訪問修飾符或 virtual、abstract、override、new、sealed 或 extern 修飾符。

分部方法可能沒有多個實現聲明

這是一個偽代碼:

MyDbContext1.cs - 由Scaffold-DbContext生成

public partial class MyDbContext : DbContext
{
    public MyDbContext()
    {
    }

    public MyDbContext(DbContextOptions<MyDbContext> options)
        : base(options)
    {
    }

    public virtual DbSet<Client> Clients { get; set; }

    protected override partial void OnModelCreating(ModelBuilder modelBuilder)
    {
        modelBuilder.Entity<Client>(entity =>
        {
            // some code ...
        }
    }
}

MyDbContext2.cs - 我每次在搭建腳手架后都將這段代碼添加到 dbContext 中:

public partial class MyDbContext
{
    public virtual DbSet<JustAnotherEntity> AnotherEntity { get; set; }

    protected override partial void OnModelCreating(ModelBuilder modelBuilder)
    {
        modelBuilder.Entity<JustAnotherEntity>(entity =>
        {
            entity.HasKey(e => new {e.Id, e.IdAction, e.IdState})
                .ForSqlServerIsClustered(false);
        });
    }
}

EFCore 3 -他們終於解決了這個問題!

您現在可以在像這樣的OnModelCreatingPartial類中實現OnModelCreatingPartial 注意class 和 method上的partial關鍵字:

public partial class RRStoreContext : DbContext
{
    partial void OnModelCreatingPartial(ModelBuilder builder)
    {
        builder.Entity<RepeatOrderSummaryView>().HasNoKey();
    }
}

如果您查看生成的上下文文件 - 就在OnModelCreating(...)最后,您會看到...

 OnModelCreatingPartial(modelBuilder);

注意:我使用腳手架,但我需要為存儲過程手動添加HasNoKey (使用未以其他方式腳手架的自定義返回類型)。

另一種方法是創建另一個從 MyDbContext 繼承的上下文類,它實際上包含所有自定義代碼。 然后使用這個新類作為你的上下文。 這樣,就不需要更新生成的代碼。

public class MyDbContext2 : MyDbContext 
{
    public MyDbContext2()
    {
    }

    public MyDbContext2(DbContextOptions<MyDbContext> options)
        : base(options)
    {
    }

    public virtual DbSet<JustAnotherEntity> AnotherEntity { get; set; }

    protected override void OnModelCreating(ModelBuilder modelBuilder)
    {
        base.OnModelCreating(modelBuilder);
        modelBuilder.Entity<JustAnotherEntity>(entity =>
        {
            entity.HasKey(e => new {e.Id, e.IdAction, e.IdState})
                .ForSqlServerIsClustered(false);
        });
    }
}

您不能覆蓋分部類中的方法,因為所有“部分”都成為一個類。 但是您可以通過讓主 OnModelCreating 調用部分方法來實現這一點。 像這樣:

public partial class Db : DbContext
{
    partial void OnModelCreating2(ModelBuilder modelBuilder)
    {
       //additional config
    }
}

public partial class Db : DbContext
{

    public DbSet<Person> Persons { get; set; }

    partial void OnModelCreating2(ModelBuilder modelBuilder);
    protected override void OnModelCreating(ModelBuilder modelBuilder)
    {
        base.OnModelCreating(modelBuilder);

        OnModelCreating2(modelBuilder);
    }
    protected override void OnConfiguring(DbContextOptionsBuilder optionsBuilder)
    {
        optionsBuilder.UseSqlServer("Server=localhost;database=efcore2test;integrated security=true");
        base.OnConfiguring(optionsBuilder);
    }
}

分部類的目的是您可以創建另一個同名的分部類。 您可以在此處利用部分類的好處。

創建另一個與“MyDbContext”同名的類,但設置不同的文件名,例如“MyCustomDbContext”。

public partial class MyDbContext
{
    partial void OnModelCreatingPartial(ModelBuilder modelBuilder){
        // Right your custom code here
    }
}

現在,無論何時您再次生成模型,它都不會重寫您的自定義上下文類。

可以通過以下方式使用部分方法:

public partial class MyDbContext : DbContext
{
    public MyDbContext()
    {
    }

    public MyDbContext(DbContextOptions<MyDbContext> options)
        : base(options)
    {
    }

    ...

    protected override void OnModelCreating(ModelBuilder modelBuilder)
    {
        OnModelCreatingPartial(modelBuilder);
    }

    partial void OnModelCreatingPartial(ModelBuilder modelBuilder);
}

這實際上是由 EF Core Power Tools 生成的:

https://marketplace.visualstudio.com/items?itemName=ErikEJ.EFCorePowerTools

鑒於自動生成的 DbContext 准備了一個未完全實現的方法,您可以自己在另一個文件的其他地方輕松實現它:

public partial class MyDbContext : DbContext
    partial void OnModelCreatingPartial(ModelBuilder modelBuilder)
    {
        // Your own stuff here!
    }
}

當然,上面要求您為生成的部分方法提供“模板”(就像這個工具一樣)。 否則,您需要控制代碼並能夠在生成的類中修改幾行代碼。

有關如何使用部分方法的更多信息:

https://docs.microsoft.com/en-us/dotnet/csharp/programming-guide/classes-and-structs/partial-classes-and-methods#partial-methods

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM