Invalid Column exception - c#

Hi guys I am getting this exception when I try to run the vehicles page.
Invalid column name 'MakeID'.
I have two models:
public class Vehicle
{
public int VehicleID { get; set; }
public string Title { get; set; }
[ForeignKey("Make")]
public int MakeID { get; set; }
public virtual Make Make { get; set; }
}
public class Make
{
public int MakeID { get; set; }
public string Title { get; set; }
}
The error is being thrown in my vehicles controller here
public ActionResult Index()
{
var vehicles = db.Vehicles.Include(v => v.Make);
return View(vehicles.ToList());
}

Add/Enable Migrations. Update the Database. Most of the case improper update causes the issue. There is no problem with your above code.
Make sure: you have Updated the Database Tables after adding new columns.
Run the Update-Database command in Package Manager Console.
Make sure your column Foreign Key Relationship / Mappings are ok.
You have to check it out manually.
There are four ways to Drop and Create the Database. Based on several conditions. OR you can manually delete the Database from SQL Server.
Good Article and Source can be found here - Programatically.
Note: Recreating the Database will lose the entire existing data. There is one way to avoid this problem. It's providing Seed Data to the database / Tables on create.

Related

MVC code first approach not fetching data from table using DbContext

I am using the code-First approach of MVC facing the below issue.
I have 1 The Admin model which has 2 properties that represent a separate class as shown below respectively.
public class Admin
{
[Key]
[DatabaseGenerated(DatabaseGeneratedOption.Identity)]
public int Id { get; set; }
public string Name { get; set; }
public List<IdProof> IdProofDocs { get; set; }
public Subscription subscription { get; set; }
}
public class IdProof
{
[Key]
[DatabaseGenerated(DatabaseGeneratedOption.Identity)]
public int Id { get; set; }
public string File { get; set; }
}
public class Subscription
{
[Key]
[DatabaseGenerated(DatabaseGeneratedOption.Identity)]
public int Id { get; set; }
public double TotalAmount { get; set; }
public double PaidAmount { get; set; }
}
When I try to save it, it successfully saves values in 3 tables including the last 2 (i.e. IdProof, Subscription) of the Admin Model. see below code
[HttpPost]
public ActionResult AddHotel(Admin admin)//saving correctly in 3 table i.e. admin, subscription,IdProof
{
dbContext.Admins.Add(admin);
dbContext.SaveChanges();
return RedirectToAction("someActionMethod");
}
till now it's good, but from here
when I try to get records by using the below code
public ActionResult AllAdmins()
{
List<Admin> ListAdmin= dbContext.Admins.ToList();//here its fetching records from admin table only ;(
return View(ListAdmin);
}
It gives me only Admin table data, not the other 2 tables*** i.e IdProof & Subscription. I was wondering that EF automatically saves data in the other 2 tables by its model, so at the time of fetching why it's not giving me data from the other 2 tables.
I am using the Code-First approach in mvc5, what is needed to change in my code. I am new in mvc.
Thanks in advance
You need to include other tables if you want EF to load it for you.
List<Admin> ListAdmin= dbContext.Admins
.Include(x => x.IdProofDocs).Include(x => x.Subscription).ToList()
EF is having concept of Lazy Loading and Eager Loading.
Lazy Loading
In Lazy loading EF not load the related entities until ask for it.
Link: https://www.entityframeworktutorial.net/lazyloading-in-entity-framework.aspx
Eager Loading
In Eager Loading, Related Entity mentioned at the Query time using Include method.
Link : https://www.entityframeworktutorial.net/eager-loading-in-entity-framework.aspx
Depend on requirement, you can choose option.

EF Code First Migration - Property migration

So Imagine this situation:
namespace SC.BL.Domain
{
public class User
{
public String Name { get; set; }
public String Adress { get; set; }
public int PhoneNumber { get; set; }
public char Gender { get; set; }
}
}
EF Code first migration is enabled. I implemented code-based migration by using 'enable-migrations'
My DbInitializer is set to use the MigrateDatabaseToLatestVersion initializer
Now my question is, I would like to migrate one property into multiple properties, without the loss of data, after this the old property may be removed!
Suppose I have in my database the following,
Name: User1
Address: Emmalaan 2, Gelderland
PhoneNumber: 0471250950
Gender: M
Now I want to change my User class to the following:
namespace SC.BL.Domain
{
public class User
{
public String Name { get; set; }
public String StreetName { get; set; }
public int HouseNumber { get; set; }
public String City { get; set; }
public int PhoneNumber { get; set; }
public char Gender { get; set; }
}
}
So now I want that after migrations, the data in the database is changed (without dataloss) and put in the right properties.
Where can I till the migrator to do something like this?
Name: User1
StreetName: Emmalaan 2
HouseNumber: 2
City: Gelderland
PhoneNumber: 0471250950
Gender: M
Is this possible via migration? And how is this done?
I think that the only thing you could do is the editing of the generated migration to do the transformation you want.
Inside Up() method of the migration:
use the Sql() method to write the data into a temporary table
migrate the table to the new structure (with the generated code)
use the Sql() method to take all the data (splitted as you want) from the temporary table so you can fill the edited table
in the Down() method the inverse of Up().
I don't think that this is possible via migration. You want to change structure of table, and you want that migration automatically separate data in different columns. I think that this is not possible. I think that better way is to only add columns by migration and after that you can create SQL procedure for splitting and updating data to different columns.

Cannot migrate new table in asp.net because there is an existing table in code first migration

I am developing a ASP.NET MVC website. For interacting with database, I am using Entity Framework with code first approach. But now I am having a problem in adding/migrating new table and entity to my model and database.
First I created a entity class
public class Category
{
public int Id { get; set; }
[Required]
[MaxLength(40)]
public String Name { get; set; }
[MaxLength(60)]
public String MmName { get; set; }
}
But for this entity, I created database manually. I did not use any migration command. Then I run the app and register a user using built-in identity registration system. So database tables are created successfully. Then I continued development. I was working fine. After I developed everything dealing with Category, I tried to add another entity and database table.
So I created a entity class like this
public class Region
{
public int Id { get; set; }
[Required]
[MaxLength(50)]
public String Name { get; set; }
[MaxLength(70)]
public String MmName { get; set; }
[MaxLength(30)]
public String GeoLocation { get; set; }
[MaxLength(200)]
public String Description { get; set; }
[MaxLength(250)]
public String MmDescription { get; set; }
}
Then I run the following command to update database
enable-migrations
add-migration "CreateRegion"
update-database
I got this error
Here is already an object named 'Category' in the database.
This is my initiaizer class
public class ContextInitializer : System.Data.Entity.DropCreateDatabaseIfModelChanges<AyarDbContext>
{
protected override void Seed(AyarDbContext context)
{
}
}
How can I update database using command line? I want to migrate from command line because I am practising code first approach.
I see two options at this point:
1) Drop the table from the database and re run the migration. It will create both tables for you.
2) Modify the migration file so it's not trying to create the Category table. This goes against how Code First is supposed to work but you're already in that situation by having existing tables.

Collection on model not updating to database

I have a collection on a model:
[Table("Templates")]
public class Template
{
[Key]
public Guid ID { get; set; }
public virtual IList<TemplateSection> Sections { get; set; }
}
[Table("TemplateSections")]
public class TemplateSection
{
internal TemplateSection() { Fields = new List<TemplateField>(); }
[Key]
public Guid ID { get; set; }
[Required]
public Guid TemplateID { get; set; }
public virtual Template Template { get; set; }
}
This appears to create the correct relationships in the database.
When I update my database any sections I have added are not saved to the database. Here's how I'm updating the dabatase:
Template existingtemplate = db.Templates.Find(sltemplate.ID);
db.Entry(existingtemplate).CurrentValues.SetValues(template);
db.SaveChanges();
If I update inspect the existingtemplate before db.SaveChanges(); the Sections collection is null. Any other changes will have been updated onto existingtemplate.
If I add:
existingtemplate.Sections = template.Sections;
before db.SaveChanges(); then the sections will be saved to the database but aren't reloaded if I load the template again.
Obviously I have missed something in declaring the one-to-many relationship but having read dozens of articles I can't see what it might be.
The construct CurrentValues.SetValues only sets scalar properties, in other words, the non-navigation properties.
I'm a bit surprised that existingtemplate.Sections = template.Sections; apparently saves the TemplateSection objects, but doesn't establish the associations. I would have expected it to do neither or both.
One way to make sure that everything is saved correctly is to first load existingtemplate.Sections and Add() each TemplateSection object to it. This requires a database roundtrip though.
It's more efficient to attach the TemplateSection objects to the context and set their TemplateID property.

Strange entity updating in Entity Framework Code-First

I'm solving the problem with updating entity before saving to database and got strange behavior.
I'm using Entity Framework 4.1 Code-First in ASP.NET MVC 3 web application. Here is model:
public class Order
{
public int OrderId { get; set; }
public int CarId { get; set; }
public DateTime BeginRentDate { get; set; }
public DateTime EndRentDate { get; set; }
public decimal RentPrice { get; set; }
public virtual Car Car { get; set; }
}
public class Car
{
public int CarId { get; set; }
public string Brand { get; set; }
public string Model { get; set; }
public string NumberPlate { get; set; }
public decimal RentPrice { get; set; }
}
Each Car has a RentPrice. This price should be copied to Order's RentPrice when creating one. The car is selecting by user so initially Order.RentPrice is 0.
Here I want to copy price value:
[HttpPost]
public ActionResult Create(Order order)
{
order.RentPrice = _context.Cars.Find(order.CarId).RentPrice;
if (ModelState.IsValid)
{
_context.Orders.Add(order);
_context.SaveChanges();
return RedirectToAction("Index");
}
return View(order);
}
It's not working because of an error on the SaveChanges that entity has validation errors. OK. I found that need first to call UpdateModel(order); and then change values.
So what I have. Working code:
_context.Orders.Add(order);
UpdateModel(order);
order.RentPrice = 777;
_context.SaveChanges();
Not working code:
_context.Orders.Add(order);
UpdateModel(order);
order.RentPrice = _context.Cars.Find(order.CarId).RentPrice;
_context.SaveChanges();
Working code (!):
_context.Orders.Add(order);
UpdateModel(order);
var t = (double)_context.Cars.Find(order.CarId).RentPrice;
order.RentPrice = (decimal)t;
_context.SaveChanges();
Can someone explain, please, what is going on here? Especially magic on the 3nd and 4th lines in the last block of code.
Update
I'm getting DbEntityValidationException: "Validation failed for one or more entities. See 'EntityValidationErrors' property for more details."
From the inner exception: "OriginalValues cannot be used for entities in the Added state."
When you get
"Validation failed for one or more entities. See
'EntityValidationErrors' property for more details." From the inner
exception: "OriginalValues cannot be used for entities in the Added
state."
It means there was errors such as NOT NULL collumns that were blank or other constraints , check the entity validation errors by debugging or like
try{
...
catch ( DbEntityValidationException ex )
{
foreach ( var validationErrors in ex.EntityValidationErrors )
{
foreach ( var validationError in validationErrors.ValidationErrors )
{
System.Diagnostics.Trace.TraceInformation( "Property: {0} Error: {1}", validationError.PropertyName, validationError.ErrorMessage );
}
}
}
OriginalValues cannot be used for entities in the Added state.
Can be corrected by ensuring that non identity primary key fields are specified as not generated in the model.
modelBuilder
.Entity<T>()
.HasDatabaseGeneratedOption(DatabaseGeneratedOption.None);
// this can also be achieved using attributes on the entity.
The error is actually self explanatory when you have context, but baffling otherwise. The database generates two statements for the insert, the second of which is:
SELECT [PrimaryKeyId]
FROM [dbo].[Entity]
WHERE ##ROWCOUNT > 0 AND [PrimaryKeyId] = scope_identity()
/* SP:StmtCompleted... */
This statement will not return any rows for non identity columns. Hence the OriginalValues will remain unaltered in the added state. This also explains why this exception is wrapped in an OptimisticConcurrencyException as the number of rows affected is used to detect existing altered data.
Have you declared the primary key anywhere? You should do that either using FluentAPI or attribute like this:
public class Order
{
[Key]
public int OrderId { get; set; }
public int CarId { get; set; }
public DateTime BeginRentDate { get; set; }
public DateTime EndRentDate { get; set; }
public decimal RentPrice { get; set; }
public virtual Car Car { get; set; }
}
public class Car
{
[Key]
public int CarId { get; set; }
public string Brand { get; set; }
public string Model { get; set; }
public string NumberPlate { get; set; }
public decimal RentPrice { get; set; }
}
Or in your Context, you can use Fluent API to declare the key, like this
builder.Entity<Car>().HasKey(x=>x.CarId);
builder.Entity<Order>().HasKey(x=>x.OrderId);
I have an idea, but it's more of a guess... Maybe that by the time you get in that Create function, the context already knows of that Order? If it does, trying to re-add it again could maybe give you that error.
In your last piece of code (the one that surprisingly work), have you tried to use an intermediary var without casting to double?
I'm also intrigued of that UpdateModel... I use EF but not MVC so maybe it has nothing to do about it, but if it's a custom function, what does it do?
I am sure the problem would have been rectified ages ago, just wanted to contribute my 2 cents.
I also ran into an issue with the same error message, I was using Oracle and EF 5.0. Finally I got a solution after wasting more than 12 hours.
For me it was lack of the permissions for the user on the table where I was trying to insert values and the error message absolutely had no hints of the actual permission issue, which was really weird.
Hope someone finds this useful and doesn't waste hours like me in troubleshooting.
Cheers,
Avi

Categories