0

Consider a simple microblogging platform with the data model defined as follows:

[Table("users")]
public class User
{
    [Column("id"), Key, DatabaseGenerated(DatabaseGeneratedOption.Identity)]
    public long Id { get; set; }

    [Column("name"), MaxLength(45), Index(IsUnique = true)]
    public string Name { get; set; }

    [Column("password"), MaxLength(45)]
    public string Password { get; set; }

    public virtual ICollection<Message> Messages { get; set; }
}


[Table("messages")]
public class Message
{
    [Column("id"), Key, DatabaseGenerated(DatabaseGeneratedOption.Identity)]
    public long Id { get; set; }

    [Column("text"), MaxLength(512)]
    public string Text { get; set; }

    [Column("author")]
    public virtual User Author { get; set; }
}

When I were designing it the database (SQL DDL) first way, I have included the messages.author referencing users.id as a foreign key. I like it this way: tidy and explanatory.

When I have tried the code-first way, however, I have found that it names the foreign key column messages.User_Id rather than messages.author despite the fact I have specified the [Column("author")] attribute explicitly.

How can this behaviour be possibly corrected?

I would agree to name it simply .user (instead of my original .author idea) to make the reference more obvious if necessary, but certainly not .User_Id - I totally dislike it when this obvious, redundant and ugly _Id gets appended to key columns.

I use an SQLite database with the SQLiteCodeFirst library and am not sure whether this is normal Entity Framework behaviour or just a bug in this particular library.

Ivan
  • 63,011
  • 101
  • 250
  • 382

1 Answers1

1

Just to preface, when I tested your code using LocalDb I get similar behaviour but the generated key is Author_ID instead of User_ID. I assume your description just hasn't been updated to reflect code changes while you were trying things out.

The issue is that you don't have a property defined in your Message class to hold the reference to the User, so it generates one itself (Author_ID). If you add one yourself and move the column annotation to that, your database will use the names you're expecting.

So your Message class will now be:

[Table("messages")]
public class Message
{
    [Column("id"), Key, DatabaseGenerated(DatabaseGeneratedOption.Identity)]
    public long Id { get; set; }

    [Column("text"), MaxLength(512)]
    public string Text { get; set; }

    [Column("author")]
    public long AuthorId { get; set; }

    public virtual User Author { get; set; }
}
Tone
  • 1,701
  • 1
  • 17
  • 18