能否创建一个DbContext接口或抽象类,并将其用于注入不同的DbContext对象?

14
我有一个软件产品,其数据库是在 SQLServer 上创建的,表和列名是由开发团队定义的,然后使用 Database First 方法将模型导入到 Visual Studio 中。现在我们正在为另一家使用 ORACLE 的公司开发相同类型的解决方案,并请求为表和列指定命名约定,以便不更改现有代码并使用 Code-First 方法。我使用 [Column] 属性为所有类属性创建了具有正确命名约定的 DbContext,但现在我正在尝试创建一个接口,以便可以注入不同的 DbContext,从而使我们在未来拥有更灵活的解决方案。

我对 .Net 还很陌生,但我的方法是为 DbContext 创建抽象类,并为每个代表表的类创建一个接口,因此,在每个这些类的实现中,如果需要,我可以更改表和列名。我的问题是,这种方法可行吗?这是一个好的方法吗?


我不确定这是否可能,但似乎您的问题可以更简单地通过资源文件来解决,该资源文件将底层表和列名称定义为编译时常量。只需在编译时切换资源文件以使用不同的后端即可。 - esmoore68
我还有一个额外的问题,就是使用Guid。对于SQL Server来说,映射是直接的,但对于Oracle,我们一直在使用字符串并相应修改代码,这是我想要停止做的另一件事情,谢谢。 - Nicolas Restrepo
看看EF7,有几个提供程序,你可能能够创建另一个 https://blogs.msdn.microsoft.com/dotnet/2015/11/18/entity-framework-7-rc1-available/ - Sten Petrov
@NicolasRestrepo 我很好奇实验进展如何。看起来计划很不错。 - enorl76
3个回答

15

没有现成的。但你可以按照以下方式自己创建一个:

interface IDbContext : IDisposable
{
    DbSet<TEntity> Set<TEntity>() where TEntity : class;

    Task<int> SaveChangesAsync();
}

public class MyDbContext : DbContext, IDbContext
{
    public MyDbContext()
        : base("myConnectionString")
    { }

    //implementation
}

需要时注入IDbContext


需要上下文对象的控制器会在LINQ语句中使用它,例如:from p in context.ExecutionLog where p.ProcessCode == processCode,所以我的IDbContext需要定义一个ExecutionLog DbSet,并且我需要一个IExecutionLog接口,以便我可以在LINQ语句中引用该类的通用属性,那么我如何使用您的方法实现呢?谢谢。 - Nicolas Restrepo
使用 context.Set<ExecutionLog> 获取表格数据。 - Cheng Chen
是的,我昨天意识到这是做法,现在它正常运作了,我只需要重构一些代码。我唯一遇到的问题是 SQLServer 数据库使用 Guid 作为主键创建的,当迁移到 Oracle 后,由于 Oracle 没有直接映射到 Guid 的数据类型,他们使用了 varchar,因此需要改变代码... 所以我现在正在评估一种在两个数据库中使用相同数据类型的方法。 - Nicolas Restrepo

0

0

您可以使用带有多个类型参数约束的通用类,并且例如具有受限类型的公共属性以注入您的DbContext

class Stuff<T> where T : DbContext, IMyContext
{
    public T Context { get; set; }
    // other members
}

这可以让你在类型为 T 的变量中使用 DbContextIMyContext 的功能。

不是真的,你的类必须同时是DbContext和IMyContext。 - Sten Petrov
@Sten-Petrov,这只是一种注入实现特定模型签名的不同数据库上下文的方法。 - stop-cran

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接