Reputation: 21420
Consider the following code:
// check record exists
Adjuster adj = new Adjuster();
if (db.Adjusters.Where(x => x.userID == user.id).Any())
{
adj = db.Adjusters.Where(x => x.userID == user.id).FirstOrDefault();
}
else
{
// create adjuster record
adj.id = Guid.NewGuid();
adj.userID = user.id;
db.Adjusters.InsertOnSubmit(adj);
}
Notice how I first call .Any()
and then I call .FirstOrDefault()
. This would be two separate queries to the database, right? How can I limit this to just one?
Now, consider the following code:
adj.isPropertyAdjuster = user.SomeEntity.someProperty;
adj.isCasualityLiabilityAdjuster = user.SomeEntity.someProperty;
adj.isLargeLossAdjuster = user.SomeEntity.someProperty;
db.SubmitChanges();
Using LINQ/ EF, I can access different entities which have relationships with eachother. But, doesn't this incur multiple calls to the database, each time I do this? For instance, are all three of these separate calls to the database?
adj.isPropertyAdjuster = user.SomeEntity.someProperty;
adj.isCasualityLiabilityAdjuster = user.SomeEntity.someProperty;
adj.isLargeLossAdjuster = user.SomeEntity.someProperty;
How can I limit this to a singular call to the database? I assume the only way is to instantiate an object like so:
SomeEntity obj = user.SomeEntity;
And, then call the properties like so:
adj.isPropertyAdjuster = obj.someProperty;
What are your thoughts?
Upvotes: 2
Views: 911
Reputation: 3289
For your first example, you can just call FirstOrDefault()
and leave Any()
out of the mix entirely:
Adjuster adj = db.Adjusters.Where(x => x.userID == user.id).FirstOrDefault();
if (adj == null)
{
// create adjuster record
adj.id = Guid.NewGuid();
adj.userID = user.id;
db.Adjusters.InsertOnSubmit(adj);
}
As for whether accessing a navigation property of an entity causes repeated round-trips to the database, the answer is (thankfully!) no. Depending on whether you have lazy loading enabled, the value of that property is either loaded along with the rest of the entity when it's first created, or else it's loaded the first time the property is accessed, and then cached for future use.
So, your example...
adj.isPropertyAdjuster = user.SomeEntity.someProperty;
adj.isCasualityLiabilityAdjuster = user.SomeEntity.someProperty;
adj.isLargeLossAdjuster = user.SomeEntity.someProperty;
...should only require at most one extra database query, and maybe not even that if you're using eager loading when you first load user
.
Upvotes: 2
Reputation: 5858
You can fix the first code with
Adjuster adj = db.Adjusters.Where(x => x.userID == user.id).FirstOrDefault();
if (adj == null)
{
// create adjuster record
adj = new Adjuster();
adj.id = Guid.NewGuid();
adj.userID = user.id;
db.Adjusters.InsertOnSubmit(adj);
}
And the second part is fine.
adj.isPropertyAdjuster = user.SomeEntity.someProperty;
adj.isCasualityLiabilityAdjuster = user.SomeEntity.someProperty;
adj.isLargeLossAdjuster = user.SomeEntity.someProperty;
db.SubmitChanges();
It shouldn't keep pulling someEntity from the database once it's loaded once. Also, it won't save anything until submit is called.
Upvotes: 2
Reputation: 13696
In regards to the first question:
var adjuster = db.Adjusters.FirstOrDefault(x => x.userID == user.id);
if (adjuster == null)
{
// create adjuster record
adjuster.id = Guid.NewGuid();
adjuster.userID = user.id;
db.Adjusters.InsertOnSubmit(adjuster);
}
In regards to the second, I believe EF caches data when it loads it, so your first access of user.SomeEntity.someProperty
will hit the DB, but all subsequent ones won't. You might want to look into Eager Loading, though.
Upvotes: 5