博客 (110)

在数据库连接字符串可设置是否将 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 7 年前
9,957

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 7 年前
8,532

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 7 年前
7,413

要将 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 7 年前
8,074

安装最新的:MySQL for Visual Studio

安装版本一致的:MySQL Connector NetMySql.DataMySql.Data.Entity

若仍闪退,在 MySQL Application Configuration 中勾选 Entity FrameworkUse MySQL with Entity Framework

image.png

image.png

或直接升级 MySql.Data 到 8.x 


xoyozo 7 年前
4,525

image.png

在任意一个连接上点击鼠标右键,选择 管理组-新建组,将连接拖入到该分组即可。

xoyozo 7 年前
9,045

当 MySQL 中使用 tinyint(1) 作为布尔值类型时,ASP.NET Core DBFirst 创建模型时会将其定义为 sbyte,运行时会抛出异常:

InvalidCastException: Unable to cast object of type 'System.Boolean' to type 'System.SByte'.

我们可以在数据库连接字符串中加入 TreatTinyAsBoolean=false 来实现不抛出异常,但程序中赋值和判断该字段时还是会比较麻烦。

因此我更倾向于将数据库中该字段类型改为 bit(1)


2019.11.28 注:这回遇到 tinyint(1) 映射到了 C# 的 bool,而 bit(1) 却映射到了 ulong。具体什么原因未作排查,反正哪个最终为 bool 就选哪个吧。

xoyozo 7 年前
6,080

本文使用 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 7 年前
10,211

mesh-topology.png

路由器模式:使用 mesh 主体拨号,缺点是由于 mesh 主体不适合放入弱电箱,那么就有两条网线连接到弱电箱(不需要有线回程或不需要接交换机的忽略此缺点)。

AP 模式:适合已有拨号路由器的环境,mesh 路由器主体与分身之间用 AP 模式连接(小米路由器 Mesh 不支持 AP 模式,估计跟“不分子母”有关);


布线方案:

如果 mesh 作拨号路由器功能够用,那么直接使用路由器模式。家庭新装修的朋友建议在合适的位置(如客厅电视机柜)预留两条网线到弱电箱,一条用于连接光猫到 Mesh 主体,再用另一条有线回程到弱电箱的交换机,无线回程者随意。

如果选择其它路由器作拨号路由器(如软路由,或看中小米路由器强大的 App 功能又不想用小米 mesh),那么 mesh 路由器使用 AP 模式,本体接任意墙壁网口即可。建议关闭拨号路由器的 WiFi,并考虑带机量。


顺便提一下 AC+AP 方案的布线:

同样的,如果无其它拨号路由器,那么可以选择路由/AC/PoE 一体机,配合 AP 使用;如果有指定的拨号路由器,那么选择单独的 AC 控制器 + 交换机 + AP 即可。

AC 和 AP 可二层组网、三层组网,可直连式组网、旁挂式组网。

旁挂组网时,如果 AC 控制器选择百兆网口,不会影响千兆交换机和 AP 的传输效率,因为 AC 控制器仅用来管理 AP,不进行数据传输。

AP 有面板式、吸顶式、户外等可选,PoE 或 DC 供电,有胖瘦之分。胖 AP 有独立管理后台,瘦 AP 无管理后台,必须与 AC 配合使用。

据说:TL-AC100 支持快速漫游,TL-AC300 支持无缝漫游。

xoyozo 7 年前
85,902

确保磁盘未满,否则会提示各种无法连接。


  1. 在“小米WiFi”App 中开启对应路由器的“SAMBA 协议”(工具箱 - 更多工具 - SAMBA)。

  2. 在“小米WiFi”App 中开启相应电脑或设备的“全盘访问”。

  3. 通过 miwifi.com 下载安装 PC 客户端。

  4. 打开“此电脑”,“映射网络驱动器”或“添加一个网络位置”,填写路由器的地址和目录,如:“\\192.168.31.1\下载”。

  5. 如果上一步无法成功添加,那么首先需要检查 samba 服务器是否正常,可以在 iPhone 上安装“Remote File Manager”来验证。

  6. 如果 iPhone 连接正常,那么在电脑上打开“本地组策略编辑器”(命令行:gpedit.msc),在“计算机配置 - 管理模板 - 网络 - Lanman 工作站”右侧,双击“启用不安全的来宾登录”,改为“已启用”。Win7 用户参考此文


注意:电脑必须运行 PC 客户端才能访问小米路由器硬盘。

xoyozo 7 年前
23,558