我有First()
的两个查询,在检测First
,ToList
等方法时,EF总是针对数据库执行查询。
我的提交包括检查是否存在新的,然后检查用户是否已投票。
int theId = 33;
// Check if the new exists
var theNew =
await this.context
.News
.FirstAsync(x => x.Id == theId);
// The new doesn't exist
if (theNew == null)
{
return NotFound();
}
// Check if the user has voted the new
var voted =
await this.context
.UserVoteNews
.FirstAsync(x => x.UserId == this.UserId && x.NewId == theId);
if (voted == null)
{
return BadRequest(@"User didn't vote");
}
else
{
return Ok("User voted");
}
我已经尝试了
using (var dbContextTransaction = this.context.Database.BeginTransaction())
但服务器在此之前使用FirstAsync执行查询
await this.context.SaveChangesAsync();
dbContextTransaction.Commit();
答案 0 :(得分:1)
首先,我认为你误解了交易的目的。 (主要)用于修改数据库的事务。如果您只想读取所有内容,那么通常无需担心提交等等。
其次,在使用EF时,除了非常具体的用例外,您无需在所有中使用事务。你可以这样做:
using (var context = new Context())
{
// Stuff
context.SaveChanges();
}
我可以从你的例子中看出你有this.context
,你可能在整个班级中使用using
。推荐的方法是没有单个上下文,但在需要时创建一个新上下文,就像我刚刚展示的示例一样。这使您可以有效地使用EF的实体跟踪,从而无需使用事务。
在SaveChanges
块中,您可以执行涉及上下文,读取和写入的任何(有效)操作。 EF会跟踪任何和所有更改,并在您致电SaveChanges
时提交。当您致电using (var context = new Context()) // Create a new context for this
{
int theId = 33;
var theNew = await context.News.FirstAsync(x => x.Id == theId);
if (theNew != null)
{
var voted = await context.UserVoteNews.FirstAsync(x => x.UserId == this.UserId && x.NewId == theId);
// Returns are mutually exclusive so clean up by removing else clauses
if (voted != null)
{
return Ok("User voted");
}
return BadRequest(@"User didn't vote");
}
return NotFound();
}
时,不会执行读取查询,而是在转换后立即将其发送给提供商。
以下是您的代码的修订版本:
SaveChanges
请注意,我从不致电SaveChangesAsync
或@Component({
selector: "page-job-details",
templateUrl: "job-details.html",
animations: [
trigger('expand', [
state('ActiveGroup', style({opacity: '1', height: '*'})),
state('NotActiveGroup', style({opacity: '0', height: '0', overflow: 'hidden'})),
transition('ActiveGroup <=> NotActiveGroup', animate('300ms ease-in-out'))
])
]
})
ionViewDidLoad() {
this.items = [
{title: 'First Button', data: 'First-content', activeGroup: 'NotActiveGroup'},
{title: 'Second Button', data: 'Second-content', activeGroup: 'NotActiveGroup'},
{title: 'Third Button', data: 'Third-content', activeGroup: 'NotActiveGroup'}
];
}
expandItem(item){
this.items.map(listItem => {
if (item == listItem){
listItem.activeGroup = listItem.activeGroup === 'ActiveGroup' ? 'NotActiveGroup' : 'ActiveGroup';
}
return listItem;
});
}
,因为我们没有修改任何内容。
答案 1 :(得分:1)
仅使用实体框架就无法实现这种行为。
但是,某些第三方库允许这样做。
免责声明:我是该项目的所有者Entity Framework Plus
此库允许您Defer
查询Immediate
此类First
方法。
该库还允许您通过Future
功能批量处理多个查询。因此,所有挂起的查询都在相同的commit
或数据库往返中执行。
var theNewDeferred = context.News.DeferredFirst(x => x.Id == theId).FutureValue();
var votedDeferred = context.UserVoteNews.DeferredFirst(x => x.UserId == this.UserId && x.NewId == theId).FutureValue();
// Both FutureValue will be executed in the same database round-trip
var theNew = await theNewDeferred.ValueAsync();
if(theNew != null)
{
}
答案 2 :(得分:0)
要么我不了解你,要么你不理解EF。一旦查询生效,读取操作将立即发送到数据库,例如通过调用FirstAsync
。您似乎认为只要您调用SaveChangesAsync
或Commit
,就会执行读取查询。 SaveChangesAsync
将在数据库上启动写入操作。像INSERT,DELETE和UPDATE一样。