问题
How can I force Orchard to rerun the Migrations.Create method to re-create my module's data? All the tutorials I've seen use the Migrations.UpdateFrom methods to make Orchard recognize module data changes, but this means I'll have to create a new method every time I make a change during development. These methods make sense for actual version updates, but not for initial development.
I've tried disabling and re-enabling the module, no dice. I've also tried uninstalling and reinstalling the module, but running the uninstall command permanently deleted the module from my computer, bypassing the recycling bin.
回答1:
I'm a little confused by you question, but I'll try to answer
Migrations update the database, and data in the database. If you want to make a change to a view you see in the dashboard, you shouldn't neet to re-run migrations.
however if you want to change the model and data, you do need to either run more migrations or reset the database and run the create migration.
When I rebuild a module I'm working on it will run any outstanding migration with out having to disable / enable the module on my local version,
That is to say if the current migration version is 1 and there is an UpdateFrom1 method, in the migration, this will be run when the project is built.
you can check the current version number in the following table Orchard_Framework_DataMigrationRecord
If you want to force rerun a migration, you can reset the value of table in the database. Or you can back up the database, and restore before running the entire suite of migrations.
While developing I use short migrations, creating a method each time I need to add data, I try and keep these small so I can identify any issues easily during development.
then before completing the module, amalgamate migrations into 2 or 3 logical blocks of code
Here's a migration for a custom type
public int Create()
{
// Define the project type
ContentDefinitionManager.AlterTypeDefinition("Project", cfg => cfg
.WithSetting("Stereotype", "Content")
.CommomPart()
.AutoroutePart("our-work")
.BodyPart()
.WithPart("TitlePart")
.WithPart("PublishLaterPart")
.WithPart("MenuPart", builder => builder
.WithSetting("MenuPart.OnMenu", "true")
.WithSetting("MenuPart.CurrentMenu", "Project Menu"))
.WithPart("Project")
.Creatable()
.Draftable());
return 1;
}
public int UpdateFrom1()
{
// Define project part - having a part with the same name will create fields in the project type
ContentDefinitionManager.AlterPartDefinition("Project", builder => builder
.MediaPickerField("MainImage")
.MediaPickerField("MediumImage")
.MediaPickerField("SmallImage")
.MediaPickerField("Logo")
.TextField("ShortDescription", Flavour.TextArea)
.TextField("Features", Flavour.Markdown)
.TextField("ClientTitle", Flavour.DefaultFlavour)
.TextField("ClientName", Flavour.DefaultFlavour)
.TextField("ClientQuote", Flavour.Textarea)
.BooleanField("MainProjectOnHomePage", false)
.Attachable());
return 2;
}
I added some extension methods to make this less verbose.
here they are
public static class MigrationExtentionHelpers
{
// part definitions
public static ContentPartDefinitionBuilder MediaPickerField(this ContentPartDefinitionBuilder builder,
string name, bool required = true, string hint = "")
{
var displayName = SplitCamel(name);
// default implementation of Media picker field - create overloads for more options
return builder.WithField(name, fieldBuilder => fieldBuilder
.OfType("MediaPickerField")
.WithDisplayName(displayName)
.WithSetting("MediaPickerFieldSettings.Required", required.ToString(CultureInfo.InvariantCulture))
.WithSetting("MediaPickerFieldSettings.AllowedExtensions", "jpg png gif")
.WithSetting("MediaPickerFieldSettings.Hint", hint));
}
public static ContentPartDefinitionBuilder TextField(this ContentPartDefinitionBuilder builder,
string name, Flavour flavor, bool required = true, string hint = "")
{
var strFlavor = SplitCamel(flavor.ToString());
// default implementation of Media picker field - create overloads for more options
return builder.WithField(name, fieldBuilder => fieldBuilder
.OfType("TextField")
.WithSetting("TextFieldSettings.Required", required.ToString(CultureInfo.InvariantCulture))
.WithSetting("TextFieldSettings.Flavor", strFlavor)
.WithSetting("TextFieldSettings.Hint", hint));
}
public static ContentPartDefinitionBuilder BooleanField(this ContentPartDefinitionBuilder builder,
string name, bool defalut, string hint = "")
{
// default implementation of Media picker field - create overloads for more options
return builder.WithField(name, fieldBuilder => fieldBuilder
.OfType("BooleanField")
.WithSetting("BooleanFieldSettings.Hint", hint)
.WithSetting("BooleanFieldSettings.DefaultValue", defalut.ToString(CultureInfo.InvariantCulture)));
}
// type definitions
public static ContentTypeDefinitionBuilder AutoroutePart(this ContentTypeDefinitionBuilder builder, string pathPrefix = "")
{
var pattern = string.Format("[{{Name:'{0}/Title', Pattern: '{0}/{{Content.Slug}}', Description: 'my-page'}}]", pathPrefix);
return builder.WithPart("AutoroutePart", partBuilder => partBuilder
.WithSetting("AutorouteSettings.PatternDefinitions", pattern));
}
public static ContentTypeDefinitionBuilder BodyPart(this ContentTypeDefinitionBuilder builder,
Flavour defaultFlavour = Flavour.Markdown)
{
return builder.WithPart("BodyPart", partBuilder => partBuilder
.WithSetting("BodyTypePartSettings.Flavor", defaultFlavour.ToString()));
}
public static ContentTypeDefinitionBuilder CommomPart(this ContentTypeDefinitionBuilder builder)
{
return builder.WithPart("CommonPart")
.WithSetting("OwnerEditorSettings.ShowOwnerEditor", false.ToString(CultureInfo.InvariantCulture).ToLower());
}
private static string SplitCamel(string enumString)
{
StringBuilder sb = new StringBuilder();
char last = char.MinValue;
foreach (char c in enumString)
{
if (char.IsLower(last) && char.IsUpper(c))
{
sb.Append(' ');
sb.Append(c.ToString(CultureInfo.InvariantCulture).ToLower());
}
else
{
sb.Append(c);
}
last = c;
}
return sb.ToString();
}
}
回答2:
Basically there is no way to run a migration twice I am aware of unless you restore db from previously created backup or tweak it directly. As for me it's not a problem, because during the development in my team we use local instances of dbs and after combine all the migrations into initial one and deploy to test/staging environment.
来源:https://stackoverflow.com/questions/11819970/orchard-cms-module-development-workflow