2015-12-14 43 views
0

我目前在项目中使用Witty和DBO以及SQLite3,现在我需要加入相关表才能获得行数。ORM获取已加入的表行数

CREATE TABLE "rfnode" (
    "mac" varchar(16) not null, 
    "zone" integer not null, 
    "subZone" integer not null, 
    "unit" text not null, 
    "pwm" integer not null, 
    "led" integer not null, 
    "network" integer not null, 
    "lastContact" text, 
    "ioConfiguration" integer not null, 
    primary key ("mac") 
) 

CREATE TABLE "nodemeasure" (
    "id" integer primary key autoincrement, 
    "mac" text not null, 
    "type" integer not null, 
    "date" text, 
    "batchDate" text, 
    "value" real not null 
) 

通常情况下,SQL查询是:

SELECT 
    rn.*, 
    COUNT(nm.id) AS measuresCount 
FROM rfnode rn 
LEFT JOIN nodemeasure nm 
    ON nm.mac = rn.mac 
GROUP BY rn.mac 

现在的问题是,我无法弄清楚如何查询和使用重量得到结果/ DBO库。

首次尝试

class RFNode 
{ 
    public: 
     std::string mac, unit; 
     int zone = 0, subZone = 0, pwm = 0, led = 0, network = 0, ioConfiguration = 0, measuresCount = 0; 
     Wt::WDateTime lastContact; 

     RFNode() 
     { 
      mac    = ""; 
      zone   = 0; 
      subZone   = 0; 
      unit   = ""; 
      pwm    = 8; 
      led    = 8; 
      network   = 0; 
      ioConfiguration = 0; 
      measuresCount = 0; 
     } 

     RFNode(std::string p_sMAC, int p_nZone, int p_nSubZone, std::string p_sUnit, int p_nPWM, int p_nLED, int p_nNetwork, Wt::WDateTime p_oLastContact, int p_nIOConfiguration, int p_nMeasuresCount = 0) 
     { 
      mac    = p_sMAC; 
      zone   = p_nZone; 
      subZone   = p_nSubZone; 
      unit   = p_sUnit; 
      pwm    = p_nPWM; 
      led    = p_nLED; 
      network   = p_nNetwork; 
      lastContact  = p_oLastContact; 
      ioConfiguration = p_nIOConfiguration; 
      measuresCount = p_nMeasuresCount; 
     } 

     template<class Action> 
     void persist(Action& a) 
     { 
      dbo::id(a,  mac,   "mac",16); 
      dbo::field(a, zone,   "zone"); 
      dbo::field(a, subZone,  "subZone"); 
      dbo::field(a, unit,   "unit"); 
      dbo::field(a, pwm,   "pwm"); 
      dbo::field(a, led,   "led"); 
      dbo::field(a, network,  "network"); 
      dbo::field(a, lastContact, "lastContact"); 
      dbo::field(a, ioConfiguration,"ioConfiguration"); 
      dbo::field(a, measuresCount, "measuresCount"); 
     }; 
}; 

与查询:

Wt::Dbo::collection<Wt::Dbo::ptr<RFNode>> lTemp = m_oSession.query<Wt::Dbo::ptr<RFNode>>("SELECT rn.*, COUNT(nm.id) AS measuresCount FROM rfnode rn LEFT JOIN nodemeasure nm ON nm.mac = rn.mac").resultList(); 

是导致Session::query(): too many aliases for result

第二次尝试

同一类RFNode使用,除了移除字段measuresCount

typedef Wt::Dbo::ptr_tuple<RFNode, int>::type RFNodeJoin; 
     typedef Wt::Dbo::collection<RFNodeJoin> RFNodeJoinC; 

     RFNodeJoinC lTemp = m_oSession.query<RFNodeJoin>("SELECT rn.*, COUNT(nm.id) AS measuresCount FROM rfnode rn LEFT JOIN nodemeasure nm ON nm.mac = rn.mac GROUP BY rn.mac").resultList(); 

     std::vector<RFNodeJoin> lTransition(lTemp.begin(),lTemp.end()); 

但它不编译,结果错误:error: request for member ‘persist’ in ‘obj’, which is of non-class type ‘int’。我想我需要为每个表映射一个类,但因为我想要一个计数并且没有现有的字段,所以我认为一个int类不会完成这项工作。

回答

0

最后通过试验和错误我找到了解决办法...

首先,RFNode类没有现场measuresCount了。

请求和迭代是由如下:

Wt::Dbo::collection<boost::tuple<Wt::Dbo::ptr<RFNode>, int>> lTemp = m_oSession.query<boost::tuple<Wt::Dbo::ptr<RFNode>, int>>("SELECT rn, COUNT(nm.id) FROM rfnode rn LEFT JOIN nodemeasure nm ON nm.mac = rn.mac GROUP BY rn.mac").resultList(); 

for(Wt::Dbo::collection<boost::tuple<Wt::Dbo::ptr<RFNode>, int>>::const_iterator i = lTemp.begin();i != lTemp.end();++i) 
{ 
    Wt::Dbo::ptr<RFNode> pRFNode; 
    int nNodeMeasureCount; 

    boost::tie(pRFNode,nNodeMeasureCount) = *i; 

    lNodes.push_back(
      RFNode(
        pRFNode->mac, 
        pRFNode->zone, 
        pRFNode->subZone, 
        pRFNode->unit, 
        pRFNode->pwm, 
        pRFNode->led, 
        pRFNode->network, 
        pRFNode->lastContact, 
        pRFNode->ioConfiguration, 
        nNodeMeasureCount 
      ) 
    ); 
} 

希望这将帮助别人一天!