Method to do a "join" when using LINQ in db4o? -
whats correct linq navigate end leaf node of following data structure?
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"
in other words, if select "apple", "2010-10-19", should return "apples on friday".
the following not work (it selects cartesian product every single combination) of symbol , date):
var daysforsymbols1 = symbol s in db4o.db date t in db4o.db (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); }
i'd love use join - db4o object database, , doesn't let reference id each object.
update:
@gamlor gave brilliant answer, works charm.
i should mention current version of db4o not support indexing on collections. since form of 1-to-many hierarchy constructed using ilist collection holds subclasses, breaking database down hierarchy slow things down, both speed , maintenance wise.
hogan answered need use join: example this:
var daysforsymbols1 = s in database.cast<symbol>() join t in database.cast<tradingday>() on s equals t.symbolglobal (s.symbolglobal == "ibm" && t.date == new datetime(2010, 10, 20)) select new { s.symbolglobal, t.date, t.meta };
now db4o-parts. can use reference join. don't need id (as shown above)
however there not big issue. linq db4o implementation doesn't support linq-operator @ (you can see using go declaration on join). means falls linq objects. means objects loaded memory , linq object executed on objects. thats extremely slow.
currently query cannot executed efficiently on db4o. way such stuff db4o have day-collection on symbol. collection contains days of symbol. can query symbol , data.
another method split query:
var ibmsymbols = symbol s in database s.symbolglobal == "ibm" select s; // run tradingday selection optimized linq db4o implementation // rest linq objects var allsymbols = ibmsymbols.selectmany(s => tradingday t in database t.symbolglobal==s && t.date == new datetime(2010, 10, 20) select t);
edit: want add case when symbol has tradingdays in list other collection. can this:
var ibmsymbols = symbol s in database s.symbolglobal == "ibm" select s; var tradingdays = symbol in ibmsymbols day in symbol.tradingdays day.date == new datetime(2010, 10, 20) select day;
Comments
Post a Comment