【问题标题】:Using LINQ to query nested classes in db4o?使用 LINQ 查询 db4o 中的嵌套类?
【发布时间】:2011-02-23 17:31:25
【问题描述】:

在 db4o 和简单的嵌套结构中遇到了一个棘手的问题。

问题:当我使用 LINQ 从 db4o 中提取数据时,它提取的数据过多(即“where”子句似乎不起作用)。

我有一些嵌套对象:

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”的数据。

我做错了什么吗?

【问题讨论】:

    标签: linq linq-to-objects db4o


    【解决方案1】:

    您没有发布您的类的确切定义,但您目前在 Linq 查询中执行 cartesian product - 您正在创建每个可能的组合,而您实际上只想要“匹配”组合(因为您的交易日由于某种原因,模式似乎与符号相关联)。你应该做的是加入,比如:

      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))
      ...
    

    【讨论】:

    • 错误原因完全正确。不幸的是,db4o 并没有真正很好地支持连接,因为它回退到 LINQ-to-objects 并将整个数据库加载到内存中以尝试找到正确的解决方案。我认为放弃LINQ并使用QBE(Query By Example)来解决问题可能会更好。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2017-11-29
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2010-09-30
    相关资源
    最近更新 更多