I am trying to get Codedom to generate the following code:
public class NewContext : DbContext
{
public NewContext()
: base("NewContext")
{
EntityToRegisterDictionary = new ConcurrentDictionary<string, Assembly>();
}
static NewContext()
{
Database.SetInitializer(new DropCreateDatabaseIfModelChanges<EFEntityModelContext>());
}
}
I can generate
public class NewContext : DbContext
without any problems. I'm running into problems with writing the code that creates the two constructors. I have created two methods, one method for each constructor. This is what my methods look like:
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;
}
This code doesn't produce exactly the code I want above, however. I get:
public NewContext() :
base("connectionStr")
{
.EntityToRegisterDictionary = new ConcurrentDictionary<string, Assembly>();
}
NewContext()
{
new Database.SetInitializer(new DropCreateDatabaseIfModelChanges<EFEntityModelContext>();
}
The problem in the "public NewContext()" constructor is that there is a '.' before
EntityToRegisterDictionary
I assume this is because of the line
body.Left = new CodeFieldReferenceExpression(new CodeFieldReferenceExpression(), "EntityToRegisterDictionary");
Does anyone know how to make it without the period?
There are three problems with the "static NewContext()" constructor:
Codedom doesn't write static before NewContext()
It writes new before Database.
I can't add a right parenthesis after the () at the end because () is added automatically after whatever I write.
Does anyone know how to just make it write
Database.SetInitializer(new DropCreateDatabaseIfModelChanges<EFEntityModelContext>());
without the new keyword and with the addition right parenthesis?
Edit: By the way, EntityToRegisterDictionary is something I define below as:
public IDictionary<string, Assembly> EntityToRegisterDictionary { get; private set; }
I just haven't included all of this context class.
The problem in the "public NewContext()" constructor is that there is a '.' before
Yes, you are providing a CodeFieldReferenceExpression
with no actual field reference so it's just using an empty string. What you're looking for is CodeThisReferenceExpression
since you're just accessing a member on the same class.
body.Left = new CodeFieldReferenceExpression(new CodeThisReferenceExpression(), "EntityToRegisterDictionary");
This will generate the assignment using the this
keyword as shown below:
this.EntityToRegisterDictionary = new ConcurrentDictionary<string, Assembly>();
Codedom doesn't write static before NewContext()
You are using CodeConstructor
which creates an instance constructor. The fact that one of the attributes you can provide is MemberAttributes.Static
is a little misleading, but it becomes clear when you read the remarks section of the documentation . You should be using CodeTypeConstructor
to generate a static
constructor.
It writes new before Database. I can't add a right parenthesis after the () at the end because () is added automatically after whatever I write.
You are using CodeObjectCreateExpression
, which is used to create a new instance of a type, to try and call a static
method. To call a method, you would use CodeMethodInvokeExpression
. You should first create an expression for the Database.SetInitializer
method and pass the argument using CodeObjectCreateExpression
.
var method = new CodeMethodReferenceExpression(new CodeTypeReferenceExpression("Database"), "SetInitializer");
var body = new CodeMethodInvokeExpression(method, new CodeObjectCreateExpression("DropCreateDatabaseIfModelChanges<EFEntityModelContext>"));
constructor.Statements.Add(body);
CodeAssignStatement body = new CodeAssignStatement();
body.Left = new CodeFieldReferenceExpression(null, "Propiedad ");
body.Right = new CodeFieldReferenceExpression(null, "parametro");
------------------------------- OUTPUT--------------------------------
private Metodo(string parametro) {
Propiedad = parametro;
}
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.