我需要从某个点向下加载整个LINQ-to-SQL对象图,加载所有子集合及其中的对象等。这将用于将对象结构和数据转储到XML。
有没有办法在不生成大型硬编码DataLoadOptions集来“塑造”我的数据的情况下这样做?
答案 0 :(得分:2)
不,我不相信有。
答案 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);
答案 2 :(得分: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