46

I've made a simple Entity Framework ASP Core Application that works but I do not know why:

I've made a context like this:

public class AstootContext : DbContext
{
    public AstootContext(DbContextOptions<AstootContext> options)
        : base(options)
    { }

    public DbSet<Account> Accounts { get; set; }
    public DbSet<User> Users { get; set; }
}

And I have two tables with models like this:

public class Account
{
    public int Id { get; set; }
    public string Username { get; set; }
    public string PasswordHash { get; set; }
    public DateTime Created { get; set; }

    List<User> Users { get; set; }
}

public class User
{
    public int Id { get; set; }
    public string FirstName { get; set; }
    public string LastName { get; set; }
    public string Email { get; set; }
    public DateTime Birthday { get; set; }
    public Account Account { get; set; }
}

The interesting thing is that when I run my application it actually can pick up the data. It just seems weird because I have not specified any table mapping. I'm assuming this just automaps because the specified tables are the same name.

My questions are:

  1. How do I specify Table explicit table mapping in case I do not want my model names to be exactly the same as the DB?

  2. How do I specify Custom Column Mapping.

  3. Is there anything special I have to specify for Primary/Foreign Keys

edit

To clarify

  1. Say I had a table in the DB MyAccounts and I wanted to map that to an entity Accounts.

  2. Say I had a column password and I wanted that to map to a POCO property PasswordHash

DavidG
  • 113,891
  • 12
  • 217
  • 223
johnny 5
  • 19,893
  • 50
  • 121
  • 195
  • You have a bunch of questions here, you should really only be asking one. – DavidG Feb 12 '17 at 17:40
  • 1
    @DavidG they're all related to to specific mapping, future users will only need to go to one question to find a nice full answer, I will put a bounty if need be – johnny 5 Feb 12 '17 at 17:46
  • What do you mean by question 2, are you wanting to name your columns? – DavidG Feb 12 '17 at 17:48
  • My column in the database is named password but it's named in the model passwordHash, I can't imagine that entityframework could automatically resolve that, how can I point that property to the column – johnny 5 Feb 12 '17 at 17:50
  • It's not possible that EF has renamed your password column, are you sure you have no code that is doing it for you? Any attributes you are not showing or the context setup? – DavidG Feb 12 '17 at 17:51
  • @DavidG entityframework7 is all code first, I named it something different but I want to specify it maps to a different column than the exact name – johnny 5 Feb 12 '17 at 17:52
  • @DavidG I edited the question to clarify – johnny 5 Feb 12 '17 at 17:56
  • PK/FK is a bit more involved, but I've answered the first 2 for you. I recommend [reading the docs](https://learn.microsoft.com/en-us/ef/core/modeling/keys) – DavidG Feb 12 '17 at 17:58

1 Answers1

67
  1. To specify the name of the database table, you can use an attribute or the fluent API:

    Using Attributes:

     [Table("MyAccountsTable")]
     public class Account
     {
          public string PasswordHash { get; set; }
     }
    

    Using Fluent API:

     public class YourContext : DbContext
     {
         protected override void OnModelCreating(ModelBuilder builder)
         {
             builder.Entity<Language>(entity => {
                 entity.ToTable("MyAccountsTable");
             });
         }
     }
    
  2. To name your columns manually, it's very similar and you can use an attribute or the fluent API:

    Using Attributes:

     public class Account
     {
         [Column("MyPasswordHashColumn")]
         public string PasswordHash { get; set; }
    
     }
    

    Using Fluent API:

     public class YourContext : DbContext
     {
         protected override void OnModelCreating(ModelBuilder builder)
         {
             builder.Entity<Language>(x => x
                 .ToTable("MyAccountsTable")
                 .Property(entity => entity.PasswordHash)
                     .HasColumnName("MyPasswordHashColumn")
             );
         }
     }
    
DavidG
  • 113,891
  • 12
  • 217
  • 223
  • Thanks this is perfect, do you happen to have a link to where in the documentation is specifies the it's auto magic way of syncing to the Model names to the DB – johnny 5 Feb 12 '17 at 18:01
  • 1
    You can see some of it in [here](https://learn.microsoft.com/en-us/ef/core/modeling/backing-field) regarding the column names and in [here](https://learn.microsoft.com/en-us/ef/core/modeling/). – DavidG Feb 12 '17 at 18:03
  • Table attribute does not seem to work anymore. Neither DbSet names. The only way I can achieve my custom names is the fluent api on the builder. (as of .NET Core 3 Preview 5) – g.pickardou Jun 10 '19 at 18:26
  • @g.pickardou Well, I'm not going to comment on something that is only in preview, come back when the platform has stabilised a bit more. – DavidG Jun 11 '19 at 13:59
  • @DavidG is it stable yet? – devhl Jul 11 '20 at 23:22
  • @devhl Core 3 has been out for quite some time now, so yes. – DavidG Jul 12 '20 at 00:05
  • Why is the type ````? – Yannic Hamann Jan 12 '21 at 18:41
  • To map a property to a column name, you should be using `HasColumnName` instead of `HasField`. – luizs81 Feb 09 '22 at 09:19