1

I'm a Java guy and I'm working on learning the .Net realm. One of the things I'm learning is EF4, and I noticed this interesting thing. When you declare an entity with a 1:n relationship to another entity, you have to do something like this:

public int CategoryId { get; set; }
public virtual Category Category { get; set; }

My question is:

Is there a good reason that the framework requires both declarations?

In the Java world, the framework is smart enough to figure out what the primary key is and adds that record to the DB without having to have a separate field on the entity class. Why didn't .Net follow suit on this minor, but annoying, issue?

ametren
  • 2,186
  • 15
  • 19
  • 1
    You don't need both: http://stackoverflow.com/a/5282275/270591 + the link at the end of the answer. Two links more: http://stackoverflow.com/questions/4703378/ef4-independent-associations-why-avoid-them and http://stackoverflow.com/questions/9253234/what-is-the-point-of-creating-foreign-key-properties-when-using-entity-framework – Slauma Aug 08 '12 at 15:20
  • @Slauma, Thanks a ton for the extra info. That really helped shed some light -- I didn't realize these were different types of associations. If you'll post that as an answer, I'd like to accept it. – ametren Aug 08 '12 at 17:07
  • You should accept @Yuck's answer. He explained very clearly that you *can* work without FK properties with examples and everything, that was your question and he answered it. I only had a little veto to the "you shouldn't" use FK properties. But that's more an opinionated debate. You'll find equally often answers where people say "you should". – Slauma Aug 08 '12 at 18:35
  • Possible duplicate of [Code First: Independent associations vs. Foreign key associations?](https://stackoverflow.com/questions/5281974/code-first-independent-associations-vs-foreign-key-associations) – Michael Freidgeim Feb 16 '18 at 07:21

2 Answers2

1

You don't have to do that. In fact you shouldn't because you can leave your object in an inconsistent state. Let's say you have:

public class Category {
    public Int32 Id { get; set; }
}

public class SomeClass {
    public Int32 Id { get; set; }
    public virtual Category Category { get; set; }
}

This is valid. You just need to tell EF in its configuration how to find the foreign key. Based on the above it will try to use SomeClass.Category_Id, but you can change to it whatever you'd like.

EDIT: If you want to change the foreign key you can do so by adding a configuration class and adding it during the OnModelCreating event:

internal class ForSomeClassEntities : EntityTypeConfiguration<SomeClass> {
    public ForSomeClassEntities(String schemaName) {
        this.HasRequired(e => e.Category)
            .WithMany()
            .Map(map => map.MapKey("CategoryId"));
        this.ToTable("SomeClass", schemaName);
    }
}

In your overridden Context class:

protected override void OnModelCreating(DbModelBuilder modelBuilder) {
    base.OnModelCreating(modelBuilder);

    modelBuilder.Configurations
        .Add(new ForSomeClassEntities("SomeSchema"))
        ;
}

Using the same classes above this would tell EF to look for a foreign key property called SomeClass.CategoryId instead.

Yuck
  • 49,664
  • 13
  • 105
  • 135
  • Thanks, that's interesting -- so why do I see it the way I described it in all the tutorials? – ametren Aug 08 '12 at 13:57
  • 2
    @ametren: Because it's easier to work with. For that reason I disagree a bit with Yuck that "you shouldn't" use FK properties. – Slauma Aug 08 '12 at 15:26
  • @Slauma I'll agree to disagree and just add that because "*it's easier*" more often than not doesn't mean it's a good design practice. For example, WebForms is **really** easy to work with but the page model is horrendous. – Yuck Aug 08 '12 at 17:39
1

When you add a virtual Collection/Model to your model, Entity Framework automatically adds a <ClassName>Id field to it. Developers usually decide to explicitly declare the <ClassName>Id for readability purposes, so that other developers know explicitly that it is there (not relying on the convention over configuration). That is the case for tutorials, for example, because they want to make things clear.

Entity Framework is smart enough to use the existing <ClassName>Id if it has already been explicitly declared. Thus, addressing other responses to this topic, it doesn't lead to an inconsistent state. Also, from a performance perspective, it still fits the Lazy Loading pattern, because preloading an int (the ID, in this case) is still very fast (and not even remotely comparable to pre-loading a whole object).

Heitor Castro
  • 833
  • 6
  • 9