Subsonic 3 ActiveRecord вложенный выбор для NotIn ошибка? - PullRequest
2 голосов
/ 08 июня 2010

У меня есть следующий запрос 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.Однако в этом случае, когда два запроса Select вложены, я ожидал, что выходные данные будут иметь два параметра с именами @ 0 и @1.

Мой запрососнован на 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 ]

1 голос
/ 30 января 2012

Только что столкнулся с точно такой же проблемой в последнем выпуске, так что, видимо, она еще не исправлена.Я попытался изменить порядок условий (сначала поместив условие 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 голос
/ 09 июня 2010

Я не уверен насчет SubSonic 3, но в SubSonic 2, если вы запустите этот код, сначала будет выполнен внутренний запрос, а второй запрос будет иметь уже идентифицированные CategoryIds в качестве параметра в запросе.
Может быть, этоэто ошибка, и вы должны опубликовать ее на 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 в качестве параметра до выполнения внешней части.

Не настоящее решение, но быстрое решение на данный момент (если это не влияет на производительностьмного).

...