标签: dapper

用Dapper调用自定义构造函数?

我正在尝试使用Dapper与ASP.NET SQL Membership Provider表进行交互.我包装了SqlMembershipProvider类并添加了一个额外的方法来获取MembershipUsers给出一些与我的一些自定义表相关的标准.

使用Dapper查询数据时,似乎Dapper首先使用无参数构造函数实例化该类,然后将返回的列"映射"到对象的属性中.

但是,MembershipUser类上的UserName属性没有setter.从Dapper SqlMapper.cs中的第1417行开始,该方法GetSettableProps()只获得可设置的属性.

我试图做一个MultiMap查询来调用构造函数,但问题是传递给查询的对象已经缺少UserName.

我猜我可以修改GetSettableProps()方法,但我不确定这是否有效,或者它是否会影响我现有的代码.

反正我是否要调用MembershipUser类具有的自定义构造函数?

或者我是否可以对Dapper做出合理的改变以支持我的情况?

**更新**

Marc使用非泛型/动态Query()方法的答案是正确的,但对后人来说,这是我在Dapper中引用的方法:

static List<PropInfo> GetSettableProps(Type t)
{
    return t
          .GetProperties(BindingFlags.Public | BindingFlags.NonPublic | BindingFlags.Instance)
          .Select(p => new PropInfo
          {
              Name = p.Name,
              Setter = p.DeclaringType == t ? p.GetSetMethod(true) : p.DeclaringType.GetProperty(p.Name).GetSetMethod(true),
              Type = p.PropertyType
          })
          .Where(info => info.Setter != null)
          .ToList();  
}
Run Code Online (Sandbox Code Playgroud)

c# reflection asp.net-membership dapper

18
推荐指数
1
解决办法
7914
查看次数

小巧玲珑.映射到SQL列,列名称中包含空格

我已经成功地将今天的东西作为小沙箱/ POC项目运行起来,但似乎在一个问题上让我头疼...

题:

有没有办法让dapper映射到带有空格的SQL列名.

作为我的结果集,我有一些这样的效果.

例如:

SELECT 001 AS [Col 1], 
       901 AS [Col 2],
       00454345345345435349 AS [Col 3],
       03453453453454353458 AS [Col 4] 
FROM [Some Schema].[Some Table]
Run Code Online (Sandbox Code Playgroud)

我的班级看起来像这样

    public class ClassA
    {          
        public string Col1 { get; set; }    

        public string Col2 { get; set; }

        ///... etc
     }
Run Code Online (Sandbox Code Playgroud)

我的实现目前看起来像这样

 public Tuple<IList<TClass>, IList<TClass2>> QueryMultiple<TClass, TClass2>(object parameters)
 {
      List<TClass> output1;
      List<TClass2> output2;

      using (var data = this.Connection.QueryMultiple(this.GlobalParameter.RpcProcedureName, parameters, CommandType.StoredProcedure))
      {
           output1 = data.Read<TClass>().ToList();
           output2 = data.Read<TClass2>().ToList();
      }

      var result = new …
Run Code Online (Sandbox Code Playgroud)

c# dapper dapper-rainbow

18
推荐指数
3
解决办法
1万
查看次数

"WHERE x IN"子句与dapper和postgresql抛出42601:语法错误在"$ 1"处或附近

我有一个字符串数组,我想要一个包含IN子句的查询,如:

"... WHERE t.name IN ('foo', 'bar', 'baz')..>"
Run Code Online (Sandbox Code Playgroud)

这是我的查询的最后一位,其中包含"where in X in"子句:

...
left join genre_tag_band_join tj on hb.id = tj.band_id or ob.id = tj.band_id
left join genre_tags t on tj.genre_tag_id = t.id
inner join venues v on e.venue_id = v.id

where t.name IN @tagsParam...
Run Code Online (Sandbox Code Playgroud)

我像这样做一个Dapper电话

var shows = con.Query<Event, Band, Band, GenreTag, Venue, Event>(query, (e, hb, ob, gt, v) =>
{
    Event show;
    ...
    return e;
},
new { tagsParam = tagsArr}).AsQueryable();
Run Code Online (Sandbox Code Playgroud)

其中tagsArr是一个字符串[].

我得到例外:

{"42601:语法错误位于或附近\"$ 1 \""}

c# postgresql asp.net-mvc npgsql dapper

18
推荐指数
1
解决办法
2055
查看次数

无法在Dapper中使用多映射

和Dapper一起玩,我对目前的结果非常满意 - 很有趣!

但现在,我的下一个场景是从两个表中读取数据 - a StudentAddress表.

Student表有一个主键StudentID (INT IDENTITY),Address有一个AddressID (INT IDENTITY).Student还有一个名为AddressID链接到Address表中的FK .

我的想法是创建两个类,每个表一个,具有我感兴趣的属性.另外,我在C#中将PrimaryAddress类型的属性Address放到我的Student类中.

然后我尝试在单个查询中检索学生和地址数据 - 我模仿Github页面上给出的样本:

var data = connection.Query<Post, User>(sql, (post, user) => { post.Owner = user; });
var post = data.First();
Run Code Online (Sandbox Code Playgroud)

在这里,检索a Post和a User,并将帖子的所有者设置为用户 - 返回的类型是Post- 正确吗?

所以在我的代码中,我为通用Query扩展方法定义了两个参数- Student作为第一个应该返回的参数,Address第二个参数将存储到学生实例中:

var student = _conn.Query<Student, Address> …
Run Code Online (Sandbox Code Playgroud)

c# dapper multi-mapping

17
推荐指数
1
解决办法
2万
查看次数

Dapper MultiMap不适用于具有NULL值的splitOn

我在dapper试图拆分包含的列时出现MultiMaps问题NULL.Dapper似乎没有实例化对象,我的映射函数接收null而不是对象.

这是我的新测试:

    class Product
    {
        public int Id { get; set; }
        public string Name { get; set; }
        public Category Category { get; set; }
    }
    class Category
    {
        public int Id { get; set; }
        public string Name { get; set; }
        public string Description { get; set; }
    }
    public void TestMultiMapWithSplitWithNullValue()
    {
        var sql = @"select 1 as id, 'abc' as name, NULL as description, 'def' as name";
        var product = connection.Query<Product, …
Run Code Online (Sandbox Code Playgroud)

dapper

17
推荐指数
1
解决办法
5212
查看次数

从dapper调用存储过程,接受用户定义的表类型列表

我有一个存储过程InsertCars,它接受用户定义的表类型列表CarType.

CREATE TYPE dbo.CarType
AS TABLE
(
    CARID int null,
    CARNAME varchar(800) not null,
);

CREATE PROCEDURE dbo.InsertCars
    @Cars AS CarType READONLY
AS
-- RETURN COUNT OF INSERTED ROWS
END
Run Code Online (Sandbox Code Playgroud)

我需要从Dapper调用这个存储过程.我用Google搜索并找到了一些解决方案.

 var param = new DynamicParameters(new{CARID= 66, CARNAME= "Volvo"});

 var result = con.Query("InsertCars", param, commandType: CommandType.StoredProcedure);
Run Code Online (Sandbox Code Playgroud)

但是我收到一个错误:

过程或函数InsertCars指定了太多参数

存储过程也InsertCars返回插入行的计数; 我需要得到这个值.

问题的根源在哪里?

我的问题是我在通用列表中有汽车List<Car> Cars,我希望将此列表传递给存储过程.它优雅的方式存在怎么办?

public class Car
{
    public CarId { get; set; }
    public CarName { get; set; }
}
Run Code Online (Sandbox Code Playgroud)

谢谢你的帮助

EDITED …

c# sql-server stored-procedures dapper

17
推荐指数
2
解决办法
2万
查看次数

精致无限的多映射

所以我有一种情况,我必须加入(并映射)超过7个实体(据我所知,这是Dapper的当前限制).这是我到目前为止(伪代码):

using (var connection = new SqlConnection(_connectionString)) {
   IEnumerable<BigEntity> results = 
      connection.Query<BigEntity, Lookup1, Lookup2, ... around 10 of them>(sql, 
         (b, l1, l2, l3) => {
            // map and return here
         },
         splitOn: "split1, split2 ...");
}
Run Code Online (Sandbox Code Playgroud)

这种限制有什么办法吗?以前有人面对这个吗?也许一些Dapper扩展?

c# dapper

17
推荐指数
2
解决办法
2444
查看次数

使用Dapper.TVP TableValueParameter和其他参数

我有一个过程,它接受一个表值参数,以及其他:

CREATE PROCEDURE [dbo].[Update_Records]
    @currentYear INT,
    @country INT,
    @records Record_Table_Type READONLY
AS
Run Code Online (Sandbox Code Playgroud)

我试图用Dapper.TVP来称呼它.

这是我到目前为止的代码:

        var recordsParameter = new List<SqlDataRecord>();

        // This metadata matches 'Record_Table_Type' in the Database
        var recordsMetaData = new[]
        {
            new SqlMetaData("OriginalValue", SqlDbType.Decimal, 19, 4),
            new SqlMetaData("NewValue", SqlDbType.Decimal, 19, 4),
            new SqlMetaData("NewPercent", SqlDbType.Decimal, 7, 2),
        };

        foreach (var r in records)
        {
            var record = new SqlDataRecord(recordsMetaData);
            record.SetDecimal(0, r.OriginalValue);
            record.SetDecimal(1, r.NewValue);
            record.SetDecimal(2, r.NewPercent);
            recordsParameter.Add(record);
        }

        var spParams = new DynamicParameters(new
        {
            currentYear = filter.currentYear,
            country = filter.country,
        }); …
Run Code Online (Sandbox Code Playgroud)

sql-server dapper

17
推荐指数
2
解决办法
1万
查看次数

现在有办法将TVP传递给.Net Core上的精致吗?

我正在使用.net核心和dapper,第一个没有DataTables,第二个使用它们用于TVP.

我试图将a转换List<T>为a List<SqlDataRecord>,使用此列表创建一个SqlParameter然后将其转换为DynamicParameter但遗憾的是我得到了:The member of type Microsoft.SqlServer.Server.SqlDataRecord cannot be used as a parameter value

UPDATE

玩了一下之后IDynamicParameters,我就开始了.

扩展方法 IEnumerable

public static DynamicWrapper toTVP<T>(this IEnumerable<T> enumerable, string tableName, string typeName)
{
    List<SqlDataRecord> records = new List<SqlDataRecord>();
    var properties = typeof(T).GetProperties().Where(p => Mapper.TypeToSQLMap.ContainsKey(p.PropertyType));
    var definitions = properties.Select(p => Mapper.TypeToMetaData(p.Name, p.PropertyType)).ToArray();
    foreach (var item in enumerable)
    {
        var values = properties.Select(p => p.GetValue(item, null)).ToArray();
        var schema = new SqlDataRecord(definitions);
        schema.SetValues(values);
        records.Add(schema);
    }

    SqlParameter result = new SqlParameter(tableName, SqlDbType.Structured); …
Run Code Online (Sandbox Code Playgroud)

c# sql reflection dapper .net-core

17
推荐指数
1
解决办法
2994
查看次数

无法使用.NET Core 2.0连接到SQL 2008数据库

UPDATE

我永远无法使用"Windows身份验证"(域)用户进行此操作.但是使用"SQL Server身份验证"用户,一切都像它应该的那样工作.

原始问题

我的connectionString: Server=ip;Database=dbname;User Id=xxx\user;Password=pass;

连接字符串位于appsettings.json中,如下所示:

{
  "Logging": {
    "IncludeScopes": false,
    "LogLevel": {
      "Default": "Warning"
    }
  },
  "ConnectionStrings": {
    "ConnectionString": "Server=ip;Database=dbname;User Id=xxx\user;Password=pass;"
  }
}
Run Code Online (Sandbox Code Playgroud)

然后我将它传递给"Startup.cs"文件中的静态类,如下所示:

public void ConfigureServices(IServiceCollection services)
{
    // Add framework services.
    services.AddMvc();

    Orm.DatabaseConnection.ConnectionString = Configuration["ConnectionStrings:ConnectionString"];
}
Run Code Online (Sandbox Code Playgroud)

这是我发起连接的地方:

using System.Data.SqlClient;

namespace MyProject.Orm
{
    public static class DatabaseConnection
    {
        public static string ConnectionString { get; set; }

        public static SqlConnection ConnectionFactory()
        {
            return new SqlConnection(ConnectionString);
        }
    }
}
Run Code Online (Sandbox Code Playgroud)

这是我的控制器:

public string Get()
{
    using (var databaseConnection = …
Run Code Online (Sandbox Code Playgroud)

sql-server sql-server-2008 dapper .net-core asp.net-core-2.0

17
推荐指数
1
解决办法
1056
查看次数