AD700
AD700

Reputation: 91

When using Entity Framework, should I set the navigation property or foreign key property, when setting the FK?

I have some code that looks like this:

var customer = dbcontext.Customers.Find(1);

var order = new Order();
order.CustomerId = customer.Id;

dbcontext.Orders.Add(order);
dbcontext.SaveChanges();

Is it best practice to this or set the relationship by setting the navigation property:

var customer = dbcontext.Customers.Find(1);

var order = new Order();
order.Customer = customer; //Set navigation prop as opposed to FK field

dbcontext.Orders.Add(order);    
dbcontext.SaveChanges();

What approach is considered best practice or preferred?

Upvotes: 9

Views: 3952

Answers (3)

JerMah
JerMah

Reputation: 763

Are you worried about performance?

A) No: if you are not then you shouldn't worry about this and always use navigation properties for readability.

B) Yes: Then you should have queried the customer with a .Select(c => c.id) to begin with and still only use navigation properties. In this case it is clear you will not be updating any other field of Customer because you are comparing it to only setting the FK.

var customer = dbcontext.Customers
                        .Find(1)
                        .Select(b => new Customer { Id = b.Id } );

var order = new Order();
order.Customer = customer; //Set navigation prop as opposed to FK field

dbcontext.Orders.Add(order);    
dbcontext.SaveChanges();

C) Yes very much: In this simplified example you gave, it's pointless to query the Customer with it's PK to then only use the PK. You already have all the info you need, you could have set it directly in the Order. However we will have to attach it manually or efcore will try to create a Customer that already exists.

var order = new Order();
order.Customer = new Customer { Id = 1 };
dbcontext.Attach<Customer>(order.Customer); 

dbcontext.Orders.Add(order);    
dbcontext.SaveChanges();

Upvotes: 4

Steve Py
Steve Py

Reputation: 34908

My recommendation is that entities should expose navigation properties or foreign keys, but never both. If you use a navigation property use shadow properties (EF Core) for the FK.

The reason is Updates and ensuring that an entity is always in a complete state. When you have both then EF doesn't sync them until SaveChanges() is called. This can lead to bugs if code expecting one or the other is called between an update and SaveChanges(). (Validation calls, etc.) I.e. you set the FK, but then some code checks the Nav property.

I favour navigation properties in most cases, but use FKs for references I don't really ever need to load (beyond satisfying data integrity) such as Constants/Enum keys, or in cases where I want max performance for something like bulk update operations.

Upvotes: 5

Claudio Valerio
Claudio Valerio

Reputation: 2342

If your code needs the customer object for further operations, both ways are ok, EF proxies will take care of everything.

Otherwise, by setting the FK you can avoid querying the Customers dbset to retrieve customer information, improving operation efficiency (you already have the customer id). I usually prefer this way.

Upvotes: 1

Related Questions