如何使用Codedom正确设置自定义构造函数

时间:2015-06-29 22:51:56

标签: c# constructor codedom

我正在尝试让Codedom生成以下代码:

public class NewContext : DbContext
{

    public NewContext()
        : base("NewContext")
    {
        EntityToRegisterDictionary = new ConcurrentDictionary<string, Assembly>();
    }

    static NewContext()
    {
        Database.SetInitializer(new DropCreateDatabaseIfModelChanges<EFEntityModelContext>());
    }
}

我可以生成

public class NewContext : DbContext

没有任何问题。我在编写创建两个构造函数的代码时遇到了问题。我创建了两个方法,每个构造函数都有一个方法。这就是我的方法:

public static CodeConstructor BaseStringConstructor(string connectionStr)
{
    CodeConstructor baseStringConstructor = new CodeConstructor();
    baseStringConstructor.Attributes = MemberAttributes.Public;
    baseStringConstructor.BaseConstructorArgs.Add(new CodeVariableReferenceExpression("\"connectionStr\""));
    CodeAssignStatement body = new CodeAssignStatement();
    body.Left = new CodeFieldReferenceExpression(new CodeFieldReferenceExpression(), "EntityToRegisterDictionary");
    body.Right = new CodeObjectCreateExpression("ConcurrentDictionary<string, Assembly>");
    baseStringConstructor.Statements.Add(body);
    return baseStringConstructor;
}

public static CodeConstructor StaticInitializerConstructor()
{
    CodeConstructor constructor = new CodeConstructor();
    constructor.Attributes = MemberAttributes.Static;
    CodeObjectCreateExpression body = new CodeObjectCreateExpression("Database.SetInitializer(new DropCreateDatabaseIfModelChanges<EFEntityModelContext>");            
    constructor.Statements.Add(body);
    return constructor;
}

但是,此代码并不能完全生成我想要的代码。我明白了:

public NewContext() : 
        base("connectionStr")
{
    .EntityToRegisterDictionary = new ConcurrentDictionary<string, Assembly>();
}

NewContext()
{
    new Database.SetInitializer(new DropCreateDatabaseIfModelChanges<EFEntityModelContext>();
}

&#34; public NewContext()&#34;中的问题构造函数是有一个&#39;。&#39;之前

EntityToRegisterDictionary

我认为这是因为行

body.Left = new CodeFieldReferenceExpression(new CodeFieldReferenceExpression(), "EntityToRegisterDictionary");

有没有人知道如何在没有这段时间的情况下制作它?

&#34;静态NewContext()&#34;有三个问题。构造:

  1. Codedom在NewContext()之前没有写静态

  2. 它在数据库之前写入新内容。

  3. 我不能在最后的()之后添加右括号因为()是在我写完之后自动添加的。

  4. 有谁知道如何写它

    Database.SetInitializer(new DropCreateDatabaseIfModelChanges<EFEntityModelContext>());
    

    没有new关键字并附加右括号?

    编辑:顺便说一下,EntityToRegisterDictionary是我在下面定义的:

    public IDictionary<string, Assembly> EntityToRegisterDictionary { get; private set; }
    

    我还没有包含所有这个上下文类。

2 个答案:

答案 0 :(得分:0)

  

&#34; public NewContext()&#34;中的问题构造函数是有一个&#39;。&#39;前

是的,您提供的CodeFieldReferenceExpression没有实际的字段引用,因此它只使用空字符串。您正在寻找的是CodeThisReferenceExpression,因为您只是访问同一班级的成员。

body.Left = new CodeFieldReferenceExpression(new CodeThisReferenceExpression(), "EntityToRegisterDictionary");

这将使用this关键字生成作业,如下所示:

this.EntityToRegisterDictionary = new ConcurrentDictionary<string, Assembly>();
  

Codedom在NewContext()

之前不会写静态

您正在使用CodeConstructor创建实例构造函数。您可以提供的其中一个属性MemberAttributes.Static有点误导,但是当您阅读documentation的备注部分时,它就会变得清晰。您应该使用CodeTypeConstructor生成static构造函数。

  

它在数据库之前写入新内容。   我不能在最后的()之后添加右括号因为()在我写完之后自动添加。

您正在使用CodeObjectCreateExpression来尝试调用static方法,该Use cases of std::multimap用于创建类型的新实例。要调用方法,您可以使用CodeMethodInvokeExpression。您应该首先为Database.SetInitializer方法创建表达式,并使用CodeObjectCreateExpression传递参数。

var method = new CodeMethodReferenceExpression(new CodeTypeReferenceExpression("Database"), "SetInitializer");
var body = new CodeMethodInvokeExpression(method, new CodeObjectCreateExpression("DropCreateDatabaseIfModelChanges<EFEntityModelContext>"));
constructor.Statements.Add(body);

答案 1 :(得分:0)

CodeAssignStatement body = new CodeAssignStatement();
body.Left = new CodeFieldReferenceExpression(null, "Propiedad ");
body.Right = new CodeFieldReferenceExpression(null, "parametro");

------------------------------- OUTPUT--------------------------------
private Metodo(string parametro) {
    Propiedad = parametro;
}