如何在repository的objectcontext中指定连接字符串

时间:2012-06-07 13:50:58

标签: entity-framework connection repository t4

我们正在尝试为EF项目使用存储库模式。允许用户选择三个独立(但结构相同)数据库中的一个来登录(有一个用于培训,一个用于测试,一个用于生产)。

我们目前正在使用EF 4实现,并通过ADO.Net EntityObject Generator生成了我们的T4。我们的存储库基类如下所示:

public class RepositoryBase<C> : IDisposable
    where C : ObjectContext, new()
{
    private C _DataContext;

    public virtual C DataContext
    {
        get
        {
            if (_DataContext == null)
            {
                _DataContext = new C();
            }
            return _DataContext;
        }
    }

    //other code cut for brevity...
}

我认为我们想要的是能够修改“_DataConext = new C();” line,以便它可以使用在运行时生成的连接字符串指向正确的数据库。不幸的是,像这样传递连接字符串:_DataConext = new C(connectionString);不允许并导致此消息:“参数无法传递给类型参数上使用的'新'。”

我可以在model.tt文件的代码后面看到有三个构造函数:默认的无参数构造函数,一个具有EntityConnection参数的构造函数,第三个具有连接字符串参数(我们想要使用的参数)

问题是我们该如何做到这一点?任何帮助表示赞赏!

2 个答案:

答案 0 :(得分:1)

嗯,问题是在泛型类型上指定一个带参数的构造函数。这是不允许的。 第一种解决方案是使用反射。 如果您知道定义的构造函数是什么:

public virtual C DataContext
{
    get
    {
        if (_DataContext == null)
        {
            _DataContext = (C)Activator.CreateInstance(typeof(C), new object[]{ connectionString });
        }
        return _DataContext;
    }
}

更好的解决方案是将C的实例提供给您的存储库的构造。

希望有所帮助

答案 1 :(得分:0)

我是否可以加入这个线程,对创建一个新的ObjectContext泛型实例有好奇心? 当我在没有Activator的情况下使用CreateContext方法(下面)时,它会创建一个带有“default”连接字符串的新实例,无论我给它什么连接。 使用Activator,它能够正确查找和创建它,我迷路了......

在我的app.config中有两者,但它只使用在制作edmx时创建的那个。

    /// <summary>
    /// Base repository
    /// </summary>
    public RepositoryBase(Connection.ConnectionManagerBase connectionmanager)
    {
        this.pContext = this.CreateContext(connectionmanager, (x => new C()));
        this.ContextObjectSet = this.pContext.CreateObjectSet<T>();
    }

    /// <summary>
    /// Create context with connection string
    /// </summary>
    /// <param name="connectionmanager">Connection manager</param>
    /// <param name="factory">Factory context</param>
    /// <returns>Instance</returns>
    private C CreateContext(Connection.ConnectionManagerBase connectionmanager, Func<string, C> factory)
    {
        // this create instance with correct connection
        return (C)Activator.CreateInstance(typeof(C), new object[] { connectionmanager.ConnectionString }); 
        // this use the "default" connection, no matter what is in connectionmanager.ConnectionString
        return factory(connectionmanager.ConnectionString);
    }