Вызывать пользовательский конструктор с помощью Dapper? - PullRequest
17 голосов
/ 25 января 2012

Я пытаюсь использовать Dapper для взаимодействия с таблицами ASP.NET SQL Membership Provider. Я обернул класс SqlMembershipProvider и добавил дополнительный метод, чтобы получить членство в MembershipUsers с учетом определенных критериев, касающихся некоторых пользовательских таблиц.

При запросе данных с помощью Dapper создается впечатление, что Dapper сначала создает экземпляр класса с помощью конструктора без параметров, а затем «сопоставляет» возвращенные столбцы со свойствами объекта.

Однако свойство UserName в классе MembershipUser не имеет установщика. Судя по строке 1417 в Dapper SqlMapper.cs, метод GetSettableProps() получает только устанавливаемые свойства.

Я пытался выполнить запрос MultiMap для вызова конструктора, но проблема в том, что объекты, переданные в запрос, уже пропускают имя пользователя.

Полагаю, я мог бы изменить метод GetSettableProps(), но я не уверен, сработает ли это или повлияет ли это на мой существующий код.

Можно ли в любом случае вызвать пользовательский конструктор, который есть в классе MembershipUser?

Или есть ли разумное изменение, которое я мог бы внести в Dapper, чтобы поддержать мою ситуацию?

** ОБНОВЛЕНИЕ **

Ответ Марка об использовании неуниверсального / динамического метода 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();  
}

Ответы [ 2 ]

30 голосов
/ 25 января 2012

Я бы использовал здесь неуниверсальный API запросов ...

 return connection.Query(sql, args).Select(row =>
     new AnyType((string)row.Foo, (int)row.Bar) {
         Other = (float)row.Other }).ToList();

Используя это, вы можете использовать как конструкторы не по умолчанию, так и присваивания свойств, без каких-либо изменений, используя "динамический" какпромежуточный шаг.

2 голосов
/ 16 февраля 2015

Я пользуюсь этим, может быть, это поможет кому-то

YourList = connection.Query<YourQueryClass>(Query, arg)
              .Select(f => new ClassWithConstructor(f.foo,f.bar))
              .ToList();  
...