tags:

views:

118

answers:

4

I have Two tables.

1.Users table (Username , Name)

2.Picture table( ID , Username , IsPrimary)

Each user can have zero to many pictures.

I'm Trying to write a query that will return all users (with or without pictures) and a single picture Id (of the picture with IsPrimary = true).

I wrote this Linq query :

var v = from u in Users
    join p in Photos on u.Username equals p.Username 
    select new
    {
     u.Username,
     p.ID
          };

This works but returns duplicate user rows. (if user has more than one photo).

I want to get one row per user. Is that possible?

+1  A: 

This should do exactly what you want.

from u in Users
let p = Photos.Where(p => p.Username == u.Username).FirstOrDefault()
where p <> null
select new
{
    u.Username,
    p.ID
};

However, it is worth noting that you may be better off writing hand optimized SQL and retrieving the objects using db.ExecuteQuery<User> or similar.

John Gietzen
Is this query really bad for performance?
Shar
No, not really. It should do just fine; but, it seems a little wonky.
John Gietzen
+1  A: 

You could use grouping:

from p in photos
group p by p.username into g
select new
    {
     Username = g.Key,
     PicId = g.First().Id
    };

Instead of First() you could do some other filtering...

Will
Should this go with my join code or as a standlone?can you write the complete code plz?
Shar
Your join code was useless, as you were just grabbing the username from the users table, where the pictures table *already had this*. Take advantage of situations like this.
Will
I see. but this query doesn't enable me to select certian users .i want to first select users based on several params(lets say for example Username>1000) and then get a photo for each user.
Shar
+1  A: 

You should put IsPrimary in a where condition. Plus, since a user can have zero picture, you need a left join.

EDIT: exmaple is following, (may have typo)

from u in Users
join p in (from p1 in Pictures where p1.IsPrimary select p1) on u.Username equals p.Username into pp
from p in pp.DefaultIfEmpty()
select new
{
  u.UserName,
  PicturePath = p == null ? "DummyPath" : p.PicturePath
}

EDIT: By the way, John Gietzen answer seems does not give the answer you were asking.

Codism
Any chance you can give me an example? plz.
Shar
A: 

var upic = from u in users
           join p in pictures on u.UserName equals p.UserName into g
           from o in g.DefaultIfEmpty()
          where o == null || o.IsPrimary == true
         select new { UserName = u.UserName, Id = ( o == null ? "(No picture)" : o.Id ) };

Partha Choudhury