I use Linq for Entities in code, but I often use LINQ to SQL in LINQPad, and I am pretty familiar with it. I'm not quite sure that I understand where you ran into difficulties, but I think the following should work:
var sites = from s in DataContext.Sites orderby s.PrimaryAddress.AddressLine1, s.PrimaryAddress.City, s.PrimaryAddress.State, s.PrimaryAddress.Country select new { s.Id, s.SiteName, s.PrimaryAddress };
Let me know if there is something that I do not understand.
Update
I am not sure why this does not work for you. I just did the following in LINQPad (LINQ to SQL mode):
from p in person orderby p.clue_type.clue_type_id, p.clue_type.clue_type select new { p.person_id, p.clue_type }
All results have clue_type = null. LINQ to SQL simply treats null references as values ββwith all-null properties. Here is the generated SQL:
SELECT TOP (10) [t0].[person_id], [t2].[test], [t2].[clue_type_id], [t2].[clue_type] FROM [person] AS [t0] LEFT OUTER JOIN ( SELECT 1 AS [test], [t1].[clue_type_id], [t1].[clue_type] FROM [clue_types] AS [t1] ) AS [t2] ON [t2].[clue_type_id] = [t0].[clue_type_id] ORDER BY [t2].[clue_type_id], [t2].[clue_type]
Pay attention to the LEFT OUTER JOIN. Would it not do what you ask for?
Update 2
Creating a dynamic query can be quite complicated, depending on how dynamically you create it. Here is one solution if you want to be able to order on any of the properties that you return, based on the string value that is passed to your method:
public class SiteDisplayInfo { public int Id {get;set;} public string SiteName {get;set;} public string PrimaryAddress {get;set;} public static readonly Dictionary<string, Func<IQueryable<Site>, IOrderedQueryable<Site>>> OrderByFuncs = new Dictionary<string, Func<IQueryable<Site>, IOrderedQueryable<Site>>> { {"Id", q => q.OrderBy(s => s.Id)}, {"SiteName", q => q.OrderBy(s => s.SiteName)}, {"PrimaryAddress", q => q.OrderBy(s => s.PrimaryAddress.AddressLine1) .ThenBy(s => s.PrimaryAddress.City)} }; } ... public IEnumerable<SiteDisplayInfo> GetSites(string orderByString) { IQueryable<Site> sites = DataBase.Sites; if (orderByString != null && SiteDisplayInfo.OrderByFuncs.ContainsKey(orderByString)) { sites = SiteDisplayInfo.OrderByFuncs[orderByString](sites); } var query = from s in sites select new SiteDisplayInfo { Id = s.Id, SiteName = s.SiteName, PrimaryAddress = s.PrimaryAddress.AddressLine1 + s.PrimaryAddress.City }; return query.ToList(); }
There are several other ways to do something like this, but it gives you an idea.