Linq to SQL: тип возвращаемого значения соединения нескольких таблиц, не сгенерированный dbml

Я пытаюсь найти лучший способ решить простую проблему: у меня есть простое соединение LINQ с двумя таблицами. Я знаю, как вернуть тип для одной таблицы, поскольку он совпадает с сгенерированным классом dbml. Однако что, если я хочу вернуть данные из обеих таблиц - разве нет способа вернуть обе и использовать их отношения? Мне действительно нужно создавать другой тип возвращаемого значения, чтобы возвращать данные из обеих таблиц? К вашему сведению, я не хочу возвращать выходной параметр с другим объектом таблицы; Я также не очень заинтересован в возврате анонимного типа. Какая рекомендация лучше всего?

    public IQueryable<Consumer_Question> GetQuestions(int subCategoryId)
    {
        //create DataContext
        MototoolsDataContext mototoolsDataContext = new MototoolsDataContext();
        mototoolsDataContext.Log = Console.Out;

        var subcategoriestag = (from subCatTag in mototoolsDataContext.Consumer_SubCategoriesTags
                                join tagQuestion in mototoolsDataContext.Consumer_TagQuestions on subCatTag.TagID equals tagQuestion.TagID
                                join question in mototoolsDataContext.Consumer_Questions on tagQuestion.QuestionsID equals question.ID
                                where subCatTag.SubCategoriesID == subCategoryId
                                orderby subCatTag.ID descending
                                select question);
                                //select new { question, tagQuestion });

        return subcategoriestag;
    }

Спасибо за любую помощь,


person mytwocents    schedule 16.09.2009    source источник


Ответы (2)


Если вы определили свои отношения в конструкторе LINQ-to-SQL, то вашему вышеуказанному запросу синтаксис соединения вообще не нужен, просто «пройдитесь по дереву» по мере необходимости, например:

var subCategoriesTag = (
    from subCatTag in motoToolsDataContext
    from tagQuestion in subCatTag.TagQuestions
    from question in tagQuestion
    where subCatTag.SubCategoriesID == subcategoryId
    orderby subCatTag.ID descending
    select question
);

Обратите внимание, что 2-й и 3-й операторы «from» используют объект из предыдущего, поскольку LINQ-to-SQL уже должен знать об отношении.

Не зная больше о ваших отношениях, труднее дать более точный ответ. Мне пришлось сделать некоторые предположения о связанных свойствах.

person Timothy Walters    schedule 16.09.2009
comment
Возникает другой вопрос: если я уже назначил отношения своим таблицам в базе данных (первичные ключи, внешние ключи), я заметил, что созданный dbml класс создает для меня атрибут ассоциации для некоторых отношений, а не для всех. Так вы говорите, что если эта ассоциация отношений построена правильно, то я могу вернуть родительский тип и пройтись с детьми? Это то, что я хочу! Мне придется исследовать ошибку ассоциации dbml, которая у меня, кажется, есть. - person mytwocents; 17.09.2009
comment
Оказывается, проблема с dbml, генерирующим мои атрибуты ассоциаций для отношений, заключалась не в том, что я забыл часть отношения внешнего ключа, а в том, что мне не хватало обозначения первичного ключа в родительской таблице. Теперь я могу перемещаться по дочернему объекту из объекта вопроса и не беспокоиться о настраиваемом возвращаемом типе, включающем все нужные мне данные. Прохладный. - person mytwocents; 18.09.2009
comment
@mytwocents: Рад слышать, что после того, как все настроено правильно, LINQ-to-SQL стал довольно приятным, в нем все еще есть некоторые области, которые немного болезненны, но он, наконец, получил некоторые улучшения для VS2010. - person Timothy Walters; 18.09.2009

Мне кажется, что вы ищете DataLoadOptions.LoadWith ‹>. Таким образом вы возвращаете свой объект Question, и связанные объекты заполняются одновременно с помощью определенных ассоциаций. Что-то вроде этого:

public IQueryable<Consumer_Question> GetQuestions(int subCategoryId)
{
    //create DataContext
    using (MototoolsDataContext mototoolsDataContext = new MototoolsDataContext())
    {
        mototoolsDataContext.Log = Console.Out;
        DataLoadOptions options = new DataLoadOptions();
        options.LoadWith<Consumer_Questions>(q => q.Consumer_TagQuestions);
        options.LoadWith<Consumer_TagQuestions>(tag => tag.Consumer_SubCategoriesTags);
        mototoolsDataContext.LoadOptions = options;

        var questions = (from subCatTag in mototoolsDataContext.Consumer_SubCategoriesTags
                                join tagQuestion in mototoolsDataContext.Consumer_TagQuestions on subCatTag.TagID equals tagQuestion.TagID
                                join question in mototoolsDataContext.Consumer_Questions on tagQuestion.QuestionsID equals question.ID
                                where subCatTag.SubCategoriesID == subCategoryId
                                orderby subCatTag.ID descending
                                select question);
                                //select new { question, tagQuestion });

        return questions;
    }
}
person Jacob Proffitt    schedule 17.09.2009
comment
Да, это тоже сработает, но разве LoadWith не подходит для немедленной загрузки? - person mytwocents; 18.09.2009
comment
Правильный. Он извлечет все значения вместе. - person Jacob Proffitt; 18.09.2009