是否有正确的LINQ导航到以下数据结构的结束叶节点?
Root ----Symbol (APPLE)
| |------Day 1: Date: 2010-10-18, string "Apples on Thursday"
| |------Day 2: Date: 2010-10-19, string "Apples on Friday"
|
|
|-----Symbol (PEAR)
|------Day 1: Date: 2010-10-18, string "Pears on Thursday"
|------Day 2: Date: 2010-10-19, string "Pears on Friday"
换句话说,如果我选择“APPLE”,然后选择“2010-10-19”,它应该返回“星期五的苹果”。
以下不工作(它从符号和日期的每个组合的Cartesian Product中选择)
var daysForSymbolS1 = from Symbol s in db4o.db
from Date t in db4o.db
where (s.SymbolGlobal == "APPLE"
&& t.Date == new DateTime(2010, 10, 18))
select new
{
s.SymbolGlobal,
t.Date,
t.Meta
};
foreach (var d in daysForSymbolS1)
{
Console.WriteLine("{0} - {1} - {2}", d.SymbolGlobal, d.Date.Date, d.Meta);
}
我喜欢使用连接 - 但db4o是一个对象数据库,它不允许您引用每个对象的ID。
更新
@Gamlor给出了一个精彩的答案,它就像一个魅力。
我还应该提一下,db4o的当前版本不支持对集合进行索引。由于任何形式的1对多层次结构都是使用类似于包含某些子类的IList集合构造的,因此将数据库分解为层次结构可能会减慢速度和维护速度。
答案 0 :(得分:2)
我希望它看起来更像这样......但是如果没有看到db4o.db的def那么很难说清楚
var mySym = from Symbol s in db4o.db
where (s.SymbolGlobal == "APPLE")
var mySomething = from xxx x in mySym.x
where (x.Date == new DateTime(2010, 10, 18)
select new
{
mySym.SymbolGlobal,
x.Date,
x.Meta
};
foreach (var d in mySomething)
{
Console.WriteLine("{0} - {1} - {2}", d.SymbolGlobal, d.Date.Date, d.Meta);
}
答案 1 :(得分:1)
Hogan已经回答你需要使用join:例如:
var daysForSymbolS1 = from s in database.Cast<Symbol>()
join t in database.Cast<TradingDay>() on s equals t.SymbolGlobal
where (s.SymbolGlobal == "IBM" && t.Date == new DateTime(2010, 10, 20))
select new
{
s.SymbolGlobal,
t.Date,
t.Meta
};
现在到db4o-parts。您可以使用引用本身来进行连接。您不需要任何ID(如上所示)
然而,没有大问题。目前LINQ to db4o实现根本不支持LINQ-Operator(实际上你可以通过在连接上使用Go To Declaration来看到它)。这意味着它回退到LINQ to Objects。这意味着所有对象都被加载到内存中,然后在这些对象上执行LINQ to Object。那太慢了。
目前无法在db4o上有效执行查询。你通常用db4o做这些东西的方法是在符号上有一个Day-collection。该集合始终包含该符号的所有日期。然后,您可以查询符号,然后获取数据。
另一种方法是拆分查询:
var ibmSymbols = from Symbol s in database
where s.SymbolGlobal == "IBM"
select s;
// run the TradingDay selection with the optimized LINQ to db4o implementation
// do the rest with LINQ to objects
var allSymbols = ibmSymbols.SelectMany(s => from TradingDay t in database
where t.SymbolGlobal==s && t.Date == new DateTime(2010, 10, 20)
select t);
编辑:我只想在符号列表中列出其他集合中的TradingDays时添加案例。然后你可以这样做:
var ibmSymbols = from Symbol s in database
where s.SymbolGlobal == "IBM"
select s;
var tradingDays = from symbol in ibmSymbols
from day in symbol.TradingDays
where day.Date == new DateTime(2010, 10, 20)
select day;