2011-08-04 10 views
29

Tengo una tabla de base de datos llamada Etiquetas (Id, Nombre) desde la que me gustaría seleccionar aquellas en las que el nombre coincide con un nombre en una lista. En SQL que usaría algo como:¿Cómo uso el constructo SQL WHERE IN con PetaPoco?

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

Pero ahora usando PetaPoco en un proyecto de ASP.Net MVC3 estoy atascado encontrar la manera de hacerlo correctamente. Hasta ahora he intentado:

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

que se traduce en el siguiente SQL, donde sólo el primer nombre en mi lista de tagsToFind se utiliza para que coincida con los datos de la tabla en lugar de todos ellos.

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

Es un poco frustrante, sabiendo que esto probablemente no sea tan difícil ... ¡se agradece cualquier ayuda!

Actualización: descubrí que se puede hacer de otra manera

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) 

la que consigo lo que quiero durante el uso de SqlParameters. Así que supongo que es lo suficientemente bueno por ahora, aunque no es súper bonito.

/Mike

Respuesta

54

Esto funcionará a menos que usted no puede utilizar la sintaxis @ 0 (ordinal). Debe usar parámetros con nombre; de ​​lo contrario, cree que son parámetros individuales.

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

Esto dará lugar a

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

Genial, eso me ayudó a utilizar múltiples parámetros en general con PetaPoco, ¡gracias! – Mitch99

+1

Cuando lo intenté con una matriz de enteros, simplemente dejó la cláusula como "campo en (@ 0)" En su lugar, realicé una cadena.Enlazar (",", integerArray) como el parámetro. Esto parecía más eficiente de todos modos, ya que la clase PetaPoco ParametersHelper itera el elemento enumerable. –

+0

Holy Smokes! Eso es un pensamiento externo – Gaspa79

12

publicar esto para los solicitantes de futuros. Esto funciona.

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

Aquí se presenta una otra muestra:

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 utiliza connectionstring LocalDB, por lo que podría cambiarlo.)

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

Si desea utilizar la clase matriz con Petapoco puede utilizar esta

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

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

Que '' .ToArray() '' solucionó el problema que estaba teniendo. '' itemLists = rep.Find ("WHERE ItemId IN (@ 0)", items.ToArray()). ToList() '' gracias. – iiminov

0

Tal vez, no es un buen ajuste de demasiado camino muchos params en 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()); 

La construcción de SQL bipedestador en la cadena, y comprobar la última Excute-SQL, todos los días que coincida con sus necesidades.

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