Take the 2-minute tour ×
Programmers Stack Exchange is a question and answer site for professional programmers interested in conceptual questions about software development. It's 100% free, no registration required.

In a EF 4.1 Code First tutorial the following code is given:

public class Department
{
    public int DepartmentId { get; set; }
    [Required]
    public string Name { get; set; }
    public virtual ICollection<Collaborator> Collaborators { get; set; }
}

Then it is explained that the fluent interface is more flexible:

Data Annotations are definitely easy to use but it is preferable to use a programmatic approach that provides much more flexibility.

The example of using the fluent interface is then given:

protected override void OnModelCreating(ModelBuilder modelBuilder)
{
    modelBuilder.Entity<Department>().Property(dp => dp.Name).IsRequired();
    modelBuilder.Entity<Manager>().HasKey(ma => ma.ManagerCode);
    modelBuilder.Entity<Manager>().Property(ma => ma.Name)
        .IsConcurrencyToken(true)
        .IsVariableLength()
        .HasMaxLength(20);
}

I can't understand why the fluent interface is supposedly better. Is it really? From my perspective it looks like the data annotations are more clear, and have more of a clean semantic feel to it.

My question is why would a fluent interface be a better option than using attributes, especially in this case?

(Note: I'm quite new to the whole concept of fluent interfaces, so please expect no prior knowledge on this.)

Reference: http://codefirst.codeplex.com/

share|improve this question
    
This question is not really about fluent interfaces. The difference is between using attributes and normal code. If the code wasn't fluent, it wouldn't change much about your question. –  svick Aug 2 '12 at 9:09
    
@svick fluent interfaces are basically normal code, but it expresses it in a different way. We moved away from specifying things in plain code to attributes, now with fluent interfaces it looks like some are backtracking and moving toward specifying things in code again. I just want to understand why you would use code instead of attributes. Do fluent interfaces warrant moving away from attributes and back to simply coding everything again? –  Tjaart Aug 2 '12 at 9:25

4 Answers 4

up vote 7 down vote accepted

Data annotations are static, for instance this method declaration cannot change at runtime:

  [MinLength(5)]
  [MaxLength(20,ErrorMessage="Le nom ne peut pas avoir plus de 20 caractères")]
  public new string Name { get; set; }

The fluent interface can be dynamic:

   if (longNamesEnabled)
   {
      modelBuilder.Entity<Manager>().Property(ma => ma.Name)
        .HasMaxLength(100);
   }
   else
   {
      modelBuilder.Entity<Manager>().Property(ma => ma.Name)
        .HasMaxLength(20);
   }

not to mention the code can be reused between properties.

share|improve this answer
    
why would you think that length (or any other property) of the same property would change in run-time ? –  Yusubov Aug 1 '12 at 19:22
    
@ElYusubov: I'd start with the scenarios where I didn't know the field length at coding time. –  Wyatt Barnett Aug 1 '12 at 19:39
    
@WyattBarnett: it may make sense to have field length as a variable only when domain parameters are fetched dynamically from some service or external un-typed source. However, dealing dynamically with domain properties would require defensive coding approach. –  Yusubov Aug 1 '12 at 19:54
1  
@ElYusubov you could have two properties that need to be exactly the same except for the length so I pass them into a function that sets them up dynamically. This is why the author called them more flexible. –  Garrett Hall Aug 1 '12 at 20:26
1  
@ElYusubov, you could make the field length a setting in the project settings, which feeds into the app.config or web.config. Then if a database field length changed, you could change the length in the .config file without a recompile and redeploy of the app. –  Kyralessa Aug 8 '12 at 18:54

Answer to your question is provided in the link.

Then you define your constraints applicable to your domain within this method programmatically.

Basically, it is more or less preference to use Attributes vs programmatic approach, where programmatic approach has more control over the entity. However, there a custom way of adding Attributes to decorate your model that you may look as well.

When using this approach you may even describe relations between tables and columns. Bottom line, if you are willing to have more fine-grain control over your domain you may use this new approach that comes with EF4.1.

However, for common scenarios of validation applying Attributes should work fine because it is robust to cover most cases; and in addition it might save you time.

share|improve this answer
    
Can you illustrate how the programmatic way gives you more control? I'm not really getting it at this point. –  Tjaart Aug 1 '12 at 14:39
    
For example, take this " .IsConcurrencyToken(true)" - how you would do this on a Attribute definition? –  Yusubov Aug 1 '12 at 14:41
    
[ConcurrencyCheck] <- which actually seems simpler –  Tjaart Aug 1 '12 at 14:55
    
good catch, how would you then describe " relations between tables and columns" ? –  Yusubov Aug 1 '12 at 15:02
    
[ForeignKey("PersonId")] <- like so, which probably isnt as straightforward as .HasForeignKey(t => t.ProjectId), although all that is needed is to let ForeignKey() take a lambda just like the fluent interface. It still does not explain why one is better than the other. –  Tjaart Aug 1 '12 at 15:14

My thought is that they recommend the fluent API for code first implementations because you explicitly describe how the relationships are created in the database. If you use data annotations the database created by Entity Framework may not be what you expect. Your initial example is very simple so, like you, I would just use the data annotation method.

share|improve this answer
    
Can you give an example of the databse not being what you expect and how a fluent interface prevents this from happening? –  Tjaart Aug 2 '12 at 7:27

I don't think that statement should be broadly applied; it is very specific to Code First. In Code First, data annotations include only a subset of the functionality that is available in the fluent API. In other words, there are certain model configurations that can only be done using the fluent API.

For example, here are some of the things that can't be specified using the annotations:

  • The precision of a DateTime property
  • The precision and scale of numeric properties
  • A String or Binary property as fixed-length
  • A String property as non-unicode
  • The on-delete behavior of relationships
  • Advanced mapping strategies

Personally, I tend to use the validation-related data annotations whenever possible since other technologies like MVC can also take advantage of these. For everything else, I prefer the fluent API.

share|improve this answer
    
Can you give an example of what can only be done using the fluent API? It would also be interesting to know why they have chose to do it this way. Im trying to understand fleunt APIs versus more conventional methods and entity framework is only an example. I want to know why they would prefer it over attributes. To me attributes seem more correct and readable. –  Tjaart Aug 2 '12 at 7:28
    
@Tjaart I've added some examples. While designing this, there were two main motivating principles. First, allow devs to choose. Some people view attributes as a violation of POCO, others like their declarative nature. Second, leverage existing attributes and only introduce new ones for common scenarios. You'll probably agree that the examples I gave above are relatively uncommon. –  bricelam Aug 8 '12 at 18:47
    
I did notice that OnDelete behaviour seems only to be available in the fluent API. Can you think of why they chose to do it this way? This is really what Im trying to get at with this question. The POCO violation may be a good reason if you are sharing the classes between projects. You may end up pulling in an entity framework dependency that you don't want if you use attributes! –  Tjaart Aug 13 '12 at 5:59
    
@Tjaart, I don't remember the exact reasons. I joined the team towards the end of the Code First feature and wasn't here for it's design. I'll see if I can get someone else from the team to weigh in though. –  bricelam Aug 13 '12 at 20:20

Your Answer

 
discard

By posting your answer, you agree to the privacy policy and terms of service.

Not the answer you're looking for? Browse other questions tagged or ask your own question.