Saif Khan
Saif Khan

Reputation: 18792

Help with Subsonic3 ActiveRecord LINQ query

I have the following subsonic entities

TInvoiceHeader
TAccountAssociation

How can I achieve the following in LINQ (subsonic)

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

I need to bind the results to a GridView.

Update: I tried

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() 

But I get an error "...nested function dows not have the same signature as delegate"

Update:

I really dont freaking get this...

why does this work

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


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

But this doesn't

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

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

Update

I ended up using the 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()

Hopefully someone will show me something better.

Upvotes: 0

Views: 331

Answers (3)

Rebecca
Rebecca

Reputation: 14402

The answer to your question (but in C#), and using In rather than the join, would be:

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>();

I have a similar question on SO regarding NotIn: Subsonic 3 ActiveRecord nested select for NotIn bug?

Upvotes: 0

Doug
Doug

Reputation: 6518

There is a good answer to subquery's in linq here that will help:

how to do subquery in LINQ

i have never had to do subqueries with subsonic 3 however i would suggest that anything advanced SQl wise is better to do as a view or a stored proc so that you don't come up against any missing parts of the linq query builder in subsonic (last time i checked there were a few things it didn't fully do yet)

Upvotes: 0

Patrick
Patrick

Reputation: 1167

Have a look at this 101 linq examples. There is some great stuff here. Also read through Scott Gu's blog - the examples are with Linq to SQL but the LINQ stuff should be very similar.

You could do something like this:

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();

This will work as long as long as ID.custid and aa.custid are the same type (and are both nullable or non nullable). If this is not the case, you'll need something like this:

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 would be used if IH.custid is a nullable type

You can now bind query directly to a gridview.

I have not tested this code - and there are several other ways to accomplish your goal.

Good luck,

Patrick

Upvotes: 1

Related Questions