【发布时间】:2021-04-10 02:55:25
【问题描述】:
我正在编写一个网络应用程序来提交视频以供投票。 因为遇到了线程和数据库的问题,所以我从 core 3.0.1 升级到了 5.0.1
在我使用 services.AddDbContext 之前,它不起作用。现在我正在使用这个:
services.AddDbContextFactory<LogicDbContext>(
dbContextOptions => dbContextOptions
.UseMySql(serverVersion: ServerVersion.AutoDetect(connectionString), connectionString: connectionString)
.EnableSensitiveDataLogging()
.EnableDetailedErrors());
我的前端:
@page "/VideoPage"
@using WebProject.Data
@using Google.Apis.YouTube.v3.Data
@using Microsoft.AspNetCore.Identity
@using Microsoft.EntityFrameworkCore.Diagnostics
@using System.Security.Claims
@using Microsoft.AspNetCore.Identity.EntityFrameworkCore
@using Microsoft.EntityFrameworkCore
@inject YoutubeApiService YoutubeApiService;
@inject SignInManager<IdentityUser> SignInManager
@inject UserManager<IdentityUser> UserManager
@inject VideoManager VideoManager;
@inject VoteManager VoteManager;
@inject ApplicationDbContext _identityContext
<h1>Videos</h1>
<div style="visibility: @(busy?"visible":"hidden")">
<text>
Working...
</text>
</div>
<table class="table table-bordered">
<thead>
<tr>
<th>Thumbnail</th>
<th>Title</th>
<th>Channel</th>
<th>Date</th>
<th>Submitter</th>
<th>Votes</th>
</tr>
</thead>
<tbody>
@foreach (var video in VideosList)
{
<tr>
<td><img src="@video.Thumbnail" alt="Thumbnail not found" width="200" /></td>
<td><a href="https://www.youtube.com/watch?v=@video.VideoId">@video.Title</a></td>
<td>@video.ChannelTitle</td>
<td>@video.PublicationDate?.ToString("dd.MM.yyyy")</td>
<td>@_identityContext.Users.FirstOrDefault(u => u.Id == video.Submitter)?.UserName</td>
<td>
@(VoteManager.GetVotesAsync(video).Result)
</td>
</tr>
}
</tbody>
</table>
@code
{
public List<Videos> VideosList = new List<Videos>();
public bool busy;
protected override async void OnInitialized()
{
await RefreshList();
}
public async Task RefreshList()
{
busy = true;
VideosList = await VideoManager.GetVideosAsync();
busy = false;
this.StateHasChanged();
}
}
投票管理器
using System;
using System.Collections.Generic;
using System.Linq;
using System.Security.Claims;
using System.Threading.Tasks;
using WebProject.Data;
using Microsoft.AspNetCore.Identity;
using Microsoft.EntityFrameworkCore;
namespace WebProject.Data
{
public class VideoManager
{
private readonly IDbContextFactory<LogicDbContext> _contextFactory;
private readonly YoutubeApiService _youtubeApiService;
public VideoManager(IDbContextFactory<LogicDbContext> contextFactory, YoutubeApiService youtubeApiService)
{
_contextFactory = contextFactory;
_youtubeApiService = youtubeApiService;
}
public async Task<List<Videos>> GetVideosAsync()
{
var videos = new List<Videos>();
await using (var context = _contextFactory.CreateDbContext())
{
videos = await context.Videos.ToListAsync();
}
return videos;
}
}
}
在更换新版本和使用工厂之前,代码可以获取视频列表并显示出来。
现在,当我进入页面后,会显示“工作中...”消息,然后没有任何反应。在 VS 中调试时(我没有使用 VS 代码)它告诉我 VideoList 实际上已填充。忙也设置为假。
使用 this.StateHasChanged(); 什么都不做。有时整个网站都死机了,我什至无法点击链接。
有什么我没看到的吗?
【问题讨论】:
-
我在您的代码中发现了一些错误。您有 async void OnInitialized,这是不正确的。您应该覆盖异步任务 OnInitializedAsync()。然后,在确定列表已填充之前,您不应访问 VideoList。我建议你不要初始化它,因为你会为它分配一个新实例。最好将其保留为 null 并仅在 VideoList 有值时才渲染表。
-
您能解释一下为什么 VideoLists 应该为空吗?是性能问题吗?
-
i ran into problems with threading and databases,什么问题? EF Core 3.1 没有线程问题。如果您的代码使用错误的访问模式,升级 ORM 将无法修复它们。 DbContext 在设计上是非线程安全的。这不是要重用的连接,而是工作单元 -
i was using the services.AddDbContext, wich did not work什么不起作用?您使用的是哪个 MySQL 提供商?甲骨文的供应商因其错误和有点……延迟更新而臭名昭著。毕竟,Oracle 对支持 .NET Core 没有兴趣。这就是人们改用开源 Pomelo 驱动程序的原因。 -
更多问题 -
async void仅用于事件处理程序。OnInitialized不是事件处理程序。您需要改用async Task OnInitializedAsync。无法等待async void方法,这意味着即使RefreshList仍在运行,应用程序也会继续运行。当它完成时,页面已经被渲染并发送到浏览器
标签: entity-framework-core blazor blazor-server-side