Models and EF are making them plural - hauler/haulers [duplicate] - asp.net-mvc

This question already has answers here:
How do I singularize my tables in EF Code First?
(3 answers)
Closed 6 years ago.
This has happened twice on the same project. I'm using MVC/VS2015 community and I'm adding 2 classes: hauler and sale.
namespace CarThingy2.Models
{
public class Sale
{
public int ID { get; set; }
public int CoNbr { get; set; }
public int Locn { get; set; }
public int Ticket { get; set; }
public int Haul_Code { get; set; }
}
}
so I go to save - then I add the controller, and everything's good except I change the controller "title" (it was scaffolded as "SalesController") to SaleController. Run the project and it gives me an error about "it can't find dbo.Sales" in the "InnerException". I ended up having to enable-migrations, add-migration addsomethingelse and then finally update-database. TWICE (once for hauler, once for sale)!
Am I doing something wrong that grabs the "pluralized" name? This has happened to me before and I would least like an explanation as to why. The weirdest thing now is that the website will work, but the Tables ARE PLURAL (Haulers and Sales).

So were the tables originally called 'dbo.Sale' and 'dbo.Hauler'?
EF default convention is to use singular entity names and plural table names. You can manually specify the table name in the mapping though.
Note - now that you've added migrations, this will trigger another migration (or just delete the Migrations folder in the project and the dbo._MigrationHistory table in the database if you don't want migrations).
In the DbContext:
protected override void OnModelCreating(DbModelBuilder modelBuilder)
{
modelBuilder.Entity<Hauler>().ToTable("Hauler");
modelBuilder.Entity<Sale>().ToTable("Sale");
}
If you have an existing database with all singular names, you can globally remove the pluralization convention in the above method as well:
modelBuilder.Conventions.Remove<PluralizingTableNameConvention>();
Or via attribute on the entity:
[Table("Sale")]
public class Sale
{
}

Related

Entity Framework creates an empty migration file

I created my initial project in Visual Studio and discovered I had used SQL Server after I created my initial migration. I then changed all the connection information to use MYSQL and connected successfully. I created the initial migration again and it created all the ASP security tables. I added a new model and updated the database, but it created an empty migration (just UP/DOWN methods)
I've tried multiple fixes I found here and other sites. I backed out the second migration and retried. I tried forcing the migration again (-f). I dropped the new MYSQL db and deleted the migrations then started over, all with the same result.
Here is my model code:
using System.Collections.Generic;
using System.Linq;
using System.Web;
namespace congresssucks_conversion.Models
{
public class BlogPost : DBContext
{
public int Id { get; set; }
public string Title { get; set; }
public string ShortPost { get; set; }
public string Post { get; set; }
public string Tags { get; set; }
public DateTime Updated { get; set; }
}
}
And here is the migration file:
namespace congresssucks_conversion.Migrations
{
using System;
using System.Data.Entity.Migrations;
public partial class blogpost : DbMigration
{
public override void Up()
{
}
public override void Down()
{
}
}
}
It completes successfully and no errors in the Terminal Window.
You're combining two separate things, your model class and your database context.
Your BlogPostm class shouldn't inherit DbContext, it should be just a plain C# class.
Then you make a new class that looks something like this:
public class BlogDbContext : DbContext
{
public DbSet<BlogPostm> Posts { get; set; }
}
Now you have a class that can represent a single post, and another class that can represent a database with a table of multiple blog posts. The migration generator is looking for those DbSet<whatever> properties, so you should see real migrations after this change.
There are a lot more ways you can describe what you want Entity Framework to do with your database, so it would be worth reviewing an Entity Framework tutorial.
Try to delete a record of last migration from _MigrationHistory table. Maybe This record had been incorrectly created before added DbSet for the new model object to DbContext class. After this delete, new migration was created with correct Up() and Down() methods.

Why need use OnModelCreating (MVC 5 EF code first)?

I don't understand what is the reason of using OnModelCreating function?
when I can do something like
[Key]
[DatabaseGenerated(DatabaseGeneratedOption.Identity)]
public Int Id { get; set; }
public Int LanguageId { get; set; }
[ForeignKey("LanguageId")]
public Language Language { get; set; }
Maybe I am wrong but when I reads about this,it is explained as it's for Many-to-Many relationship.
so why not do something like this.
ICollection<User> Users
For making relationship between entities, we have two options
DataAnnotation (Which you are using)
Fluent API.
When we are using fluent API we need to specify our relationship in this OnModelCreating(DbModelbuilder modelbuilder) method.So when model is created first time they should maintain relationship between entities.
Common Example for using this method is given in this below code snnipet
modelBuilder.Entity<Department>().Property(t => t.Name).HasMaxLength(50);
the same can be achieved using data annotation attribute.
[MaxLength(50)]
public string Name {get;set;}
So if you dont want to use DataAnotation Use Fluent API to serve your purpose.

Add new table to an existing database using Code First approach in EF 6 and MVC 5

I know this should be simple, but I was unable to find correct tutorial or explanation on web on this subject. There is a lot of videos and posts about adding new column to an existing table, using code first approach, but I can not find any with step by step explanation on how to add whole new table into existing database.
Which is weird, I was pretty sure that I will find many examples. Maybe my search criteria is bad. So if anybody has any good link or video, please share.
What I'm trying to do is to add table Post into existing Default Database, created by MVC 5 project.
I've made model class first, named it Post and it has a simple definition:
public class Post
{
[Key]
public int PostId { get; set; }
public string PostText { get; set; }
public byte[] ImagePost { get; set; }
public byte[] FilePost { get; set; }
public string TextPost { get; set; }
public string UserId { get; set; }
}
Then I have first doubts. I know I should create DbContext, but if I want to hit an existing database, should I use existing DbContext, already created by default in Web.config file like this:
<add name="DefaultConnection" connectionString="Data Source=(LocalDb)\v11.0;AttachDbFilename=|DataDirectory|\aspnet-StudentBookApp-20150114035149.mdf;Initial Catalog=aspnet-StudentBookApp-20150114035149;Integrated Security=True"
providerName="System.Data.SqlClient" />
Or I should use all new DbContext created for Post class?
Anyhow I've tried it both, but no success. When I created this new context I was doing following in PMC:
Enable-Migrations
Add-Migration "PostMigration"
Update-Database
Usually, or all goes well, but I don't get any new table in database, or I get an error: AspNetUsers already exists, and AspNetUsers is one of auto-created tables that I've changed by adding new columns to it.
Update: My context right now is in seperated class named PostContext and it looks like this:
public class PostContext : DbContext
{
public PostContext() : base("name=PostContext")
{
}
public DbSet<Post> Posts { get; set; }
}
Second try:
Since my first approach didn't gave any result. I've tried doing what's described in this link. Adding mapping to my project:
I've crated new class PostConfiguration for mapping:
public class PostConfiguration : EntityTypeConfiguration<Post>
{
public PostConfiguration() : base()
{
HasKey(p => p.PostId);
ToTable("Post");
HasOptional(p => p.PostText);
ToTable("Post");
HasOptional(p => p.ImagePost);
ToTable("Post");
HasOptional(p => p.TextPost);
ToTable("Post");
HasOptional(p => p.FilePost);
ToTable("Post");
HasRequired(p => p.UserId);
ToTable("Post");
}
}
In the class Post I've added context class too PostContext with modelBuilder variable as they've suggested in listed link above:
public class PostContext : DbContext
{
static PostContext()
{
Database.SetInitializer(new DropCreateDatabaseIfModelChanges<PostContext>());
}
public DbSet<Post> Posts { get; set; }
protected override void OnModelCreating(DbModelBuilder modelBuilder)
{
modelBuilder.Properties()
.Where(p => p.Name == "Key")
.Configure(p => p.IsKey());
modelBuilder.Configurations.Add(new PostConfiguration());
}
}
I've run all PMC commands again, and still no success, table Post is missing from default database.
What has happened here is that you had existing database tables before Migrations where enabled.
So Entity Framework thinks that ALL your database objects need to created, this could be seen by opening up your PostMigration migration file.
The best way is to trick EF into to doing the initial migration with every before you added the Post table and then do the Posts migration after.
Steps
Comment out the Posts in the DBContext so EF doesn't know about posts
//public DbSet<Post> Posts { get; set; }
Enable Migrations
Enable-Migrations
Add an initial migration with all tables prior to your changes
Add-Migration "InitialBaseline" –IgnoreChanges
Now update the database, this will create a MigrationHistory table so that EF knows what migrations have been run.
Update-Database
Now you can uncomment the line in 1 to "Do your change"
Create a new migration with the addition of Posts
Add-Migration "PostMigration"
Now do an update... and hopefully it should all work.
Update-Database
Now that migrations are all setup and they are baselined future migrations will be easy.
For more information I found this link useful:
http://msdn.microsoft.com/en-us/data/dn579398.aspx
You can resolve that by going to migration folder and delete Post-Migration file, then inside migration folder you will find a file named ApplicationContextModelSnapshot or something like that, then delete modelBuilder.Entity related to your post model.
After that do:
Add-Migration "PostMigration"
Update-Database

Overly complicated many-to-many relationship with ASP.NET MVC

While researching whether or not ASP.NET MVC is suited for my next website, I've come across an annoying issue.
I have followed ASP.NET MVC since version 2, and it's gotten better. For instance, it's now fairly easy to get going with migrations in the entity framework with code first, which used to be a hassle.
This means that I now can get running with a database migrations and code first within half an hour (as I usually don't remember the steps involved, I have to follow a guide I wrote).
Now, fairly early on I always get a many-to-many relationship between entities (e.g. tags and posts) in my database, and what I've found is that getting this relationship exposed via MVC framework is surprisingly complicated! Example from asp.net Example from mikesdotnetting
It involves special methods to retrieve the relationship's data that is not an inherent part of the framework.
Is there really no better/easier way of treating the many-to-many relationship?
You should add a virtual key word to the Many port
public class Post
{
[Key]
public int ID { get; set; }
public string Title { get; set; }
public virtual ICollection<Tag> Tags {get;set;}
}
public class Tag
{
public int ID { get; set; }
public string Name { get; set; }
public virtual ICollection<Post> Posts {get;set;}
}

MVC Scaffolding with Repository Pattern - Saving children objects as a transaction

I have been scouring forums and repository pattern blogs for some clear direction on how I should be coding my project and I'm stuck. Any help or guidance from you guys would be much approciated :)
I started my project as EF5 MVC4 Razor Code First and decided to use MVCScaffolding to generate all my controllers, views and repositories. This was my first project with these technologies, I was just told that this was how the team was doing it now (but the previous developers did model first and hand coded their contexts).
SO, all is great, we're coding a bunch of screens, but one of our screens is a complex one that involves many models/sub modlels (ie/ Object model has FKs to Responses, Attachments, Reviewers, etc...). The user adds a bunch of data, selects one or more reviewers, adds 0 or more attachments. Then they hit Save!
Now my big problem is that I want to save all this data as one transaction, and if something fails on one of the children models (ie/ attachments) the transaction will roll back. However, the way the MVCScaffolding repositories are created, each model has it's own instance of DB Context and it's own Save. And the controllers accept each unique repository as parameters for loading the screen data. Another thing to note is for this screen we are using a ViewModel to load the data, and then wrote custom mappers to map back to the different models for saving. We can save each piece separately, and possibly the solution is just to wrap TransactionScope around my save, but I also want to reduce the number of calls to the db, as each repository save does a call.
I thought I could add code to the parent repository for a UnitsOfWork type save that would add/edit all the child obejcts in one context object, but that seems like a hack more than anything, and I want to code this properly.
One of the other projects here just made a custom DB context and all Save methods were in that class, is that the best way to do it? Another dev did code first but hand coded all his Save methods. None of them are in a standard place and he is using TransactionScope with a DBContext inside (is that overkill or does DBContext not handle transactions)?
Since I'm so new to this, I need help and no one I work with seems to agree on a proper method. I'm not sure if my model is wrong for an "MVC App" since I'm such a database heavy thinker.
Below is a sample of my models, any guidance is appreciated. Thanks :)
public class Anomaly
{
[Key]
public int AnomalyId { get; set; }
public string Subject { get; set; }
public int PlantId { get; set; }
[ForeignKey("PlantId")]
public virtual Plant Plant { get; set; }
public DateTime? ReviewByDate { get; set; }
public virtual ICollection<AnomalyReviewer> AnomolyReviewers { get; set; }
public virtual ICollection<AnomalyAttachment> AnomalyAttachments { get; set; }
}
public class AnomalyAttachment
{
[Key]
public int AnomalyAttachmentId { get; set; }
public int AnomalyId { get; set; }
[ForeignKey("AnomalyId")]
public virtual Anomaly Anomaly { get; set; }
public string FilePath { get; set; }
public string FileName { get; set; }
public string FileExtension { get; set; }
public string Notes { get; set; }
}
ps. that is just a sample... thanks!
Just create a class 'Master' that inherits from Controller.
Then write all your queries there as in public User GetUserById(Int32 id)
Finally create a function that does a call to the private!! implementation of DbContext.
I would usually give that function a enum of SystemEvents so i've got a reference of whats happening if something would fail... of course you would need to write your own notificator or model to record your own errors into the database for personal testing...
ive done all this because I can write all my code and found out that Repository Pattern is overkill most of the time if you actually think about it.

Resources