#c# #sql-server #dapper
#c# #sql-server #dapper
Вопрос:
У меня есть список объектов с различными свойствами. Я хочу запросить базу данных, используя эти свойства, и получить список результатов обратно.
Это то, что я пробовал:
public async Task<IEnumerable<Animal>> GetAnimalsFromAttributesAsync(IEnumerable<AnimalInfo> attributeSets)
{
using (var myDB = new SqlConnection(connectionString))
{
await myDB.OpenAsync();
var results = new List<Animal>();
foreach (var attributeSet in attributeSets)
{
var sql = @"select AnimalID, AnimalTypeID, AnimalColor
from Animals
where AnimalTypeID = @AnimalTypeID
and AnimalColorID = @AnimalColorID";
var result = myDB.Query<Animal>(sql, attributeSet);
results.AddRange(result);
}
return results
}
}
Это нормально работает для небольшого количества свойств. Но если у меня много свойств, то я получаю эту ошибку:
Ошибка: входящий запрос содержит слишком много параметров. Сервер поддерживает максимум 2100 параметров. Уменьшите количество параметров и повторно отправьте запрос.
Есть ли лучший способ сделать это?
Комментарии:
1. Вы действительно запрашиваете базу данных с помощью предложения where с 2k параметрами одновременно?
2. Привет — что
AnimalInfo
здесь? Я изо всех сил пытаюсь понять, почему это вызывает взрыв параметров (контекст: я основной автор dapper)3. Попробуйте использовать оператор SQL «in» и укажите свои идентификаторы в виде массива.
4. что-то, что нужно попробовать:
var result = myDB.Query<Animal>(sql, new { attributeSet.AnimalTypeId, attributeSet.AnimalColorID });
— должно сделать невозможным возникновение чего-либо слишком странного5. Там вполне может быть 3000 сведений, но ваш запрос принимает только два параметра одновременно — вам нужно было бы выполнить его 3000 раз. Альтернативой может быть запрос на основе TVP.
Ответ №1:
Благодаря предложению @MarcGravell я решил переписать свой запрос как запрос TVP.
SQL:
create type AnimalInfo as table
(
AnimalTypeID int,
AnimalColorID int
)
go
C#:
public async Task<IEnumerable<Animal>> GetAnimalsFromAttributesAsync(DataTable attributeSets)
{
using (var myDB = new SqlConnection(connectionString))
{
await myDB.OpenAsync();
var sql = @"select AnimalID, AnimalTypeID, AnimalColor
from Animals
inner join @animalInfos animalInfos on
animalInfos.AnimalColorID = Animals.ColorID
and
animalInfos.AnimalTypeID = Animals.AnimalTypeID";
var result = await myDB.QueryAsync<Animal>(sql, new { animalInfos = attributeSets.AsTableValuedParameter("AnimalInfo") };
return resu<
}
}