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
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 think this is going to be easy (famous last words) but I'm new to EF7 and the Code First concept in general and .Net 5 and EF7 is relatively new at this point as well so there's not much out there yet. I'm converting a project from old school ASP 2.0 to .Net 5 and I'm recreating the whole database structure so Code First Migrations is good choice for me here.
I have an AdvertisementHistory table that links back to an Advertisement table and for every Advertisement record there will be a record in the AdvertisementHistory table for every month of every year the ad is running. I'm basically tracking Ad "Hit Counts" by month and year. I want to put a unique index in AdvertisementHistory on "AdvertisementID, Year, Month" and I certainly know how to do this in SQL, but EF Code First is yelling at me the way that I'm doing:
public class Advertisement
{
public int ID { get; set; }
[Required]
public string ImageURL { get; set; }
[Required]
public string DestinationURL { get; set; }
{{....Removing other fields you don't care about}}
}
public class AdvertisementHistory
{
public int ID { get; set; }
[Required]
public Advertisement Advertisement { get; set; }
[Required]
public int Year { get; set; }
[Required]
public int Month { get; set; }
[Required]
public int Clicked { get; set; }
{{....Removing other fields you don't care about}}
}
public class ApplicationDbContext : IdentityDbContext<ApplicationUser>
{
public DbSet<Advertisement> Advertisements { get; set; }
public DbSet<AdvertisementHistory> AdvertisementHistory { get; set; }
{{....Removing other classes you don't care about}}
protected override void OnModelCreating(ModelBuilder builder)
{
base.OnModelCreating(builder);
builder.Entity<AdvertisementHistory>()
.HasIndex(p => new { p.Advertisement, p.Year, p.Month })
.IsUnique();
}
}
Then I break out the Command Window since we don't have a project console for .Net 5 EF7 yet:
CMD> dnx ef migrations add Initial_FS
Here are the results:
{{....A bunch of stuff gets generated properly}}
The property 'Advertisement' cannot be added to the entity type 'AdvertisementHistory' because a navigation property with the same name already exists on entity type 'AdvertisementHistory'.
So if I remove "p.Advertisement" from my .HasIndex call everything works fine and it generates the code to make a proper index (although a bad one since I need the Ad ID). But it means this is definitely related to the fact them I'm using a field in my index that is a Foreign Key. I've tried a TON of different variations and annotations on the classes but nothing gets me a clean migration.
As you can see I'm trying very hard to code this from a minimalist perspective and letting .Net "Do its thing" wherever I can. This is why I think I'm missing something very simple here since this is not an unusual concept.
And in case you're wondering this (for the most part) is an initial migration since the only tables that currently exist in the database are the ones you get from AspNet.Identity.
Thanks in advanced community...
Try this. What you really want is to add a foreign key annotation for Advertisement and use this in your index:
public class Advertisement
{
public int ID { get; set; }
[Required]
public string ImageURL { get; set; }
[Required]
public string DestinationURL { get; set; }
}
public class AdvertisementHistory
{
public int ID { get; set; }
public int AdvertisementID { get; set; }
[Required]
[ForeignKey("AdvertisementID")]
public Advertisement Advertisement { get; set; }
[Required]
public int Year { get; set; }
[Required]
public int Month { get; set; }
[Required]
public int Clicked { get; set; }
}
protected override void OnModelCreating(ModelBuilder builder)
{
base.OnModelCreating(builder);
builder.Entity<AdvertisementHistory>()
.HasIndex(p => new { p.AdvertisementID, p.Year, p.Month })
}
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'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?