Entity Framework Code First MySql Pluralizing Tables - c#

I am using the Microsoft Entity Framework with code first to manage my data (with MySQL). I have defined a POCO object, however, when I try to add data it says table Users doesn't exist. I looked in the DB and it created table User not Users. How can I remedy this? It is driving me nuts!
Thanks!
public class User
{
[Key,Required]
public int UserId { get; set; }
[StringLength(20), Required]
public string UserName { get; set; }
[StringLength(30), Required]
public string Password { get; set; }
[StringLength(100), Required]
public string EmailAddress { get; set; }
[Required]
public DateTime CreateDate { get; set; }
[Required]
public bool IsActive { get; set; }
}

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Data.Entity;
using System.Data.Entity.ModelConfiguration.Conventions;
namespace YourNamespace
{
public class DataContext : DbContext
{
protected override void OnModelCreating(DbModelBuilder dbModelBuilder)
{
dbModelBuilder.Conventions.Remove<PluralizingTableNameConvention>();
}
public DbSet<User> User { get; set; }
}
}

I have not used MySQL with EF yet but regardless I think the solution is unbias. You need to turn off Pluralize Table Convention.
using System.Data.Entity;
using System.Data.Entity.ModelConfiguration.Conventions.Edm.Db;
public class MyDbContext: DbContext
{
protected override void OnModelCreating(ModelBuilder modelBuilder)
{
modelBuilder.Conventions.Remove<PluralizingTableNameConvention>();
}
}
Now EF will look for the literal of your object name to the table name.
Some great video tutorials are at http://msdn.microsoft.com/en-us/data/aa937723 under the Continue Learning Entity Framework. For additional learning experience, you can not specify the above but rather explicitly map the object 'user' to the table 'user'.
Additional References:
http://blogs.msdn.com/b/adonet/archive/2010/12/14/ef-feature-ctp5-fluent-api-samples.aspx

You can put an attribute on the class telling the name of the table:
[Table("Users")]
public class User
{
//...
}
...or you could use the fluent API. To do this you will override the OnModelCreating method in your DbContext class.
public class MyDbContext : DbContext
{
protected override void OnModelCreating(DbModelBuilder modelBuilder)
{
modelBuilder.Entity<User>().Map(t => t.ToTable("Users"));
}
}
In future versions of EF, we've been promised the ability to write our own conventions. Thats not in there yet as of version 4.1...
(Haven't tried it with MySQL...)

Related

In code first "ies" (plural) is mandatory

Here im trying to get data from database using code-first but if I have a tabel Like Country, like this:
public class Country
{
public int id { get; set; }
public string Name { get; set; }
}
contextdb
public class ContextDb: DbContext
{
public ContextDb() { }
public DbSet<Country> Country { get; set; }
...
}
when I implements as Countrys its throwing an error:
Countries not have dbo
Please try to make it explicit which specific table you want for this particular type
public class ContextDb : DbContext
{
protected override void OnModelCreating(DbModelBuilder modelBuilder)
{
modelBuilder.Entity<Country>().ToTable("Country");
}
public ContextDb() { }
public DbSet<Country> Country { get; set; }
}
As an alternative, you can turn off the pluralizing convention
protected override void OnModelCreating(DbModelBuilder modelBuilder)
{
modelBuilder.Conventions.Remove<PluralizingTableNameConvention>();
}
Another option, as mentioned in Stefan's answer, is to have an attribute over your model class (which makes the class "not-that-POCO-anymore" but technically is perfectly valid).
Usually we use plurals in the DbContext like this:
public DbSet<Country> Countries { get; set; }
EF uses an auto plural convention, so your entity
public class Country
will translate to a datatable [dbo].[Countries] in your database.
If you want to explicitly override the name of the table in the database you can use the following attribute.
[Table("YourNameHere")]
public class Country
{
public int id { get; set; }
public string Name { get; set; }
}
I think there is a mixup in this logic somewhere in your code.
Alternativly you can also put your table in a differnt schema if you like:
[Table("YourNameHere", Schema = "YourSchemaNameHere")]
public class Country
{
public int id { get; set; }
public string Name { get; set; }
}
Beware with renaming the schema though, I have experienced that some migrations will break because to database index names are not always handled correctly.
note
See #Wiktor Zychla 's solution to disable the plural conventions on the whole context.

C# - Entity Framework enable FK with SQLite

I'm working in a Entity Framework + SQLite app, and i don't know how activate PRAGMA foreign_keys = 1 in the Model for C# application.
Here my model (My_model.Context.cs)
using System;
using System.Data.Entity;
using System.Data.Entity.Infrastructure;
public partial class My_Model : DbContext
{
public My_Model()
: base("name=My_Model")
{
}
protected override void OnModelCreating(DbModelBuilder modelBuilder)
{
throw new UnintentionalCodeFirstException();
}
public virtual DbSet<My_TABLE1> My_TABLE1 { get; set; }
public virtual DbSet<My_TABLE2> My_TABLE2 { get; set; }
public virtual DbSet<My_TABLE3> My_TABLE3 { get; set; }
public virtual DbSet<My_TABLE4> My_TABLE4 { get; set; }
}
Any idea?
I have tried modify App.conf doesn't works.
I have found many examples but no works for me.
In your App.Config file, add "foreign keys=true" to the connection string, like this:
data source=c:\wherever\whatever.sqlite;DateTimeFormat=InvariantCulture;foreign keys=true

c# MVC 5: how to add new table to the existing database

I want to add a new table in my database which my MVC 5 Project generated (with tables like: adoNetRoles, adoNetUser etc..).. I want my table to have two foreign keys on a user.. here is what my POCO-class looks like:
using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using System.Data.Entity;
using System.ComponentModel.DataAnnotations.Schema;
namespace GameApp.Models
{
[Table("Invitation")]
public class Invitation
{
public string Host { get; set; }
public string Invitee { get; set; }
}
public class InvitationContext : DbContext
{
public InvitationContext()
{
if (Database.Exists())
{
Database.Initialize(true);
}
}
public DbSet<Invitation> Inv { get; set; }
}
}
I really don't know where to put this code and how to set the foreign key. I enabled CodeFirst-Migrations already and know how it works. I know how all this works if I would create my own project and database.. but the mvc5 project confuses me. Please help me because Google couldn't!
I think the "existing database" bit is throwing people. What you're calling an "existing database" seems to be simply the tables generated by Identity, as part of your application. In other words, the whole thing is Code First, but you've already done the initial migration.
The default MVC 5 project with individual auth gives you, among other things, a context, ApplicationDbContext, and a user entity, ApplicationUser, out of the box. You will simply, then, just extend these. Namely, you will add a new DbSet to ApplicationDbContext, rather than creating a new context (InvitationContext). Generally speaking, one context == one database. If you want Invitation and ApplicationUser to interact, then they both need to be in the same context. Then, you will add a foreign key(s) to Invitation. If I understand the relationship: user has many invitations (as host) and invitation has one host, and user has many invitations (as invitee) and invitation has one invitee. In other words, you've got two foreign keys to a "user" per invitation, resulting in two separate one-to-many relationships to the same table.
public class Invitation
{
[Key]
public int Key { get; set; }
[ForeignKey("Host")]
public string HostId { get; set; }
public virtual ApplicationUser Host { get; set; }
[ForeignKey("Invitee")]
public string InviteeId { get; set; }
public virtual ApplicationUser Invitee { get; set; }
}
Assuming you already know how Code-first migrations works here what is missing for your code:
using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using System.Data.Entity;
using System.ComponentModel.DataAnnotations;
using System.ComponentModel.DataAnnotations.Schema;
namespace GameApp.Models
{
[Table("Invitation")]
public class Invitation
{
[Key]
public int Key { get; set; }
public string Host { get; set; }
public string Invitee { get; set; }
}
public class InvitationContext : DbContext
{
public InvitationContext() : base("YourConnectionString")
{ }
public DbSet<Invitation> Inv { get; set; }
}
}
I highly recomend you to separate tables and context in diferent files for better maintainability.
Understanding what I did now:
//I don't think you need this line and if you need it the condition should have a !
if (Database.Exists())
{
Database.Initialize(true);
}
//The constructor of DbContext can be empty, but it facilitates your work if you pass the connection string
public InvitationContext() : base("YourConnectionString")
//Use the anotation Key say to code-first migrations what is your, well, your key. Se set one key and then migrate your database.
[Key]
public int Key { get; set; }
It mostly problems with code-first than MVC, just some adjusts and you're ready to go.
source: http://www.dotnet-tricks.com/Tutorial/entityframework/R54K181213-Understanding-Entity-Framework-Code-First-Migrations.html

Scaffolding migration up/down shows Empty

I want to create a new datatable in my database.
I ran Add-Migration items, it shows empty for both up() and down()
namespace myapp.Migrations
{
using System;
using System.Data.Entity.Migrations;
public partial class items : DbMigration
{
public override void Up()
{
}
public override void Down()
{
}
}
}
I have a model:
public class Item
{
public string name { get; set; }
public int defineindex { get; set; }
}
public class ItemContext : DbContext
{
public DbSet<Item> Items { get; set; }
}
I also created a mapping when the above code doesnt generate useful scaffold. But it still didnt solve my problem.
There is a ContextKey value in my Migrations/Configuration.cs for my EF, which is set to a class name. So my EF will only care about that class. I need to put my DbSets all under that class for it to work instead of creating a new class.

Creating Primary Key field on MVC class

I am new to MVC and C#. I just stumbled on it and found it interesting. I encountered an issue which will not allow me proceed.
Here is my code:
using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using System.Web.Mvc;
namespace MyHotel.Models
{
public class AccountTypes
{
public int AccountTypeID { get; set; }
public string AccountTypeName { get; set; }
}
}
I created the controler and the view thereafter.
And for this, I keep got this error:
One or more validation errors were detected during model generation:
System.Data.Edm.EdmEntityType: : EntityType 'AccountTypes' has no key defined. Define the key for this EntityType.
System.Data.Edm.EdmEntitySet: EntityType: EntitySet "AccountTypes" is based on type "AccountTypes" that has no keys defined.
I google that the answers were to add [Key] over the public int AccountTypeID { get; set; } so it could look like this:
namespace MyHotel.Models
{
public class AccountTypes
{
[Key]
public int AccountTypeID { get; set; }
public string AccountTypeName { get; set; }
}
}
But no result until now.
Note: I am using MVC 4
Description
Entity Framework CodeFirst recognize the key, by default, by name.
Valid names are Id or <YourClassName>Id.
Your property should named Id or AccountTypesId
Another way is to use the ModelBuilder to specify the key.
Sample
public class MyDbContext : DbContext
{
public DbSet<AccountTypes> AccountTypes { get; set; }
protected override void OnModelCreating(ModelBuilder modelBuilder)
{
modelBuilder.Entity<AccountTypes>.HasKey(x => x.AccountTypeID);
base.OnModelCreating(modelBuilder);
}
}
Mode Information
Entity Framework Code First Tutorial
Try using [EdmScalarPropertyAttribute(EntityKeyProperty=true, IsNullable=false)] property to indicate the key field.
The regular field would go with EntityKeyPropert=false.
public class MyDbContext : DbContext
{
public DbSet<AccountTypes> AccountTypes { get; set; }
protected override void OnModelCreating(ModelBuilder modelBuilder)
{
modelBuilder.Entity<AccountTypes>().HasKey(x => x.AccountTypeID);
base.OnModelCreating(modelBuilder);
}
}
Hi Peter it seens you are missing an "s"
Your Account int should be:
public int AccountsTypeID { get; set; }
Hope it can be solved; Fernando.

Categories