views:

883

answers:

2

I am using LINQ and am having a hard time understanding how I can make new "domain model" classes work within LINQ while querying across tables. I am using Linq to SQL, and C# in .NET 3.5.

Suppose I want an Extended Client class:

public class ExtendedClient 
{
    public int ID { get; set; }
    public string Name { get; set; }
    public string strVal { get; set; }
}

and in my data layer, I want to populate this from two tables (dc is my DataContext):

public ExtendedClient getExtendedClient(int clientID)
{
    var c = dc.GetTable<tClient>();
    var cs = dc.GetTable<tClientSetting>();
    var q = from client in c
            join setting in cs
            on client.ClientID equals setting.ClientID
            where client.ClientID == clientID
            select new ExtendedClient { client, setting.strValue };
    return q;   
}

I am trying to return the row in the table tClient plus one extra column in tClientSetting.

The annoying errors I get are : Cannot initialize type 'ExtendedClient' with a collection initializer because it does not implement 'System.Collections.IEnumerable' and Cannot implicitly convert type 'System.Linq.IQueryable' to 'ExtendedClient'. An explicit conversion exists (are you missing a cast?)

I realize this is a basic error, but I cannot determine how BEST to implement the IEnumerable because I cannot find an example.

Do I have to do this every time I want a specialized object? Thanks in advance.

+2  A: 
public ExtendedClient getExtendedClient(int clientID)
{
    var c = dc.GetTable<tClient>();
    var cs = dc.GetTable<tClientSetting>();
    var q = from client in c
            join setting in cs
            on client.ClientID equals setting.ClientID
            where client.ClientID == clientID
            select new ExtendedClient { ID = client.ClientID, Name = client.Name, strVal = setting.strValue };
    return q.Single();
}

You'll have to do a similar thing every time you need to return a specialized object. If you don't need to return it, you don't have to specify the type and you won't need a special class. You could use anonymous types:

from client in c
join setting in cs
on client.ClientID equals setting.ClientID
where client.ClientID == clientID
select new { ID = client.ClientID, Name = client.Name, strVal = setting.strValue };
Mehrdad Afshari
A: 

Why do you use a special type for this?

I think you can do client.Settings.strValue if you setup the Client-Settings relationship to create a property Client.Settings (instead of Settings.Client). And as far as I remember such configuration is possible in LINQ.

Andrey Shchekin