【问题标题】:How do i populate a POCO (child) IList property from a Linq2Sql query?如何从 Linq2Sql 查询中填充 POCO(子)IList 属性?
【发布时间】:2010-09-27 02:33:14
【问题描述】:

我有两个班:

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

public class Answer
{ .. }

在我的 Linq2Sql 设计器中,设计器上有两个 L2S 对象,它们之间有正确的 0many 箭头。邱尔。

我不确定如何在一次调用中检索这些问题/答案并填充我的 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。

其次,我喜欢指向执行 Answers = q.Answers.ToList() 的答案,但这也不起作用,因为它试图将 Linq2Sql 类设置为 POCO 类。

【问题讨论】:

  • 您不需要“选择新问题” - 只需“选择 q”;事实上,LINQ-to-sql 不会让你这样做。
  • 嗨,马克 - 我已经在主要问题中添加了一个更新,以帮助澄清我为什么要这样做。

标签: .net linq-to-sql poco


【解决方案1】:

如果您的 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&lt;T&gt;)。

要强制预先填充 Answers 属性,而不是为每个问题触发另一个查询,您可以使用 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(),
       }

【讨论】:

  • 是否会调用 ToList() 意味着查询会在 那个时间点被触发到数据库...或者它会在完整查询被“触发”时发生.此外,它会生成 sql 作为主查询的一部分,还是作为第二次往返的一部分?
  • 我会为你补充答案。
  • 嗯。它仍然无法正常工作。我得到了结果(好),但它不是一个 db 往返(坏)。另外,我不能返回 Answers.ToList() 因为那不是 POCO --> 你会更新我的主要问题来解释。
  • 谢谢 -> 这很好用。另外,我检查了 SQL Profiler,当我执行上述 sub-linq-query 时,我不需要 DataLoadOptions。
【解决方案2】:

关联数据通常通过EntitySet&lt;T&gt; 类处理(如果您使用 dbml 生成的代码,则会为您创建该属性)。

关联可以是惰性的或提前加载的;默认情况下,惰性(即它在第一次需要时加载) - 但要使用 DataLoadOptions/LoadWith() 强制它提前加载 - 请参阅 here。要复制 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 查询 *per Customer** 以获取此数据(但仅当/当您要求时)。

【讨论】:

    【解决方案3】:

    如果您返回的 Question 类型与 _db.Questions 中的类型相同,您可以编写

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

    【讨论】:

      【解决方案4】:

      这更容易。假设您的数据库模式已规范化并包含正确的关系,只需将延迟加载切换为 false:

      私有 DBDataContext mDB = new DBDataContext(ConfigurationManager.ConnectionStrings["KeyFromWebConfig"].ConnectionString);

      mDB.DeferredLoadingEnabled = false

      现在任何使用 mDB 的 linq 查询也将获取子对象。当然,您可能希望根据需要打开和关闭此功能,以尽量减少对性能的影响。

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2011-06-09
        相关资源
        最近更新 更多