Помощь с запросом Subsonic3 ActiveRecord LINQ - PullRequest
0 голосов
/ 10 июня 2010

У меня есть следующие дозвуковые объекты

TInvoiceHeader
TAccountAssociation

Как я могу добиться следующего в LINQ (subsonic)

SELECT * from TInvoiceHeader
WHERE custid IN 
  (SELECT custid FROM TAccountAssociation
     WHERE username = 'a')

Мне нужно связать результаты с GridView.

Обновление: я пытался

Dim accounts As List(Of TAccountAssociation) = _
TAccountAssociation.Find(Function(x) x.UserName = "a")

        GridView1.DataSource = TInvoiceHeader.All() _
             .Where(Function(x) accounts.Contains(x.custID))
        GridView1.DataBind() 

Но я получаю ошибку "... у вложенных функций dow не совпадает с сигнатурой делегата"

Обновление:

Я действительно не волнуюсь, получаю это ...

why does this work

        Dim accounts() As String = {"N12345", "A12455"}


        GridView1.DataSource = TInvoiceHeader.All(). _
Where(Function(c) accounts.Contains(c.custID))
        GridView1.DataBind()

Но это не

Dim accounts  = TAccountAssociation.Find(Function(x) x.UserName = "a")

        GridView1.DataSource = TInvoiceHeader.All(). _
Where(Function(c) accounts.Contains(c.custID))
        GridView1.DataBind()

Обновление

В итоге я использовал Fluent Query

GridView1.DataSource = New customerWEBDB().Select.From(Of TInvoiceHeader)_
              .Where("custID") _
              .In(New customerWEBDB().SelectColumns("custID") _
              .From(Of TAccountAssociation) _
              .Where("UserName").IsEqualTo("aaa")) _
              .ExecuteTypedList(Of TInvoiceHeader)()

 GridView1.DataBind()

Надеюсь, кто-нибудь покажет мне что-нибудь получше.

Ответы [ 3 ]

1 голос
/ 10 июня 2010

Посмотрите на этот 101 пример linq. Здесь есть кое-что интересное. Также прочитайте блог Скотта Гу - примеры с Linq to SQL, но LINQ должен быть очень похожим.

Вы могли бы сделать что-то вроде этого:

var query = (from IH in db.TInvoiceHeader
              join AA in db.TAccountAssociation on 
               IH.custid equals AA.custid
              where aa.username.equals("a")
              select ID).ToList();

Это будет работать до тех пор, пока ID.custid и aa.custid имеют один и тот же тип (и оба могут быть обнуляемыми или не обнуляемыми). Если это не так, вам нужно что-то вроде этого:

var query = (from IH in db.TInvoiceHeader
                  join AA in db.TAccountAssociation on 
                  new { ID = IH.custid.Value } equals new {ID = AA.custid}
                  where aa.username.equals("a")
                  select ID).ToList();

IH.custid.Value будет использоваться, если IH.custid имеет тип nullable

Теперь вы можете привязать запрос напрямую к сетке.

Я не проверял этот код - и есть несколько других способов достичь вашей цели.

Удачи,

Patrick

0 голосов
/ 11 июня 2010

Ответ на ваш вопрос (но в C #) с использованием In вместо соединения будет:

var q = Db.Select.From<TInvoiceHeader>()
    .Where(TInvoiceHeaderTable.custidColumn)
    .In(Db.SelectColumns(TAccountAssociationTable.custidColumn)
             .From<TAccountAssociation>()
             .Where(TAccountAssociationTable.usernameColumn)
             .IsEqualTo("a")
    );

List<TInvoiceHeader> collection = q.ExecuteTypedList<TInvoiceHeader>();

У меня есть похожий вопрос по SO в отношении NotIn: Subsonic 3 ActiveRecord, вложенный выбор для ошибки NotIn?

0 голосов
/ 10 июня 2010

В linq есть хороший ответ на подзапрос, который поможет:

как сделать подзапрос в LINQ

мне никогда не приходилось делать подзапросы с дозвуковой 3, однако я бы предположил, что что-либо более продвинутое в SQl лучше делать в виде представления или хранимого процесса, чтобы вы не сталкивались с отсутствующими частями построителя запросов linq. в дозвуковом (в прошлый раз я проверял, есть несколько вещей, которые он еще не сделал полностью)

...