Использование LINQ для запроса вложенных классов в db4o? - PullRequest
0 голосов
/ 23 февраля 2011

Встретить хитрую проблему с db4o и простыми вложенными структурами.

Проблема: когда я использую LINQ для извлечения данных из db4o, он извлекает слишком много данных (т. Е. Предложение «где» не работает).

У меня есть несколько вложенных объектов:

Root ----Symbol (SPX)                
   |          |------Day 1: Date: 2010-10-18, string "SPX meta"
   |          |------Day 2: Date: 2010-10-19, string "SPX meta"
   |
   |
   |-----Symbol (IBM)               
              |------Day 1: Date: 2010-10-18, string "IBM meta"
              |------Day 2: Date: 2010-10-19, string "IBM meta"

Я создаю два символа:

  Symbol sym1 = new Symbol("SPX");
  Symbol sym2 = new Symbol("IBM");

Затем я создаю несколько торговых дней:

  // SPX
  TradingDay day1 = new TradingDay(new DateTime(2010, 10, 18), "SPX meta");
  TradingDay day2 = new TradingDay(new DateTime(2010, 10, 19), "SPX meta");

  // IBM
  TradingDay day3 = new TradingDay(new DateTime(2010, 10, 18), "IBM meta");
  TradingDay day4 = new TradingDay(new DateTime(2010, 10, 19), "IBM meta");

Затем я назначаю пару дней каждому символу:

  sym1.AssignTradingDay(day1);
  sym1.AssignTradingDay(day2);

  sym2.AssignTradingDay(day3);
  sym2.AssignTradingDay(day4);

Затем я сохраняю его в базе данных объекта db4o:

  // Store in the database.
  db4o.db.Store(sym1);
  db4o.db.Store(sym2);
  db4o.db.Commit();  

Пока довольно просто.

Я проверяю базу данных с помощью "db4o Object Manager Enterprise", и, конечно же, есть два символа, и если я нажимаю на каждый символ, каждый из них содержит два дня.

Теперь я делаю запрос LINQ для извлечения данных:

 var daysForSymbolS1 = from Symbol s in db4o.db
                       from TradingDay t in db4o.db
                       where (s.SymbolGlobal == "IBM" 
                              && t.Date == new DateTime(2010, 10, 19))
                       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);
 } 

И происходит нечто странное:

IBM - 10/19/2010 12:00:00 AM - SPX meta     // This line should not appear because we have specified "IBM" in the filter.
IBM - 10/19/2010 12:00:00 AM - IBM meta

Несмотря на то, что я указал, что он должен возвращать данные только для "SPX", он также возвращает данные от "IBM".

Я что-то делаю явно неправильно?

1 Ответ

1 голос
/ 23 февраля 2011

Вы не опубликовали точное определение своих классов, но в настоящее время вы делаете декартово произведение в своем запросе Linq - вы создаете все возможные комбинации, тогда как вам действительно нужны только "совпадающие" комбинации (так какторговый день в вашей схеме по какой-то причине связан с символом).Вместо этого вам следует выполнить соединение, например:

  from TradingDay t in db4o.db
  join Symbol s in db4o.db
  on s.SymbolGlobal equals t.SymbolGlobal 
  where (s.SymbolGlobal == "IBM" 
         && t.Date == new DateTime(2010, 10, 19))
  ...
...