代码之家  ›  专栏  ›  技术社区  ›  Paddy

linq to sql急切地加载整个对象图

  •  2
  • Paddy  · 技术社区  · 14 年前

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

    有没有一种方法可以做到这一点,而不生成一个大的硬编码数据加载选项集来“塑造”我的数据?

    3 回复  |  直到 14 年前
        1
  •  2
  •   Dave Markle    14 年前

    不,我不相信有。

        2
  •  2
  •   Steven    14 年前

    是的,你可以用投影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
                }
        };
    

    如您所见,在第二个查询中,我有另一个子查询,LinqToSQL将为您解决这个问题。在我的示例中,我使用匿名类型,但您也可以使用普通的旧命名类型。我认为通过在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
  •  0
  •   Peter T. LaComb Jr.    14 年前

    如果不想手动维护这些数据加载选项,可以使用 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