1

All my POCO classes have two letter prefix LK_. Entity framework conventions for primary & foreign keys would not work. Considering I have ~200 classes to decorate with Key or ForeignKey attribute its a cumbersome process & does not sound like a smart way of doing it.

Could you please suggest custom convention?

public class LK_Employee
{
    public Guid EmployeeID {get; set;}
    public string Name {get; set;}      
}

public class LK_Company
{
    public Guid CompanyID {get; set;}
    public string Name {get; set;}      
}

public class LK_Employee_LK_Company
{
    public Guid EmployeeID {get; set;}      
    public Guid CompanyID{get; set;}        
}
2
  • LK_EmployeeId should work, No? Commented Dec 4, 2015 at 13:03
  • Which are your rules for defining FK and primary key in "many to many bridge table"? If you explain it with word, perhaps I can propose a solution for you. Commented Dec 4, 2015 at 13:34

1 Answer 1

1

This will set any filed like LK_TableName as the table's primary key, when there is a simple column key:

protected override void OnModelCreating(DbModelBuilder modelBuilder)
{
    modelBuilder.Properties<Guid>()
        .Where(p => "LK_" + p.Name == p.DeclaringType.Name + "Id")
        .Configure(p => p.IsKey());
}

To support composite keys, as well as simple kesy, you need to do this:

// Counter: keeps track of the order of the column inside the composite key
var tableKeys = new Dictionary<Type,int>();

modelBuilder.Properties<Guid>()
.Where(p =>
{
    // Break the entiy name in segments
    var segments = p.DeclaringType.Name.Split(new[] {"LK_","_LK_"},
                      StringSplitOptions.RemoveEmptyEntries);
    // if the property has a name like one of the segments, it's part of the key
    if (segments.Any(s => s + "ID" == p.Name))
    {
        //  If it's not already in the column counter, adds it
        if (!tableKeys.ContainsKey(p.DeclaringType))
        {
            tableKeys[p.DeclaringType] = 0;
        }
        // increases the counter
        tableKeys[p.DeclaringType] = tableKeys[p.DeclaringType] + 1;
        return true;
    }
    return false;
})
.Configure(a =>
{
    a.IsKey();
    // use the counter to set the order of the column in the composite key
    a.HasColumnOrder(tableKeys[a.ClrPropertyInfo.DeclaringType]);
});

Creating the convention for foreing keys is much more complex. You can have a look at EF6 convention in this route: / src/ EntityFramework.Core/ Metadata/ Conventions/ Internal/ ForeignKeyPropertyDiscoveryConvention.cs, on EF6 github. And see the tests for illustration of use: / test/ EntityFramework.Core.Tests/ Metadata/ ModelConventions/ ForeignKeyPropertyDiscoveryConventionTest.cs

Sign up to request clarification or add additional context in comments.

3 Comments

Thanks. for key properties I have not kept any prefix. E.g. Id or EmployeeId for LK_Employee table, any suggestions?
This code checks if "LK_" + PropertyName = EntityName + "Id". If so, that's the key. I have not found a solution for composite keys yet.
@Abhijeet I've updated my answer to support also composite keys. Tested with your entities. Be aware that in your example you show "ID" and in the coment you show "Id". This code is key sensitive, but you can change it easyly.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.