我正在使用实体框架5进行如下查询:
var query =
from i in context.Instrument
from p in i.InstrumentPerformance // 1 : n
where p.PortfolioScenarioID == 6013
select i;
我想在内存中存储此(已过滤)查询的可查询表示。理想情况下,我可以断开上下文并仍然请求特定的InstrumentPerformance集合,如下所示:
var perf = query.First(i => i.InstrumentID == 407240).InstrumentPerformance;
但是 - 当然 - 这不会产生预期的结果,因为“perf”对象将包含一个InstrumentPerformance集合,其中包含每个1:n加入的InstrumentPerformance实体(无论其PortfolioScenarioID是否为6013),它将检索这些实体通过延迟加载,使用context.ContextOptions.LazyLoadingEnabled = false(或超出范围的上下文)查询不会产生任何结果。
所以这远远不是我想要的地方:从原始查询中轻松查询内存中表示。我试图实现字典和类似的方法,但最终编码自定义数据对象的结果,我想避免。
所以我的问题是:获取此类内存中视图的推荐方法是什么?
编辑: 我目前正在使用两个字典来缓存数据,例如:
var instruments = (
from i in context.Instrument
from p in i.InstrumentPerformance
where p.PortfolioScenarioID == 6013
select i)
.ToDictionary (i => p.InstrumentID, i => i);
var performances = (
from i in context.Instrument
from p in i.InstrumentPerformance
where p.PortfolioScenarioID == 6013
select p)
.ToDictionary (p => p.InstrumentID, p => p);
然而,这需要两次到数据库的往返,其中一个看起来足够,更重要的是查询性能数据的语义(现在是性能[InstrumentID])与EF查询方式(应该是instrument.InstrumentPerformance)不一致.First()之类的。)
答案 0 :(得分:1)
可以首先检索一个对象,然后通过以下方式创建词典:
var query =
(from i in context.Instrument
select new {
i,
ps = i.InstrumentPerformance
.Where(p.PortfolioScenarioID == 6013)
}).AsEnumerable()
.Select(x => x.i);
这实现并选择了Instrument
个实体,这就是技巧,它们的部分加载的 InstrumentPerformance
集合。即这些工具仅包含符合条件InstrumentPerformance
的{{1}}个实体。这是因为EF运行称为 relationship fixup 的过程,当从数据库中提取子对象时,它们将子对象绑定到右父对象。
所以现在你可以处理上下文以及之后的任何时间
PortfolioScenarioID == 6013
或使用var perf = query.First(i => i.InstrumentID == 407240).InstrumentPerformance;
代替from i in query
来构建词典。
重要提示:应禁用延迟加载,否则EF会在解决后仍尝试加载完整的收藏。
答案 1 :(得分:0)
查看EntityCollection<T>
CreateSourceQuery和Attach。我想你可以这样做(未经测试):
var instrumentQuery =
from i in context.Instrument
from p in i.InstrumentPerformance // 1 : n
where p.PortfolioScenarioID == 6013
select i;
var instruments = instrumentQuery.ToList();
foreach (var instrument in instruments) {
var performanceQuery =
instrument.InstrumentPerformance.CreateSourceQuery()
.Where(p => p.PortfolioScenarioID == 6013);
instrument.InstrumentPerformance.Attach(performanceQuery);
}
这会立即执行所有操作(没有延迟加载)并且有一些代码重复,但它会生成Instrument
列表,其中每个i.InstrumentPerformance
返回已过滤的集合,这意味着任何后续代码对其进行操作可以将其视为任何其他EF集合,而无需了解查询的详细信息。