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

问题描述 投票:0回答:3

我正在使用 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);
        });
    }
}
c# entity-framework-core dbcontext partial partial-classes
3个回答
81
投票

EFCore 3 - 他们终于解决了这个问题!

您现在可以在像这样的部分类中实现

OnModelCreatingPartial
。请注意 类和方法上的
partial
关键字:

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

如果您查看生成的上下文文件 - 在

OnModelCreating(...)
的最后,您会看到...

 OnModelCreatingPartial(modelBuilder);

注意:我使用脚手架,但我需要为存储过程手动添加

HasNoKey
(具有未以其他方式搭建的自定义返回类型)。


43
投票

另一种方法是创建另一个继承自 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);
        });
    }
}

8
投票

您无法重写分部类中的方法,因为所有“部分”都成为一个类。但是您可以通过让主 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);
    }
}
© www.soinside.com 2019 - 2024. All rights reserved.