【问题标题】:LINQ-to-SQL eagerly load entire object graphLINQ-to-SQL 急切地加载整个对象图
【发布时间】:2010-10-16 06:43:42
【问题描述】:

我需要从某个点向下加载整个 LINQ-to-SQL 对象图,加载所有子集合及其中的对象等。这将用于将对象结构和数据转储到XML。

有没有办法在不生成大量硬编码的 DataLoadOptions 来“塑造”我的数据的情况下做到这一点?

【问题讨论】:

  • 有没有办法自动完成?不,不是我知道的。但是,我可以建议您可能想尝试的方法。我没有这方面的工作示例,但它应该可以工作。您可以使用反射来检查根对象的属性,查找属于实体集(子集合)的属性。每次找到一个时,您都可以使用该信息以编程方式即时构建 DataLoadOptions。添加一些递归,一些重复检查,你应该被设置。
  • @Mel - 有趣的想法 - 我可能会看看做类似的事情,但我开始对(a)大型 SQL 结果集急切地加载所有内容和(b ) 进行一次缓慢的操作并为其添加反射只是为了让它慢一点......我认为回到绘图板。

标签: linq-to-sql eager-loading


【解决方案1】:

不,我不相信有。

【讨论】:

    【解决方案2】:

    是的,您可以通过使用投影 a.k.a. select 来做到这一点。 LINQ to SQL select 将启用优化查询并仅检索需要的内容。有两种基本情况。一个沿着关系树上行,从多到一,另一个沿着关系树下行,从一到多。这是一个多对一的例子:

    var unshippedOrders =
        from order in db.Orders
        where order.ShipDate == null
        select
        {
            OrderId = order.Id,
            CustomerId = order.Customer.Id,
            CustomerName = order.Customer.Name
        };
    

    这里是一个一对多的例子:

    var unshippedOrdersPerCustomer =
        from customer in db.Customers
        select
        {
            CustomerId = customer.Id,
            CustomerName = customer.Name
            UnshippedOrders =
                from order in customer.Orders
                where order.ShipDate == null
                select
                {
                    OrderId = order.Id,
                    OrderPrice = order.Price
                }
        };
    

    如您所见,在第二个查询中,我有另一个子查询,LINQ to SQL 将为您解决这个问题。在我的示例中,我使用了匿名类型,但您也可以使用普通的旧命名类型。我认为您甚至可以通过在您的 LINQ to SQL 查询中创建 XElement 节点来将您的 LINQ to SQL 代码与您的 LINQ to XML 混合使用:-)。天空才是极限。


    什么鬼,让我举个例子,如果 LINQ to SQL+XML。

    XElement xml = new XElement("customers", 
        from customer in db.Customers
        select new XElement("customer",
            from order in customer.Orders
            where order.ShipDate == null
            select new XElement("order",
                new XAttribute("id", order.Id),
                new XAttribute("price", order.Price)
            )
        ));
    
    Console.WriteLine(xml);
    

    【讨论】:

    • 不错的答案,但仍然需要在投影中编码出整个层次结构,这会有点麻烦(它相当深)。
    • 我认为这里的关键概念是,如果你想要一个完整的图表,那是因为你有一些你打算在它最远的叶子上执行的操作。只要这些叶子在投影中表示出来,那么你应该得到你想要的。如果您对叶子没有特定用途,那么为什么要首先检索它们?
    【解决方案3】:

    如果您不想手动维护这些 DataLoadOptions,您可以使用 T4 Toolbox 生成您的 L2S 类并自定义 DataContext 生成器以构建一个 DataLoadOptions 属性,您可以在需要时将其分配给 DataContext LoadOptions 属性.这就是我所做的,现在,当我想对一个对象及其所有后代进行 XML 序列化时,我可以。

    我将此代码添加到 LinqToSqlDataContextTemplate.tt

        /// <summary>
        /// Sets up a property that will allow loading of all child properties.
        /// This is done to make serializing and entire object graph easier.
        /// </summary>
        private void SetupChildLoading() {
    
    #>
            private DataLoadOptions loadAllChildrenOptions;
    
            public DataLoadOptions LoadAllChildrenOptions
            {
                get
                {
                    if (loadAllChildrenOptions == null) {
                        loadAllChildrenOptions = new DataLoadOptions();
    <#+
        this.PushIndent("                    ");
        foreach (Table t in this.Database.Table) {
            for (int i = 0; i < t.Type.Items.Length; i++)
            {
                Association association = t.Type.Items[i] as Association;
                if (association != null)
                {
                    if (association.AccessModifier == GeneratedTextTransformation.AccessModifier.Public && !association.IsForeignKey) {
                        this.WriteLine("loadAllChildrenOptions.LoadWith<{0}>(Q => Q.{1});",t.Type.Name.ToString(),association.Member);
                    }
                }
            }
        }
        this.PopIndent();
    #>
                    }
                    return loadAllChildrenOptions;
                }
            }
    <#+
        }
    

    在TransformText方法中:

            #region LoadOptions
    <#+ SetupChildLoading(); #>
            #endregion
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2011-03-12
      • 1970-01-01
      • 1970-01-01
      • 2011-02-02
      • 2012-02-13
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多