db.Entry().Entity will always return you a POCO, and will not return the proxy object that handles the implementation of virtual navigation properties:
var o = db.Entry(myPoco).Entity; // always returns a POCO
You will normally get a proxy object instead of a POCO when calling Find()
or Where()
against the database context. However, within the context in which an object is first added to the database, these methods will (unexpectedly?) return the POCO instead of the proxy object. You actually have to leave the context and open a new one to get the proxy:
// create a new POCO object, and connect to it to another object already in the DB
MyPoco myPoco = new MyPoco();
myPoco.MyOtherPocoId = myPoco2.MyOtherPocoId; // make reference to existing object
using (var db = new MyContext())
{
// Add myPoco to database.
db.MyPocos.Add(myPoco);
db.SaveChanges();
// One would think you get a proxy object here, but you don't: just a POCO
var test10 = db.MyPocos.Find(myPoco.Id); // returns a MyPoco
var test11 = db.MyPocos.Where(x => x.Id == myPoco.Id).First(); // returns a MyPoco
var test12 = db.Entry(myPoco).Entity; // returns a MyPoco
// ...so, you can't access the referenced properties through virtual navigation properties:
MyOtherPoco otherPoco1 = myPoco.Poco2; // returns NULL
}
// leave the context and build a new one
using (var db = new MyContext())
{
// Now, the same Find() and Where() methods return a proxy object
var test20 = db.MyPocos.Find(myPoco.Id); // returns a proxy object
var test21 = db.MyPocos.Where(x => x.Id == myPoco.Id).First(); // returns a proxy object
// ...which means the virtual properties can be accessed as expected:
MyOtherPoco otherPoco = myPoco.Poco2; // works as expected
// Note that db.Entry().Entity still returns a POCO:
var test22 = db.Entry(myPoco).Entity; // returns a MyPoco
}
There may be some magic incantation to make the context in which the object is added give you back a proxy object, but I haven't come across it.