博客 (56)

方法一:

在 DbContext.cs 文件中找到 OnConfiguring 方法,添加代码:

#if DEBUG
    optionsBuilder.EnableSensitiveDataLogging();
    optionsBuilder.LogTo(Console.WriteLine); // 输出日志到控制台
    //optionsBuilder.LogTo(message => Debug.WriteLine(message)); // 输出日志到“输出”窗口
#endif

搞定。

若原来是 => 形式的,改为 { } 形式写法即可。


方法二:使用 Logging

打开 DbContext 文件,添加

using Microsoft.Extensions.Logging;
using Microsoft.Extensions.Logging.Debug;

optionsBuilder.UseMySql

替换为

optionsBuilder.UseLoggerFactory(MyLoggerFactory).UseMySql

添加方法

public static readonly LoggerFactory MyLoggerFactory = new LoggerFactory(new[] {
    new DebugLoggerProvider()
});

即可在“输出”窗口看到生成的 SQL 语句了。


xoyozo 2 年前
1,984

查询占用带宽的设备 IP 地址:

image.png

查看 IP 地址对应的 MAC 地址:

image.png

image.png

IP 流量限制:

image.png

端口映射:

image.png

xoyozo 2 年前
2,620

经常有人碰到这样一种情况,我的 918+ 有 4 个硬盘呢,怎么空间很快就没了,最重要的是,自己查看统计了所有文件占用情况,和实际的占用空间不符。这个首先可以肯定的就是空间必然是文件占用了。但是呢,有些文件是不能从 File Station 里面直接看到的,所以很多用户就搞不懂了,有时候文件删除了,空间也不见增加。今天,就来教大家一个大招,让这些不能直接看到的文件无处遁形。

一、SSH 登陆群晖

这里我们要用到一个叫 putty 的软件

putty下载链接:点此下载

在开始之前,我们要开启群晖的 SSH 或是 telnet 服务功能(控制台 - 终端机和 SNMP - 勾选启动 SSH 功能)。

 1.png

打开 putty,在主机名称输入群晖的局域网 IP 地址,然后点击下面的【打开】。

2.png

会弹出一个黑色的窗口。登入账号输入管理员:admin,按回车,然后输入 admin 的密码,要注意的是,输入密码的时候,光标是不会动的,你尽管输就行。有些用户看到代码就头疼,其实我们用到的都是些非常简单基础的命令代码,你只要照着这个步骤一步一步去做,肯定能成功,成功把空间腾出来后,你会很有成就感,哈哈!

3.jpg

切换到 root 权限,输入 sudo -i,按回车,然后也是输入 admin 的密码。

4.jpg

MAC 电脑用终端也可以登录 :

  1. 打开终端

  2. 输入命令:ssh -p 999 admin@192.168.1.9

  3. 上面 999 为自定义端口号,admin 为自己的用户名


二、查询文件

到这里我们就登陆到群晖里面了,在这里可以执行命令。

输入 cd /volume1 命令后按回车,意思是进入存储空间 1(若您的储存空间为 2,则改成 volume2,依此类推)。

输入 du -ah --max-depth=1,可以查看当前目录文件大小,这个过程可能会需要数分钟到数小时不等,依您的文件数及空间大小而定。实测 8TB 机械硬盘耗时两个多小时。

image.png

三、删除文件

像上面图片中的 @download 就是 Download Station 的缓存文件,有时候操作不当,会造成缓存不能自动删除,这个时候就需要使用代码的方法来删除缓存,才能释放存储空间了。

比如要删除 Download Station 的缓存文件夹,就是上图的 @download 文件夹,可以使用下面这个命令:rm -rf /volume1/@download

6.jpg

这个命令要慎用,一旦删除就不能恢复了!

四、还有哪些文件占用存储空间而不能直接查询

除了 Download Station的缓存文件之外,还有 File Station 里面删除了文件,但启用了回收站,文件实际上还没彻底删除,也会造成删除文件,空间没有增加的情况。这个时候清空一下回收站即可。

清除某个文件夹回收站:

7.jpg

也可以直接一次性清空所有文件夹的回收站:

8.jpg

还有 Drive 的版本控制和 Drive本身自带的回收站;

9.jpg

@synologydrive/@sync/repo 是 Synology Drive Client 的缓存目录,我删除这个目录就释放了 5TB 的空间。

除此之外,还有 Cloud Station 保留的版本,Snapshot Replication 套件生成的快照文件等。


如果发现 /volume1/@synologydrive/@sync/repo/ 这个目录占用空间过大,请参考这篇文章

转自 清风 2 年前
14,008

论坛出现动态页面打开或刷新非常慢(超过半分钟),甚至打不开,该页无法显示,502 Bad Gateway 等情况,TTFB 计时需要好几秒。

微信图片_20220528233028.png

切换 nginx 版本、php 版本 等均无效果,甚至购买新的 ECS 重新搭建环境也是效果甚微。

最终在阿里云 RDS 管理中,手动主备库切换,问题得以解决。

image.png

因此大概率是原主库有问题(有损坏的表需要修复或锁等情况)。

查询故障时间段的慢 SQL,发现某表的锁等待时间特别长,不知道是不是这个表的原因导致的。

image.png

次日,提交工单得到回复是原主库(现备库)会自动修复,经再次主备库切换测试得到了肯定的结果。

再次日,又遇到同样的打开慢的情况,这次直接找到慢 SQL 中锁等待时间较长的表,优化(OPTIMIZE TABLE)(虽然是 InnoDB),立刻解决了问题。

xoyozo 3 年前
5,019
public static class EntityFrameworkCoreExtension
{
    private static DbCommand CreateCommand(DatabaseFacade facade, string sql, out DbConnection connection, params object[] parameters)
    {
        var conn = facade.GetDbConnection();
        connection = conn;
        conn.Open();
        var cmd = conn.CreateCommand();
        cmd.CommandText = sql;
        cmd.Parameters.AddRange(parameters);
        return cmd;
    }

    public static DataTable SqlQuery(this DatabaseFacade facade, string sql, params object[] parameters)
    {
        var command = CreateCommand(facade, sql, out DbConnection conn, parameters);
        var reader = command.ExecuteReader();
        var dt = new DataTable();
        dt.Load(reader);
        reader.Close();
        conn.Close();
        return dt;
    }

    public static List<T> SqlQuery<T>(this DatabaseFacade facade, string sql, params object[] parameters) where T : class, new()
    {
        var dt = SqlQuery(facade, sql, parameters);
        return dt.ToList<T>();
    }

    public static List<T> ToList<T>(this DataTable dt) where T : class, new()
    {
        var propertyInfos = typeof(T).GetProperties();
        var list = new List<T>();
        foreach (DataRow row in dt.Rows)
        {
            var t = new T();
            foreach (PropertyInfo p in propertyInfos)
            {
                if (dt.Columns.IndexOf(p.Name) != -1 && row[p.Name] != DBNull.Value)
                {
                    p.SetValue(t, row[p.Name], null);
                }
            }
            list.Add(t);
        }
        return list;
    }
}

调用示例:

var data = db.Database.SqlQuery<List<string>>("SELECT 'title' FROM `table` WHERE `id` = {0};", id);


转自 我的个去 4 年前
2,396

测试表数据量 152 万条,测试跳过 100 万取 10 条。

测试一:直接使用 limit 跳过 1000000 取 10,耗时 2.4s;

SELECT *
FROM `pre_forum_post`
ORDER BY `pid`
LIMIT 1000000, 10
> OK
> 时间: 2.394s

测试二:先使用 limit 跳过 1000000 取 1,再使用配合 where 条件,使用 limit 取 10,耗时 0.2s。

SELECT *
FROM `pre_forum_post` 
WHERE `pid` >= (
		SELECT `pid` 
		FROM `pre_forum_post` 
		ORDER BY `pid` 
		LIMIT 1000000, 1
		)
ORDER BY `pid`
LIMIT 10
> OK
> 时间: 0.207s

两次测试耗时相差约 10 倍。测试取 100 条或取 1 条,耗时都相差约 10 倍。

但若测试跳过条数较小时,测试一效率更高,因此应按照项目的实际需要选择适当的查询方法。

xoyozo 4 年前
2,274

按产品类型查询:费用 - 费用分析,右侧可筛选产品,可按月按天查询,自动合计

按实例查询:费用 - 费用账单,搜索实例ID,按月查询

另:已通过提交工单确认无法查询 OSS 按 Bucket 的账单及 CDN 按域名的账单。

xoyozo 4 年前
1,981

“DatabaseFacade”未包含“ExecuteSqlCommand”的定义,并且找不到可接受第一个“DatabaseFacade”类型参数的可访问扩展方法“ExecuteSqlCommand”(是否缺少 using 指令或程序集引用?)


参:原生 SQL 查询

思路:(以 Entity Framework Core 5.0 为例)

先借用 SELETE 的 IQueryable 语句,将 SELETE 关键字替换成 DELETE,再使用 FromSqlRaw 执行。这样可准确使用真实的数据库表名和字段名。

如:

using Microsoft.EntityFrameworkCore;
string sql = db.表.Where(c => c.Date < minDate).ToQueryString();
sql = Regex.Replace(sql, @"SELECT\s.*?\sFROM", "DELETE FROM", RegexOptions.Singleline); // SET @__minDate_0 = '2020-01-14'; DELETE FROM `表` AS `d` WHERE `d`.`Date` < @__minDate_0
sql = Regex.Replace(sql, @"\sAS\s`(.*?)`", "", RegexOptions.Singleline); // SET @__minDate_0 = '2020-01-14'; DELETE FROM `表` WHERE `d`.`Date` < @__minDate_0
sql = Regex.Replace(sql, @"`([^`]*?)`\.`", "`", RegexOptions.Singleline); // SET @__minDate_0 = '2020-01-14'; DELETE FROM `表` WHERE `Date` < @__minDate_0
db.Database.ExecuteSqlRaw(sql);

以上例子针对 MySQL,且未考虑字符串内容中包含符号 ` 的情况。实例操作中应严格防范 SQL 注入。

封装成方法:

using Microsoft.EntityFrameworkCore;

const RegexOptions ro = RegexOptions.Singleline;

/// <summary>
/// 组装一个 DELETE SQL 语句
/// </summary>
/// <typeparam name="T">数据库表实体类</typeparam>
/// <param name="queryableWithConditions">IQueryable,可带筛选条件</param>
/// <returns></returns>
public static string AssembleDeleteSql<T>(IQueryable<T> queryableWithConditions) where T : class
{
    // MySQL 版
    string sql = queryableWithConditions.ToQueryString(); // SET @__minDate_0 = '2020-01-14'; SELECT `d`.`Date`, `d`.`Code6` FROM `表` AS `d` WHERE `d`.`Date` < @__minDate_0
    sql = Regex.Replace(sql, @"SELECT\s.*?\sFROM", "DELETE FROM", ro); // SET @__minDate_0 = '2020-01-14'; DELETE FROM `表` AS `d` WHERE `d`.`Date` < @__minDate_0
    sql = Regex.Replace(sql, @"\sAS\s`(.*?)`", "", ro); // SET @__minDate_0 = '2020-01-14'; DELETE FROM `表` WHERE `d`.`Date` < @__minDate_0
    sql = Regex.Replace(sql, @"`([^`]*?)`\.`", "`", ro); // SET @__minDate_0 = '2020-01-14'; DELETE FROM `表` WHERE `Date` < @__minDate_0
    return sql;
}
/// <summary>
/// 组装一个 UPDATE SQL 语句
/// </summary>
/// <typeparam name="T">数据库表实体类</typeparam>
/// <param name="queryableWithConditions">IQueryable,可带筛选条件</param>
/// <param name="columnsAndValues">需要更改的字段和值</param>
/// <returns></returns>
public static string AssembleUpdateSql<T>(IQueryable<T> queryableWithConditions, Dictionary<string, object> columnsAndValues) where T : class
{
    // MySQL 版
    string sql = queryableWithConditions.ToQueryString(); // SET @__minDate_0 = '2020-01-14'; SELECT `d`.`Date`, `d`.`Code6` FROM `表` AS `d` WHERE `d`.`Date` < @__minDate_0
    sql = Regex.Replace(sql, @"SELECT\s.*?\sFROM", "UPDATE", ro); // SET @__minDate_0 = '2020-01-14'; UPDATE `表` AS `d` WHERE `d`.`Date` < @__minDate_0
    sql = Regex.Replace(sql, @"\sAS\s`(.*?)`", "", ro); // SET @__minDate_0 = '2020-01-14'; UPDATE `表` WHERE `d`.`Date` < @__minDate_0
    sql = Regex.Replace(sql, @"`([^`]*?)`\.`", "`", ro); // SET @__minDate_0 = '2020-01-14'; UPDATE `表` WHERE `Date` < @__minDate_0
    string sets = string.Join(",", columnsAndValues.Select(c => $"`{c.Key.Replace("`", @"\`")}` = '{c.Value.ToString().Replace("'", @"\'")}'"));
    sql = Regex.Replace(sql, @"`\s*WHERE", $"` SET {sets} WHERE", ro); // SET @__minDate_0 = '2020-01-14'; UPDATE `表` SET `field1` = 'value1', `field2` = 'value2' WHERE `Date` < @__minDate_0
    return sql;
}

调用示例:

using Microsoft.EntityFrameworkCore;

// 删除记录
DateTime minDate = DateTime.Today.AddYears(-1).AddMonths(-1);
string sql = AssembleDeleteSql(db.表.Where(c => c.Date < minDate));
db.Database.ExecuteSqlRaw(sql);

// 更新记录
var sets = new Dictionary<string, object>();
foreach (var p in db.Model.FindEntityType(typeof(表)).GetProperties())
{
    switch (p.Name)
    {
        case nameof(表.字段一): sets.Add(p.GetColumnBaseName(), 123); break;
        case nameof(表.字段二): sets.Add(p.GetColumnBaseName(), 456); break;
    }
}
DateTime minDate = DateTime.Today.AddYears(-1).AddMonths(-1);
string sql = AssembleUpdateSql(db.表.Where(c => c.Date < minDate), sets);
db.Database.ExecuteSqlRaw(sql);


xoyozo 4 年前
8,067

纯真 IP 数据库官方下载地址:http://www.cz88.net/

下载安装纯真 IP,将 qqwry.dat 文件复制到项目下。(本文以放在 /App_Data/ 目录下为例)

在 qqwry.dat 上右键打开属性窗口,将“复制到输出目录”切换到“始终复制”或“如果较新则复制”。

通过 nuget 安装 QQWry,喜欢依赖注入方式的可以选择 QQWry.DependencyInjectio。

var config = new QQWryOptions
{
    DbPath = dbPath ?? (AppContext.BaseDirectory + @"App_Data\qqwry.dat")
};

var ipSearch = new QQWryIpSearch(config);

var ipl = ipSearch.GetIpLocation(ip);

return new IpLocation
{
    Ip = ipl.Ip,
    Country = ipl.Country?.Replace("CZ88.NET", "").Trim(),
    Area = ipl.Area?.Replace("CZ88.NET", "").Trim(),
};

github 开源地址:https://github.com/JadynWong/IP_qqwry


xoyozo 5 年前
3,836

核心文件路径:/theme/html/demo*/src/js/components/core.datatable.js

所有参数的默认值见该文件 3369 行起。

data:

属性 功能
type 数据源类型 local / remote
source 数据源 链接或对象(见下方)
pageSize 每页项数 默认 10
saveState 刷新、重新打开、返回时仍保持状态 默认 true
serverPaging 是否在服务端实现分页 默认 false
serverFiltering 是否在服务端实现筛选 默认 false
serverSorting 是否在服务端实现排序 默认 false
autoColumns 为远程数据源启用自动列功能 默认 false
attr

data.source:

属性 功能
url 数据源地址
params 请求参数
query: {
}
headers 自定义请求的头
{
    'x-my-custom-header': 'some value',
    'x-test-header': 'the value'
}
map 数据地图,作用是对返回的数据进行整理和定位
function (raw) {
    console.log(raw)
    // sample data mapping
    var dataSet = raw;
    if (typeof raw.data !== 'undefined') {
        dataSet = raw.data;
    }
    return dataSet;
}

layout:

属性 功能
theme 主题 默认 default
class 包裹的 CSS 样式
scroll 在需要时显示横向或纵向滚动条 默认 false
height 表格高度 默认 null
minHeight 表格最小高度 默认 null
footer 是否显示表格底部 默认 false
header 是否显示表头 默认 true
customScrollbar 自定义的滚动条 默认 true
spinner Loading 样式
{
	overlayColor: '#000000',
	opacity: 0,
	type: 'loader',
	state: 'primary',
	message: true,
}
icons 表格中的 icon
{
	sort: {
	    asc: 'flaticon2-arrow-up', 
	    desc: 'flaticon2-arrow-down'
	},
	pagination: {
		next: 'flaticon2-next',
		prev: 'flaticon2-back',
		first: 'flaticon2-fast-back',
		last: 'flaticon2-fast-next',
		more: 'flaticon-more-1',
	},
	rowDetail: {
	    expand: 'fa fa-caret-down', 
	    collapse: 'fa fa-caret-right'
	},
}
sortable 是否支持按列排序 默认 true
resizable
是否支持鼠标拖动改变列宽 默认 false
filterable 在列中过滤 默认 false
pagination
显示分页信息 默认 true
editable
行内编辑 默认 false
columns
见本文下方
search
搜索
{
	// 按回车键确认
	onEnter: false,
	// 文本内容
	input: null,
	// 搜索延时
	delay: 400,
	// 键名
	key: null
}

layout.columns:

属性 功能 解释
field 字段名 对应 JSON 的属性名,点击表头时作为排序字段名
title 表头名 显示在表格头部
sortable 默认排序方式 可选:'asc' / 'desc'
width 单元格最小宽度 值与 CSS 值一致,填数字时默认单位 px
type 数据类型 'number' / 'date' 等,与本地排序有关
format 数据格式化 例格式化日期:'YYYY-MM-DD'
selector 是否显示选择框 布尔值或对象,如:{ class: '' }
textAlign 文字对齐方式 'center'
overflow 内容超过单元格宽度时是否显示 'visible':永远显示
autoHide 自适应显示/隐藏 布尔值
template 用于显示内容的 HTML 模板 function(row) { return row.Id; }
sortCallback 排序回调 自定义排序方式,参 local-sort.js

其它:

属性 功能 解释
translate 翻译

参 core.datatable.js 3512 行,简体中文示例:

translate: {
    records: {
        processing: '加载中...',
        noRecords: '没有找到相关内容',
    },
    toolbar: {
        pagination: {
            items: {
                default: {
                    first: '首页',
                    prev: '前一页',
                    next: '后一页',
                    last: '末页',
                    more: '更多',
                    input: '请输入跳转页码',
                    select: '设置每页显示项数',
                },
                info: '当前第 {{start}} - {{end}} 项 共 {{total}} 项',
            },
        },
    },
},


extensions

暂时没有找到对字符串内容进行自动 HTML 编码的属性,这可能带来 XSS 攻击风险,在 remote 方式中必须在服务端预先 HtmlEncode。即使在 layout.columns.template 中进行处理也是无济于事,恶意代码会在 ajax 加载完成后立即执行。


方法和事件:待完善。


更多信息请查询官方文档:https://keenthemes.com/keen/?page=docs&section=html-components-datatable

xoyozo 5 年前
5,411