数据库优先和实体框架动态连接字符串

时间:2015-03-08 16:54:02

标签: c# wpf entity-framework azure

在我的WPF应用程序(数据库优先EF)中,我需要提供一种方法,让用户在运行时更新/修改数据库连接字符串(位于azure)。我通过添加以下方法来扩展自动生成的MyContext部分类。但是我收到了错误

  

已存在相同签名的方法

添加动态连接字符串的正确步骤是什么?

THX

错误讯息:

  

输入' MyServDataCollection.Models.MyContext'已经定义了一个名为' MyContext'使用相同的参数类型

MyContext上课

using System.Data.Entity;
using System.Data.Entity.Core.EntityClient;

public partial class MyContext : DbContext
{
    public MyContext() : base(GetConnectionString())
    {
    }

    private static string GetConnectionString()
    {
        var model = "MyServDataCollectionModel";
        var providerConnectionString = "metadata=res://*/Models.MyServDataCollectionModel.csdl|res://*/Models.MyServDataCollectionModel.ssdl|res://*/Models.MyServDataCollectionModel.msl;provider=System.Data.SqlClient;provider connection string="data source=xxx.database.windows.net;initial catalog=xxxx;persist security info=True;user id=xxxxxxx;password=xxxxx;MultipleActiveResultSets=True;App=EntityFramework"";

        var efConnection = new EntityConnectionStringBuilder();
        efConnection.Provider = "System.Data.SqlClient";
        efConnection.ProviderConnectionString = providerConnectionString;

        // based on whether you choose to supply the app.config connection string to the constructor
        efConnection.Metadata = string.Format("res://*/Model.{0}.csdl|res://*/Model.{0}.ssdl|res://*/Model.{0}.msl", model);
        // Make sure the "res://*/..." matches what's already in your config file.
        return efConnection.ToString();
    }

2 个答案:

答案 0 :(得分:1)

此错误消息是正确的。无参数构造函数已包含在生成的部分类中(由Visual Studio生成)。要使用自定义连接字符串进行连接,只需使用连接字符串(或配置键 - 请参阅帮助)调用构造函数。我认为这个构造函数已经生成但如果不是,那么你可以简单地创建它,将这个代码添加到你的部分类中:

public partial class MyContext : DbContext
{
  public MyContext(string connectionStringOrKey)
    : base(connectionStringOrKey)
  {
  }
}

方法GetConnectionString()只能使用public而不是private来创建。
然后简单地调用

MyContext myCtx = new MyContext(MyConnection.GetConnectionString()) 
例如,

。 另一个解决方案是使用添加静态方法CreateMyContext:

修改您的分部类
public partial class MyContext : DbContext
{
  private static string GetConnectionString()
  {
  }

  public static MyConnection CreateMyContext()
  {
    return new MyContext(MyContext.GetConnectionString());
  }
}

在这种情况下,但将这些方法放到另一个类(扩展类?)可能会更好。

答案 1 :(得分:1)

如果您希望允许使用无参数构造函数来创建DBContext的实例,则可以修改T4模板以确保自动生成的类不定义无参数构造函数:

从MyContext.Context.tt文件中删除以下内容:

    public <#=code.Escape(container)#>()
        : base("name=<#=container.Name#>")
    {
    <#

    if (!loader.IsLazyLoadingEnabled(container))
    {
    #>
        this.Configuration.LazyLoadingEnabled = false;
    <#

    }

foreach (var entitySet in container.BaseEntitySets.OfType<EntitySet>())
{
    // Note: the DbSet members are defined below such that the getter and
    // setter always have the same accessibility as the DbSet definition
    if (Accessibility.ForReadOnlyProperty(entitySet) != "public")
    {
    #>
            <#=codeStringGenerator.DbSetInitializer(entitySet)#>
    <#
        }
    }
    #>
    }

这将允许您的部分课程按预期工作。