I have a SQL Server based ASP.NET MVC 5 app, and I'm using Entity Framework 6 to talk to the database.
We're using a "hybrid" approach - we manage all the database structure with classic SQL scripts which we deploy onto our DB server, and then we generate the "code-first" classes from that SQL Server database. This works reasonably well, for the most part.
One thing that bugs me is the if a given table has multiple FK link to another table, the naming convention used by the EF6 code generation is pretty lame....
Assume I have a table (and therefore entity) Site
which represents a site somewhere, and this site has three links to a Contact
table for various roles - the "main" contact, the "support" contact, and a "sales" contact. So my table in SQL Server looks something like this:
CREATE TABLE dbo.Site
(
SiteID INT NOT NULL
CONSTRAINT PK_Site PRIMARY KEY CLUSTERED,
.... some other properties, of no interest or relevance here .....
MainContactId INT NOT NULL
CONSTRAINT FK_Site_MainContact FOREIGN KEY REFERENCES dbo.Contact(ContactId),
SalesContactId INT NOT NULL
CONSTRAINT FK_Site_SalesContact FOREIGN KEY REFERENCES dbo.Contact(ContactId),
SupportContactId INT NOT NULL
CONSTRAINT FK_Site_SupportContact FOREIGN KEY REFERENCES dbo.Contact(ContactId)
)
I had been hoping that the EF6 code-first from existing database generation would be smart enough to read those column names and come up with meaningful names for the navigation properties on the entity - but alas, this is what I get instead:
[Table("Site")]
public partial class Site
{
[DatabaseGenerated(DatabaseGeneratedOption.None)]
public int SiteID { get; set; }
public int MainContactId { get; set; }
public int SalesContactId { get; set; }
public int SupportContactId { get; set; }
public virtual Contact Contact { get; set; }
public virtual Contact Contact1 { get; set; }
public virtual Contact Contact2 { get; set; }
}
While the actual FK columns are OK - the "deduced" navigation properties are horrible - Contact
, Contact1
and Contact2
- seriously, is this the best naming??? I think not... I would much prefer to called them "MainContact", "SalesContact", "SupportContact" - wouldn't that make a lot more sense? And be clearer for later use?
I installed the custom T4 templates (Nuget package "EntityFramework.CodeTemplates.CSharp"), and I see that there are a few interesting and potentially very useful helper classes being used (CSharpCodeHelper
, EdmHelper
, EntitySet
, DbModel
from the Microsoft.Data.Entity.Design
and System.Data.Entity.Infrastructure
namespaces) - unfortunately, most of them are sparsely documented, and also often their constructors are internal - so I cannot really build my own tool based on those ready-made classes.
Any other approach? I'd really like to teach the code generation a few smarts - this right now is just not up to usual standards and requires me to make a lot of manual changes to generated files - a labor in vain, flushed down the digital toilet each time I need to re-generate the classes from the database.....