Как мне использовать конструкцию SQL WHERE IN с PetaPoco? - PullRequest
31 голосов
/ 04 августа 2011

У меня есть таблица базы данных с именем Tags (Id, Name), из которой я хотел бы выбрать те, в которых имя совпадает с именем в списке. В SQL я бы использовал что-то вроде:

Select * from Tags Where Name In ('Name1', 'Name2', 'xxx...)

Но теперь, используя PetaPoco в проекте ASP.Net MVC3, я застрял, пытаясь понять, как это сделать правильно. Пока я пробовал:

var tagsToFind = new string[] { "SqlServer", "IIS" };
var sql = PetaPoco.Sql.Builder.Select("*").From("Tags").Where("Name in (@0)", tagsToFind);
var result = db.Query<Tag>(sql);

Что приводит к следующему SQL, где только первое имя в моем списке tagsToFind используется для сопоставления данных таблицы, в отличие от всех них.

SELECT * FROM Tags WHERE (Name in (@0)) -> @0 [String] = "SqlServer"

Это немного расстраивает, зная, что это, вероятно, не так сложно ... любая помощь приветствуется!

Обновление: Я узнал, что это можно сделать по-другому

var sql = PetaPoco.Sql.Builder.Append("Select * from tags Where Name IN (@0", tagNames[0]);
foreach (string tagName in tagNames.Where(x => x != tagNames[0])) {
    sql.Append(", @0", tagName);
}        
sql.Append(")");
var result = db.Query<Tag>(sql)

, который дает мне то, что я хочу, используя sqlparameters. Так что я думаю, что пока это достаточно хорошо, хотя и не очень красиво.

/ Mike

Ответы [ 5 ]

56 голосов
/ 05 августа 2011

Это будет работать, за исключением того, что вы не можете использовать синтаксис @ 0 (порядковый). Вы должны использовать именованные параметры, в противном случае он думает, что это отдельные параметры.

var tagsToFind = new string[] { "SqlServer", "IIS" };
var sql = PetaPoco.Sql.Builder.Select("*").From("Tags").Where("Name in (@tags)", new { tags = tagsToFind });
var result = db.Query<Tag>(sql);

Это приведет к

select * from Tags where name in (@0, @1);
@0 = SqlServer, @1 = IIS
12 голосов
/ 15 августа 2013

Публикация этого для будущих искателей. Это работает.

    public IEnumerable<Invoice> GetInvoicesByStatus(List<string> statuses)
    {
        return _database.Fetch<Invoice>(@"
            select *
            from Invoices                   
            where Status IN (@statuses)",
            new { statuses });
    }
4 голосов
/ 08 марта 2016

Если вы хотите использовать класс массива с Petapoco, вы можете использовать это

string[] array = new string[] {"Name1","Name2" };

var foo = BasicRepository<Personnel>.Fetch("WHERE PersonnelId IN (@0)", array.ToArray());
0 голосов
/ 31 августа 2017

Может быть, это неправильный способ установки слишком большого количества параметров в sql, максимальный предел параметров составляет 2100 .

@ Мурат

string[] array = new string[] {"Name1","Name2" };
var foo = BasicRepository<Personnel>.Fetch("WHERE PersonnelId IN > (@0)", array.ToArray());

Построение стандартного SQL в строке и проверка LAST excute-sql, всегда соответствуют вашим потребностям.

var userIDs = from user in UserList select user.UserID;
db.Delete<User>("where UserID in (" + string.Join(",", userIDs) + ")");
0 голосов
/ 04 мая 2014

Вот еще один пример:

program.cs:

public static void Main(string[] args)
{
    using (var db = new PetaPoco.Database("Northwind"))
    {
        var sql = "Select * from customers where Country in (@Countries)";
        var countries = new { @Countries = new string[] { "USA", "Mexico" } };
        var customers = db.Query<Customer>(sql, countries);
        foreach (var customer in customers)
        {
            Console.WriteLine("{0} - {1} from {2}", customer.CustomerID, customer.CompanyName, customer.Country);
        }
    }
}

customer.cs:

public class Customer
{
    public string CustomerID { get; set; }
    public string Address { get; set; }
    public string City { get; set; }
    public string CompanyName { get; set; }
    public string ContactName { get; set; }
    public string ContactTitle { get; set; }
    public string Country { get; set; }
    public string Fax { get; set; }
    public string Phone { get; set; }
    public string PostalCode { get; set; }
    public string Region { get; set; }
}

App.config: (Строка соединения использует строку соединения localdb, так что вы можете изменить ее.)

<?xml version="1.0" encoding="utf-8" ?>
<configuration>
    <startup> 
        <supportedRuntime version="v4.0" sku=".NETFramework,Version=v4.5" />
    </startup>
  <connectionStrings>
    <clear/>
    <add name="Northwind"
         connectionString="Data Source=(localdb)\v11.0;Initial Catalog=northwind;Integrated Security=True;"
         providerName="System.Data.SqlClient"/>
  </connectionStrings>
</configuration>
...