2

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

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

4

3 回答 3

2

是的,您可以通过使用投影 aka 来做到这一点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);
于 2010-05-12T13:19:43.537 回答
2

不,我不相信有。

于 2010-05-12T12:04:07.363 回答
0

如果您不想手动维护这些 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
于 2010-10-15T22:43:42.490 回答