我正在使用Linq-To-Sql来填充我的业务层。以下是我正在处理的查询的片段:
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执行查询。无论如何,我可以重新设计这个以保持相同的业务对象结构(IE-与基金的关系 - > FundEntity - >业务对象中的CapitalCall),但一次加载完整的表?理想情况下,会有一个带有大量连接的SQL查询,这会产生一个完全填充的基金。
答案 0 :(得分:3)
问题的解决方案是同时执行多个查询并将结果数据绑定在一起。虽然LINQ to SQL可以执行此操作,但它本身不支持此类功能。
PLINQO是一个开源替代品,它是LINQ to SQL的替代品,它为框架增加了额外的功能。特别是,您会对批量查询和未来查询感兴趣。
上查看希望有所帮助! -Tom DuPont(PLINQO开发团队成员)
答案 1 :(得分:1)
var fund = GetFund();
var fundGroup = GetFundGroup();
var dataContest = GetDataContext();
List<int> feIds = fundGroup.tFunds.Select(fe => fe.FundEntityId).ToList();
//before: iterate through local collection fundGroup.tFunds
// and issue one CapitalCall query per fundEntity.
//after: send all the fundEntityIds into the database in one query
// that also fetches related CapitalCalls.
var query =
from fe in dataContext.tFunds
where feIds.Contains(fe.FundEntityId))
let capitalCalls = fe.tCapitalCalls
select new {FundEntity = fe, CapitalCalls = capitalCalls.ToList() };
foreach(var record in query)
{
FundEntity fundEntity = new FundEntity()
{
CloseDate = record.fe.closeDate ?? new DateTime(),
...
}
fundEntity.CapitalCalls = ...
}
答案 2 :(得分:0)
对我而言似乎是你倒退而不是前锋。你正试图去基金 - &gt; FundEntity - &gt; CapitalCalls,但随后试图给每个人一个对其容器的引用。
您可以考虑对数据库进行更简单的查询,在其上调用ToList
,然后使用Linq to Objects将其重新投影到所需的结构中。
您还可以考虑以其他方式编写查询并使用group by。从概念上讲,您将获得资本要求,并按基金实体对其进行分组,然后按基金对这些进行分组。
如果您认为没有容器引用就可以生存,那么您拥有的查询可以表示如下,该查询应该在一个查询中使用连接。
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
};
}
}
});
答案 3 :(得分:0)
我会选择像SteadyEddi这样的东西(我包含了FundEntity),但我认为你可以像你想要的那样表达它(或者像SteadyEddi那样的非LINQ方式):
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
}
}
如果没有,我认为你的数据库映射正在发生的事情,无论如何都应该重新考虑:)错误的名称等等.DateDate == CommitmentEndDate。您的代码的问题可能是您自己构建CapitalCalls,因此LINQ-TO-SQL可能无法正确解码表达式树。但同样,我显然没有测试我的代码,所以我不知道我的代码是否有效。