Linq to sql LINQtoSQL急切地加载整个对象图
我需要从某一点向下加载整个LINQ到SQL对象图,加载所有子集合和其中的对象等。这将用于将对象结构和数据转储到XMLLinq to sql LINQtoSQL急切地加载整个对象图,linq-to-sql,eager-loading,Linq To Sql,Eager Loading,我需要从某一点向下加载整个LINQ到SQL对象图,加载所有子集合和其中的对象等。这将用于将对象结构和数据转储到XML 有没有一种方法可以在不生成大量硬编码的DataLoadOptions集的情况下“塑造”我的数据?没有,我认为没有 是的,您可以使用投影a.k.a.选择来执行此操作。linqtosqlselect将启用优化查询并仅检索所需内容。有两种基本情况。一个沿着关系树向上移动,从多到一,另一个向下移动,从一到多。以下是多对一的示例: var unshippedOrders = fro
有没有一种方法可以在不生成大量硬编码的DataLoadOptions集的情况下“塑造”我的数据?没有,我认为没有 是的,您可以使用投影a.k.a.选择来执行此操作。linqtosqlselect将启用优化查询并仅检索所需内容。有两种基本情况。一个沿着关系树向上移动,从多到一,另一个向下移动,从一到多。以下是多对一的示例:
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将为您解决这个问题。在我的示例中,我使用了匿名类型,但也可以使用普通的旧命名类型。我认为您甚至可以通过在LINQtoSQL查询中创建XElement节点,将LINQtoSQL代码与LINQtoXML混合使用:-。天空是极限
见鬼,让我举一个例子,如果LINQ转换为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);
如果不希望手动维护这些DataLoadOptions,可以使用生成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
有没有一种方法可以自动完成?不,据我所知不是。不过,我可以建议您尝试一种方法。我没有一个有效的例子,但它应该有效。您可以使用反射来检查根对象的属性,查找属于EntitySets子集合的属性。每次找到一个时,都可以使用该信息以编程方式动态构建DataLoadOptions。添加一点递归,一些重复检查,你应该被设置。@Mel-有趣的想法-我可能会考虑这样做,但我开始对一个大的SQL结果集有点警惕,它急切地加载所有内容,b采取一个缓慢的操作并向其添加反射,只是为了让它慢一点。。。回到绘图板上,我认为。答案不错,但仍然需要在投影中对整个层次结构进行编码,这会有点麻烦,因为它相当深。我认为这里的关键概念是,假设你想要一个完整的图形,这是因为你打算在最远的叶子上执行一些操作。只要这些叶子在投影中被表示,那么你就应该得到你想要的。如果你没有叶子的特定用途,那么为什么要首先检索它们呢?