Error While Enabling Code-First Migrations On Mobile Services Database - c#

I have an Azure Mobile Services project (C# backend) that I recently created and attached to an Azure SQL database. I have been trying to enable Code-First Migrations on that backing database, but it throws errors when I try to update the database.
I ran through all of the conventional steps to enable migrations (Enable-Migrations, Add-Migration). But when I try to Update-Database, it returns the following error:
Cannot create more than one clustered index on table 'dbo.Appointments'. Drop the existing clustered index 'PK_dbo.Appointments' before creating another.
Why is this happening? There aren't any tables in my database, and the project is pretty much the default.

Several of the answers about deriving from a custom entity class will work, but they are not the ideal solution. As the EF team (and others) have mentioned, you need to simply add this line to your Context Configuration constructor.
SetSqlGenerator("System.Data.SqlClient", new EntityTableSqlGenerator());
This will remove your errors when creating migrations and allow you to update the database via powershell command.

If you are getting this error on update-database after creating the migration class, Then have a look # your migration class. The migration class will take primary is clustered index. So remove that from the up() method.
.PrimaryKey(t => t.Id, clustered: false)
.Index(t => t.CreatedAt, clustered: true);
If you using it on azure mobile service, do not call 'update-database' manually.
refer http://azure.microsoft.com/en-in/documentation/articles/mobile-services-dotnet-backend-how-to-use-code-first-migrations/

I was fighting with this problem today for a few hours. Until I found this link:
How to make data model changes to a .NET backend mobile service
If you follow the instructions there, it will definitely work. The main thing is, that the migration will take place, when you hit F5 during a local debugging session.

I just had the same issue.
It is caused by the definition of EntityData that is our base class:
public class OrgTest : EntityData
{
public string Prop1 { get; set; }
}
I replaced EntityData with my own implementation "CustomEntity" where I removed the attribute [Index(IsClustered = true)] on the CreatedAt column:
public abstract class CustomEntity : ITableData
{
// protected CustomEntity();
[DatabaseGenerated(DatabaseGeneratedOption.Identity)]
[TableColumn(TableColumnType.CreatedAt)]
public DateTimeOffset? CreatedAt { get; set; }
[TableColumn(TableColumnType.Deleted)]
public bool Deleted { get; set; }
[Key]
[TableColumn(TableColumnType.Id)]
public string Id { get; set; }
[DatabaseGenerated(DatabaseGeneratedOption.Computed)]
[TableColumn(TableColumnType.UpdatedAt)]
public DateTimeOffset? UpdatedAt { get; set; }
[TableColumn(TableColumnType.Version)]
[Timestamp]
public byte[] Version { get; set; }
}
and now I inherit from this one:
public class OrgTest : CustomEntity // EntityData
{
public string Prop1 { get; set; }
}
Probably I will have troubles further on, but for the time being I can create my model!
Hope you can also start like this!

See this article:
avoid nightmares using ef first migration in azure mobile services
EntityData define a cluster indext to CreateAt and Id is by default a cluster index, this way it provide an error and you should define only one.

Related

Adding New Table Entity Framwork Code First Approach

That solution does not work in .net core 2 tied to SQL Server 2016. Original Question: Trying to jump into entity framework, using the "Code First Approach". I have my new class setup “NewTable” shown below. I can’t figure out what in the Program Manger Console I need to type to get this table created in my Default Connection String (pointing to a local instance of Sql Server 2016). The database is working and the user in this .net core 2 web app can register his/her name then log in using that new created account. Thanks in advance!!
Default Connection String:
"ConnectionStrings": {
"DefaultConnection" "Server=localhost\RCDSE_Dev;Database=Some Database;User ID=sa;Password=SomePass;"
},
[Table("NewTable")]
public class NewTable
{
[DatabaseGenerated(DatabaseGeneratedOption.Identity)] //Database generated key
[Key] //Primary Key
public long Id { get; set; }
[Required]
public string Manager { get; set; }
}
public class NewTableContext : DbContext
{
public DbSet<NewTable> NewTables{ get; set; }
}
Add a constructor to the DbContext as below:
public class NewTableContext : DbContext
{
public DbSet<NewTable> NewTables{ get; set; }
public NewTableContext() : base("DefaultConnection") { }
}
I figured this out. Will post a detailed step by step guide for others in the next couple of days. There are specific things that need to be done in .net core 2 project file that were NOT COVERED in any of the referenced examples by users here. Thanks for all the help..it got me somewhat pointed in a direction, to find the right direction...lol.

Mapping One-to-Zero-or-One with EF7

I am currently in the process of cleaning up a fairly large database. Part of the database has a relationship which is a one-to-zero-or-one mapping. Specifically:
User -> UserSettings
Not all users will have user settings, but a user setting cannot exist without the user. Unfortunately, the tables already exist. User has an PK ID. UserSettings has a PK ID and a column, User_Id_Fk which, at this point in time, is not a true FK (there is no relationship defined).
I'm in the process of fixing that and have done so from the DB perspective through SQL and have confirmed with tests. (Added the FK constraint. Added a unique constraint on User_Id_Fk.) This was all done on the UserSettings table. (Note: I am not using EF Migrations here. I have to manually write the SQL at this point in time.)
However, I now need to wire up an existing application to properly handle this new mapping. The application is using ASP.NET Core 1.0 and EF7. Here are (shortened) versions of the existing data models.
public class User
{
public int Id { get; set; }
public virtual UserSettings UserSettings { get; set; }
}
public class UserSettings
{
public int Id { get; set; }
[Column("User_Id_Fk")]
public int UserId { get; set; }
[ForeignKey("UserId")]
public virtual User User { get; set; }
}
I have this Fluent Mapping as well:
builder.Entity<UserSettings>()
.HasOne(us => us.User)
.WithOne(u => u.User)
.IsRequired(false);
When I go to run the application and access these items in the database, I get this error followed with a cryptic set of messages that has no information relating directly back to my application.:
ArgumentNullException: Value cannot be null.
Parameter name: navigation
Microsoft.Data.Entity.Utilities.Check.NotNull[T] (Microsoft.Data.Entity.Utilities.T value, System.String parameterName) <0x10d28a650 + 0x00081> in <filename unknown>, line 0
After doing research, someone had mentioned that the ID of the UserSettings class must be the same as the foreign key, like so:
public class UserSettings
{
[Key, ForeignKey("User")]
public int Id { get; set; }
public virtual User User { get; set; }
}
I don't really have this as an option as the DB is being used for other applications I have no control over at this point. So, am I stuck here? Will I just have to maintain a 1:many mapping (which could happen now, though it hasn't) and not have proper constraints for a 1:0..1 mapping?
Update
Looking at octavioccl's answer below, I tried it out without any success. However, I then removed User from the mapping in UserSettings (but I left UserId). Everything appeared to work as far as I can tell. I'm really confused what is going on here, however, and if this is even the right answer, or if I'm just getting lucky.
Remove the data annotations and try with these configurations:
builder.Entity<UserSettings>()
.Property(b => b.UserId)
.HasColumnName("User_Id_Fk");
builder.Entity<User>()
.HasOne(us => us.UserSettings)
.WithOne(u => u.User)
.HasForeignKey<UserSettings>(b => b.UserId);
From EF Core documentation:
When configuring the foreign key you need to specify the dependent
entity type - notice the generic parameter provided to HasForeignKey
in the listing above. In a one-to-many relationship it is clear that
the entity with the reference navigation is the dependent and the one
with the collection is the principal. But this is not so in a
one-to-one relationship - hence the need to explicitly define it.
The example that is presented in the quoted link (Blog-BlogImage) is pretty much the same of what are you trying to achieve.
If the solution that I show above doesn't work, then you should check if User_Id_Fk column allows null. If that is the case, change the FK property type to int?:
public class UserSettings
{
public int Id { get; set; }
public int? UserId { get; set; }
public virtual User User { get; set; }
}

ASP NET MVC 3 - How to reset database in code first, with two tables and Database.Setinitializer?

My problem lies in the lack of experience in MVC. Basically, I have two tables in DB
-Person
-Offer
For each I have created a model and a controller and a model, so the structure looks like that:
public class Offer
{
public int OfferID { get; set; }
public string OfferTitle { get; set; }
public string State { get; set; }
public string Description { get; set; }
}
public class OfferDBContext : DbContext
{
public DbSet<Offer> Offers { get; set; }
}
This is the Offer model.
public class Person
{
public int PersonID { get; set; }
public string Username { get; set; }
public DateTime Birthday { get; set; }
public string Education { get; set; }
public string Email { get; set; }
}
public class PersonDBContext : DbContext
{
public DbSet<Person> Persons { get; set; }
}
This is the Person model.
Firstly I created the Person model, that added itself to db without any problems. Then I wanted to add Offer table, and I had to use the DropCreateDatabaseIfModelChanges method. I used it for OfferInitializer and PersonInitializer and then there is the Global.asax.cs file
protected void Application_Start()
{
Database.SetInitializer<OfferDBContext>(new OfferInitializer());
Database.SetInitializer<PersonDBContext>(new PersonInitializer());
//Database.SetInitializer<PersonDBContext>(new PersonInitializer());
AreaRegistration.RegisterAllAreas();
RegisterGlobalFilters(GlobalFilters.Filters);
RegisterRoutes(RouteTable.Routes);
}
From what I understand, I cant do that simply because I am dropping database 2 times, each time populating only one table at a time. How do I reorganize it all, so that I can populate both or more tables at a time, or the whole database?
First things first, you should not create individual DbContext classes for each table. You should instead put all your DbSets in the same DbContext. Doing this will simplify things greatly for you.
Secondly, you should look into using migrations. You should start using them very early in your project.
You work with code first migrations using the Package Management Console.
enable-migrations
Does exactly what the name implies. Initializes migrations in your project. This will create a folder inside your project and generate the files needed.
add-migration InitialCreate
This creates a migration. InitialCreate is actually a string and you can change it to whatever you want. This command will generate the scripts needed to create the database from strach.
update-database
This command verifies the database and applies the migration (or migrations - there can be multiple) required in order to get the database up-to-date.
This is the initial setup. If you do further changes to your first code first classes, or add more, you will just have to add a new migration and then execute it.
add-migration AddedFirstName
update-database
It's that simple!
There are some more advanced concepts like seed, rollback, update to specific migration, etc., but what I have typed above covers the basics and the day to day usage of migrations.
I recommend you to read this article which explains everything in much more detail: http://www.asp.net/mvc/overview/getting-started/getting-started-with-ef-using-mvc/migrations-and-deployment-with-the-entity-framework-in-an-asp-net-mvc-application

Entity framework 6 add-migration adding all tables/entities in Migration Script

I am trying to run the code first migration in entity framework 6.0. I have added 4 new entities in my entities modal. However when i run the "add-migration" command in VS 2013, the generated migration file contains the script of all entitles (just like the initial migration) in my modal, though they are already in linked database. Obviously when I rum "Update-Database" commends, it generates entity already exists error. My DBContext class looks like following:
public class BidstructDbContext : DbContext
{
public BidstructDbContext() : base(nameOrConnectionString: "Bidstruct")
{
this.Configuration.LazyLoadingEnabled = false;
}
public DbSet<User> Users { get; set; }
public DbSet<Role> Roles { get; set; }
public DbSet<Permission> Permissions { get; set; }
public DbSet<Company> Company { get; set; }
// New Added Table
public DbSet<Gadgets> Gadgets { get; set; }
public DbSet<Language> Language { get; set; }
public DbSet<LanguageKeys> TranslationKeys { get; set; }
public DbSet<Translations> Translations { get; set; }
static BidstructDbContext()
{
Database.SetInitializer(new DatabaseInitializer());
}
protected override void OnModelCreating(DbModelBuilder modelBuilder)
{
modelBuilder.Conventions.Remove<PluralizingTableNameConvention>();
modelBuilder.Conventions.Remove<OneToManyCascadeDeleteConvention>();
}
}
and DatabaseInitializer class looks like as following:
public class DatabaseInitializer :
// CreateDatabaseIfNotExists<BidstructDbContext> // when model is stable
DropCreateDatabaseIfModelChanges<BidstructDbContext> // when iterating
{
private const int AttendeeCount = 1000;
// EF is NOT a good way to add a lot of new records.
// Never has been really. Not built for that.
// People should (and do) switch to ADO and bulk insert for that kind of thing
// It's really for interactive apps with humans driving data creation, not machines
private const int AttendeesWithFavoritesCount = 4;
protected override void Seed(BidstructDbContext context)
{
}
}
Any idea, how to resolve this problem. Its was working fine for me few days back but now I am facing this problem :(
Check to see if your context keys have changed, in your migration history.
I'm working on a project that has been using automatic migrations, but the automatic migration was not occurring due to a lot of class changes. In trying to switch to non-automatic migration, Add-Migration was regenerating the entire schema.
So I tried putting the manual table changes into the Up() of the DbMigration, and this applied a migration and an entry into the __MigrationHistory table, but with a different context key (the namespace and class name of my configuration file.)
A quick test of renaming the previous (older) migration record's context key to be the same as the current one caused the migration up/down to generate correctly.
Even then...it may not be 100%. Most of my changes were correct, but it started out adding a table which already existed, then turned around and removed it.

Excplicit id values using EF Code-first and migrations

I develop my ASP.NET MVC4 app using EF Code-first, also im using Migrations feature. I have specific entity and i want to set explicit id values for some reasons. How can i do this? I tried to mark id property with attribute like this:
public class NewsSource
{
[Key, DatabaseGenerated(DatabaseGeneratedOption.None)]
public int Id { get; set; }
public string Title { get; set; }
public string WebSiteUrl { get; set; }
}
Then i add corresponding migration, delete database and try to update database using Seed() method like this:
context.NewsSources.AddOrUpdate(x => x.Title,
new NewsSource {Id = 654, Title = "ABC", WebSiteUrl = #"http://www.abc.com/"},
new NewsSource {Id = 22, Title = "XYZ", WebSiteUrl = #"http://XYZ.ru/"});
And ive got this error: "Cannot insert explicit value for identity column in table 'NewsSources' when IDENTITY_INSERT is set to OFF". How can i set identity_insert to ON using EF and migrations. As i understood from many topics its impossible and i have to use direct SQL-commands. Am i wrong?
I had a problem when I tried to change a column to an IDENTITY field when it was originally not an identity field. See this question and this one. You have to remove the column and recreate it to remove IDENTITY so fixing up foreign keys etc is probably a step too far for Entity Framework to do in a migration. You will have to alter the Up() and Down() methods yourself, or you may get away with doing it in the database.
What happens if you remove the DatabaseGenerated attribute and just leave the [Key] attribute?
public class NewsSource
{
[Key]
public int Id { get; set; }
public string Title { get; set; }
public string WebSiteUrl { get; set; }
}
I ran into this issue awhile back and I believe this was a work around for me. I can't test it now since I don't have any projects in front of me with EF in them. All I can say is EF code first and the nuget migrations package is a great thing, if you treat it the way you are supposed to treat it. I have gotten myself into a number of WTF moments when using the two together and trying to seed complex related models. Good luck!

Categories

Resources