Запрос Dapper со списком параметров
Я пытаюсь запустить запрос с помощью Dapper с известным набором параметров, но со списком значений для этих параметров. Простым примером того, что я пытаюсь сделать, было бы:
DateTime endDate = DateTime.Now;
DateTime startDate = endDate.AddHours(-24);
string query = "select COUNT(*) from Test where Status = @Status AND DateCreated <= @Hour;";
var stuff = con.Query(query, (startDate).ByHourTo(endDate).Select(hour => new
{
Status = 1,
Hour = hour,
}));
Dapper создает исключение с "параметром" @Status "должен быть определен". Я знаю, что Dapper может обрабатывать списки параметров при выполнении массовых вставок и обновлений, но не может ли он сделать это для выбора?
4 ответов
попробуйте это:
List<string> names = new List<string> { "Bob", "Fred", "Jack" };
string query = "select * from people where Name in @names";
var stuff = connection.Query<ExtractionRecord>(query, new {names});
Я знаю, что опаздываю на эту вечеринку, но, думаю, я понимаю, что этот запрос означает, что вы просто хотите передать некоторые свойства и создать свой запрос на основе этих динамических свойств.
С кодом ниже я могу использовать любой тип, а затем просто заполнить и передать объект этого типа с несколькими значениями (я называю это мой объект запроса), и запрос будет сгенерирован, чтобы найти объекты, соответствующие значениям, которые вы установили в своем объекте запроса.
*быть осторожны, значений и вещи, которые имеют значения по умолчанию.
Динамический Запрос
public IEnumerable<T> Query<T>(T templateobject) {
var sql = "SELECT * From " + typeof(T).Name + " Where ";
var list = templateobject.GetType().GetProperties()
.Where(p => p.GetValue(templateobject) != null)
.ToList();
int i = 0;
Dictionary<string, object> dbArgs = new Dictionary<string, object>();
list.ForEach(x =>
{
sql += x.Name + " = @" + x.Name;
dbArgs.Add(x.Name, x.GetValue(templateobject));
if (list.Count > 1 && i < list.Count - 1) {
sql += " AND ";
i++;
}
});
Debug.WriteLine(sql);
return _con.Query<T>(sql, dbArgs).ToList();
}
использование
*repo-это класс, который содержит вышеуказанную функцию
var blah = repo.Query<Domain>(new Domain() { Id = 1, IsActive=true });
выход
SELECT * From Domain Where Id = @Id AND IsActive = @IsActive
затем он выплевывает любые "домены", которые соответствуют вышеуказанному запросу.
DECLARE @Now datetime
SET @Now = getdate()
SELECT
DATEADD( hh, -n, @Now ) AS StartDate,
DATEADD( hh, -n+1, @Now ) AS EndDate
INTO
#DateRanges
FROM
Numbers
WHERE
n <= 24
SELECT
COUNT(*) AS [Count],
#DateRanges.StartDate
FROM
Test
JOIN
#DateRanges
ON Test.DateCreated >= #DateRanges.StartDate
AND Test.DateCreated < #DateRanges.EndDate
GROUP BY
#DateRanges.StartDate
вот как я бы это сделал, но это предполагает одно: у вас есть таблица в вашей базе данных с именем "Numbers", в которой есть произвольное число целых чисел, по одному на строку, начиная с 1, С по крайней мере 24 числами в нем.
то есть, таблица выглядит так:
n
-----
1
2
3
4
5
...
если у вас нет такой таблицы, очень быстро и легко сделать ее только для этой команды:
CREATE TABLE #Numbers
(
n int
)
SET NOCOUNT ON
INSERT #Numbers values (1);
GO
INSERT #Numbers SELECT n + (SELECT COUNT(*) FROM #Numbers) FROM #Numbers
GO 16 --execute batch 16 times to create 2^16 integers.
вы не можете иметь несколько пакетов в хранимой процедуре, но вы можете в текстовой команде. GO 16
запускает предыдущий пакет 16 раз. Если вам это нужно в хранимой процедуре, вы можете повторить второй