我正在协助某人进行与dapper相关的集成,目前我们有一些数据需要进入存储过程。所以我们可以编写我们想要的存储过程,并且可以编写我们想要的dapper位,但该对象看起来像:
public class SomeComplexObject
{
public string Something {get; set;}
public string SomethingElse {get;set;}
}
这将在一个数组内,其中包含1-N个这些对象。因此,我们需要将这些传递给存储过程,以便将其用作内部查询内容的一部分。
所以,如果我做的事情如下:
new SqlParameter("arrayOfGoodies", arrayOfComplexObjects);
然而它给了我们错误:
对象类型
不存在映射
这是有意义的,因为它如何知道如何将这个Pocos数组转换为SQL世界的东西,但不知何故我需要将这些数据存入存储过程。那么有没有办法做到这一点,或者告诉dapper关于这种类型,或者可能使用其中一个表值参数的东西?
答案 0 :(得分:1)
我找到了使用PostgreSQL的方法。
为进行解释,请选择具有指定ID和登录名的用户列表。
在数据库中:
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答案 1 :(得分:0)
您可以将数组作为表值参数传递。不幸的是,您必须先将其转换为DataTable。
例如:
Intent intent = new Intent(Intent.ACTION_VIEW);
Uri uri = Uri.withAppendedPath(MediaStore.Audio.Media.INTERNAL_CONTENT_URI,"1");
intent.setData(uri);
intent.setType("audio/*");
List<ResolveInfo> apps = getPackageManager().queryIntentActivities(intent, 0);
for (ResolveInfo rInfo : apps) {
//process list here
}
更多示例here