博客 (231)

在数据库连接字符串可设置是否将 tinyint(1) 映射为 bool,否则为 sbyte:

TreatTinyAsBoolean=false/true

tinyint(1) 一般用于表示 bool 型字段,存储内容为 0 或 1,但有时候也用来存储其它数字。

以 Discuz! 的表 pre_forum_post 为例,字段 first 和 invisible 都是 tinyint(1),但 first 只储存 0 和 1,invisible 却有 -1、-5 之类的值。

因此我们一般设置 TreatTinyAsBoolean=false,程序中 first 与 invisible 均以 sbyte 处理。


设置 TreatTinyAsBoolean=true 后,EF 或 EF Core 自动将该类型映射为 bool,方便在程序中作进一步处理。

一旦设置 TreatTinyAsBoolean=true,那么所有查询结果中 tinyint(1) 字段的返回值永远只有 1 和 0(即 True/False),即使真实值为 -1,也返回 1。

因为我们必须在确保所有的 tinyint(1) 类型字段都仅表示布尔值是才设置 TreatTinyAsBoolean=true。

一旦部分 tinyint(1) 类型字段用于存放 0 和 1 以外的数,那么就应该设置 TreatTinyAsBoolean=false。


在数据库优先的项目中,以 TreatTinyAsBoolean=false 生成数据模型后,可将明确为布尔类型的字段改为 bool。列出 MySQL 数据库中所有表所有字段中类型为 tinyint(1) 的字段值


以 .edmx 为例:

在项目中搜索该字段名,在搜索结果中找到 .edmx 文件中的两处。

.edmx 文件中的注释已经表明其包含 SSDL、CSDL、C-S mapping 三块内容,

在 SSDL content 下方找到该字段:

<Property Name="字段名" Type="tinyint" Nullable="***" />

改为

<Property Name="字段名" Type="bool" Nullable="***" />


在 CSDL content 下方找到该属性:

<Property Name="属性名" Type="SByte" Nullable="***" />

改为

<Property Name="属性名" Type="Boolean" Nullable="***" />

在解决方案管理器中展开 .edmx ->库名.tt -> 表名.cs 文件,

将模型类中的属性

public sbyte invisible { get; set; }

改为

public bool invisible { get; set; }

或 sbyte? 改为 bool?。


在 EF Core 中,直接打开对应数据表的 .cs 文件,更改属性类型即可。


相关报错:

错误: 指定的成员映射无效。类型中的成员的类型“Edm.SByte[Nullable=False,DefaultValue=]”与类型中的成员的“MySql.bool[Nullable=False,DefaultValue=]”不兼容。

InvalidOperationException: The property '***' is of type 'sbyte' which is not supported by the current database provider. Either change the property CLR type, or ignore the property using the '[NotMapped]' attribute or by using 'EntityTypeBuilder.Ignore' in 'OnModelCreating'.

尝试先连接一次能解决此问题(概率),非常的莫名其妙:

using Data.Discuz.db_bbs2021Context dbd = new();
var conn = dbd.Database.GetDbConnection();
conn.Open();
conn.Close();


参考:

https://mysqlconnector.net/connection-options/

https://stackoverflow.com/questions/6656511/treat-tiny-as-boolean-and-entity-framework-4


2023年1月注:本文适用于 Pomelo.EntityFrameworkCore.MySql 6.0,升级到 7.0 后会出现:

System.InvalidOperationException:“The 'sbyte' property could not be mapped to the database type 'tinyint(1)' because the database provider does not support mapping 'sbyte' properties to 'tinyint(1)' columns. Consider mapping to a different database type or converting the property value to a type supported by the database using a value converter. See https://aka.ms/efcore-docs-value-converters for more information. Alternately, exclude the property from the model using the '[NotMapped]' attribute or by using 'EntityTypeBuilder.Ignore' in 'OnModelCreating'.”

解决方法:https://xoyozo.net/Blog/Details/the-sbyte-property-could-not-be-mapped-to-the-database-type-tinyint-1

xoyozo 5 年前
7,455

安装 Nuget 包:

BuildBundlerMinifier


项目根目录创建绑定配置文件:bundleconfig.json

示例:

[
  {
    "outputFileName": "wwwroot/css/site.min.css",
    "inputFiles": [
      "wwwroot/css/site.css",
      "wwwroot/css/custom.css"
    ]
  },
  {
    "outputFileName": "wwwroot/js/site.min.js",
    "inputFiles": [
      "wwwroot/js/site.js"
    ],
    "minify": {
      "enabled": true,
      "renameLocals": true
    },
    "sourceMap": false
  }
]

配置文件中所有路径都相对于项目根目录(而非静态文件根目录 wwwroot),因此配置的路径都要以“wwwroot”开头。

outputFileName 是压缩合并后的文件,inputFiles 是被压缩合并的原始文件集合。

对于 js 配置部分,minify.enabled 配置是否缩小,renameLocals 配置是否修改变量名,sourceMap 配置是否生成 map 映射文件。


引用示例:

<link rel="stylesheet" href="~/css/site.min.css" asp-append-version="true" />

asp-append-version 表示是否在引用路径添加版本参数,可实现在文件有修改时及时在客户端浏览器中生效。


* 注意:有时候“生成”不一定生效,“重新生成”肯定会生效。


更多高级用法请参考官方文档

xoyozo 5 年前
7,351

ASP.NET Core 缓存 Caching 提供了包括但不限于以下几种存储方式:

内存缓存:https://xoyozo.net/Blog/Details/aspnetcore-memory-cache

SQL Server 缓存:https://xoyozo.net/Blog/Details/aspnetcore-sql-cache

Redis 缓存:https://xoyozo.net/Blog/Details/aspnetcore-redis-cache

MySQL 缓存:https://xoyozo.net/Blog/Details/aspnetcore-mysql-cache


Nuget 安装:Microsoft.Extensions.Caching.SqlServer

执行 .NET Core CLI 命令,在数据库中创建表“TestCache”

dotnet sql-cache create "数据库连接字符串" dbo TestCache

若提示

找不到 "dotnet sql-cache" 命令,请运行以下命令进行安装

则运行

dotnet tool install --global dotnet-sql-cache

表和索引创建成功提示:

Table and index were created successfully.

表结构:

image.png

在 Startup.cs 文件的方法 ConfigureServices() 中添加:

services.AddDistributedSqlServerCache(options =>
{
    options.ConnectionString = "数据库连接字符串";
    options.SchemaName = "dbo";
    options.TableName = "TestCache";
});

在控制器中注入 IDistributedCache:

public class TestController : Controller
{
    private readonly IDistributedCache cache;

    public TestController(IDistributedCache cache)
    {
        this.cache = cache;
    }

    public IActionResult Index()
    {
        string k = "count";
        int v = Convert.ToInt32(cache.GetString(k));
        v++;
        cache.SetString(k, v.ToString());
        return Content(v.ToString());
    }
}

结果:

image.png

更多用法详见官方文档:https://docs.microsoft.com/zh-cn/aspnet/core/performance/caching/distributed?view=aspnetcore-3.0


若要实现将 Session 保存至 SQL Server 中,参此文:https://xoyozo.net/Blog/Details/aspnetcore-session-sql

xoyozo 5 年前
6,971

ASP.NET Core 缓存 Caching 提供了包括但不限于以下几种存储方式:

内存缓存:https://xoyozo.net/Blog/Details/aspnetcore-memory-cache

SQL Server 缓存:https://xoyozo.net/Blog/Details/aspnetcore-sql-cache

Redis 缓存:https://xoyozo.net/Blog/Details/aspnetcore-redis-cache

MySQL 缓存:https://xoyozo.net/Blog/Details/aspnetcore-mysql-cache


Nuget 安装:Microsoft.Extensions.Caching.StackExchangeRedis

在 Startup.cs 文件的方法 ConfigureServices() 中添加:

services.AddStackExchangeRedisCache(options =>
{
    // 连接字符串
    options.Configuration = "192.168.111.134,password=aW1HAyupRKmiZn3Q";
    // 键名前缀
    options.InstanceName = "xoyozo_";
});

在控制器中注入 IDistributedCache:

public class TestController : Controller
{
    private readonly IDistributedCache cache;

    public TestController(IDistributedCache cache)
    {
        this.cache = cache;
    }

    public IActionResult Index()
    {
        string k = "count";
        int v = Convert.ToInt32(cache.GetString(k));
        v++;
        cache.SetString(k, v.ToString());
        return Content(v.ToString());
    }
}

结果:

image.png

更多用法详见官方文档:https://docs.microsoft.com/zh-cn/aspnet/core/performance/caching/distributed?view=aspnetcore-3.0


注:.NET 6 已不支持 Redis on Windows 3.0。


经过以上配置,Session 也会保存到 Redis 中,键名是 前缀_Guid 格式。

关于 Session,参此文:https://xoyozo.net/Blog/Details/aspnetcore-session-redis

xoyozo 5 年前
6,265

要将 ASP.NET Core 中的会话存储在 Redis 中,可以按照以下步骤进行操作:

安装必要的 NuGet 包:

首先,确保你已经安装了 Microsoft.Extensions.Caching.StackExchangeRedis 包,这是与 Redis 集成的主要包。

在 Visual Studio 中,你可以使用 NuGet 包管理器控制台执行以下命令:

Install-Package Microsoft.Extensions.Caching.StackExchangeRedis

配置 Redis 连接:

在你的 ASP.NET Core 应用程序的 Startup.cs 文件中,使用 AddStackExchangeRedisCache 方法配置 Redis 连接。在 ConfigureServices 方法中添加以下代码:

services.AddStackExchangeRedisCache(options =>
{
    options.Configuration = "your_redis_connection_string";
    options.InstanceName = "your_instance_name";
});

请将 "your_redis_connection_string" 替换为你的 Redis 连接字符串,并将 "your_instance_name" 替换为你的 Redis 实例名称。

配置会话中间件:

Startup.csConfigureServices 方法中,使用 AddSession 方法配置会话中间件,并在 Configure 方法中启用它:

services.AddSession(options =>
{
    options.IdleTimeout = TimeSpan.FromMinutes(30); // 设置会话超时时间
});

使用会话中间件:

Startup.csConfigure 方法中,在调用 app.UseRouting() 之前添加以下代码来启用会话中间件:

app.UseSession();

在控制器或视图中使用会话:

现在,你可以在控制器或视图中使用会话来存储和检索数据。例如:

// 存储数据到会话
HttpContext.Session.SetString("Key", "Value");

// 从会话中检索数据
var value = HttpContext.Session.GetString("Key");

通过这种方式,你可以将会话数据存储在 Redis 中,而不是默认的内存中。

请确保根据你的应用程序的需求进行适当的配置和安全措施,以确保 Redis 连接的安全性和可靠性。

xoyozo 5 年前
6,322

打开 appsettings.json,添加一项配置(如下方示例中的“SiteOptions”项)

image.png

* 注意,如需配置开发环境与生产环境不同的值,可单独在 appsettings.Development.json 文件中配置不同项,格式层次须一致;


C# 中习惯用强类型的方式来操作对象,那么在项目根目录添加类(类名以 SiteOptions为例),格式与 appsettings.json 中保持一致:

public class SiteOptions
{
    public ERPOptions ERP { get; set; }
    public WeixinOpenOptions WeixinOpen { get; set; }
    public WeixinMPOptions WeixinMP { get; set; }
    public SMSOptions SMS { get; set; }
    public AliyunOSSOptions AliyunOSS { get; set; }

    /// <summary>
    /// 单个文件上传的最大大小(MB)
    /// </summary>
    public int MaxSizeOfSigleFile_MB { get; set; }

    /// <summary>
    /// 单个文件上传的最大大小(字节)
    /// </summary>
    public int MaxSizeOfSigleFile_B => MaxSizeOfSigleFile_MB * 1024 * 1024;

    public class ERPOptions
    {
        public int ChannelId { get; set; }
        public string AppKey { get; set; }
    }
    public class WeixinOpenOptions
    {
        public string AppId { get; set; }
        public string AppSecret { get; set; }
    }
    public class WeixinMPOptions
    {
        public string AppId { get; set; }
        public string AppSecret { get; set; }
    }
    public class SMSOptions
    {
        public string AppKey { get; set; }
    }
    public class AliyunOSSOptions
    {
        public string Endpoint { get; set; }
        public string AccessKeyId { get; set; }
        public string AccessKeySecret { get; set; }
        public string BucketName { get; set; }

        /// <summary>
        /// 格式://域名/
        /// </summary>
        public string CdnUrl { get; set; }
    }
}


在 Startup 中注入 IConfiguration,并在 ConfigureServices() 方法中添加服务(注意使用 GetSection() 映射到自命名的“SiteOptions”项)

image.png


在控制器中使用

在控制器类中键入“ctor”,并按两次 Tab 键,创建构造函数

image.png

在构造函数中注入“IOptions”,并在 Action 中使用

using Microsoft.Extensions.Options;

public class TestController : Controller
{
    private readonly IOptions<SiteOptions> options;

    public TestController(IOptions<SiteOptions> options)
    {
        this.options = options;
    }

    public IActionResult Index()
    {
        return View(options.Value.ERP.ChannelId.ToString());
    }
}


在视图中使用

@using Microsoft.Extensions.Options
@inject IOptions<SiteOptions> options

@options.Value.ERP.ChannelId


xoyozo 5 年前
3,963

在“对象管理器”中选中一个或多个对象,

选择菜单“文件”,“导出”,

在导出对话框中勾选“只是选定的”,并指定路径和格式,

完成。


xoyozo 5 年前
7,375

本文环境:CentOS 7、nginx 1.16、ASP.NET Core 3.0


  1. 安装 nginx,可以使用宝塔面板。

    创建网站,保证网站静态页面能够正常访问。

    必要时配置 SSL 证书。

  2. 安装 ASP.NET Core 运行时:

    安装说明见:https://dotnet.microsoft.com/download,切换到 Linux,选择 Install .NET Core Runtime

    选择操作系统,按页面说明安装即可。

  3. 发布一个 ASP.NET Core 项目到网站目录,运行应用程序:

    dotnet 应用的程序集文件名.dll

    必须先 cd 到项目所在目录再执行,否则“Content root path”不会指向网站根目录,从而导致无法访问静态文件。

    image.png

    观察到端口为 5000(默认),该 Url 用于下一步设置反向代理。

  4. 配置 nginx 反向代理:(使用宝塔面板时建议使用面板中提供的“反向代理”功能)

    location / {
       proxy_pass http://localhost:5000;
    }
  5. 查看官方详细说明:使用 Nginx 在 Linux 上托管 ASP.NET Core


xoyozo 5 年前
6,437

image.png

你可能下载到 /home/Drive/... 里去了,右键“编辑”更改目的地文件夹到 /homes/(用户名)/Drive/... ,再右键“恢复”,即可 100% 完成。


若是因为磁盘满导致的,清理磁盘后重启系统即可。

xoyozo 6 年前
5,011

本文使用 Pomelo 提供的 Pomelo.EntityFrameworkCore.MySql,如使用 MySql.Data.EntityFrameworkCore 请移步

对比 MySql.Data.EntityFrameworkCore 与 Pomelo.EntityFrameworkCore.MySql


本文以 Visual Studio 2019、ASP.NET Core 3.0 开发环境为例。

  1. 新建 ASP.NET Core Web 应用程序。

  2. 安装 NuGet 包:

    Microsoft.EntityFrameworkCore.Tools

    Pomelo.EntityFrameworkCore.MySql(3.0.0 预发行版以上)

    image.png

  3. 根据已有数据库创建数据模型。在 NuGet 的程序包管理(Package Manager)控制台中(PowerShell)执行命令:

    Scaffold-DbContext "server=数据库服务器;uid=数据库用户名;pwd=数据库密码;database=数据库名;" Pomelo.EntityFrameworkCore.MySql -OutputDir Data -Force

    .Net Core CLi:

    dotnet ef dbcontext scaffold "server=数据库服务器;uid=数据库用户名;pwd=数据库密码;database=数据库名;" Pomelo.EntityFrameworkCore.MySql -o Data -f
  4. 搞定。


补充:其它数据库提供程序请参考:https://docs.microsoft.com/zh-cn/ef/core/providers/


代码参数说明:

-OutputDir (-o) *** 实体文件所存放的文件目录

-ContextDir *** DbContext文件存放的目录

-Context *** DbContext文件名

-Schemas *** 需要生成实体数据的数据表所在的模式

-Tables(-t) *** 需要生成实体数据的数据表的集合

-DataAnnotations

-UseDatabaseNames 直接使用数据库中的表名和列名(某些版本不支持)

-Force (-f) 强制执行,重写已经存在的实体文件


更多高级用法请参考官方文档


xoyozo 6 年前
8,423