I have convention to put [Key] as an Annotation Attribute
in Entity
and rest of the configuration into FluentAPI (ForeignKey
s mostly). I worked great, but then I found out that EF6 has this "magic conventions", that will create PK or FK if the name is in the specific format (I found out asking this question).
Then I thought, what if I'm doing something wrong and EF is saving my butt? And I don't even know that. So I removed all conventions, following this answer. Here's the code:
private void RemoveAllConventions(DbModelBuilder modelBuilder)
{
var conventions = AppDomain.CurrentDomain.GetAssemblies()
.SelectMany(a => a.GetTypes().Where(t => t.IsClass && t.GetInterface("IConvention") != null));
var remove = typeof(ConventionsConfiguration).GetMethods().Where(m => m.Name == "Remove" && m.ContainsGenericParameters).First();
foreach (var item in conventions)
{
try
{
remove.MakeGenericMethod(item).Invoke(modelBuilder.Conventions, null);
}
catch (Exception)
{
}
}
}
protected override void OnModelCreating(DbModelBuilder modelBuilder)
{
RemoveAllConventions(modelBuilder);
}
After that I got exceptions like:
CodeFirstNamespace.Item: : EntityType 'Item' has no key defined. Define the key for this EntityType.
The thing is.. Item
does have [Key]
attribute! When I add:
modelBuilder.Entity<Item>().HasKey(i => i.itemID);
The exception is gone.
Looks like, if you start Fluent API, you must put everything there. Is that true? Or I'm doing something wrong?
The issue is that you are removing all conventions on load, then using Fluent API. You can freely mix use of annotations and Fluent API. They each have strengths and weaknesses. I use both, wherever each is appropriate, in a project currently.
However, if you remove all your conventions every time OnModelCreating
is called, you're removing all previous conventions. This includes annotations, which are loaded before the system calls OnModelCreating