C# 如何优化此LINQ查询以仅执行单个SQL命令?
我正在使用LINQtoSQL填充我的业务层。下面是我正在处理的查询的一个片段:C# 如何优化此LINQ查询以仅执行单个SQL命令?,c#,linq,linq-to-sql,C#,Linq,Linq To Sql,我正在使用LINQtoSQL填充我的业务层。下面是我正在处理的查询的一个片段: fund.FundEntities = fundGroup.tFunds .Select(fe => { var fundEntity = new FundEntity() { BankAccount = null, CloseDate = fe.closeDate ?? new DateTime(),
fund.FundEntities = fundGroup.tFunds
.Select(fe =>
{
var fundEntity = new FundEntity()
{
BankAccount = null,
CloseDate = fe.closeDate ?? new DateTime(),
Commitment = fe.commitment ?? 0,
CommitmentEndDate = fe.closeDate ?? new DateTime(),
Fund = fund
};
fundEntity.CapitalCalls = fe.tCapitalCalls
.Select(cc =>
{
return new CapitalCall()
{
Amount = cc.agrAmount ?? 0,
FundEntity = fundEntity
};
}
);
return fundEntity;
});
当我运行这段代码时,它会在运行时执行对单个CapitalCalls的查询。我是否可以重新构建它以保持相同的业务对象结构(即,业务对象中来自Fund->FundEntity->CapitalCall的关系),但一次加载完整的表?理想情况下,将有一个包含大量联接的SQL查询,这将导致一个完全填充的基金。问题的解决方案是同时执行多个查询并将其结果数据绑定在一起。虽然LINQtoSQL可以做到这一点,但它本身并不支持这种功能 PLINQO是LINQtoSQL的开源替代品,它为框架添加了额外的功能。特别是,您会对批处理查询和将来的查询感兴趣 查看
希望有帮助-Tom DuPont(PLINQO开发团队成员)该问题的解决方案是同时执行多个查询并将其结果数据绑定在一起。虽然LINQtoSQL可以做到这一点,但它本身并不支持这种功能 PLINQO是LINQtoSQL的开源替代品,它为框架添加了额外的功能。特别是,您会对批处理查询和将来的查询感兴趣 查看 希望有帮助-Tom DuPont(PLINQO开发团队成员)
var fund=GetFund();
var fundGroup=GetFundGroup();
var dataContest=GetDataContext();
List feIds=fundGroup.tFunds.Select(fe=>fe.FundEntityId.ToList();
//之前:迭代本地集合fundGroup.tFunds
//并为每个基金实体发出一个CapitalCall查询。
//之后:在一次查询中将所有FundEntityId发送到数据库中
//这也会获取相关的资本调用。
变量查询=
来自dataContext.tFunds中的fe
其中feIds.Contains(fe.FundEntityId))
设capitalCalls=fe.tCapitalCalls
选择new{FundEntity=fe,CapitalCalls=CapitalCalls.ToList()};
foreach(查询中的var记录)
{
FundEntity FundEntity=新的FundEntity()
{
CloseDate=record.fe.CloseDate??新日期时间(),
...
}
fundEntity.CapitalCalls=。。。
}
var-fund=GetFund();
var fundGroup=GetFundGroup();
var dataContest=GetDataContext();
List feIds=fundGroup.tFunds.Select(fe=>fe.FundEntityId.ToList();
//之前:迭代本地集合fundGroup.tFunds
//并为每个基金实体发出一个CapitalCall查询。
//之后:在一次查询中将所有FundEntityId发送到数据库中
//这也会获取相关的资本调用。
变量查询=
来自dataContext.tFunds中的fe
其中feIds.Contains(fe.FundEntityId))
设capitalCalls=fe.tCapitalCalls
选择new{FundEntity=fe,CapitalCalls=CapitalCalls.ToList()};
foreach(查询中的var记录)
{
FundEntity FundEntity=新的FundEntity()
{
CloseDate=record.fe.CloseDate??新日期时间(),
...
}
fundEntity.CapitalCalls=。。。
}
在我看来,你是在倒退,而不是前进。您正在尝试转到Fund->FundEntity->CapitalCalls,但随后尝试为每个帐户提供对其容器的引用
你可以考虑对数据库做一个简单的查询,在上面调用<代码> Toistist<代码>,然后使用LINQ to对象重新投影到你想要的结构。
您也可以考虑以另一种方式编写查询,并使用GROUPBY。从概念上讲,您将获得资本调用,并按基金实体对其进行分组,然后按基金对其进行分组
如果您认为没有容器引用也可以生存,那么您所拥有的查询可以表示为如下所示,它应该在一个查询中使用联接fund.FundEntities = fundGroup.tFunds
.Select(fe =>
{
new FundEntity
{
BankAccount = null,
CloseDate = fe.closeDate ?? new DateTime(),
Commitment = fe.commitment ?? 0,
CommitmentEndDate = fe.closeDate ?? new DateTime(),
CapitalCalls = fe.tCapitalCalls
.Select(cc =>
{
new CapitalCall
{
Amount = cc.agrAmount ?? 0
};
}
}
});
在我看来,你是在倒退,而不是前进。您正在尝试转到Fund->FundEntity->CapitalCalls,但随后尝试为每个帐户提供对其容器的引用
你可以考虑对数据库做一个简单的查询,在上面调用<代码> Toistist<代码>,然后使用LINQ to对象重新投影到你想要的结构。
您也可以考虑以另一种方式编写查询,并使用GROUPBY。从概念上讲,您将获得资本调用,并按基金实体对其进行分组,然后按基金对其进行分组
如果您认为没有容器引用也可以生存,那么您所拥有的查询可以表示为如下所示,它应该在一个查询中使用联接fund.FundEntities = fundGroup.tFunds
.Select(fe =>
{
new FundEntity
{
BankAccount = null,
CloseDate = fe.closeDate ?? new DateTime(),
Commitment = fe.commitment ?? 0,
CommitmentEndDate = fe.closeDate ?? new DateTime(),
CapitalCalls = fe.tCapitalCalls
.Select(cc =>
{
new CapitalCall
{
Amount = cc.agrAmount ?? 0
};
}
}
});
我会选择像SteadyEddi这样的东西(包括FundEntity),但我认为你可以像这样表达它(或者类似于SteadyEddi的非LINQ方式):
如果不是这样,我认为您的数据库映射中发生了一些事情,无论如何都应该重新考虑:)坏名称等。CloseDate==commissionenddate。代码的问题可能是您自己在构造CapitalCalls,因此LINQ-TO-SQL可能无法正确解码表达式树。但是,很明显,我还没有测试我的代码,所以我不知道我的代码是否有效 我会选择像SteadyEddi这样的东西(包括FundEntity),但我认为你可以像这样表达它(或者类似于SteadyEddi的非LINQ方式):
如果不是这样,我认为您的数据库映射中发生了一些事情,无论如何都应该重新考虑:)坏名称等。CloseDate==commissionenddate。代码的问题可能是您自己在构造CapitalCalls,因此LINQ-TO-SQL可能无法正确解码表达式树。但是,很明显,我还没有测试我的代码,所以我不知道我的代码是否有效 调用ToList()的原因是什么?因为FundEntity上的CapitalCall属性的类型是ListHrmm,我想我可以将它们设置为IENumber,但在运行时它们仍然会被逐个查询…
ToList()
fund.FundEntities =
from fe in fundGroup.tFunds
select new FundEntity()
{
BackAccount = null,
CloseDate = fe.closeDate ?? new DateTime(),
Commitment = fe.commitment ?? 0,
CommitmentEndDate = fe.closeDate ?? new DateTime(),
Fund = fund,
CapitalCalls = from cc in fe.tCapitalCalls
select new CapitalCall()
{
Amount = cc.agrAmount ?? 0,
FundEntity = fundEntity
}
}