I've managed somehow to get my databases out of sync. I'm using the code-first approach in building this MVC 4 C#.
public class RandomTable
{
public int Id { get; set; }
public int UserId { get; set; }
public string FullName { get; set; }
public string Link { get; set; }
public bool? Verified { get; set; }
}
In adding a new table into an existing model I've tried using add-migration RandomTable and then update-database.
However I've noticed the migration is empty so I believe it is out of sync completely.
How do I recover this?
Related
I'm using context.Database.EnsureCreated(); to map and create automatically tables considering their entities on Mac OS. But, it doesn't create new tables for new entities newly created.
When I run the following codes, I see 3 tables in the db. But when I add Battle.cs and uncomment -
public DbSet<Battle> Battles { get; set; }
in DbContext, the context.Database.EnsureCreated(); call doesn't create the Battle table in database.
Models -
public class Samurai
{
public Samurai()
{
Quotes = new List<Quote>();
}
public int Id { get; set; }
public string Name { get; set; }
public List<Quote> Quotes { get; set; }
public Clan Clan { get; set; }
}
public class Clan
{
public int Id { get; set; }
public string ClanName { get; set; }
}
public class Quote
{
public int Id { get; set; }
public string Text { get; set; }
public Samurai Samurai { get; set; }
public int SamuraiId { get; set; }
}
DbContext -
public class SamuraiContext : DbContext
{
public DbSet<Samurai> Samurais { get; set; }
public DbSet<Quote> Quotes { get; set; }
public DbSet<Clan> Clans { get; set; }
// public DbSet<Battle> Battles { get; set; }
protected override void OnConfiguring(DbContextOptionsBuilder optionsBuilder)
{
optionsBuilder.UseMySQL(#"Server=localhost;port=3306;Database=exercise;Uid=root;Pwd=password;allowPublicKeyRetrieval=true;");
base.OnConfiguring(optionsBuilder);
}
}
The Battle model -
public class Battle
{
public int Id { get; set; }
public string Name { get; set; }
public DateTime StartDate { get; set;}
public DateTime EndDate { get; set; }
}
Program -
class Program
{
private static SamuraiContext context = new SamuraiContext();
static void Main(string[] args)
{
context.Database.EnsureCreated();
}
}
As Jeremy commented, EnsureCreated() simply doesn't do what you want to do. From the documentation page:
Ensures that the database for the context exists. If it exists, no
action is taken. If it does not exist then the database and all its
schema are created. If the database exists, then no effort is made to
ensure it is compatible with the model for this context.
EnsureCreated() is great if for example you're integration testing on an in-memory SQLite database.
Normally you want to generate a schema for the current model by running dotnet ef migrations add <MigrationName>, and then if you want to programmatically ensure that the database reflects the current schema, call database.Migrate(). Of course you can also call dotnet ef database update from the cli.
That said, if you're working with a throwaway database of some sorts, and you don't want to bother at all with generating schema or migrations, then ...
database.EnsureDeleted();
database.EnsureCreated();
... should work fine, because these Ensure* methods don't rely on migrations.
(I just tested it by adding an extra entity to a DbContext, then calling EnsureDeleted() followed by EnsureCreated() without a prior migration, and it indeed recreated the database, with a table for the new entity as well.)
If you have additional questions, feel free to comment, and I'll address them. :)
I am having a weird issue with my project. I have 2 models in my project and they are called Job and Jobs. Originally when I started the project it created the tables in SQL as Jobs and Jobs1. I am confused as to why it called the tables these names. When I deleted the tables in SQL and recreated them to add changes I named them Job and Jobs. When I run the project and try to retrieve the data it is telling me it cannot find dbo.Jobs1. I do not have anything in my code that would make entity framework create these tables in the first place. Also my AspNet _Migration table does not exist anymore. I deleted it due to changes and the system usually puts a new one back but it doesn't appear to do this either. Not important to me unless someone can tell me that it will break the system if not there or that the problem I am having is related. I have done a search in the project for dbo.Jobs1 and just Jobs1 and nothing comes up. Could someone direct me as to where to correct this and maybe why it created these tables in that fashion in the first place. Thank you.
These are the models of question in my project:
public class Job
{
public Job()
{
SubJobs = new List<Jobs>();
}
[Key]
public string TopLvlJob { get; set; }
public string Description { get; set; }
public string ExtDescription { get; set; }
public string PartNumber { get; set; }
public string Drawing { get; set; }
public bool UpgradeAvailable { get; set; }
public virtual IEnumerable<Jobs> SubJobs { get; set; }
}
}
public class Jobs
{
public Jobs()
{
Parts = new List<MaterialRequired>();
}
[Key]
public string JobNumber { get; set; }
public string Drawing { get; set; }
public string PartNumber { get; set; }
public string Description { get; set; }
public string ExtDescription { get; set; }
public string TopLvlJob { get; set; }
public bool IsViewable { get; set; }
public virtual IEnumerable<MaterialRequired> Parts { get; set; }
}
I am working with a .Net API project. The trouble is, that I have a kind of slow computer and I was working with VS 2013. After some time I installed VS 2015, and it worked perfectly until I removed VS 2013. Besides, the uninstallation of VS 2013 was pretty difficult, because I had to follow up this guide: Cannot uninstall, install or repair Visual Studio 2012 & 2013 (download whole setup, and use command line). Now problem is that now SQL server does not accept ManagerIds and WorkerIds that I pass.
My document class:
public class ConstructionSite
{
public int Id { get; set; }
public int CreatorId { get; set; }
public List<int> ManagerIds { get; set; }
public List<int> WorkerIds { get; set; }
public DateTime CreatedAt { get; set; }
public bool IsActive { get; set; }
}
But when I hit "Show table data" button, it only gives me this type of view:
I tried to change Configuration.cs class Seed method like this:
protected override void Seed(ReportRest.Models.ApplicationDbContext context)
{
context.ConstructionSites.AddOrUpdate(new ConstructionSite
{
CreatorId = 2,
CreatedAt = new DateTime(2000, 01, 01),
IsActive = false,
ManagerIds = new List<int> {1},
WorkerIds = new List<int> {2},
});
}
Then I removed existing Migrations folder, opened Nugget Package Manager Console and fired these commands:
Enable-Migrations
Add-Migration First
Update-Database.
Unfortunately, that hadn't helped me to recover ManagerIds and WorkerIds. So, before messing with unstable Microsoft setups, I would like to ask you if there is a way to remind my database of forgotten variables. Thanks in advance!
Not realy sure what columns your are missing, since all 4 normal columns are shown in database and the both lists should normaly be stored in own database-tables.
But if you use the default setup with ASP.net and EntityFramework and you already had a Migrations-folder, there should be also a "__MigrationHistory"-Table in database.
Means, if you deleted the old Migrationsfolder, your are also needed to delete the entries of the table. After that you can create an new "Add-Migration InitialCreate" and should get a whole first Migration of your current code base.
// For creating the new initial Datbase-Update to get a working migration for future changes:
Add the new Migration,
then cut the content of Up() and Down() Methode from new the migration file
Run Update-Database (to create the entry for __MigrationHistory-table)
Strg-Z in the migration-file to backup the original content
After that you are able to run Add-Migration and Update-Database for future changes of your Models
If you want one-to-may relations to Managers and Workers, you have to create something like this:
public class MyDbContext : DbContext
{
public DbSet<ConstructionSite> ConstructionSites { get; set; }
public DbSet<Manager> Managers { get; set; }
public DbSet<Worker> Workers { get; set; }
public MyDbContext()
: base("YourConnectionStringName")
{
}
}
public class ConstructionSite
{
public Guid Id { get; set; }
public int CreatorId { get; set; }
public List<Manager> Managers { get; set; }
public List<Worker> Workers { get; set; }
public DateTime CreatedAt { get; set; }
public bool IsActive { get; set; }
}
public class Manager
{
public Guid Id { get; set; }
public string Name { get; set; }
public Guid ConstructionSiteId { get; set; }
}
public class Worker
{
public Guid Id { get; set; }
public string Name { get; set; }
public Guid ConstructionSiteId { get; set; }
}
This creates relations you want
I've been trying to solve this issue for 3 days now, and just can't figure it out. I've searched the web a lot and most of the solutions suggest using null initializer which doesn't solve my problem:
This is my model:
public class JobsRecord
{
[Key]
public int Index { get; set; }
[Required]
[Index]
public int TaskID { get; set; }
[ForeignKey("TaskID")]
public virtual TasksRecord Task { get; set; }
[Required]
[Index]
public Int64 DeviceID { get; set; }
[Required]
public DateTime NextRunTimestamp { get; set; }
public DateTime TimeOfRun { get; set; }
public TasksJobsMisc.RunResultEnum RunResult { get; set; }
public int JobResult { get; set; }
public double JobResultValue { get; set; }
public string ExtendedResults { get; set; }
public string Comments { get; set; }
}
public class JobsRecordHistory
{
[Key]
public int Index { get; set; }
[Required]
[Index]
public int TaskID { get; set; }
[ForeignKey("TaskID")]
public virtual TasksRecord Task { get; set; }
[Index]
public Int64 DeviceID { get; set; }
public TasksJobsMisc.RunResultEnum RunResult { get; set; }
public int JobResult { get; set; }
public double JobResultValue { get; set; }
public string ExtendedResults { get; set; }
public string Comments { get; set; }
}
public class TasksRecord
{
[Key]
public int TaskID { get; set; }
[Required]
public int Interval { get; set; } //minutes
[Required]
public string TaskObjName { get; set; }
[Required]
[Index]
public ReporterType Type { get; set; }
public int MaxDaysSinceLastReport { get; set; }
public int MinVersion { get; set; }
public int MaxVersion { get; set; }
public int FailureInterval { get; set; } //minutes
public string Site { get; set; }
public string TaskName { get; set; }
public string JSONConfig { get; set; } //extra configuration
public int ParallelLevel { get; set; } //control parallelism for each task
public int EnableDisable { get; set; }
}``
What I'm trying to do is to add the last field, EnableDisable, to the TaskRecord class. Up until now I worked with EF Code First migrations and was pretty happy about it, but now, when I try to add the EnableDisable field to that class and run 'Add-Migration TasksEnable' and then Update-Database, although it runs successfully, When I run my code I get the 'The model backing the 'TasksJobsDbContext' context has changed since the database was created' error where I use my context for the first time:
using (var db = new TasksJobsDbContext())
{
var blankjobs = db.JobsRecords.Include("Task").Where(x => x.RunResult == TasksJobsMisc.RunResultEnum.Blank);
Log.DebugFormat("Found {0} jobs", blankjobs.Count());
jobs = blankjobs.Where(x => DateTime.Now.CompareTo(x.NextRunTimestamp) > 0).ToList();
}
I know I can 'restart' the migrations like I read in some other stackoverflow thread, by dropping the migrations table and directory and just start from scratch and let the database and the migrations be recreated, but obviously I don't want to lose my data and more important, I want to figure it out so that I can handle it in the future.
I tried the null initializer and it didn't help.
Every time I get this error I just revert the last migration by 'Update-Database -TargetMigration: 'my last working migration'' and that fixes the problem.
I tried some debugging to add some more data:
using (var db = new TasksJobsDbContext())
{
Log.DebugFormat("compatible (with metadata): {0}", db.Database.CompatibleWithModel(true));
Log.DebugFormat("compatible: {0}", db.Database.CompatibleWithModel(false));
Log.DebugFormat("exists: {0}", db.Database.Exists());
db.Database.Initialize(true);}
What I get is (initializer set do Database.SetInitializer(null);
or to Database.SetInitializer(new CreateDatabaseIfNotExists());, same results for both)
: false, false, true, then this exception again...
I'm using VS2013, EF 6.9.6.0, Code First, MySQL, and this is my first project with EF (went pretty well up until now).
So, as we've found in comments everything seems ok, except the error itself..
I can't guess the actual reason of it, but have some proposals to mitigate the outcome.
Generate scripts for all the data you have (SQL management studio has such possibility, for example), delete your db, run all the migrations for db creation, restore data and work like this never happened (actually I've never met such a weird behaviour before, so with high probability it will not repeat)
Delete your MigrationHistory table and all the migrations (code and resources), then create migration starting from actual db state with use of -IgnoreChanges flag for add-migration command.
As written in docs for -IgnoreChanges.
Scaffolds an empty migration ignoring any pending changes detected in the current model. This can be used to create an
initial, empty migration to enable Migrations for an existing
database. N.B. Doing this assumes that the target database schema is
compatible with the current model.
But with this approach you won't be able to recreate your db on another server using migrations only.
I'm developing a Class library using C# using the latest version of Entity Framework and VS2010. I have this class:
public class User
{
public int UserId { get; set; }
public String Name { get; set; }
public int Age { get; set; }
public String City { get; set; }
public String Country { get; set; }
public String Email { get; set; }
public String InterestIn { get; set; }
public List<User> Friends { get; set; }
public List<User> FromWhomIsFriend { get; set; }
public List<Activity> WantsToDo { get; set; }
public List<Message> MessagesSent { get; set; }
public List<Message> MessagesReceived { get; set; }
}
EF has generated these two tables on SQLEXPRESS:
I have three questions:
How can I rename the table dbo.UserUsers to dbo.UserFriends?
How can I rename its two columns to UserId and FriendId?
How can I set columns UserId and FriendId as PK for dbo.UserFriends table?
NOTE: This is my first time working with EF Code First.
The easiest option is to create this table in your model. If EF detect such table it won't create another one.
To customize column name look here: How to customize foreign key column name using Entity Framework Code-first