Entity Framework renaming mistake - c#

I am using Entity Framework Code First in my project, and I did something quite silly I can't fix. I have renamed a table in SQL Server Management Studio, and then deleted it there. I then recreated the correct table (just an 's' that wasn't supposed to be here). Now it's not here anymore and I keep getting exceptions in my queries since EF looks for a table that does not exist anymore (even though I renamed it everywhere!). Now my table is called RelImpUser and it used to be RelImpUsers.
So I have tried recreating the table in SQL Server, then making a migration with :
public override void Down()
{
DropTable("dbo.RelImpUsers");
}
But this does not delete my table. And everytime I execute a query, it looks in RelImpUsers, it does not go for RelImpUser which is the only name I put in my code. Any ideas how to fix this? I can add some code if you want, I just felt it doesn't help much here.
Edit 1: It might have to do with the pluralization of my tables. So all my tables all had plural names, but the new one doesn't, BUT EF still pluralizes because I checked the option when creating DB Code First.
Thanks!

Code First uses its models to build the queries. You will need to annotate your RelImpUser class (or add comparable fluent code):
using System.ComponentModel.DataAnnotations.Schema;
[Table("RelImpUser")]
public class RelImpUser
{
public int RelImpID { get; set; }
public string Field1{ get; set; }
...
}
Fluent equivalent:
modelBuilder.Entity<RelImpUser>().ToTable("RelImpUser");
If you don't want pluralized names, you can turn that convention off:
protected override void OnModelCreating(DbModelBuilder modelBuilder)
{
modelBuilder.Conventions.Remove<PluralizingTableNameConvention>();
}

Related

Prevent table generation for a specific entity in EF6

How do I disable table generation for a specific entity when my DB context is initialized?
public class MyDbContext : DbContext {
public DbSet<MyEntity> MyEntity{ get; set; }
protected override void OnModelCreating(DbModelBuilder modelBuilder) {
modelBuilder.Ignore<MyEntity>();
base.OnModelCreating(modelBuilder);
}
}
This code helps but it excludes the entity completely and I still need to query it.
Without getting into too much detail, EF compares generated code your DB structure to the previous generated code when looking at migrations: it doesn't actually compare against the raw DB every time.
You should be able to bypass it wanting to create a table by creating a new migration, deleting/commenting out the table create code in UP and table remove code in DOWN, and apply the empty migration. It'll still have the view in the generated code, so it won't try to add it again.
You can create an empty migration as the first migration with the -IgnoreChanges flag to allow Entity Framework to get a snapshot of the existing database. For example:
Add-Migration InitialMigration -IgnoreChanges
This will map your entity to already existing table or a view in your case
modelBuilder.Entity<entityname>().ToTable("Tablename");
or using data annotations like this
[Table("tablename")]
public class ClassName {
....
}

Why does EF 5.x use plural name for table?

I've had some experiences in ORM framework such as Hibernate, even Entity Framework 3.0.
By default, those frameworks use singular name for table. For example, class User will map to table User.
But when I migrate to EF 5.x by using Visual Studio 2012, it uses plural name and causes many errors unless I manually map that class by using TableAttribute as:
[Table("User")]
public class User {
// ...
}
Without TableAttribute, if I have a DbContext as below:
public CustomContext : DbContext {
// ...
public DbSet<User> Users { get; set; }
}
Then calling:
var list = db.Users.ToList();
The generated sql looks like:
Select [Extent1].[Username] From [Users] as [Extent1]
Therefore, the error will occur because I don't have any table named Users. Futhermore, I refer to name tables in singular form to plural form. You can see why in this link
I wonder why Microsoft implement EF 5.x that way rather than same to EF 3.0?
Updated:
We can tell EF not use pluralized name by using this code in the context class:
protected override void OnModelCreating(DbModelBuilder modelBuilder)
{
modelBuilder.Conventions.Remove<PluralizingTableNameConvention>();
base.OnModelCreating(modelBuilder);
}
Even if EF tool generates pluralized name, it should keep the mappings to the original database, shouldn't it? Because some users might want to change a few name of fields on their class. EF 3.0 works well, but EF 5.x does not.
Guys, can you give my a reason, please!
That convention is defined in the PluralizingTableNameConvention convention defined by default in the DbModelBuilder.Conventions
If you want to exclude it from all tables, you can use the code from this question.
Why this is done the way it is, I do not know, but I must say that I am, personally, in the camp that thinks that table names should be pluralized :)
Of the example databases provided with an SQL Server instance, Northwind has plurals, and AdventureWorks uses a singular form, so at best, there is no established standard. I've had quite a few discussion for or against each one, but one thing that everybody can agree on is that when once pick a naming strategy, you should stick with it.
When you generate your model with entity framework, uncheck "Pluralize or singularize generated object names"

Is there a way to force all property name maps to use ALL CAPS in EF 4.3 Code-First?

I'm using EF 4.3 code-first with an Oracle database. One weird thing about the database is that it automatically makes table and column names ALL CAPS. My domain properties are in PascalCase. Unfortunately, EF doesn't know to capitalize column names, so my queries don't work. I have hundreds of properties on several classes that should map to oracle columns. I would really rather not manually code all those mappings. Is there a way to use a convention to capitalize column names?
SUMMARY:
I need for Entity Framework to use ALL CAPS for all column names. How can I do that?
Haven't tried this, but what about something like this:
public class SomeEntities : DbContext
{
public DbSet<Entity> Entities { get; set; }
protected override void OnModelCreating(DbModelBuilder modelBuilder)
{
// Configure Code First to ignore ColumnTypeCasing convention
modelBuilder.Conventions.Remove<ColumnTypeCasingConvention>();
}
}

Can I change the default schema name in entity framework 4.3 code-first?

Currently I am deploying my application to a shared hosting environment and code-first with migrations has been working great except for one minor hiccup. Everytime I want to push the site I have to use the "Update-Database -script" option because I have to prepend every table name with [dbo] because by default the shared host creates a default schema name that is the same name as the database username.
If I log into my shared host and create a database, I then have to create a user. If I name that user admin, then the tables code-first creates while logged in as admin look something like this "[admin].[BlogPosts]". When the application runs all the tables are created but I get an EF exception because it says "[dbo].[BlogPosts]" is invalid. If I rename the table's schema name to "[dbo]" instead of "[admin]" that fixes it.
To get around this I have to generate a migrations script to be executed manually and add "[dbo]" in front of all the table names because the script only references the tables by their name, not by their schema and their name.
Is there an easy way to get around this? It would be so nice if all I had to do was publish the application and everything just worked. If it wasn't for the schema name discrepancy it would be a one click deploy and everything would be glorious.
For those using Entity Framework 6, just use the HasDefaultSchema method:
public class Contexto : DbContext
{
public DbSet<User> Users { get; set; }
protected override void OnModelCreating(DbModelBuilder modelBuilder)
{
modelBuilder.HasDefaultSchema("MyDefaultDbSchema");
}
}
You could use the ToTable method to specify the schema name. If you do not specify the schema name, EF will by convention use dbo.
public class MyContext
{
private string schemaName = "Foo";
protected override void OnModelCreating(DbModelBuilder modelBuilder)
{
modelBuilder.Entity<MyEntity>().ToTable("MyTable", schemaName);
}
}
In EF Code first, by default, everything is set up based on user access with a managerial access "DBO-Schema" in the SQL Server. But if a specific user is defined to work with a database that is common in shared hosting, then there will no longer be Dbo management access. This time the names of our tables are dbo.tableName, for example, someUser.tableName, and inaccuracy of this point makes it impossible to run the program. To modify and explicitly assign a user connected to a database. If you use metadata, the following method should be used:
[Table("MyTableName", Schema="MySchemaName")]
public class MyClassName
{
//Other Lines...
}
Or (Whether or not Fluent API is customizable as follows:)
modelBuilder.Entity<Blog>().ToTable("MyTableName", schemaName:"MySchemaName");
Notice the following:
a good reference for study:
http://www.c-sharpcorner.com/article/fluent-api-in-code-first-approach/
For database-first implementations, it's easy. Open the edmx file, right click -> Properties and set the default database schema.
For code-first, this article seems most promising: https://web.archive.org/web/20150210181840/http://devproconnections.com/entity-framework/working-schema-names-entity-framework-code-first-design
I would like to add since this is for C#, I have written one below for VB
Public Class ClientDbContext
Inherits DbContext
Public Property Clients As DbSet(Of Client)
Protected Overrides Sub OnModelCreating(modelBuilder As DbModelBuilder)
modelBuilder.HasDefaultSchema("dbo")
End Sub
End Class

SqlException (0x80131904): Invalid object name 'dbo.Categories'

I am getting the exception above when I run an application. The application is using asp.net mvc 3 / C#. I made an mdf file and added it under App_Data folder in Visual Web Developer Express. I added connection strings to the web.config folder but when I run and browse to /store, I get the error above with the line var categories = storeDB.Categories.ToList(); highlighted. My database contains 6 tables and one of them is Category.
Controller:
EventCalendarEntities storeDB = new EventCalendarEntities();
public ActionResult Index()
{
var categories = storeDB.Category.ToList();
return View(categories);
}
Connection strings in web.config file:
<connectionStrings>
<add name="EventCalendarEntities"
connectionString="data source=.\SQLEXPRESS;
Integrated Security=SSPI;
AttachDBFilename=|DataDirectory|\MvcEventCalendar.mdf;
User Instance=true"
providerName="System.Data.SqlClient" />
</connectionStrings>
This usually means a simple configuration issue:
perhaps there genuinely is no such table
perhaps the table is there, but there is no dbo scheme (it might be in Fred.Categories)
perhaps the db is case-sensitive (which is fine), and the table is actually dbo.CATEGORIES
Any of these will cause the above exception. In particular, you state:
My database contains 6 tables and one of them is Category.
Now to a machine, Category != Categories
Try using model builder class. It is the way to configure or explicitly define the mapping between table and model class.
In your entity/context class try adding this code
protected override void OnModelCreating(DbModelBuilder modelBuilder)
{
base.OnModelCreating(modelBuilder);
modelBuilder.Entity<Category>().ToTable("Category");
}
It's a method. Make sure you are using all the including statements.
Since this was still top search hit on the exception in April of 2018 and it led me to a solution, let me tack this on for a specific situation...
Our application is based on ABP and ABP.Zero, and we already have a pattern that fit Marc's answer. While I bet explicit mapping in the OnModelCreating method (a la Dhananjay's answer) would have worked perfectly, it seemed like ABP's mapping was working perfectly up to this point and I didn't want to break the pattern.
My solution was to add a table attribute to the entity class, and this settled EF's confusion.
using System;
using Abp.Domain.Entities;
using System.ComponentModel.DataAnnotations.Schema;
namespace Discovery.History
{
[Table("HistoryRecords")]
public class HistoryRecord : Entity<int>
{
public int ResearcherCount { get; set; }
public DateTime DateSubmitted { get; set; }
public string Comments { get; set; }
}
}
What you really want to do to fix this is in you Context class you should have a method called OnModelCreating... make sure it has this:
protected override void OnModelCreating(DbModelBuilder modelBuilder)
{
modelBuilder.Conventions.Remove<PluralizingTableNameConvention>();
}
Proven,tested & verified for table with name category or any SQL keywords named table use ToTable to instruct specific table name
protected override void OnModelCreating(DbModelBuilder modelBuilder)
{
modelBuilder.Entity<category>().ToTable("category");
}
If you have a Class for mapping properties and keys without this.Map.(a table in db necessary to mapping), EntityFramework expect you have one table named like Category but convert in plural, so "Categories".. To resolve you can add this.Map(in correct table existing in your DB).
in your DbContext where you create DbSet change Categories to Category
I resolved same issue by this way

Categories

Resources