Как заполнить POCO (дочернее) свойство IList из запроса Linq2Sql? - PullRequest
4 голосов
/ 16 декабря 2008

У меня есть два класса:

public class Question
{
    public IList<Answer> Answers { get; set; }
}

public class Answer
{ .. }

В моем конструкторе Linq2Sql на конструкторе есть два объекта L2S с правильной стрелкой 0 <-> между ними. Kewl.

Я не уверен, как я могу получить эти вопросы / ответы за один вызов и заполнить мои объекты POCO ..

это то, что у меня есть ... кто-то может заполнить пробелы?

public IQueryable<Question> GetQuestions()
{
    return from q in _db.Questions
        select new Question
            {
                Title = q.Title,
                Answers = ????????   // <-- HALP! :)
            };
}

мысли

Обновление: Война POCO

Спасибо за ответы, но это еще не 100%.

Во-первых, я возвращаю класс POCO, а не класс контекста Linq2Sql. Вот почему я делаю ...

select new Question { .. };

этот класс - POCO, а не linq2sql.

Во-вторых, мне нравятся ответы, которые указывают на выполнение Responers = q.Answers.ToList (), но это также не будет работать, поскольку он пытается установить класс Linq2Sql в класс POCO.

Ответы [ 4 ]

8 голосов
/ 16 декабря 2008

Если между вашими классами LINQ to SQL есть связь, то для класса LINQ to SQL «Вопрос» должно быть сгенерировано свойство «Ответы». Таким образом, вы должны иметь возможность просто сделать это:

return from q in _db.Questions
       select new Question
       {
           Title = q.Title,
           Answers = q.Answers.ToList(),
       }

Возможно, вы сможете опустить вызов ToList () - я не уверен, какой тип LINQ to SQL использует для сгенерированных связанных строк (я полагаю, это IQueryable<T>).

Чтобы принудительно заполнить свойство «Ответы», а не запускать другой запрос для каждого вопроса, вы можете использовать класс DataLoadOptions . По сути, вы указываете LINQ to SQL загружать ответы каждый раз, когда задаете вопросы (используя метод LoadWith - см. Документацию MSDN).

Редактировать

Вы правы - поскольку ваше свойство Question.Answers является списком вашего собственного POCO, присвоение его с помощью q.Answers не является подходящим способом. Это может работать лучше:

return from q in _db.Questions
       select new Question
       {
           Title = q.Title,
           Answers = (from a in q.Answers
                     select new Answer { ... }).ToList(),
       }
2 голосов
/ 16 декабря 2008

Связанные данные обычно обрабатываются с помощью класса EntitySet<T> (свойство создается для вас, если вы используете сгенерированный dbml-код).

Ассоциации могут быть ленивыми или рано загруженными; по умолчанию, lazy (то есть он загружается при первой необходимости), но чтобы заставить его загружаться раньше, используя DataLoadOptions / LoadWith() - см. здесь . Чтобы скопировать пример со страницы MSDN:

Northwnd db = new Northwnd(@"c:\northwnd.mdf");
DataLoadOptions dlo = new DataLoadOptions();
dlo.LoadWith<Customer>(c => c.Orders);
db.LoadOptions = dlo;

var londonCustomers =
    from cust in db.Customers
    where cust.City == "London"
    select cust;

foreach (var custObj in londonCustomers)
{
    Console.WriteLine(custObj.CustomerID);
}

Здесь LoadWith означает, что при загрузке Customer их Orders выбираются одновременно. Это полезно, если вы знаете, какие связанные данные вам понадобятся. Без этого он мог бы выполнить еще один запрос TSQL * за Customer**, чтобы получить эти данные (но только если / когда вы их запросили).

0 голосов
/ 27 декабря 2008

Это даже проще. Предполагая, что ваша схема базы данных нормализована и содержит правильные отношения, просто переключитесь на отложенную загрузку в false:

частный DBDataContext mDB = новый DBDataContext (ConfigurationManager.ConnectionStrings ["KeyFromWebConfig"]. ConnectionString);

mDB.DeferredLoadingEnabled = false

Теперь любой запрос linq, использующий mDB, будет также извлекать дочерние объекты. Конечно, вы можете включать и выключать это по мере необходимости, чтобы минимизировать влияние на производительность.

0 голосов
/ 16 декабря 2008

если тип Вопроса, который вы возвращаете, совпадает с типом в _db. Вопросы, которые вы можете просто написать

return (from q in _db.Questions
        select q).ToList();
...