2011-08-04 2 views
29

Mam tabelę bazy danych o nazwie Tagi (Id, Nazwa), z którego chciałbym wybrać te, w których nazwa pasuje do nazwy na liście. W SQL chciałbym użyć czegoś takiego:Jak używać konstruktu SQL WHERE IN z PetaPoco?

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

Ale teraz za pomocą PetaPoco w projekcie ASP.Net MVC3 utknąłem na zastanawianie się, jak to zrobić poprawnie. Do tej pory próbowałem:

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); 

co skutkuje następującym SQL, gdzie tylko pierwszy nazwa w moim liście tagsToFind służy do dopasowywania danych tabeli, w przeciwieństwie do wszystkich z nich.

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

To trochę frustrujące, wiedząc, że to nie jest takie trudne ... każda pomoc jest doceniana!

Aktualizacja: I okazało się, że można to zrobić w inny sposób

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) 

które dostaje mi, co chcę podczas korzystania sqlparameters. Sądzę więc, że na razie wystarczająco dobrze, choć niezbyt ładnie.

/Mike

Odpowiedz

54

Będzie to działać z wyjątkiem ciebie nie można używać @ składni (porządkowej) 0. Musisz używać nazwanych parametrów, w przeciwnym razie są to indywidualne parametry.

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); 

To spowoduje

select * from Tags where name in (@0, @1); 
@0 = SqlServer, @1 = IIS 
+3

Świetne, pomogło mi to w użyciu wielu parametrów w ogóle dzięki PetaPoco, dzięki! – Mitch99

+1

Kiedy próbowałem tego z tablicą całkowitą, po prostu zostawiłem klauzulę jako "pole w (@ 0)" Zamiast tego, wykonałem string.Join (",", integerArray) jako parametr. Wydawało się to bardziej wydajne, ponieważ klasa PetaPoco ParametersHelper iteruje element przeliczalny. –

+0

Holy smokes! To trochę poza myśleniem – Gaspa79

12

Delegowanie to dla przyszłych poszukiwaczy. To działa.

public IEnumerable<Invoice> GetInvoicesByStatus(List<string> statuses) 
    { 
     return _database.Fetch<Invoice>(@" 
      select * 
      from Invoices     
      where Status IN (@statuses)", 
      new { statuses }); 
    } 
0

Oto druga próbka:

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: (ConnectionString używa localdb ConnectionString, więc można go zmienić.)

<?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> 
4

Jeśli chcesz użyć klasy Array z Petapoco można użyć tej

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

var foo = BasicRepository<Personnel>.Fetch("WHERE PersonnelId IN (@0)", array.ToArray()); 
+0

Że '' .ToArray() '' naprawił problem, który miałem. '' itemLists = rep.Find ("WHERE ItemId IN (@ 0)", items.ToArray()). ToList() '' thanks. – iiminov

0

Może to nie jest dobry sposób ustawiania zbyt wiele parametrów w sql, the max params limit is 2100.

@Murat

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

Konstruowanie Stander SQL w ciągu, i sprawdzić LAST excute-SQL, sprecyzowane dopasować swoje potrzeby.

var userIDs = from user in UserList select user.UserID; 
db.Delete<User>("where UserID in (" + string.Join(",", userIDs) + ")");