无法在Blazor剃刀页面(Blazor服务器端)内注入Controller,DbContext

时间:2020-08-02 01:37:46

标签: c# asp.net-core entity-framework-core blazor blazor-server-side

我正在使用最新的.NET Core技术堆栈包括:Microsoft Visual Studio Community 2019预览版 16.7.0版预览6.0版; .NET Core 5.0.100-preview.7.20366.6; Microsoft.EntityFrameworkCore.SqlServer版本5.0.0-preview.7.20365.15;适用于我的Blazor服务器端网络应用程序的Microsoft SQLServer 2019。

我在Startup.cs

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

在文件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();
}

控制器,文件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();
        }
    }
}

错误

enter image description here

CS0236:归档的初始化程序无法引用非静态字段, 方法或属性“ SystemInformation.sysAutoIdController”

CS0236:字段初始化程序无法引用非静态字段, 方法或属性“ SystemInformation.dbContext”

如何在剃刀页面成功运行sysAutoIdController.getDbSize(dbContext);之类的东西?

2 个答案:

答案 0 :(得分:1)

“字段初始化程序”在对象的构造函数之前立即运行。在Blazor页面的情况下,即在进行任何注入之前。 C#语法不允许您使用尚未构造的实例中的任何内容。

<body>

  <table border="1px" style="width:600px; line-height:40px;">
    <thead>
      <tr>
        <th>Name</th>
        <th>Email</th>
        <th>FT</th>
        <th>ST</th>

      </tr>
    </thead>
    <tbody>
      <?php
                while($row = mysqli_fetch_assoc($result)) { ?>
        <tr>
          <td>
            <?php echo $row['name'];?>
          </td>
          <td>
            <?php echo $row['email']; ?>
          </td>
          <td>
            <div class="chartpie" id='mypiechart'></div>
            <script type='text/javascript' src='https://www.gstatic.com/charts/loader.js'></script>
            <script type='text/javascript'>
              google.charts.load('current', {
                'packages': ['corechart']
              });
              google.charts.setOnLoadCallback(drawChart);

              function drawChart() {
                var data = google.visualization.arrayToDataTable([
                  ['Category', 'Score'],
                  <?php 
                                    echo "['Mind',".$row['m']."],";
                                    echo "['Will',".$row['w']."],";
                                    echo "['Emotion',".$row['e']."],";
                                    ?>
                ]);

                var options = {
                  legend: {
                    textStyle: {
                      color: '#000000'
                    }
                  },
                  backgroundColor: 'transparent',
                  'width': 550,
                  'height': 470,
                  colors: ['#808080', '#FF0000', '#0000FF']
                };

                var chart = new google.visualization.PieChart(document.getElementById('mypiechart'));
                chart.draw(data, options);
              }
            </script>

          </td>
          <td>
            <div id='piechart'></div>
            <script type='text/javascript' src='https://www.gstatic.com/charts/loader.js'></script>
            <script type='text/javascript'>
              google.charts.load('current', {
                'packages': ['corechart']
              });
              google.charts.setOnLoadCallback(drawChart);

              function drawChart() {
                var data = google.visualization.arrayToDataTable([
                  ['Category', 'Score'],
                  <?php 

                                    echo "['Reformer',".$row['p']."],";
                                    echo "['Server',".$row['s']."],";
                                    echo "['Teacher',".$row['t']."],";
                                    echo "['Encourager',".$row['ex']."],";
                                    echo "['Giver',".$row['g']."],";
                                    echo "['Administrator',".$row['a']."],";
                                    echo "['Compassion',".$row['c']."],";
                                    
                                    ?>
                ]);

                var options = {
                  backgroundColor: 'transparent',
                  'width': 550,
                  'height': 400,
                  colors: ['#c78626', '#7c499e', '#8690c2', '#e6e62e', '#4075c9', '#558a48', '#ad4a31']
                };

                var chart = new google.visualization.PieChart(document.getElementById('piechart'));
                chart.draw(data, options);
              }

              $(document).ready(function() {
                $(".chartpie").click(function() {
                  var ChartID = $(this).prop('id').replace("Image", "");
                  // you can directly use value imgID variable if its same. or you 
                  //can use from ItemID inner html
                  var yourValue = $("#ItemID" + ChartID).html();
                  alert(yourValue);
                })
              });
            </script>
          </td>

          <tr>
            <?php } ?>
    </tbody>
  </table>
</body>

侧面说明:DbContext是您需要管理的宝贵资源。让它注入Controller中,您已经注册了所有内容:

@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);
    }
}

答案 1 :(得分:0)

感谢汉克·霍尔特曼https://stackoverflow.com/a/63213132/3728901

的回答

(1)控制器

FHIR version R4 v4.0.1

(实际上,原始SQL不起作用,我通过一个简单的查询尝试过,稍后将对其进行修复。)

(2)我没有在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(); } }

中注入控制器
Startup.cs

(3)在剃刀文件上

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

然后它起作用了!

真的,我对这个问题并不十分了解,它为什么起作用,有人可以给我留言或回答更多信息。