0

Why has MS decided to use convention over configuration.

I deal with very large projects and not all projects are data centric. In fact, even with data centric projects, my entity classes have a lot of custom functionality that needs to be persistence agnostic.

With the current MSM approach, I end up having to apply attributes to non-persistence properties instead of the other way around. Shouldn't that be the point of code-first? To use a working class hierarchy and turn it into persistence compatible as an 'addition'?

I understand that some conventions are very useful such as the naming of Identity or primary key properties and foreign keys. But honestly, tell me how many developers would use code-first instead of model-first if they did NOT already have a class structure???

Raheel Khan
  • 14,205
  • 13
  • 80
  • 168

3 Answers3

3

You don't need to use any persistence dependent attributes in your classes. EF code first uses model configuration to define mapping - that configuration is either defined directly in OnModelCreating method of your derived DbContext or in separate configuration classes per every your entity and complex type. Attributes are just shortcuts converted to these configurations.

Ladislav Mrnka
  • 360,892
  • 59
  • 660
  • 670
  • Using the Fluent API is pleasant, I agree, but I am trying to generate our POCO classes from the model. I cannot use Model First because I do not want my classes tied to ObjectContext. DbContext allows much more independence from persistence. – Raheel Khan Apr 30 '12 at 15:15
  • Model first works with DbContext as well. Moreover ObjectContext works with POCOs as well providing same independence as when DbContext is used. So do I understand correctly that you don't like data annotations, you don't want to use EDMX and you don't want to use Fluent-API? I am afraid that in such case you don't want to use EF. – Ladislav Mrnka Apr 30 '12 at 15:24
  • My approach actually uses reflection to generate POCO classes from an EDMX model. These classes are persistence agnostic and need to remain as such. The problem is, I cannot dress up non-generated code. It is easy to annotate generated code. Thus the argument: convention over configuration. – Raheel Khan Apr 30 '12 at 17:28
  • Ok, I see the problem but we are back in the core issue. You would not need to annotate your non-generated code if you use EF in supposed way which means either writing or generating fluent mapping and using code first r using EDMX and using model first. There use to be custom conventions in CTP of code first but they were removed from RTM due to limited functionality of core EF features. At the moment defaul convention is simply to take all properties for persistence and manually identify which properties should not be persisted because it covers 99% of usages. – Ladislav Mrnka Apr 30 '12 at 18:54
  • That makes sense. Which of course leads me to the natural question. At compile time, we are already generating entity and context classes. I wonder if there is a way to 'hook' into that process and using reflection, mark all non-generated properties as [NotMapped]. This would not be a purely code first approach but neither would it be a model first one. If such a 'hook' were possible, then I could use the fluent API as you suggest to exclude appropriate properties in an automated way. – Raheel Khan Apr 30 '12 at 21:22
  • I have to mark this one as correct since it does explain why CF does not behave intuitively for projects with a pre-existing class structure. – Raheel Khan May 07 '12 at 02:26
2

If you are creating appropriate abstractions then this should not be a problem IMO. It sounds like you are mixing business entities and logic with data entities. If you follow the repository pattern and abstract the persistence entities, then most of your POCOs should follow convention. I would suggest re-evaluating your architecture as it sounds very coupled to the persistence layer. If you create a more loosely coupled architecture, then these conventions should make sense to you. Just my two cents, though

Justin Pihony
  • 66,056
  • 18
  • 147
  • 180
  • I appreciate that answer and would appreciate if you could give me an example of such an approach with let's say two or three classes. – Raheel Khan Apr 30 '12 at 14:59
  • Aren't the classes auto-generated by EF the "persistence entities" you're referring to? As I understand it, Raheel's issue is that he can't truly "abstract the persistence entities" using EF (at least the way he's using it) because it requires that he decorates his business entities with attributes – ssis_ssiSucks Apr 30 '12 at 18:53
  • @JimMcKeon: That's pretty much what my issue is. – Raheel Khan May 07 '12 at 02:22
1

I've worked quite a bit applying code first to pre-existing business objects to create a persistence-ignorant architecture. There's more than one way to apply EF in this context - I agree that dressing up your business objects with attributes is less than ideal. What we've done in the past is

  1. Define an interface stored in the BLL assembly that is implemented by the DAL. This is used by upper layers for CRUD operations
  2. In the DAL, map business objects using EntityTypeConfiguration(of T)

It's worked pretty well for us, and decouples the upper layers from the DAL pretty nicely

ssis_ssiSucks
  • 1,476
  • 1
  • 12
  • 11
  • You have a good point there. I am currently 'thinking' about how to use a model to generate partial POCOs while remaining persistence-ignorant without resrting to the fluent API. I will definitely revert back here with a solution soon either ways. I guess I will be able to come up with a more mature question then. – Raheel Khan Apr 30 '12 at 17:30
  • Could you elaborate a little on your first point regarding interfaces? I am trying to apply it to a situation where user interaction level state management is strongly tied to some entities. – Raheel Khan Apr 30 '12 at 21:25
  • Take a look at [this](http://www.tugberkugurlu.com/archive/generic-repository-pattern-entity-framework-asp-net-mvc-and-unit-testing-triangle) – ssis_ssiSucks Apr 30 '12 at 23:27