I'm working with asp.net mvc3 & Entity Framework5.
My database has been designed with the Code-First.
Entity Code
public class User
{
public int Id { get; set; }
public string Name { get; set; }
}
public class EFDbContext : DbContext
{
public DbSet<User> Users { get; set; }
}
Create DB Option
Database.SetInitializer(new DropCreateDatabaseIfModelChanges<EFDbContext>());
I use this option, the database has been created.
After the database has been created, I need a Role table was.
So I had to modify the code as follows.
Entity Code
public class User
{
public int Id { get; set; }
public string Name { get; set; }
}
public class Role
{
public int Id { get; set; }
public string Name { get; set; }
}
public class EFDbContext : DbContext
{
public DbSet<User> Users { get; set; }
public DbSet<Role> Roles { get; set; }
}
I use Create DB Option again.
In this case, the existing Users table will be deleted after regeneration.
I would like to be added to the Role table, but leave data in the table Users.
What should I do?
Use Code-First Migrations.
Database.SetInitializer(null);
Then in Package Manager Console write:
add-migration addedRoles
If you did't enabled migrations before, You must enable it first:
enable-migrations
and last:
update-database
Complete guid:
http://msdn.microsoft.com/en-US/data/jj591621
Edit
If you want the database to be upgraded automatically whenever you run the application, you can use MigrateDatabaseToLatestVersion initializer:
Database.SetInitializer(new MigrateDatabaseToLatestVersion<EFDbContext, Configuration>());
Learn how migrations work.
http://msdn.microsoft.com/en-us/data/jj591621.aspx
They have another initializer, MigrateDatabaseToLatestVersion. In contrast to the one you use, this one will automatically upgrade your database to latest version without recreating the whole database.
Related
I have a SQL database that I'm using currently with EF Core. I have 2 objects:
public class Contact
{
public Guid ContactGUID { get; set; }
public string Name { get; set; }
[ForeignKey("CreatedBy")]
[InverseProperty(nameof(User.ContactCreatedBy))]
public virtual User CreatedByUser { get; set; }
...
}
public class User
{
public User
{
User = new HashSet<Contact>();
}
public Guid UserGUID { get; set; }
[InverseProperty(nameof(Contact.CreatedByUser))]
public virtual ICollection<Contact> ContactCreatedBy { get; set; }
...
}
This all works fine with EF Core connected to SQL. But something I would like to do is take this object that I've grabbed and save it to a separate CosmosDB database with EF Core.
When I try to do that however, I get the following error:
Microsoft.EntityFrameworkCore: When creating the relationship between
'User.ContactCreatedBy' and 'Contact.CreatedByUser' the entity type
'Contact' cannot be set as principal.
What is the best way to get past this error? I'd rather not create a whole separate object for my cosmos database that basically looks the same but w/out all the inverseproperties/etc. Is there a way to do that, or do I have to go about the long way?
I have an Azure mobile app with an ASP.NET backend. I want to add a new column to an existing table. I have added the property and redeployed the service but this does not create the column in the table and gives me an error. I also tried to add the column manually with SQL management studio and kept the property in the DataObject class but this still errored. Please could you advise how I can add a new field to the mobile app database.
public class Petrol: EntityData
{
public int Mileage { get; set; }
public DateTime PurchaseDate { get; set; }
public float Quantity { get; set; }
public Decimal Cost { get; set; }
public string Station { get; set; }
public string Claim_Id { get; set; }
[ForeignKey("Claim_Id")]
public virtual Claim Claim { get; set; }
//This is the new column I would like to add
public string PhotoUrl { get; set; }
}
I have ran the Enable-Migrations command in Package Manager Console, but I am getting an error about the connection string.
The schema of your database is only deployed when your database is empty.
For a database already containing tables you have to implement code first migrations as described here: Implementing Table Controllers
I am developing an ASP.NET MVC project using Visual Studio 2013. I am using Entity Framework Code First Approach to interact with database. But I am having a problem with migrating data because of built-in identity system in ASP.NET. Everything was fine before I touch to identity system.
These are the steps I have done.
I registered an account from UI using built-in identity system. So AspNetUsers table is created in database.
I created AspNetUser class to my code because I need to work with it.
Then I run migration and update database command. It throws error.
This is my AspNetUser class
public class AspNetUser
{
[Required]
public String Id { get; set; }
[Required]
public String UserName { get; set; }
public String PasswordHash { get; set; }
public String SecurityStamp { get; set; }
[Required]
public String Discriminator { get; set; }
}
This is my db context class
public class AyarDbContext : DbContext
{
public AyarDbContext()
: base("DefaultConnection")
{
}
public DbSet<Category> Categories { get; set; }
public DbSet<Region> Regions { get; set; }
public DbSet<Area> Areas { get; set; }
public DbSet<Item> Items { get; set; }
public DbSet<ItemContactInfo> ItemContacts { get; set; }
public DbSet<Gallery> Galleries { get; set; }
public DbSet<Mail> Mails { get; set; }
public DbSet<AspNetUser> AspNetUsers { get; set; }
protected override void OnModelCreating(DbModelBuilder modelBuilder)
{
}
}
This is the error I got.
There is already an object named 'AspNetUsers' in the database.
How can I migrate AspNetUser class? I registered using UI because I auto create the other tables need for identity system. How can I migrate that class and map with AspNetUsers table that is already existing in database.
As the error explains, that table already exists and is accessible in this way:
var user = context.Users.First(u => u.Id == myId);
If you want to extend the user class and add properties, you can inherit it:
public class MyAppUser : IdentityUser
{
// don't include properties already in IdentityUser
public string MyNewProperty { get; set; }
}
http://johnatten.com/2014/06/22/asp-net-identity-2-0-customizing-users-and-roles/
I have the following two entities:
public class User
{
public int PKID { get; set; }
public string Login { get; set; }
public string Username { get; set; }
public string Password { get; set; }
public virtual ICollection<AppAccess> AppAccessList { get; set; }
}
public class AppAccess
{
public int PKID {get; set; }
public string Login { get; set; }
public string AppCode { get; set; }
}
The PKID field is the primary key and identity column of each table but the Login field is what links them in a one-to-many relationship where the User is the principal entity.
How can I setup the navigation property AppAccessList using the fluent API, if it is even possible, to use the Login field as the relationship key? BTW, the entities are based on existing schema that cannot be refactored at this time.
I don't believe this is possible out of the box, certainly not the ability to add a navigation property. I tried using the new power tools to reverse engineer a database and it just ignored the relationship, neither could i create it using code (annotations or fluent interface).
You can create the relationship using raw sql on the on OnModelCreating method to make the constraint, but you'd need to use join's manually to navigate between the tables.
I implemented a bidirectional 1:1 relationship based on this answer:
Primary /Foreign Key in Entity Framework
I define the bidirectional relation this way:
public class Student
{
public virtual int StudentId { get; set; }
public virtual Anamnesis Anamnesis { get; set; }
. . .
}
public class Anamnesis
{
[Key, ForeignKey("Student")]
public int AnamnesisId { get; set; }
public virtual Student Student { get; set; }
. . .
}
where, Student is the principal entity and Anamnesis it the entity that shares the PK.
Now I'd like that the relationship created had a Delete Rule = CASCADE. Actually, the relationship that is being created has Delete Rule = NO ACTION as seen in the following picture:
If I manually delete this relation inside the Table Properties window and add other relation with Delete Rule = CASCADE, the code works as I expect allowing me to delete a Student and it's shared Anamnesis that has the same ID.
So, here goes my question:
Is there a way of using Data Annotation (not Fluent API) in my class so that I get a Relation with CASCADE delete rule? I'd prefer using Data Annotation but if it's not possible, I'd be happy with some Fluent API code that makes this work.
NOTE
I have tried the Fluent API code that is shown in this post. It doesn't work in my case where I have bidirectional properties.
The following fluent API code perfectly switch on the cascade delete on the database:
public class Student
{
public virtual int StudentId { get; set; }
public virtual Anamnesis Anamnesis { get; set; }
}
public class Anamnesis
{
public int AnamnesisId { get; set; }
public virtual Student Student { get; set; }
}
public class Context : DbContext
{
public DbSet<Student> Students { get; set; }
public DbSet<Anamnesis> Anamnesises { get; set; }
protected override void OnModelCreating(DbModelBuilder modelBuilder)
{
modelBuilder.Entity<Student>()
.HasRequired(s => s.Anamnesis)
.WithRequiredPrincipal(a => a.Student)
.WillCascadeOnDelete();
}
}
Also, you can use [Required] Attribute, and it will automatically set the delete rule to "CASCADE" mode in related relationship. (and also set "Allow Null" property of that entity to "false" in DB)