ASP.net MVC 5 EF6 Error While updating the database - asp.net-mvc

I am quite new to Asp.net MVC 5 EF6. I am developing the application for Contoso Unversity which is provided by Microsoft on asp.net website. In chapter no.11 Implementing the Inheritance after adding the inheritance and adding the migration through migration command it worked but when i tried to apply the update-database command to the PMC, I faced this error:
Error Number:15248,State:1,Class:11 Either the parameter #objname is
ambiguous or the claimed #objtype (OBJECT) is wrong.
This is the code of My /inheritance migration class.
please guide me to a fix.
namespace ContosoUniversity.Migrations
{
using System;
using System.Data.Entity.Migrations;
public partial class Inheritance : DbMigration
{
public override void Up()
{
// Drop foreign keys and indexes that point to tables we're going to drop.
DropForeignKey("dbo.Enrollment", "StudentID", "dbo.Student");
DropIndex("dbo.Enrollment", new[] { "StudentID" });
RenameTable(name: "dbo.Instructor", newName: "Person");
AddColumn("dbo.Person", "EnrollmentDate", c => c.DateTime());
AddColumn("dbo.Person", "Discriminator", c => c.String(nullable: false, maxLength: 128, defaultValue: "Instructor"));
AlterColumn("dbo.Person", "HireDate", c => c.DateTime());
AddColumn("dbo.Person", "OldId", c => c.Int(nullable: true));
// Copy existing Student data into new Person table.
Sql("INSERT INTO dbo.Person (LastName, FirstName, HireDate, EnrollmentDate, Discriminator, OldId) SELECT LastName, FirstName, null AS HireDate, EnrollmentDate, 'Student' AS Discriminator, ID AS OldId FROM dbo.Student");
// Fix up existing relationships to match new PK's.
Sql("UPDATE dbo.Enrollment SET StudentId = (SELECT ID FROM dbo.Person WHERE OldId = Enrollment.StudentId AND Discriminator = 'Student')");
// Remove temporary key
DropColumn("dbo.Person", "OldId");
DropTable("dbo.Student");
// Re-create foreign keys and indexes pointing to new table.
AddForeignKey("dbo.Enrollment", "StudentID", "dbo.Person", "ID", cascadeDelete: true);
CreateIndex("dbo.Enrollment", "StudentID");
}
public override void Down()
{
CreateTable(
"dbo.Student",
c => new
{
ID = c.Int(nullable: false, identity: true),
LastName = c.String(nullable: false, maxLength: 20),
FirstName = c.String(nullable: false, maxLength: 20),
EnrollmentDate = c.DateTime(nullable: false),
})
.PrimaryKey(t => t.ID);
AlterColumn("dbo.Person", "HireDate", c => c.DateTime(nullable: false));
DropColumn("dbo.Person", "Discriminator");
DropColumn("dbo.Person", "EnrollmentDate");
RenameTable(name: "dbo.Person", newName: "Instructor");
}
}
}

Consider:
1. Deleting all Migration files in your Migrations folder
2. Renaming your database in the connection string
3. Running PM> add-migration
4. Running PM> update-database

Related

EF Core 2 1-1 relationship unexpected behaviour

I have a typical Parent : Child relationship. The classes are as follows:
public class Parent
{
public Guid Id { get; set; }
public string Name { get; set; }
public Child Child { get; set; }
}
and
public class Child
{
public Guid Id { get; set; }
public string Name { get; set; }
public Parent Parent { get; set; }
}
The model is quite simple too:
protected override void OnModelCreating(ModelBuilder modelBuilder)
{
base.OnModelCreating(modelBuilder);
modelBuilder.Entity<Child>().HasKey(p => p.Id);
modelBuilder.Entity<Child>().Property(p => p.Name).HasMaxLength(256);
modelBuilder.Entity<Child>().HasOne(p => p.Parent).WithOne(p => p.Child).IsRequired().OnDelete(DeleteBehavior.Cascade);
modelBuilder.Entity<Parent>().HasKey(p => p.Id);
modelBuilder.Entity<Parent>().Property(p => p.Name).HasMaxLength(256).IsRequired();
}
The migration looks like this:
protected override void Up(MigrationBuilder migrationBuilder)
{
migrationBuilder.CreateTable(
name: "Parent",
columns: table => new
{
Id = table.Column<Guid>(type: "uniqueidentifier", nullable: false),
Name = table.Column<string>(type: "nvarchar(256)", maxLength: 256, nullable: false)
},
constraints: table =>
{
table.PrimaryKey("PK_Parent", x => x.Id);
});
migrationBuilder.CreateTable(
name: "Child",
columns: table => new
{
Id = table.Column<Guid>(type: "uniqueidentifier", nullable: false),
Name = table.Column<string>(type: "nvarchar(256)", maxLength: 256, nullable: true),
ParentId = table.Column<Guid>(type: "uniqueidentifier", nullable: false)
},
constraints: table =>
{
table.PrimaryKey("PK_Child", x => x.Id);
table.ForeignKey(
name: "FK_Child_Parent_ParentId",
column: x => x.ParentId,
principalTable: "Parent",
principalColumn: "Id",
onDelete: ReferentialAction.Cascade);
});
migrationBuilder.CreateIndex(
name: "IX_Child_ParentId",
table: "Child",
column: "ParentId",
unique: true);
}
which is pretty much what was expected. The FK is declared in the "Child" table.
If I add a new Child, however, things change quite unexpectedly. Here's the second child and the modified Parent:
public class Child2
{
public Guid Id { get; set; }
public string Name { get; set; }
public /*virtual */Parent Parent { get; set; }
}
and
public class Parent
{
public Guid Id { get; set; }
public string Name { get; set; }
public Child Child { get; set; }
public Child2 Child2 { get; set; }
}
Again, nothing special about the model:
protected override void OnModelCreating(ModelBuilder modelBuilder)
{
base.OnModelCreating(modelBuilder);
modelBuilder.Entity<Child>().HasKey(p => p.Id);
modelBuilder.Entity<Child>().Property(p => p.Name).HasMaxLength(256);
modelBuilder.Entity<Child>().HasOne(p => p.Parent).WithOne(p => p.Child).IsRequired().OnDelete(DeleteBehavior.Cascade);
modelBuilder.Entity<Child2>().HasKey(p => p.Id);
modelBuilder.Entity<Child2>().Property(p => p.Name).HasMaxLength(256);
modelBuilder.Entity<Child2>().HasOne(p => p.Parent).WithOne(p => p.Child2).IsRequired().OnDelete(DeleteBehavior.Cascade);
modelBuilder.Entity<Parent>().HasKey(p => p.Id);
modelBuilder.Entity<Parent>().Property(p => p.Name).HasMaxLength(256).IsRequired();
}
And now the surprise. The new migration:
protected override void Up(MigrationBuilder migrationBuilder)
{
migrationBuilder.CreateTable(
name: "Child2",
columns: table => new
{
Id = table.Column<Guid>(type: "uniqueidentifier", nullable: false),
Name = table.Column<string>(type: "nvarchar(256)", maxLength: 256, nullable: true)
},
constraints: table =>
{
table.PrimaryKey("PK_Child2", x => x.Id);
});
migrationBuilder.CreateTable(
name: "Parent",
columns: table => new
{
Id = table.Column<Guid>(type: "uniqueidentifier", nullable: false),
Child2Id = table.Column<Guid>(type: "uniqueidentifier", nullable: false),
Name = table.Column<string>(type: "nvarchar(256)", maxLength: 256, nullable: false)
},
constraints: table =>
{
table.PrimaryKey("PK_Parent", x => x.Id);
table.ForeignKey(
name: "FK_Parent_Child2_Child2Id",
column: x => x.Child2Id,
principalTable: "Child2",
principalColumn: "Id",
onDelete: ReferentialAction.Cascade);
});
migrationBuilder.CreateTable(
name: "Child",
columns: table => new
{
Id = table.Column<Guid>(type: "uniqueidentifier", nullable: false),
Name = table.Column<string>(type: "nvarchar(256)", maxLength: 256, nullable: true),
ParentId = table.Column<Guid>(type: "uniqueidentifier", nullable: false)
},
constraints: table =>
{
table.PrimaryKey("PK_Child", x => x.Id);
table.ForeignKey(
name: "FK_Child_Parent_ParentId",
column: x => x.ParentId,
principalTable: "Parent",
principalColumn: "Id",
onDelete: ReferentialAction.Cascade);
});
migrationBuilder.CreateIndex(
name: "IX_Child_ParentId",
table: "Child",
column: "ParentId",
unique: true);
migrationBuilder.CreateIndex(
name: "IX_Parent_Child2Id",
table: "Parent",
column: "Child2Id",
unique: true);
}
One can easily spot the
Child2Id
FK in Parent table while there's no such key for the Child table. Also, there's another surprise - the missing
ParentId
FK in the Child2 table.
Things appear to be quite asymmetric and look much more like a chain of 1:1 relations than a parent with two children.
If, however, I add another child (code not pasted to avoid bloating) the "chain" is broken - the third child looks like the second, etc.
My questions are:
Why such asymmetry provided code is pretty much "copy-paste"?
Whatever I do (change Child2 code location in OnModelCreating() and/or swap Child and Child2 property order in Parent), Child2 is generated the same way, that is FK in Parent. So, what makes EF choose Child2 over Child for such generation? If there are three or more children Child is only generated as expected, all the rest are like Child2. What makes Child so "special" if I may "reverse" my surprise?
Any ideas?
Thanks.
PS: No explicit FKs are allowed in code!
EDIT: Commented out virtual in Child2 to avoid asymmetry. In fact it is unrelated to the problem.
The answer is basically contained in the following Note inside the Other Relationship Patterns - One-to-one section of the Relationships documentation:
EF will choose one of the entities to be the dependent based on its ability to detect a foreign key property. If the wrong entity is chosen as the dependent, you can use the Fluent API to correct this.
EF has no problem with one-to-many relationships because the many side is always the dependent. Also it has no problem with one-to-one relationships having explicit FK because the side with FK is the dependent.
But for one-to-one relationships without explicit FK like in your case, it's unclear which side the dependent, hence the choice is sort of random (it should probably being an exception) and thus unreliable.
As a rule of thumb, always explicitly specify the FK (thus the dependent entity) with HasForeignKey fluent API using the corresponding overload for explicit/shadow property:
modelBuilder.Entity<Child>()
.HasOne(p => p.Parent)
.WithOne(p => p.Child)
.HasForeignKey<Child>("ParentId")
.IsRequired()
.OnDelete(DeleteBehavior.Cascade);
modelBuilder.Entity<Child2>()
.HasOne(p => p.Parent)
.WithOne(p => p.Child2)
.HasForeignKey<Child2>("ParentId")
.IsRequired()
.OnDelete(DeleteBehavior.Cascade);
The generated migration is:
migrationBuilder.CreateTable(
name: "Parent",
columns: table => new
{
Id = table.Column<Guid>(type: "uniqueidentifier", nullable: false),
Name = table.Column<string>(type: "nvarchar(256)", maxLength: 256, nullable: false)
},
constraints: table =>
{
table.PrimaryKey("PK_Parent", x => x.Id);
});
migrationBuilder.CreateTable(
name: "Child",
columns: table => new
{
Id = table.Column<Guid>(type: "uniqueidentifier", nullable: false),
Name = table.Column<string>(type: "nvarchar(256)", maxLength: 256, nullable: true),
ParentId = table.Column<Guid>(type: "uniqueidentifier", nullable: false)
},
constraints: table =>
{
table.PrimaryKey("PK_Child", x => x.Id);
table.ForeignKey(
name: "FK_Child_Parent_ParentId",
column: x => x.ParentId,
principalTable: "Parent",
principalColumn: "Id",
onDelete: ReferentialAction.Cascade);
});
migrationBuilder.CreateTable(
name: "Child2",
columns: table => new
{
Id = table.Column<Guid>(type: "uniqueidentifier", nullable: false),
Name = table.Column<string>(type: "nvarchar(256)", maxLength: 256, nullable: true),
ParentId = table.Column<Guid>(type: "uniqueidentifier", nullable: false)
},
constraints: table =>
{
table.PrimaryKey("PK_Child2", x => x.Id);
table.ForeignKey(
name: "FK_Child2_Parent_ParentId",
column: x => x.ParentId,
principalTable: "Parent",
principalColumn: "Id",
onDelete: ReferentialAction.Cascade);
});

MVC - Additional ApplicationUser properties not getting added to AspNetUsers

I created a new project that is using MVC Entity Framework with Individual User Accounts. I want to add FirstName and LastName as properties of a user. The steps in this blog amount to these:
1) Create and run new Project
2) Enable Migrations
3) Add new Properties to ApplicationUser in IdentityModel
4) Add Migration and Update Database
- after this you can verify the new fields are in AspNetUsers table
5) Update RegisterViewModel
6) Update Register View
7) Update Account Controller's Register Post
I did steps 1 - 4, but when I look at AspNetUsers table the fields are not there and I don't understand why.
This is what I did per step 3:
Public Class ApplicationUser
Inherits IdentityUser
Public FirstName As String
Public LastName As String
But after step 4 this is what my table looks like:
Why are FirstName and LastName not getting added to the table as expected?
This is what is in my Package Manager Console:
PM> enable-migrations
Checking if the context targets an existing database...
Code First Migrations enabled for project CustomUserProperties.
PM> add-migration "name"
Scaffolding migration 'name'.
The Designer Code for this migration file includes a snapshot of your current Code First model. This snapshot is used to calculate the changes to your model when you scaffold the next migration. If you make additional changes to your model that you want to include in this migration, then you can re-scaffold it by running 'Add-Migration name' again.
PM> update-database
Specify the '-Verbose' flag to view the SQL statements being applied to the target database.
Applying explicit migrations: [201510191912542_name].
Applying explicit migration: 201510191912542_name.
Running Seed method.
PM>
This is the contents of the Migration:
Imports System
Imports System.Data.Entity.Migrations
Imports Microsoft.VisualBasic
Namespace Migrations
Public Partial Class name
Inherits DbMigration
Public Overrides Sub Up()
CreateTable(
"dbo.AspNetRoles",
Function(c) New With
{
.Id = c.String(nullable := False, maxLength := 128),
.Name = c.String(nullable := False, maxLength := 256)
}) _
.PrimaryKey(Function(t) t.Id) _
.Index(Function(t) t.Name, unique := True, name := "RoleNameIndex")
CreateTable(
"dbo.AspNetUserRoles",
Function(c) New With
{
.UserId = c.String(nullable := False, maxLength := 128),
.RoleId = c.String(nullable := False, maxLength := 128)
}) _
.PrimaryKey(Function(t) New With { t.UserId, t.RoleId }) _
.ForeignKey("dbo.AspNetRoles", Function(t) t.RoleId, cascadeDelete := True) _
.ForeignKey("dbo.AspNetUsers", Function(t) t.UserId, cascadeDelete := True) _
.Index(Function(t) t.UserId) _
.Index(Function(t) t.RoleId)
CreateTable(
"dbo.AspNetUsers",
Function(c) New With
{
.Id = c.String(nullable := False, maxLength := 128),
.Email = c.String(maxLength := 256),
.EmailConfirmed = c.Boolean(nullable := False),
.PasswordHash = c.String(),
.SecurityStamp = c.String(),
.PhoneNumber = c.String(),
.PhoneNumberConfirmed = c.Boolean(nullable := False),
.TwoFactorEnabled = c.Boolean(nullable := False),
.LockoutEndDateUtc = c.DateTime(),
.LockoutEnabled = c.Boolean(nullable := False),
.AccessFailedCount = c.Int(nullable := False),
.UserName = c.String(nullable := False, maxLength := 256)
}) _
.PrimaryKey(Function(t) t.Id) _
.Index(Function(t) t.UserName, unique := True, name := "UserNameIndex")
CreateTable(
"dbo.AspNetUserClaims",
Function(c) New With
{
.Id = c.Int(nullable := False, identity := True),
.UserId = c.String(nullable := False, maxLength := 128),
.ClaimType = c.String(),
.ClaimValue = c.String()
}) _
.PrimaryKey(Function(t) t.Id) _
.ForeignKey("dbo.AspNetUsers", Function(t) t.UserId, cascadeDelete := True) _
.Index(Function(t) t.UserId)
CreateTable(
"dbo.AspNetUserLogins",
Function(c) New With
{
.LoginProvider = c.String(nullable := False, maxLength := 128),
.ProviderKey = c.String(nullable := False, maxLength := 128),
.UserId = c.String(nullable := False, maxLength := 128)
}) _
.PrimaryKey(Function(t) New With { t.LoginProvider, t.ProviderKey, t.UserId }) _
.ForeignKey("dbo.AspNetUsers", Function(t) t.UserId, cascadeDelete := True) _
.Index(Function(t) t.UserId)
End Sub
Public Overrides Sub Down()
DropForeignKey("dbo.AspNetUserRoles", "UserId", "dbo.AspNetUsers")
DropForeignKey("dbo.AspNetUserLogins", "UserId", "dbo.AspNetUsers")
DropForeignKey("dbo.AspNetUserClaims", "UserId", "dbo.AspNetUsers")
DropForeignKey("dbo.AspNetUserRoles", "RoleId", "dbo.AspNetRoles")
DropIndex("dbo.AspNetUserLogins", New String() { "UserId" })
DropIndex("dbo.AspNetUserClaims", New String() { "UserId" })
DropIndex("dbo.AspNetUsers", "UserNameIndex")
DropIndex("dbo.AspNetUserRoles", New String() { "RoleId" })
DropIndex("dbo.AspNetUserRoles", New String() { "UserId" })
DropIndex("dbo.AspNetRoles", "RoleNameIndex")
DropTable("dbo.AspNetUserLogins")
DropTable("dbo.AspNetUserClaims")
DropTable("dbo.AspNetUsers")
DropTable("dbo.AspNetUserRoles")
DropTable("dbo.AspNetRoles")
End Sub
End Class
End Namespace
FirstName and LastName are not in "With" for the AspNetUsers table.
UPDATE:
I restarted again from scratch, and this time what I did was create the Migration, then manually added FirstName and LastName in the AspNetUsers Up function, then ran update-database. That actually worked.
So why it didn't automatically add those fields to the migration, I don't know. But if I do that manually it seems like it works that way.
Thank you!
See the answer I posted in this questions I posted subsequent to this one.
With that I am able to include additional user properties and it all works!
Whether or not that is the "best" way to do it may be another question, but since it's essentially the same as what MVC provides initially I don't see any issues with it.

MVC Application using old DBContext

I went through the Movies tutorial on asp.net, which went fine. Created the application using a local SQL Server instance, database was created flawlessly, and all functionality worked as designed. I created a new, entirely separate application without importing or copying anything from the Movies application. Defined a new model and DBContext, new controller, etc. When I try to execute the application for the same time I get the following error:
The model backing the 'OnlineAppDBContext' context has changed since the >database was created. Consider using Code First Migrations to update the >database (http://go.microsoft.com/fwlink/?LinkId=238269).
I went through the exercise of adding the migrations and noticed in the init migration I added that it is referencing the Movie model and database:
public override void Up()
{
CreateTable(
"dbo.OnlineApps",
c => new
{
ID = c.Int(nullable: false, identity: true),
FirstName = c.String(),
MiddleInitial = c.String(),
LastName = c.String(),
PreviousFullName = c.String(),
Gender = c.String(),
BirthDate = c.DateTime(nullable: false),
SSN = c.String(),
Tobacco = c.Boolean(nullable: false),
Address1 = c.String(),
Address2 = c.String(),
City = c.String(),
County = c.String(),
State = c.String(),
ZipCode = c.String(),
HomePhone = c.String(),
WorkPhone = c.String(),
CellPhone = c.String(),
Email = c.String(),
PCPChoice = c.String(),
})
.PrimaryKey(t => t.ID);
DropTable("dbo.Movies");
}
public override void Down()
{
CreateTable(
"dbo.Movies",
c => new
{
ID = c.Int(nullable: false, identity: true),
Title = c.String(maxLength: 60),
ReleaseDate = c.DateTime(nullable: false),
Genre = c.String(nullable: false, maxLength: 30),
Price = c.Decimal(nullable: false, precision: 18, scale: 2),
Rating = c.String(maxLength: 5),
})
.PrimaryKey(t => t.ID);
DropTable("dbo.OnlineApps");
}
The Up() method looks to do the correct table structure for my new model, but then tries to drop dbo.Movies. The Down() method table structure is based on the Movie model, but I have no idea how it is aware of that, and then tries to drop the dbo.OnlineApps table.
I searched through all files in the new application and just for fun rebooted the entire machine, but still having the same problem. Any ideas?
EDIT On a hunch I created a new database on my server. The movies application used a database called 'Sandbox'. I created an 'OnlineApplication' database on the same server, changed the connection string in the new application, and when it ran the objects were created without error. While this got me through the issue I'm not overly satisfied with the answer. Why would the connection string convey any relation to a model from a completely different application? Is this stored somewhere it can be edited/deleted? Can I not define multiple contexts to the same database?

validate dropdown in MVC

Model
[Required]
[Display(Name = "Source")]
[Range(typeof(string), "0","10", ErrorMessage = "Please select Source")]
public string Source { get; set; }
View
#Html.DropDownListFor(model => model.Source, new SelectList(new[]
{
new {ID="select",Name="Select"},
new{ID="Facebook",Name="Facebook"},
new{ID="Twitter",Name="Twitter"},
new{ID="LinkedIn",Name="LinkedIn"},
},
"ID", "Name", 1), new { style = "height:24px;" })
How can I validate this using data annotations? I need to store ID as text like Facebook in db.
You can use IValidatableObject interface and implement your own validation of your model class.
How do I use IValidatableObject?
#Html.DropDownListFor(model => model.Source, new SelectList(new[]
{
new{ID="Facebook",Name="Facebook"},
new{ID="Twitter",Name="Twitter"},
new{ID="LinkedIn",Name="LinkedIn"},
},
"ID", "Name", 1),"Select", new { style = "height:24px;" })
I have given like this. Its working fine now.
You have already decorated your model with data annotations. Now you only need to put unobtrusive jquery scripts to enable your validations on client side. Server side validation should work as is. I fail to understand the rationale of Range Attribute on select list though.

Define a field as autoincrement in EF5 migration

I'm creating a table using a EF migration such as:
this.CreateTable("Message",
c => new
{
Id = c.Long(nullable: false, identity: true, defaultValue: 0),
Subject = c.String(nullable: false, maxLength: 64),
Body = c.String(nullable: false, isMaxLength: true)
})
.PrimaryKey(c => c.Id)
.Index(c => c.Id, unique: true);
How can I define the Id field to be auto_increment? I'm pretty sure it has to be possible, but im just struggling to find out...
Thanks.
Ok, it seems that setting the property "identity: true" in field should be enough but for some reason the field is not defined as IDENTITY(1, 1).
Found a workaround in this post:
http://social.msdn.microsoft.com/Forums/en-US/adodotnetentityframework/thread/33db16ac-e166-455f-a47b-1e5fe0557979/
And it worked for me like this:
Id = new ColumnModel(PrimitiveTypeKind.Int64) { IsNullable = false, IsIdentity = true },
Now its defining the column as IDENTITY(1, 1)
If you do want to automatically generate it in code, you could skip the annotation on the Id field and do something like below.
public abstract class AbstractContext : DbContext {
/// <summary>
/// Custom processing when saving entities in changetracker
/// </summary>
/// <returns></returns>
public override int SaveChanges()
{
// recommended to explicitly set New Guid for appropriate entities
foreach (var entry in ChangeTracker.Entries<ModelBase>().Where(e => e.State == EntityState.Added) ) {
// only generate if property isn't identity...
Type t = entry.Entity.GetType();
var info = t.GetProperty("Id").GetCustomAttributes(
typeof(DatabaseGeneratedAttribute), true).Cast<DatabaseGeneratedAttribute>().Single();
if (info.DatabaseGeneratedOption != DatabaseGeneratedOption.Identity) {
entry.Entity.Id = Guid.NewGuid(); // now we make it
}
}
return base.SaveChanges();
}
}
For more information check Working with Entity Keys
I got this from the link Which I showed above comment.
I hope this will help to you.

Resources