Reputation: 91
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
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
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
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