2016-10-27 1 views
2

я получаю следующее исключение при попытке выполнить этот метод:При использовании мульти-картирования API для обеспечения установить splitOn параметры, если у вас есть другие, чем Id ключи «» splitOn с несколькими отношениями

Когда с помощью API, многоканальные отображения убедитесь, что вы установите splitOn параметров, если у вас есть другие, чем Id ключи «


public static IEnumerable<FinancePositionList> GetFinancialListsForConsecutiveYears(int year, int periodTypeId, int period) 
     { 
      IEnumerable<FinancePositionList> resultList; 
      using (var conn = new SqlConnection(ConfigurationManager.ConnectionStrings["Finance"].ConnectionString)) 
      { 
       conn.Open(); 
       StringBuilder query = new StringBuilder(); 
       query.Append("SELECT b.CompanyId,b.CompanyName,[Year]"); 
       query.Append(",CreationDate,AccruedExpenses,AdvancePaymentsToContractors"); 


       query.Append("FROM finance.FinanceList a INNER JOIN finance.Company b "); 
       query.Append("ON a.CompanyId = b.CompanyId "); 
       query.Append("INNER JOIN finance.ListPeriod c "); 
       query.Append("ON c.FinanceListId = a.FinanceListId "); 
       query.Append("WHERE Discriminator = " + "'" + "FinancePositionList" + "' "); 
       query.Append("AND[Year] IN @years "); 
       query.Append("AND c.PeriodTypeId = @PeriodTypeId AND c.Period = @Period "); 
       query.Append("ORDER BY b.CompanyId, a.[Year] DESC "); 

       resultList = conn.Query<FinancePositionList, Company,ListPeriod, FinancePositionList>(query.ToString(), 
        (a, b,c) => 
        { 
         a.Company = b; 
         c.FinanceList = a; 
         return a; 
        }, 
        new 
        { 
         years = new[] { year, year - 1 }, 
         PeriodTypeId = periodTypeId, 
         Period = period 
        }, 
        splitOn: "CompanyId,FinanceListId").AsEnumerable(); 
      } 
      return resultList; 
     } 

enter image description here


EDIT:

исправить эту проблему сейчас, изменяя порядок столбцов, как это: Но мне интересно, если есть более усовершенствование кода я мог сделать?

public static IEnumerable<FinancePositionList> GetFinancialListsForConsecutiveYears(int year, int periodTypeId, int period) 
     { 
      IEnumerable<FinancePositionList> resultList; 
      using (var conn = new SqlConnection(ResolveConnectionString())) 
      { 
       conn.Open(); 
       StringBuilder query = new StringBuilder(); 
       query.Append("SELECT CreationDate,AccruedExpenses,AdvancePaymentsToContractors,[Year]"); 
       query.Append(",b.CompanyId,b.CompanyName,c.FinanceListId "); 
       query.Append("FROM finance.FinanceList a INNER JOIN finance.Company b "); 
       query.Append("ON a.CompanyId = b.CompanyId "); 
       query.Append("INNER JOIN finance.ListPeriod c "); 
       query.Append("ON c.FinanceListId = a.FinanceListId "); 
       query.Append("WHERE Discriminator = " + "'" + "FinancePositionList" + "' "); 
       query.Append("AND [Year] IN @years "); 
       query.Append("AND c.PeriodTypeId = @PeriodTypeId AND c.Period = @Period "); 
       query.Append("ORDER BY b.CompanyId, a.[Year] DESC "); 

       resultList = conn.Query<FinancePositionList, Company, ListPeriod, FinancePositionList>(query.ToString(), 
        (a, b, c) => 
        { 
         a.Company = b; 
         a.CompanyId = b.CompanyId; 
         a.FinanceListId = c.FinanceListId; 
         return a; 
        }, 
        new 
        { 
         years = new[] { year, year - 1 }, 
         PeriodTypeId = periodTypeId, 
         Period = period 
        }, 
        splitOn: "CompanyId,FinanceListId").AsEnumerable(); 
      } 
      return resultList; 
     } 

ответ

3

Вы в основном поняли работу в Multimapping с помощью Dapper, Ваш запрос дает следующие столбцы:

**"CompanyId","CompanyName","Year","CreationDate","AccruedExpenses", 
"AdvancePaymentsToContractors"** 

Теперь в multimapping коде следующее щеголеватый Query перегрузки, что вы звоните (проверено с source code):

public static IEnumerable<TReturn> Query<TFirst, TSecond, TThird, TReturn>(
this IDbConnection cnn, string sql, Func<TFirst, TSecond, TThird, TReturn> map, 
object param, IDbTransaction transaction, bool buffered, string splitOn, 
int? commandTimeout, CommandType? commandType) 

Раньше я misund erstood общий вызов, но теперь, как кажется, проблема заключается только в сопоставлении типов Multi mapping, используя SplitOn, который вы уже исправили, поэтому следующее будет работать, при условии, что в результате запроса будут найдены нулевые столбцы spliton.

conn.Query<FinancePositionList, Company,ListPeriod, FinancePositionList>(query.ToString(), (a, b,c) => 
        { 
         a.Company = b; 
         c.FinanceList = a; 
         return a; 
        }, 
        new 
       { 
        years = new[] { year, year - 1 }, 
        PeriodTypeId = periodTypeId, 
        Period = period 
       }, splitOn: "CompanyId,FinanceListId") 

Теперь только точка остается выяснить, как я писал в комментарии работает от years параметра, который в основном integer array, для текущего запроса, который весь текст, это будет работать нормально, но не для stored procedures, где он ожидал бы того же, используя DataTable, с той же последовательностью и именем столбцов, что и коллекцию, которая может быть предоставлена ​​только с использованием Table Valued Parameters. Я не предвижу никаких изменений, необходимых для текущего варианта использования.

Редактировать, чтобы привести пример Анонимных параметров и динамических параметров:

AnonymousParameters

Этот простой анонимный тип в C#, проверить here, идея, что вы можете поставить все параметры с помощью простой заполнитель например {max = <value>,min=<value>} или даже как есть, если имя соответствует {max,min}, в обоих случаях параметры: @max и @min, регистр не имеет значения, вы используете AnonymousParameters в своем коде для пара метров years, PeriodTypeId, Period, он будет выводить тип и другие детали внутри и будет предполагать все, что входные параметры

{years = new[] { year, year - 1 },PeriodTypeId = periodTypeId,Period = period} 

Динамические параметры

Они больше похожи на класс параметров в ADO.NET, который получает вас добавить параметр в явном виде, являются следующие перегрузки в Dapper коде, вы должны предоставить всю информацию как Type, Direction и т.д. явно (фрагмент кода из dapper исходного кода):

public partial class DynamicParameters : SqlMapper.IDynamicParameters, SqlMapper.IParameterLookup, SqlMapper.IParameterCallbacks 
    { 
    public void Add(string name, object value, DbType? dbType, ParameterDirection? direction, int? size) 

    public void Add(string name, object value = null, DbType? dbType = null, ParameterDirection? direction = null, int? size = null, byte? precision = null, byte? scale = null) 
    } 
+0

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

+1

Параметры были бы просты, это можно сделать с помощью Анонимных типов или Динамических параметров, я предпочитаю анонимный тип, хотя они ограничены параметрами ввода, проверьте примеры @ https://github.com/StackExchange/dapper-dot-net или загрузите исходный код, который имеет хорошие тестовые примеры, чтобы понять использование –

+0

Может ли переписать мой запрос, чтобы прояснить идею, пожалуйста, –

Смежные вопросы