Subsonic 3 ActiveRecord嵌套选择NotIn bug?

时间:2010-06-08 06:48:04

标签: c# activerecord subsonic subsonic3

我有以下Subsonic 3.0查询,其中包含嵌套的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 的参数。

我的查询基于Rob Conery在他的博客上提供的one作为“Pakala”查询工具的预览,该工具成为了Subsonic 3.他的例子是:

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

还有其他人看过这种行为吗?这是一个错误,还是这个错误或我的一部分?由于我是Subsonic的新手,我猜这可能是程序员错误,但如果可能的话,我想要确认。

2 个答案:

答案 0 :(得分:1)

我不确定SubSonic 3,但在SubSonic 2中,如果您运行此代码,则首先执行内部查询,第二个查询将已将CategoryIds定义为查询中的参数。
也许这是一个bug,你应该把它发布在github上。

无论如何,你可以让你的查询暂时工作,并且表现得像SubSonic 2 Subquery这个小小的变化:

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列表作为参数。

不是真正的解决方案,而是目前的快速解决方案(如果它不会影响性能)。

答案 1 :(得分: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()");