我正在一个宠物项目上试验 Dapper。我正在使用 SQLite 运行所有测试并使用 MySql 进行“生产”。但是我不确定如何最好地使用 Dapper 来处理与数据库无关的情况。
我遇到的具体问题是 MySql 不支持 Guid 类型作为主键,因此我使用 varchar(40) 作为类型(SQLite 支持唯一标识符,是一个指南)。因此,如果我有一个如下所示的通用存储库,那么问题就来了,当我尝试从 MySql 数据库中进行选择时,我会遇到麻烦。因为 Id 属性的类型是 Guid,Dapper 会抛出“解析第 10 列时出错”,因为 varchar 类型与 guid 类型不匹配。
如果我将 Id 属性从 guid 更改为 int,那么 GetById 内的原始 sql 会更加棘手,我什至不知道如何编写。类似于:1. 开始事务,2. 插入,3. 选择最后插入的 id 并返回它。那么,如果数据库类型是 mysql,那么我是否要使用 last_insert_id,或者如果是 sqlite,则使用 last_insert_rowid?因为原始 sql 语法在不同数据库之间会有很大不同...
public IEnumerable<T> GetById(Guid id) //convention: Id is always of type Guid.
{
return UnitOfWork.DbConnection.Query<T>(
string.Format(
"select * from {0} where Id = @Id", typeof (T).Name), new {Id = id});
}
其他示例是限制返回的行数(尤其是分页)等等。那么我该如何使用 dapper 编写与数据库无关的原始 SQL 查询呢?也许 Dapper 不适合我的情况?也许我应该在这里使用相同的旧 NHibernate。有什么建议吗?我做错了吗?谢谢!
I am experimenting Dapper on a pet project. I am using SQLite to run all the tests and MySql for "production". However I am not sure how to best use Dapper to handle database agnostic situation.
The particular problem I am having is with MySql which doesn't support Guid type for primary key therefore I am using varchar(40) as the type (SQLite supports unique identifier which is a guid). So here comes the problem if I have a generic repository as below I would get into trouble when trying to select from MySql database. Because the type of Id property is Guid and Dapper will throw "Error parsing column 10" because varchar type doesn't match guid type.
If I change the Id property from guid to int then the raw sql inside the GetById would be even trickier which I am not sure how to even write. It will be something like, 1. start transaction, 2. insert, 3. select last inserted id and return it. So am I going to go with if database type is mysql, then use last_insert_id, or if it's sqlite then use last_insert_rowid? Because the raw sql syntax would be quite different from database to database...
public IEnumerable<T> GetById(Guid id) //convention: Id is always of type Guid.
{
return UnitOfWork.DbConnection.Query<T>(
string.Format(
"select * from {0} where Id = @Id", typeof (T).Name), new {Id = id});
}
Other examples would be to limit number of rows returned (especially for paging) and so on. So how am I going to write database agnostic raw sql queries with dapper? And maybe in my situation Dapper isn't suitable? Perhaps I should use the same old NHibernate here. Any suggestions? Am I doing it wrong? Thanks!
发布评论
评论(2)
尝试使用 CHAR(36) 作为 MySQL 中主键的数据类型,这会被 MySQl 连接器转换为 Guid - 我正在使用 MySQL 连接器版本 6.3.4。也可与 Dapper 配合使用。
Try to use CHAR(36) as the datatype for the primary key in MySQL, this get transalted to Guid by the MySQl Connector - I am using MySQL connector version 6.3.4. Works with Dapper as well.
两个问题
如果您所做的只是单元测试,那么您根本不应该连接到数据库。
如果您正在进行集成(以及除此之外的任何其他集成),为什么不在生产数据库版本上运行测试,因为某些特殊性可能会使您的测试成功,但生产代码将会失败。集成测试应该在与生产类似的配置上运行,否则它们是不相关的。
Two questions
If all you're doing are unit tests then you shouldn't connect to database in the first place at all.
If you're doing integration (and any other beyond that) why don't you rather run tests on the production DB version because some particularities may make your test succeed but production code will fail. Integration tests are supposed to be run on similar configuration as production otherwise they're not relevant.