0
votes

I am using latest .NET Core technology-stack include: Microsoft Visual Studio Community 2019 Preview Version 16.7.0 Preview 6.0 ; .NET Core 5.0.100-preview.7.20366.6 ; Microsoft.EntityFrameworkCore.SqlServer version 5.0.0-preview.7.20365.15 ; Microsoft SQLServer 2019 for my Blazor server-side web-app.

In Startup.cs I have

services.AddDbContext<ApplicationDbContext>(options => options.UseSqlServer(Configuration.GetConnectionString("DefaultConnection")));
services.AddSingleton<SysAutoIdController>();

In file SystemInformation.razor

@page "/system_information"
@using myproj.Forms
@using myproj.DTO
@using myproj.Models

@inject myproj.Data.ApplicationDbContext dbContext;
@inject myproj.Controllers.SysAutoIdController sysAutoIdController;


<h3>System information</h3>

database size = @foo

@code {
   string fooTemp = sysAutoIdController.getDbSize(dbContext);
   string foo = foo2.ToString();
}

Controller, file SysAutoIdController.cs

using System;
using System.Collections.Generic;
using System.Linq;
using System.Threading.Tasks;
using Microsoft.AspNetCore.Mvc;
using myproj.Data;
using myproj.Models;
using Microsoft.EntityFrameworkCore;

namespace myproj.Controllers
{
    public class SysAutoIdController : Controller
    {
        ApplicationDbContext db = new ApplicationDbContext();

        public string getDbSize(ApplicationDbContext db2)
        {
            var foo = db2.SysautoId.FromSqlRaw("" +
        " SELECT a.dbdisk " +
        " FROM " +
            "(SELECT sys.databases.name AS dbname, " +
              "      CONVERT(VARCHAR, SUM(SIZE) * 8 / 1024) + \' MB\' AS dbdisk " +
            " FROM sys.databases " +
           " JOIN sys.master_files ON sys.databases.database_id = sys.master_files.database_id " +
           " GROUP BY sys.databases.name) a " +
        " WHERE a.dbname = \'mydatabase\' ");
            return foo.ToString();
        }
    }
}

Error

enter image description here

CS0236: A filed initializer cannot reference the non-static field, method, or property 'SystemInformation.sysAutoIdController'

CS0236: A field initializer cannot reference the non-static field, method, or property 'SystemInformation.dbContext'

How to run something like sysAutoIdController.getDbSize(dbContext); at razor page success?

2

2 Answers

1
votes

A "field initializer" runs immediatley before the constructor of your object. In the case of a Blazor page that is just before any injections take place. The C# syntax will not allow you to use anything from the still unconstructed instance.

@code {
   string fooTemp; // = sysAutoIdController.getDbSize(dbContext);
   string foo => foo2?.ToString();  // string.ToString() is a little pointless

    protected override async Task OnInitializedAsync()
    {
       // see if you can make getDbSize async, that would be better
       fooTemp = sysAutoIdController.getDbSize(dbContext);
    }
}

Side note: a DbContext is a valuable resource you need to manage. Let it be injected in the Controller, you already have everything registered:

public class SysAutoIdController : Controller
{
   public SysAutoIdController(ApplicationDbContext db)
   {
      _db = db;
   }

   ... 
}

    
0
votes

Thank to the answer of Henk Holterman at https://stackoverflow.com/a/63213132/3728901

(1) Controller

using myproj.Data;

public class SysAutoIdController : Controller
{

   ApplicationDbContext _db;
    
   public SysAutoIdController(ApplicationDbContext db)
   {
      _db = db;
   }

   public string getDbSize()
        {
            var foo = _db.SysautoId.FromSqlRaw("" +
        " SELECT a.dbdisk " +
        " FROM " +
            "(SELECT sys.databases.name AS dbname, " +
              "      CONVERT(VARCHAR, SUM(SIZE) * 8 / 1024) + \' MB\' AS dbdisk " +
            " FROM sys.databases " +
           " JOIN sys.master_files ON sys.databases.database_id = sys.master_files.database_id " +
           " GROUP BY sys.databases.name) a " +
        " WHERE a.dbname = \'mydatabase\' ");
            return foo.ToString();
    }

}

(Indeed, raw SQL not work, I tried by a simple query, I will fix it later.)

(2) I don't inject controller in Startup.cs

//services.AddSingleton<SysAutoIdController>(); // Important: must comment.

(3) At razor file

@page "/system_information"
@using myproj.Forms
@using myproj.DTO
@using myproj.Models


@inject myproj.Data.ApplicationDbContext dbContext;
@*@inject myproj.Controllers.CommonController commonController;*@  @*must comment*@


Database size: @fooTemp

@code {
    string fooTemp;

    protected override async Task OnInitializedAsync()
    {
        myproj.Controllers.CommonController Cc = new Controllers.CommonController(dbContext);
        // see if you can make getDbSize async, that would be better
        fooTemp = Cc.getDbSize();
    }

}

Then it works!

Really, I don't understand the problem deeply, why it work, someone can leave comment or answer for me more information.