12

ある段階でこれを行ったことがあると確信していますが、今は方法がわかりません! 私のシナリオ:

// This is generated from EDMX
public partial class HOLDbEntities : DbContext
{
    public HOLDbEntities()
            : base("name=HOLDbEntities")
        {
        }
}

ここで、この接続文字列を簡単に変更できるようにしたい (HOLDbEntities から実装したい) ため、このコンストラクターをオーバーライドする必要があります。

私はもう試した:

public partial class HOLDbEntities
{
    private const string _contextName = "HOLDbEntities";
    public static string ContextName { get { return _contextName; } }

    public HOLDbEntities()
        : base(ContextName)
    {
    }
}

しかし、これはエラーをスローします:

HOLDbEntities は、同じパラメーター タイプを持つ "HOLDbEntities" というメンバーを既に定義しています。

このエラーの理由は理解できますが、最初にコンストラクターの自動生成を停止して、達成しようとしていることを実行するにはどうすればよいですか?

4

5 に答える 5

21

かなりエレガントな方法であるため、以前に受け入れられた回答に賛成票を投じました。ただし、別の方法として、dbContext クラスを生成する T4 テンプレートを変更することもできます。

最初に EF DB を使用すると、.edmx ファイルがあり、その下に [Entity].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)#>
<#
    }
}
#>

これで、コンテキスト クラスはコンストラクターなしで生成されるため、拡張クラスでコンストラクターを作成できるはずです。

于 2014-01-31T21:24:19.803 に答える
10

私が提案できる最善の方法は、ファクトリメソッドです。

private HOLDbEntities(string contextName) : base(contextName) { }

public static HOLDbEntities Create() {
    return new HOLDbEntities(ContextName);
}

HOLDbEntities.Create()ではなく使用しますnew HOLDbEntities()

于 2013-02-26T11:59:23.400 に答える
3

次のように context.tt を変更しました。

<#=Accessibility.ForType(container)#> partial class <#=code.Escape(container)#> : DbContext
{
    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)#>
<#
    }
}
#>
var Method = (typeof(Entities)).GetMethods(System.Reflection.BindingFlags.NonPublic | System.Reflection.BindingFlags.Instance).FirstOrDefault(x => x.Name == "OnModelConstructed");
if (Method!=null) Method.Invoke(this,null);
    }

そのため、コンテキストの部分クラスでOnModelConstructedメソッドを宣言できます。

于 2015-06-23T07:40:49.077 に答える