使用dapper将一系列复杂对象传递给存储过程

时间:2016-11-18 09:40:36

标签: stored-procedures dapper

我正在协助某人进行与dapper相关的集成,目前我们有一些数据需要进入存储过程。所以我们可以编写我们想要的存储过程,并且可以编写我们想要的dapper位,但该对象看起来像:

public class SomeComplexObject
{
   public string Something {get; set;}
   public string SomethingElse {get;set;}
}

这将在一个数组内,其中包含1-N个这些对象。因此,我们需要将这些传递给存储过程,以便将其用作内部查询内容的一部分。

所以,如果我做的事情如下:

new SqlParameter("arrayOfGoodies", arrayOfComplexObjects);

然而它给了我们错误:

  

对象类型

不存在映射

这是有意义的,因为它如何知道如何将这个Pocos数组转换为SQL世界的东西,但不知何故我需要将这些数据存入存储过程。那么有没有办法做到这一点,或者告诉dapper关于这种类型,或者可能使用其中一个表值参数的东西?

2 个答案:

答案 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