I am building an MVC 5 website with code first migration approach. Also, mention that I'm using Visual Studio Online linking to my Azure Web site. So, when I use Team Explorer in VS 2013 to do a check in, it automatically is deployed to Azure web sites.
Locally all works OK. However, when deploying it to Azure (check in) the following points are NOT performed:
If a new table is created using the code first approach, it is not created when deploying to Azure
The seed method (in the configuration.cs file) is not executed.
Due to the above, I have to manually either create the new tables or adding the test data. Google it for a solution I have read that this is a problem in the .Net framework due to the kind of index (nonclustered) to is set by default.
So, I have trying to use different alternatives. As for example:
public Configuration()
{
AutomaticMigrationsEnabled = true;
ContextKey = "MySolution.Models.ApplicationDbContext";
SetSqlGenerator("System.Data.SqlClient", new AzureSqlGenerator());
}
Where I created the AzureSqlGenerator class:
public class AzureSqlGenerator : SqlServerMigrationSqlGenerator
{
protected override void Generate(CreateTableOperation createTableOperation)
{
if ((createTableOperation.PrimaryKey != null)
&& !createTableOperation.PrimaryKey.IsClustered)
{
createTableOperation.PrimaryKey.IsClustered = true;
}
base.Generate(createTableOperation);
}
}
But, that doesn't work.
Long story short, I have the following two questions:
Is it possible to migrate the tables and its data when deploying to Azure?
If so, what would be the correct steps to do that?
Thanks in advance.
You can migrate tables. To migrate data, you should use Seed method of entity framework.
public class SchoolDBInitializer : DropCreateDatabaseAlways<SchoolDBContext>
{
protected override void Seed(SchoolDBContext context)
{
IList<Standard> defaultStandards = new List<Standard>();
defaultStandards.Add(new Standard() { StandardName = "Standard 1", Description = "First Standard" });
defaultStandards.Add(new Standard() { StandardName = "Standard 2", Description = "Second Standard" });
defaultStandards.Add(new Standard() { StandardName = "Standard 3", Description = "Third Standard" });
foreach (Standard std in defaultStandards)
context.Standards.Add(std);
base.Seed(context);
}
}
http://www.entityframeworktutorial.net/code-first/seed-database-in-code-first.aspx
In my opinion the best you can do, use Sql Server Data Tools. It will help you with tables and also data, because it uses a declarative mode. You 'declare' how should be your database, and it handles de updates.
https://www.youtube.com/watch?v=uPll3dMxTXU
Related
Microsoft Dynamics CRM 2015.
I test Asp.Net Core controller's action. When I create new Lead record some plugin generates new Guid for lead.new_master_id field (it's type is string). Therefore after creating I retrive the record to get it's generated new_master_id value. How can I emulate this plugin behaviour through Fake Xrm Easy?
var fakedContext = new XrmFakedContext();
fakedContext.ProxyTypesAssembly = typeof(Lead).Assembly;
var entities = new Entity[]
{
// is empty array
};
fakedContext.Initialize(entities);
var orgService = fakedContext.GetOrganizationService();
var lead = new Lead { FirstName = "James", LastName = "Bond" };
var leadId = orgService.Create(lead);
var masterId = orgService.Retrieve(Lead.EntityLogicalName, leadId,
new Microsoft.Xrm.Sdk.Query.ColumnSet(Lead.Fields.new_master_id))
.ToEntity<Lead>().new_master_id;
In v1.x of FakeXrmEasy you'll need to enable PipelineSimulation and register the plugin steps you would like to be fired on Create manually by registering their steps.
fakedContext.UsePipelineSimulation = true;
Once enabled, you'll need to enable the necessary steps via calling RegisterPluginStep. In your example you'll need to at least register something along the lines of:
fakedContext.RegisterPluginStep<LeadPlugin>("Create", ProcessingStepStage.Preoperation);
Where LeadPlugin would be the name of your plugin that generates the new_master_id property.
Keep in mind v1.x is limited in that it supports pipeline simulation for basic CRUD requests only.
Later versions (2.x and/or 3.x) come with a brand new middleware implementation allowing registering plugin steps for any message. Soon we'll be implementing automatic registration of plugin steps based on an actual environment and/or custom attributes.
Here's an example using the new middleware
public class FakeXrmEasyTestsBase
{
protected readonly IXrmFakedContext _context;
protected readonly IOrganizationServiceAsync2 _service;
public FakeXrmEasyTestsBase()
{
_context = MiddlewareBuilder
.New()
.AddCrud()
.AddFakeMessageExecutors()
.AddPipelineSimulation()
.UsePipelineSimulation()
.UseCrud()
.UseMessages()
.Build();
_service = _context.GetAsyncOrganizationService2();
}
}
You can find more info on the QuickStart guide here
Disclaimer: I'm the author of FakeXrmEasy :)
recently i've been trying to set up a connection to my Firestore database. I followed the instructions given in this video only that there is a runtime exception when it tries to get the data base via GetDatabase()
public static FirebaseFirestore GetDatabase()
{
FirebaseFirestore database;
var app = Firebase.FirebaseApp.InitializeApp(Application.Context);
if (app == null)
{
var options = new Firebase.FirebaseOptions.Builder()
.SetProjectId("fulcrum-7c537")
.SetApplicationId("fulcrum-7c537")
.SetApiKey("AIzaSyA8lo7k0EFPNR32-g4xdBnMkQnycn_v4G8")
.SetDatabaseUrl("https://fulcrum-7c537.firebaseio.com")
.SetStorageBucket("fulcrum-7c537.appspot.com")
.Build();
app = Firebase.FirebaseApp.InitializeApp(Application.Context , options);
}
database = FirebaseFirestore.GetInstance(app);
return database;
}
The Exception :
Java.Lang.NoClassDefFoundError
Message=Failed resolution of: Lcom/google/common/io/BaseEncoding;
I have been trying for a while to find out why it happens but found nothing. May someone has a solution?
Thanks!
I had exactly the same issue. I downloaded the code provided by Ufinix (the creator of the video). I downgraded the Xamarin.Google.Guava current version 28.2.0 I used, to the 27.1.0.1 version he used in his example. And finally, it worked.
I am creating a football manager game. I have used identity 2.0 as it will work well for my registration and login. I was able to add the extra tables that were needed but now I need to seed the data such as teams and players to these table. Any idea how to do so? The extra tables were created in the identity models using migrations. Here is a picture of the tables I am using.
In the Migrations folder, there is a file called Configuration.cs with the Seed method that you can use to create some seed data.
protected override void Seed(ApplicationDbContext context)
{
// This method will be called after migrating to the latest version.
// You can use the DbSet<T>.AddOrUpdate() helper extension method
// to avoid creating duplicate seed data. E.g.
//add roles
context.Roles.AddOrUpdate(p => p.Id,
new IdentityRole()
{
Id = EnumUtility<AspNetRoles>.GetAppRoleId(AspNetRoles.None),
Name = AspNetRoles.None.ToString()
});
}
Just run update-database and you should have data in your tables.
There are 2 Seed() methods available - one in certain initializers such as CreateDatabaseIfNotExist that is run whenever the database is created. The other is the migration Seed() which runs whenever you apply a migration via update-database.
Since it runs with every migration, you want to make sure you don't duplicate your data. You could do this by checking for existence:
if (!context.Teams.Any())
{
context.Teams.Add(new Team { Name = "Team A" });
context.Teams.Add(new Team { Name = "Team B" });
}
But there is a better way designed specifically for migrations called AddOrUpdate:
protected override void Seed(ApplicationDbContext context)
{
context.Teams.AddOrUpdate(
team => team.Id, // put the key or unique field here
new Team
{
Id = 1,
Name = "Team 1"
},
new Team
{
Id = 2,
Name = "Team 2"
});
context.SaveChanges();
}
I'm refactoring a project and want to move all the EF entities and the code-first migrations to a new project. I renamed the ContextKey in the _Migrations table to the new namespace. When running an Add-Migration, no new changes are detected (Up() and Down() are empty).
But when I remove the localdb, the db isn't re-created (it did before the move). Apparently only migrations created after the move are run (but it shouldn't).
How can I make sure all migrations (also the ones before the move) are run when creating a new db?
--edit--
Never mind :(
I dragged and dropped the existing migrations to the new project and renamed the namespaces in the migration.cs files, but forgot the code behind migration.Designer.cs
You can update all the ContextKey column values in the dbo._MigrationHistory table to match the new namespace and that's all.
For me i was moving all the code first models from ASP.NET MVC app to external Class library to share with other projects.
Below steps may help
check the dbo._MigrationHistory and you can see all records have
similar values which match the exact class of Configuration class
MyApp.Migrations.Configuration
2.(test step) run Update-Database from Package Manager Console with new class library selected and you will see for example below error
There is already an object named 'AspNetRoles' in the database.
update all the records in the ContextKey column of _MigrationHistory table to match the new namespace
MyApp.Domain.Migrations.Configuration
The reference table [__MigrationHistory] contains a ContextKey column. Unless otherwise valued, it maintains the value of the membership of DbContext namespace.
You can set a class that derives from dbMigrationsConfiguration and set the ContextKey value in the constructor.
public sealed class Configuration : DbMigrationsConfiguration<Your.Context>
{
public Configuration()
{
AutomaticMigrationsEnabled = true;
AutomaticMigrationDataLossAllowed = true;
ContextKey = "PreviousValue";
}
protected override void Seed(Your.Context context)
{
// This method will be called after migrating to the latest version.
// You can use the DbSet<T>.AddOrUpdate() helper extension method
// to avoid creating duplicate seed data. E.g.
//
// context.People.AddOrUpdate(
// p => p.FullName,
// new Person { FullName = "Andrew Peters" },
// new Person { FullName = "Brice Lambson" },
// new Person { FullName = "Rowan Miller" }
// );
//
}
}
I'm using fluent migrator to manage my database migrations, but what I'd like to do is have the migrations run at app start. The closest I have managed is this:
public static void MigrateToLatest(string connectionString)
{
using (var announcer = new TextWriterAnnouncer(Console.Out)
{
ShowElapsedTime = true,
ShowSql = true
})
{
var assembly = typeof(Runner).Assembly.GetName().Name;
var migrationContext = new RunnerContext(announcer)
{
Connection = connectionString,
Database = "SqlServer2008",
Target = assembly
};
var executor = new TaskExecutor(migrationContext);
executor.Execute();
}
}
I'm sure I had this working, but I've not looked at it for sometime (hobby project) and it's now throwing null reference exceptions when it gets to the Execute line. Sadly there are no docs for this and I've been banging my head on it for ages.
Has anyone managed to get this kind of thing working with FluentMigrator?
PM> Install-Package FluentMigrator.Tools
Manually add a reference to:
packages\FluentMigrator.Tools.1.6.1\tools\AnyCPU\40\FluentMigrator.Runner.dll
Note that the folder name will vary on version number, this illustration uses the current 1.6.1 release. If you need the .NET 3.5 runner use the \35\ directory.
public static class Runner
{
public class MigrationOptions : IMigrationProcessorOptions
{
public bool PreviewOnly { get; set; }
public string ProviderSwitches { get; set; }
public int Timeout { get; set; }
}
public static void MigrateToLatest(string connectionString)
{
// var announcer = new NullAnnouncer();
var announcer = new TextWriterAnnouncer(s => System.Diagnostics.Debug.WriteLine(s));
var assembly = Assembly.GetExecutingAssembly();
var migrationContext = new RunnerContext(announcer)
{
Namespace = "MyApp.Sql.Migrations"
};
var options = new MigrationOptions { PreviewOnly=false, Timeout=60 };
var factory =
new FluentMigrator.Runner.Processors.SqlServer.SqlServer2008ProcessorFactory();
using (var processor = factory.Create(connectionString, announcer, options))
{
var runner = new MigrationRunner(assembly, migrationContext, processor);
runner.MigrateUp(true);
}
}
}
Note the SqlServer2008ProcessorFactory this is configurable dependent upon your database, there is support for: 2000, 2005, 2008, 2012, and 2014.
I have actually accomplished running migrations in the application_start however it is hard to tell from that code what could be wrong... Since it is open source I would just grab the code and pull it into your solution and build it to find out what the Execute method is complaining about. I found that the source code for Fluent Migrator is organized pretty well.
One thing that you might have to be concerned about if this is a web app is making sure that no one uses the database while you are migrating. I used a strategy of establishing a connection, setting the database to single user mode, running the migrations, setting the database to multi user mode, then closing the connection. This also handles the scenario of a load balanced web application on multiple servers so 2 servers don't try to run migrations against the same database.