简体   繁体   English

Blazor with Entity Framework 大量性能问题

[英]Blazor with Entity Framework massive performance issue

I am building a Blazor app using Radzen controls and code first Entity Framework.我正在使用 Radzen 控件和代码优先实体框架构建 Blazor 应用程序。 I have Customers, which have Orders which have OrderLines.我有客户,他们的订单有 OrderLines。 On my page I want to display three grids;在我的页面上,我想显示三个网格;

Grid 1 shows the Customers.网格 1 显示客户。

Grid 2 shows the Customer's Orders.网格 2 显示了客户的订单。

Grid 3 shows the line items for the selected order.网格 3 显示所选订单的行项目。

All goes well with Customers and Orders, my two grids work perfectly.客户和订单一切顺利,我的两个网格完美运行。 The problem arises when I add in OrderLines.当我添加 OrderLines 时出现问题。 Then it just appears to hang, and when I run it through Visual Studio and pause when it is "hanging" the code is at Program.cs, on the line CreateHostBuilder(args).Build().Run();然后它似乎挂起,当我通过 Visual Studio 运行它并在它“挂起”时暂停时,代码位于 Program.cs 的 CreateHostBuilder(args).Build().Run();

Here are my three classes for the objects (cut down for brevity)这是我的三个对象类(为简洁起见)

public class Customer
{
    [Required, Key, DatabaseGenerated(DatabaseGeneratedOption.None)]
    public Int32 invoice_account { get; set; }
    public List<Order> Orders { get; set; }
}

public class Order
{
    [Required, Key, DatabaseGenerated(DatabaseGeneratedOption.None)]
    public Int32 int_order_ref { get; set; }
    public Int32 invoice_account { get; set; }
    
    public List<OrderLine> OrderLines { get; set; }
    public Customer Customer { get; set; }
}

    public class OrderLine
{
    [Key]
    public Int32 id { get; set; }
    public Int32? line_no { get; set; }
    public string product_code { get; set; }

    public Order Order { get; set; }

}

Extract from ApplicationDbContext.cs;从 ApplicationDbContext.cs 中提取;

    public class ApplicationDbContext : IdentityDbContext
    {
        public ApplicationDbContext(DbContextOptions<ApplicationDbContext> options)
            : base(options)
        {
        }
        public DbSet<Customer> Customers { get; set; }
        public DbSet<Order> Orders { get; set; }
        public DbSet<OrderLine> OrderLines { get; set; }
    }

    protected override void OnModelCreating(ModelBuilder builder)
    {
        base.OnModelCreating(builder);

        builder.Entity<Order>()
            .HasOne(o => o.Customer)
            .WithMany(c => c.Orders)
            .HasForeignKey(o => o.invoice_account)
            .HasPrincipalKey(c => c.invoice_account);

        builder.Entity<OrderLine>()
            .HasOne(o => o.Order)
            .WithMany(ol => ol.OrderLines)
            .HasForeignKey(o => o.int_order_ref)
            .HasPrincipalKey(o => o.int_order_ref);
    }

Extract from my service, CustomerServiceList.cs从我的服务 CustomerServiceList.cs 中提取

public interface ICustomerListService
{
    Task<List<Customer>> Get();
}
public class CustomerListService : ICustomerListService
{
    private readonly ApplicationDbContext _context;

    public CustomerListService(ApplicationDbContext context)
    {
        _context = context;
    }

    public async Task<List<Customer>> Get()
    {
        // added in the where clause to try to get back just one record;
        return await _context.Customers.Where(c => c.invoice_account == 1320).ToListAsync();
    }
}

And finally my page;最后是我的页面;

@page "/customerorders"

@using BlazorApp.Data
@using Microsoft.EntityFrameworkCore

@inject ApplicationDbContext dbContext
@inject BlazorApp.Services.CustomerListService service

<h3>Customer Orders</h3>

@if (customers == null && order == null)
{
<p><em>Loading...</em></p>
}
else
{
<div class="row">
    <div class="col-md-4">
        <RadzenGrid ColumnWidth="400px" AllowFiltering="true" AllowPaging="true" PageSize="20" 
            AllowSorting="true" Data="@customers" TItem="Customer" Value="@customer" RowSelect="@(args => customer = args)">
            <Columns>
                <RadzenGridColumn Width="100px" TItem="Customer" Property="invoice_account" Title="Account No" />
                <RadzenGridColumn Width="300px" TItem="Customer" Property="account_name" Title="Customer" />
            </Columns>
        </RadzenGrid>
    </div>
    <div class="col-md-6">
        <RadzenCard Style="margin-bottom:20px">
            Company:
            <b>@customer.account_name</b>
        </RadzenCard>
        <RadzenTabs>
        <Tabs>
            <RadzenTabsItem Text="Order Details">
                <RadzenGrid AllowFiltering="true" AllowPaging="true" PageSize="8" AllowSorting="true" Data="@customer.Orders" TItem="Order" FilterCaseSensitivity="FilterCaseSensitivity.CaseInsensitive">
                    <Columns>
                        <RadzenGridColumn TItem="Order" Property="int_order_ref" Title="Order No" />
                        <RadzenGridColumn TItem="Order" Property="when_placed" Title="Placed On">
                            <Template Context="ord">
                                @String.Format("{0:dd'-'MMM'-'yy}", ord.when_placed)
                            </Template>
                        </RadzenGridColumn>
                        <RadzenGridColumn TItem="Order" Property="town" Title="Town" />
                        <RadzenGridColumn TItem="Order" Property="placed_by" Title="Placed By" />

                    </Columns>
                </RadzenGrid>
            </RadzenTabsItem>
        </Tabs>
    </RadzenTabs>
</div>
<div class="col-md-6">
    <RadzenGrid AllowFiltering="true" AllowPaging="true" PageSize="5" AllowSorting="true"Data="@order.OrderLines" TItem="OrderLine"  FilterCaseSensitivity="FilterCaseSensitivity.CaseInsensitive">
            <RadzenGridColumn TItem="OrderLine" Property="product_code" Title="Product Code"></RadzenGridColumn>
        </RadzenGrid>
    </div>
</div>
}

@code {

    Customer customer;
    List<Customer> customers;
    Order order;

    protected override async Task OnInitializedAsync()
    {
    
        customers = await service.Get();
    
        customer = customers.FirstOrDefault();

    }
}

In my Customer's table there are just over 10k rows.在我的客户表中,只有 10k 多行。 In my Orders table there are about 120k rows.在我的 Orders 表中,大约有 120k 行。 I have not populated the OrderLines table yet, which leads me to believe it's something in my code rather than the volume of data that is causing the issue.我还没有填充 OrderLines 表,这让我相信这是我的代码中的某些东西,而不是导致问题的数据量。

Update I was using a NavMenu link to my CustomerOrders page, and that was doing nothing, which led me to believe it was hanging.更新我正在使用 NavMenu 链接到我的 CustomerOrders 页面,但它什么也没做,这让我相信它挂了。 However, when I use the URL directly, I actually see an error;但是,当我直接使用 URL 时,我实际上看到了一个错误;

An unhandled exception occurred while processing the request.
InvalidOperationException: Cannot provide a value for property 'service' on type 'BlazorApp.Pages.CustomerOrders'. There is no registered service of type 'BlazorApp.Services.CustomerListService'.
Microsoft.AspNetCore.Components.ComponentFactory+<>c__DisplayClass5_0.<CreateInitializer>g__Initialize|2(IServiceProvider serviceProvider, IComponent component)

However, I have registered the service in Startup.cs thus;但是,我已经在 Startup.cs 中注册了该服务;

public void ConfigureServices(IServiceCollection services)
{
    services.AddTransient<ICustomerListService, CustomerListService>();
}

Update 2 Using the Navlink option, nothing happens when I click on the link.更新 2使用 Navlink 选项,当我单击链接时没有任何反应。 It's not until I refresh the page that the error is shown.直到我刷新页面才显示错误。 This can't be right can it?这不可能吧?

The answer, as usual, was a PICNIC error.像往常一样,答案是 PICNIC 错误。 Rather than injecting ICustomerListService to my page, I was injecting CustomerListService.我没有将 ICustomerListService 注入我的页面,而是注入了 CustomerListService。 Close, but no cigar.关闭,但没有雪茄。 Apologies to all for wasting your time.为浪费您的时间向所有人道歉。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM