Skip to main content

· 3 min read
Alec.Ji

使用 Dapper 时,有没有遇到过类似的错误

A parameterless default constructor or one matching signature (System.Int32 CustomerID, System.String CustomerName, System.Int32 X) is required for XXX materialization

TL;DR

这是由于目标类 存在含参构造函数ctorA不存在 不含参的构造函数ctorA 与查询结果不一致(参数个数或参数类型)

问题产生

同事正常做功能迭代,已有查询多返回一个字段,改动如下

public class A{
public A(int a,
string b,
+ XXTypeEnum type
)
{
A = a;
B = b;
+ Type = type
}
}
...
var sql = @"SELECT A,
B,
+Type
FROM
...
var result = await connection.Query<A>(sql);

然后就产生了上边类似的报错

A parameterless default constructor or one matching signature (System.Int32 A, System.String C, System.SByte Type) is required for A materialization

问题分析

查了一下这个异常,说明很简单 需要一个无参的构造函数 或者 一个匹配签名的构造函数

,加一个空的构造函数试了的确是可以,但是为什么如此呢,看着现有的构造函数也是匹配的,仔细看下Type参数的类型并不匹配

debug 几次,得出如下结果

  • 不存在无参构造函数,自动映射(显式转换(比如 int -> enum))
  • 存在含参构造函数,查找对应类型,对应参数的构造函数(此处不会默认显式转换,比如枚举)
  • 存在无参构造函数,无参构造函数会正常调用,但是以最终映射为准

结论

对于 Dapper 对应结果 Model类, 最好是不写含参ctor,如果写了含参的ctor 也要写一个 不含参的ctor(private 也可以)

ps. 使用Mysql 数据库,系统枚举值使用了 tinyint(4)GetFieldType 结果为 System.SByte,附一个 tinyint 类型对应

mysql TypeFieldType
tinyint(1)System.Boolean
*可以通过修改连接字符串 TreatTinyAsBoolean=false 为System.SByte
tinyintSystem.SByte
tinyint unsignedSystem.Byte

pps. 8.0.17 中已弃用整数数据类型的显示宽度 , tinyint(1) 除外,所以最好不要用tinyint(x)的写法 具体可看mysql 8.0.19 feature

REF

· 14 min read
Alec.Ji

公司要开发一个新项目,之前是 .NET Framework + Sql Server ,这次要用 .NET Core + Mysql ,没怎么接触过 mysql ,所以做数据库设计之前,结合网上的资料,以及项目的使用,总结了一下Mysql设计规范。按照规范设计了数据库,目前项目开始正常开发,没遇到因为数据库设计产生的问题,记录一下。ps.随着开发,应该还会记录下mysql与SQL server的差异。

命名规范

基本命名原则

  • 使用有意义的英文词汇,不要使用拼音或拼音缩写。
  • 只能使用英文字母,数字,下划线,并以英文字母开头。
  • 表名库名全部小写用_分隔,列名 Pascal (避免代码中太多attribute)
  • 避免用 MySQL 的保留字,如 desc,关键字如 index
  • 命名禁止超过32个字符,须见名之意,建议使用名词不是动词
  • 数据库,数据表一律使用前缀
    • 临时库、表名必须以tmp为前缀,并以日期为后缀
    • 备份库、表必须以bak为前缀,并以日期为后缀

· 2 min read
Alec.Ji

Cookie服务的首部字段

首部字段名说明首部类型
Set-Cookie开始状态管理所使用的Cookie信息响应首部字段
Cookie服务器收到的Cookie信息请求首部字段

· 4 min read
Alec.Ji

最近在面试,很多公司都有要求使用过 Redis ,之前没有用过,既然很多公司都要求会,自然是有原因的。本文试着简单学习下 Redis ,并了解下它与 MemoryCache 有什么区别的(之前在 LPS 缓存是用的 MemoryCache )。

定义

看下官网的说明,

Redis is an open source (BSD licensed), in-memory data structure store, used as a database, cache and message broker. It supports data structures such as strings, hashes, lists, sets, sorted sets with range queries, bitmaps, hyperloglogs, geospatial indexes with radius queries and streams. Redis has built-in replication, Lua scripting, LRU eviction, transactions and different levels of on-disk persistence, and provides high availability via Redis Sentinel and automatic partitioning with Redis Cluster.

· 4 min read
Alec.Ji

WHY

每年要写年终总结,最近做的事情会记着,之前的却不一定记得那么清。个人有在 Trac 写日志的习惯,可以说是清楚的记载了工作内容,但是一天一天看也太浪费时间,而且效果也不好,没有一个实际的量化。于是就想着爬一下日志内容,分析下词频,这样就可以直观的看自己的工作内容了。

HOW

虽然也自学过一点python,但是学的很基础,而且忘得也差不多了。马上就要交年终总结了,还是用自己习惯的语言吧。大概查了一下用C#爬网页,觉得没啥问题,就开始了。嗯,没错了,想的容易,做起来总会遇到问题:

· 4 min read
Alec.Ji

WHY

公司用Trac作为管理系统。修改Ticket,或者提交工作日志时,总需要先预览才能提交(应该是有权限的人设置的),为了方便自己使用,就花了点时间写了一个浏览器插件,可以不经过预览就提交,顺便学习下Chrome插件的开发。

· 6 min read
Alec.Ji

由于工作中涉及到 API 的开发,以及第三方的对接,Postman 总是少不了使用的,除了简单的发请求,也发现了 Postman 自带的可以用到的功能,做个记录,避免再花时间学习。


Postman makes API development faster, easier, and better

· 5 min read
Alec.Ji

Question

这两个SQL查询的结果相同吗?

SELECT * FROM TableA a LEFT JOIN TableB b ON  b.AId =a.TableAId AND a.TableAId =1
SELECT * FROM TableA a LEFT JOIN TableB b ON b.AId =a.TableAId WHERE a.TableAId = 1

· 4 min read
Alec.Ji

先上个官方说明
Specifies a temporary named result set, known as a common table expression (CTE). This is derived from a simple query and defined within the execution scope of a single SELECT, INSERT, UPDATE, or DELETE statement. This clause can also be used in a CREATE VIEW statement as part of its defining SELECT statement. A common table expression can include references to itself. This is referred to as a recursive common table expression.

简单理解,就是把一个查询结果临时存到指定的表达式上,这个表达式就叫公用表表达式 CTE(Common Table Expression)。 可以简单理解为一个不会实际创建的视图。