Реализация IEnumerable

Я использую LINQ, и мне трудно понять, как я могу заставить новые классы «модели предметной области» работать в LINQ при выполнении запросов между таблицами. Я использую Linq to SQL и С# в .NET 3.5.

Предположим, мне нужен класс расширенного клиента:

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

и в моем слое данных я хочу заполнить это из двух таблиц (dc - это мой 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;   
}

Я пытаюсь вернуть строку в таблице tClient плюс один дополнительный столбец в tClientSetting.

Досадные ошибки, которые я получаю: Не удается инициализировать тип «ExtendedClient» с помощью инициализатора коллекции, поскольку он не реализует «System.Collections.IEnumerable» и не может неявно преобразовать тип «System.Linq.IQueryable» в «ExtendedClient». Существует явное преобразование (вам не хватает приведения?)

Я понимаю, что это основная ошибка, но я не могу определить, как ЛУЧШЕ реализовать IEnumerable, потому что я не могу найти пример.

Должен ли я делать это каждый раз, когда мне нужен специализированный объект? Заранее спасибо.


person Ash Machine    schedule 16.02.2009    source источник


Ответы (2)


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

Вам придется делать подобное каждый раз, когда вам нужно вернуть специализированный объект. Если вам не нужно возвращать его, вам не нужно указывать тип, и вам не понадобится специальный класс. Вы можете использовать анонимные типы:

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 };
person mmx    schedule 16.02.2009

Почему вы используете специальный тип для этого?

Я думаю, что вы можете сделать client.Settings.strValue, если вы настроите отношение Client-Settings для создания свойства Client.Settings (вместо Settings.Client). И насколько я помню такая конфигурация возможна в LINQ.

person Andrey Shchekin    schedule 16.02.2009