请考虑以下代码:
// 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);
}
请注意我首先拨打.Any()
,然后拨打.FirstOrDefault()
。这将是对数据库的两个单独查询,对吧?我怎样才能将其限制为一个?
现在,请考虑以下代码:
adj.isPropertyAdjuster = user.SomeEntity.someProperty;
adj.isCasualityLiabilityAdjuster = user.SomeEntity.someProperty;
adj.isLargeLossAdjuster = user.SomeEntity.someProperty;
db.SubmitChanges();
使用LINQ / EF,我可以访问与彼此有关系的不同实体。但是,每次执行此操作时都不会对数据库进行多次调用吗?例如,这些是对数据库的所有三个单独调用吗?
adj.isPropertyAdjuster = user.SomeEntity.someProperty;
adj.isCasualityLiabilityAdjuster = user.SomeEntity.someProperty;
adj.isLargeLossAdjuster = user.SomeEntity.someProperty;
如何将此限制为对数据库的单一调用?我假设唯一的方法是像这样实例化一个对象:
SomeEntity obj = user.SomeEntity;
然后,调用这样的属性:
adj.isPropertyAdjuster = obj.someProperty;
你有什么想法?
答案 0 :(得分:5)
关于第一个问题:
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);
}
关于第二个,我相信EF在加载数据时会缓存数据,因此您首次访问user.SomeEntity.someProperty
将会访问数据库,但所有后续访问都不会。不过,您可能希望查看Eager Loading。
答案 1 :(得分:2)
对于您的第一个示例,您只需致电FirstOrDefault()
并完全离开Any()
:
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);
}
至于访问实体的导航属性是否导致重复往返数据库,答案是(谢天谢地!)no。根据您是否启用了延迟加载,该属性的值将在首次创建时与实体的其余部分一起加载,或者在第一次访问该属性时加载,然后缓存以供将来使用。
所以,你的例子......
adj.isPropertyAdjuster = user.SomeEntity.someProperty;
adj.isCasualityLiabilityAdjuster = user.SomeEntity.someProperty;
adj.isLargeLossAdjuster = user.SomeEntity.someProperty;
...最多只需要一个额外的数据库查询,如果您在第一次加载user
时使用了预先加载,则可能不会这样。
答案 2 :(得分:2)
您可以使用
修复第一个代码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);
}
第二部分没问题。
adj.isPropertyAdjuster = user.SomeEntity.someProperty;
adj.isCasualityLiabilityAdjuster = user.SomeEntity.someProperty;
adj.isLargeLossAdjuster = user.SomeEntity.someProperty;
db.SubmitChanges();
一旦加载一次,它就不应该继续从数据库中提取一些内容。此外,在调用提交之前,它不会保存任何内容。