Can I disable automatic relationships in Entity Framework Code First?

I noticed that the Entity Framework still has many “automatic” features in its latest version. As always, this is truly a double-edged sword.

In particular, I use the OnModelBuilder event to create my model on the fly in code using fluentAPI (http://msdn.microsoft.com/en-us/library/hh295844(v=vs .103). ASPX). I have a large set of entities, and they do not all comply with Microsoft standards. For example, my identity columns are called Person_id instead of PersonId. Thus, Entity does not always automatically detect the primary key in the table, or at least it does not.

I am not opposed to being explicit when building the model, but I am worried that I’m not always sure which properties and relationships Entity will automatically detect and which ones will be mistakenly ignored or mistakenly identified. . Since most of my entities also have a partial class with auxiliary methods and properties (material for processing enumerations, etc.), I am very afraid that someday Entity will automatically create mappings between things that should not be displayed (failure may be an entity or some unsuspecting programmer).

Is there a way to disable Entity's autodepen function so that I can be 100% explicit in the OnModelBuilder method? Or, at a minimum, how can I find out when I need to add additional matching data (for example, I need to declare a field optional or when a specific navigation property will not be auto-determined)?

Thanks!

+8
entity-relationship
source share
5 answers

Automagy is performed using conventions inside the EF code. You can remove any from the agreement to disable some magic, or you can delete all of them , and after that you should be 100% explicit in your free API.

+6
source share

Well, since deleting conventions does not work, there is an easy way to not display all unconfigured properties inside EF6.x

The main thing is to use separate mapping classes, and after executing manual maps inside the class, just call the method, which with reflection will ignore all properties that have not been configured.

Here is a link to my meaning, where is the implementation. Also added a sample as a comment: https://gist.github.com/hidegh/36d92380c720804dee043fde8a863ecb

+1
source share

Just specify your relationships, keys and columns in the configuration of your entities, and this really should not be a problem.

I personally, during coding, let's assume until it breaks, and then I will fix the configuration.

protected override void OnModelCreating(DbModelBuilder modelBuilder) { Database.SetInitializer<AccountWriteContext>(null); modelBuilder.Configurations.Add(new AccountEntityTypeConfiguration()); modelBuilder.Configurations.Add(new AccountOwnerEntityTypeConfiguration()); modelBuilder.Configurations.Add(new CreditCardEntityTypeConfiguration()); modelBuilder.Configurations.Add(new TenantEntityTypeConfiguration()); //blah blah blah } class AccountOwnerEntityTypeConfiguration : EntityTypeConfiguration<AccountOwner> { public AccountOwnerEntityTypeConfiguration() { this.HasKey(p => p.ID); this.Property(p => p.ID).HasDatabaseGeneratedOption(DatabaseGeneratedOption.Identity).IsRequired(); this.HasRequired(o => o.CreditCard).WithMany().HasForeignKey(c => c.CreditCardID).WillCascadeOnDelete(true); this.ToTable("AccountOwner", "AccountWrite"); } } 
0
source share

Actually this code removes all conventions, even clears the original set ...

... but columns not mapped to EntityTypeConfiguration are displayed ...

 private void RemoveAllConventions(DbModelBuilder modelBuilder) { new List<string>() { "_configurationConventions", "_conceptualModelConventions", "_conceptualToStoreMappingConventions", "_storeModelConventions" } .ForEach(field => { var values = (IEnumerable<IConvention>)typeof(ConventionsConfiguration) .GetField(field, BindingFlags.Instance | BindingFlags.GetField | BindingFlags.NonPublic) .GetValue(modelBuilder.Conventions); modelBuilder.Conventions.Remove(values.ToArray()); }); var initialCS = typeof(ConventionsConfiguration) .GetField("_initialConventionSet", BindingFlags.Instance | BindingFlags.GetField | BindingFlags.NonPublic) .GetValue(modelBuilder.Conventions); new List<string>() { "ConfigurationConventions", "ConceptualModelConventions", "ConceptualToStoreMappingConventions", "StoreModelConventions" } .ForEach(field => { var values = (IEnumerable<IConvention>) initialCS .GetType() .GetProperty(field, BindingFlags.Instance | BindingFlags.GetProperty | BindingFlags.Public) .GetValue(initialCS); modelBuilder.Conventions.Remove(values.ToArray()); }); } 
0
source share

I would recommend using data annotation attributes for this. For example, the [key] attribute can be used to define your primary key, and the [table] attribute can be used to provide the name of your table. The [required] attribute can be used to indicate to EF that a field is required.

In my opinion, it is much easier to use attribute syntax than using free syntax to update the model, as well as self-documenting, since attributes are placed directly in the object code.

For more information, see this blog post listing all available attributes:

http://blogs.msdn.com/b/efdesign/archive/2010/03/30/data-annotations-in-the-entity-framework-and-code-first.aspx

-2
source share

All Articles