【问题标题】:How do I use the SQL WHERE IN construct with PetaPoco?如何将 SQL WHERE IN 构造与 PetaPoco 一起使用?
【发布时间】:2011-10-20 03:10:15
【问题描述】:

我有一个名为 Tags (Id, Name) 的数据库表,我想从中选择名称与列表中的名称匹配的那些。在 SQL 中我会使用类似的东西:

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

但现在在 ASP.Net MVC3 项目中使用 PetaPoco 时,我一直在想如何正确地做到这一点。到目前为止,我已经尝试过:

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 时得到了我想要的东西。所以我想它现在已经足够好了,虽然不是超级漂亮。

/迈克

【问题讨论】:

    标签: orm petapoco npoco


    【解决方案1】:

    这将起作用,除非您不能使用@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
    

    【讨论】:

    • 太好了,这有助于我在 PetaPoco 中使用多个参数,谢谢!
    • 当我尝试使用整数数组时,它只是将子句保留为“(@0) 中的字段”相反,我执行了 string.Join(",", integerArray) 作为参数。无论如何,这似乎更有效,因为 PetaPoco ParametersHelper 类迭代可枚举元素。
    • 天哪!这是一些开箱即用的想法
    • nPoco 4.01 版需要使用 .WhereSql() 而不是 .Where()。
    【解决方案2】:

    为未来的求职者发布此信息。这行得通。

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

    【讨论】:

      【解决方案3】:

      如果你想在 Petapoco 中使用数组类,你可以使用这个

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

      【讨论】:

      • .ToArray() 解决了我遇到的问题。 itemLists = rep.Find("WHERE ItemId IN (@0)", items.ToArray()).ToList() 谢谢。
      【解决方案4】:

      这是另一个示例:

      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>
      

      【讨论】:

        【解决方案5】:

        也许,在sql中设置太多参数不是一个好方法,the max params limit is 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) + ")");
        

        【讨论】:

        • 其实不要这样做。您刚刚通过绕过 SQL 参数引入了 SQL 注入漏洞。
        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 2016-08-11
        • 2016-06-10
        • 2021-04-02
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多