2010-06-08 27 views
2

我有以下的亞音速3.0的查詢,其中包含嵌套NotIn查詢:Subsonic 3 ActiveRecord嵌套選擇的NotIn錯誤?

public List<Order> GetRandomOrdersForNoReason(int shopId, int typeId) 
{ 
    // build query  
    var q = new SubSonic.Query.Select().Top("1") 
     .From("Order") 
     .Where("ShopId") 
     .IsEqualTo(shopId) 
     .And(OrderTable.CustomerId).NotIn(
      new Subsonic.Query.Select("CustomerId") 
       .From("Customer") 
       .Where("TypeId") 
       .IsNotEqualTo(typeId)) 
      .OrderDesc("NewId()"); 

    // Output query 
    Debug.WriteLine(q.ToString()); 

    // returned typed list 
    return q.ExecuteTypedList<Order>(); 
} 

內部查詢似乎是不正確的:

SELECT TOP 1 * 
FROM [Order] 
WHERE ShopId = @0 AND CustomerId NOT IN (SELECT CustomerId 
FROM [Customer] 
WHERE TypeId = @0) 
ORDER BY NewId() ASC 

你會發現,這兩個參數是@ 0。我假設參數是枚舉(從零開始),爲每個「新」選擇查詢。但是,在兩個Select查詢嵌套的情況下,我預料輸出會有兩個參數,分別命名爲@ 0@ 1

我的查詢基於one是羅布科納介紹了他的博客爲「Pakala」查詢工具,成爲亞音速3.他的榜樣的預覽是:

int records = new Select(Northwind.Product.Schema) 
    .Where("productid") 
    .In(
     new Select("productid").From(Northwind.Product.Schema) 
     .Where("categoryid").IsEqualTo(5) 
     ) 
    .GetRecordCount(); 

有其他人看到這種行爲?這是一個錯誤,或者這是一個錯誤還是我的一部分?由於我是Subsonic的新手,我猜這可能是程序員錯誤,但我希望儘可能確認。

回答

1

剛剛在最新版本中遇到這個完全相同的問題,顯然它還沒有被修復。我嘗試切換條件的順序(將NotIn條件放在第一位),並且做到了這一點。以下是新代碼的外觀,它們生成的參數@ 0和@ 1代替@ 0和@ 0:

var q = new SubSonic.Query.Select().Top("1") 
    .From("Order") 
    .Where(OrderTable.CustomerId).NotIn(
     new Subsonic.Query.Select("CustomerId") 
      .From("Customer") 
      .Where("TypeId") 
      .IsNotEqualTo(typeId) 
    ) 
    .And("ShopId") 
    .IsEqualTo(shopId) 
    .OrderDesc("NewId()"); 
1

我不確定關於SubSonic 3,但在SubSonic 2中,如果您要運行此代碼,將首先執行內部查詢,而第二個查詢將將CategoryIds allready定義爲查詢中的參數。
也許這是一個錯誤,你應該把它發佈在github上。

反正你可以使你的查詢工作的時刻,表現得像個亞音速2子查詢與這個小變化:

var q = new SubSonic.Query.Select().Top("1") 
    .From("Order") 
    .Where("ShopId") 
    .IsEqualTo(shopId) 
    .And(OrderTable.CustomerId).NotIn(
     new Subsonic.Query.Select("CustomerId") 
      .From("Customer") 
      .Where("TypeId") 
      .IsNotEqualTo(typeId) 
      .ExecuteTypedList<int>() 
    ) 
    .OrderDesc("NewId()"); 

NotIn應採取的IEnumerable作爲參數,但q將包含CustomerIds的整個列表作爲外部部分執行前的參數。

不是一個真正的解決方案,而是一個快速修復的時刻(如果它不會影響性能)。