我正在协助某人进行与dapper相关的集成,目前我们有一些数据需要进入存储过程。所以我们可以编写我们想要的存储过程,并且可以编写我们想要的dapper位,但是对象看起来像:
public class SomeComplexObject
{
public string Something {get; set;}
public string SomethingElse {get;set;}
}
这将在一个数组内,其中包含1-N个这些对象。因此,我们需要将这些传递给存储过程,以便将其用作内部查询内容的一部分。
所以,如果我做的事情如下:
new SqlParameter("arrayOfGoodies", arrayOfComplexObjects);
但它给了我们错误:
对象类型不存在映射
这是有道理的,因为它如何知道如何将这个Pocos数组转换为SQL世界的东西,但不知何故我需要将这些数据存入存储过程。那么有没有办法做到这一点,或者告诉dapper关于这种类型,或者可能使用其中一个表值参数的东西?
我找到了PostgreSQL的方法。
要解释,请选择具有指定ID和登录的用户列表。
在DB中:
create table user_apt
(
id bigint,
login varchar(100),
owner_name varchar(500),
password varchar(50),
is_active boolean,
date_edit timestamp default now()
);
create type t_user_test AS
(
id bigint,
login varchar(100),
owner_name varchar(500)
)
CREATE OR REPLACE FUNCTION test_pass_object_array(i_users t_user_test)
RETURNS SETOF t_user_test
LANGUAGE plpgsql
AS $$
BEGIN
return query
SELECT
ua.id,
ua.login,
ua.owner_name
FROM user_apt ua
inner join i_users inp ON ua.id=inp.id AND ua.login=inp.login;
END
$$;
在C#中
using Dapper;
using Npgsql;
using System;
using System.Collections.Generic;
using System.Data;
namespace DapperSPWithClass
{
public class User
{
public long ID { get; set; }
public string Login { get; set; }
public string Owner_Name { get; set; }
}
class Program
{
static void Main(string[] args)
{
var connectionString = "Server=127.0.0.1;Port=5432;Database=test;User Id=My;Password=SuperSecretPass;Timeout=15;";
var lsUser = new List<User> {
new User{
ID=13,
Login="kos@test5"
},
new User{
ID=29,
Login="nsk@autotest1"
}};
using (var conn = new NpgsqlConnection(connectionString))
{
conn.Open();
conn.TypeMapper.MapComposite<User>("t_user_test"); // Here is the magic we needed
var res = conn.Query<User>("test_pass_object_array", commandType: CommandType.StoredProcedure, param: new { i_users = lsUser });
}
Console.ReadKey();
}
}
}
conn.TypeMapper.MapComposite<T>("t_user_test");
我在文章https://www.npgsql.org/doc/types/enums_and_composites.html中找到了MapComposite