首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >这有可能有一个DbContext,迁移文件在不同的程序集中被分割吗?

这有可能有一个DbContext,迁移文件在不同的程序集中被分割吗?
EN

Stack Overflow用户
提问于 2017-04-13 15:18:22
回答 1查看 316关注 0票数 3

我已经为每个客户建立了一个系统,它有一个核心解决方案和一个自定义解决方案。Core有自己的dbcontext,每个海关对于特定于客户端的表都有自己的dbcontext。自定义解决方案引用核心解决方案dll。自定义dll正在由插件体系结构中的Core解决方案动态加载。由于Core和Custom有自己的dbcontext,所以每个dbcontext都有自己的迁移文件。

除了一件事外,我不能做一个连接核心表和自定义表的linq查询。(例:在一个查询中将ProjectCustom与Project连接起来)。我知道错误:

代码语言:javascript
复制
The specified LINQ expression contains references to queries that are associated with different contexts.

因此,为了允许来自Core和Custom的查询连接表,我正在考虑走另一条路线,其中Core定义一个基本抽象DbContext,而Custom则从这个dbcontext继承并添加它的自定义表。所以我在运行时只有一个dbcontext。

现在,对于我的问题,是否可以在Core中使用迁移文件,以及在自定义中定义另一组迁移文件?

我已经制定了一个工作解决方案,在自定义解决方案中维护所有迁移。但是,我不喜欢这样一个事实:如果我进行了影响核心表的手动迁移,我必须手动地将它传播到所有自定义解决方案。

我希望将影响核心表的迁移保留到核心解决方案中,并为海关提供另一组迁移。它们都应用于相同的dbcontext,最终实现驻留在自定义解决方案中。

这有可能吗?有任何方法来配置迁移文件的某种提供程序吗?因此,我可以首先应用在Core解决方案中定义的迁移,然后使用相同的dbcontext从自定义中应用迁移。

EN

回答 1

Stack Overflow用户

回答已采纳

发布于 2017-04-18 22:26:12

源代码

让我们首先为上下文的配置创建一个接口

代码语言:javascript
复制
public interface IDbContextRegistry
{
    void Configure(DbModelBuilder builder);
}

在我的例子中,实现存在于每个单独的上下文中,但是在diff类中实现这一点将是很好的。

代码语言:javascript
复制
public class ContextA : DbContext, IDbContextRegistry
{
    static ContextA()
    {
        Database.SetInitializer(new MigrateDatabaseToLatestVersion<ContextA, ConfigurationA>());
    }

    protected override void OnModelCreating(DbModelBuilder modelBuilder)
    {
        base.OnModelCreating(modelBuilder);
        Configure(modelBuilder);
    }

    public void Configure(DbModelBuilder modelBuilder)
    {
        modelBuilder.Entity<ModelA>();
    }
}
internal sealed class ConfigurationA : DbMigrationsConfiguration<ContextA>
{
    public ConfigurationA()
    {
        AutomaticMigrationsEnabled = false;
    }

    protected override void Seed(ContextA context)
    {
    }
}

public class ModelA
{
    public int Id { get; set; }
    public string Name { get; set; }
}

代码语言:javascript
复制
public class ContextB : DbContext, IDbContextRegistry
{
    static ContextB()
    {
        Database.SetInitializer(new MigrateDatabaseToLatestVersion<ContextB, ConfigurationB>());
    }

    protected override void OnModelCreating(DbModelBuilder modelBuilder)
    {
        base.OnModelCreating(modelBuilder);
        Configure(modelBuilder);
    }

    public void Configure(DbModelBuilder modelBuilder)
    {
        modelBuilder.Entity<ModelB>();
    }
}
internal sealed class ConfigurationB : DbMigrationsConfiguration<ContextB>
{
    public ConfigurationB()
    {
        AutomaticMigrationsEnabled = false;
    }

    protected override void Seed(ContextB context)
    {
    }
}

public class ModelB
{
    public int Id { get; set; }
    public DateTimeOffset Date { get; set; }
}

稍后在您的主要应用程序创建一个上下文,将注册所有的个人类型。

代码语言:javascript
复制
public class ContextJoin : DbContext
{
    private readonly List<IDbContextRegistry> _registry = new List<IDbContextRegistry>();

    // Constructor to allow automatic DI injection for most modern containers
    public ContextJoin(IEnumerable<IDbContextRegistry> registry)
    {
        _registry.AddRange(registry);
    }

    public ContextJoin(params IDbContextRegistry[] registry) : this(_registry.AsEnumerable())
    {
    }

    protected override void OnModelCreating(DbModelBuilder modelBuilder)
    {
        base.OnModelCreating(modelBuilder);

        foreach (var entry in _registry)
        {
            entry.Configure(modelBuilder);
        }
    }
}

瞧,每个实体都生活在ContextJoin中,随时准备使用。示例:

代码语言:javascript
复制
class Program
{
    static void Main(string[] args)
    {
        ContextA ctxA = new ContextA();
        ctxA.Set<ModelA>().Add(new ModelA());
        ctxA.SaveChanges();

        ContextB ctxB = new ContextB();
        ctxB.Set<ModelB>().Add(new ModelB());
        ctxB.SaveChanges();

        ContextJoin ctxJoin = new ContextJoin(ctxA, ctxB);
        ctxJoin.Set<ModelB>().Add(new ModelB());
        ctxJoin.Set<ModelA>().Add(new ModelA());
        ctxJoin.SaveChanges();

        var crossQuery = ctxJoin.Set<ModelA>().Join(
            ctxJoin.Set<ModelB>(), t => t.Id, t => t.Id, (a, b) => new
            {
                a.Name,
                b.Date
            }).ToList();
        crossQuery.ForEach(t => Console.WriteLine($"Name: {t.Name}, Date: {t.Date}"));
    }
}

希望能帮上忙!

票数 3
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/43396067

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档