使用DbContextScope项目为查询指定连接字符串

时间:2017-10-04 22:24:23

标签: entity-framework connection-string dbcontext

我现在正在使用Mehdi El Gueddari's DbContextScope project,我想这本书,它很棒。但我遇到了一个问题,我不确定今天如何解决。我有一个查询,我需要使用不同的数据库登录/用户执行,因为它需要额外的权限。我可以在我的web.config中创建另一个连接字符串,但我不知道如何为此查询指定,我想使用这个新的连接字符串。这是我的用法:

在我的逻辑层:

private static IDbContextScopeFactory _dbContextFactory = new DbContextScopeFactory();

public static Guid GetFacilityID(string altID)
{
            ...
            using (_dbContextFactory.CreateReadOnly())
            {
                entity = entities.GetFacilityID(altID)
            }
}

调用我的数据层看起来像这样:

private AmbientDbContextLocator _dbcLocator = new AmbientDbContextLocator();

    protected CRMEntities DBContext
    {
        get
        {
            var dbContext = _dbcLocator.Get<CRMEntities>();

            if (dbContext == null)
                throw new InvalidOperationException("No ambient DbContext....");

            return dbContext;
        }
    }

    public virtual Guid GetFaciltyID(string altID)
    {
        return DBContext.Set<Facility>().Where(f => f.altID = altID).Select(f => f.ID).FirstOrDefault();
    }

目前我的连接字符串是以默认方式设置的:

public partial class CRMEntities : DbContext
{
    public CRMEntities()
        : base("name=CRMEntities")
    {}
}

此特定查询是否可以使用不同的连接字符串以及如何使用?

1 个答案:

答案 0 :(得分:1)

我最终修改了源代码的方式让人觉得有点笨拙,但现在正在完成工作。我创建了一个新的IAmbientDbContextLocator,其中Get<TDbContext>方法覆盖接受连接字符串:

    public TDbContext Get<TDbContext>(string nameOrConnectionString) where TDbContext : DbContext
    {
        var ambientDbContextScope = DbContextScope.GetAmbientScope();
        return ambientDbContextScope == null ? null : ambientDbContextScope.DbContexts.Get<TDbContext>(nameOrConnectionString);
    }

然后我更新了DbContextCollection以将此参数传递给DbContext现有的构造函数重载。最后,我更新了DbContextCollection维护Dictionary<KeyValuePair<Type, string>, DbContext>而不是Dictionary<Type, DbContext>作为其缓存_initializedDbContexts,其中添加的stringnameOrConnectionString参数。换句话说,我更新它以缓存唯一的DbContext类型/连接字符串对。

然后我可以通过我需要的连接到达DbContext

var dbContext = new CustomAmbientDbContextLocator().Get<CRMEntities>("name=CRMEntitiesAdmin");

当然,您必须要小心,当代码应该通过同一个代码时,代码不会通过两个不同的上下文/连接字符串。在我的例子中,我将它们分成两个不同的数据访问类实现。