[odb-users] one-to-many relationship question
Boris Kolpackov
boris at codesynthesis.com
Wed Aug 13 07:50:28 EDT 2014
Hi Lidia,
Lidia Kalinovsky <lidia at lemur-soft.com> writes:
> #pragma db...
> class A
> {
> bool hidden;
> };
>
> #pragma db...
> class B
> {
> bool hidden;
>
> #pragma db unordered
> std::vector<A> manyA;
> }
>
> to load objects of B, i use
>
> typedef odb::query<T> queryT;
> queryT q;
> if (!fullLoading)
> q = queryT(queryT::hidden != true );
>
> typename odb::core::result<T> r (m_DB->query<T>(q,true));
>
> This way i have only Bs with hidden=0.
>
> Is it possible to have some condition for loaded A's objects inside manyA
> vector inside pragma (means, at compilation) ?
No, and I doubt we will support something like this. Seems very
inflexible.
> inside dynamic query ?
Also not, but this is something on our TODO list. That is, support for
containers in queries.
What you can do as a workaround in the meantime is this (I am using
raw pointers below but you will want to replace them with smart
pointers):
1. Add the "back" pointer to A:
class B;
#pragma db...
class A
{
bool hidden;
#pragma db inverse(manyA)
odb::lazy_ptr<B> oneB; // Use the lazy (and weak) pointer corresponding
// to the A's object pointer.
};
This doesn't cost anything on the database side. If you want, you can
also avoid loading it completely on the C++ side (see lazy-loaded
sections).
2. Re-implement your query in terms of querying for A, not for B:
typedef odb::query<A> queryA;
typedef odb::result<A> resultA;
queryA q (!queryA::hidden && !queryA::oneB->hidden)
resultA r (db.query<A> (q));
// Create an object cache so that Bs points to As that we have already
// loaded.
//
odb::session s;
std::setM<B*> bs;
for (resultA::iterator i (r.begin ()); i != r.end (); ++i)
{
bs.insert (i->oneB.load ());
}
// bs now contains all the Bs that are not hidden and only containing
// non-hidden As.
Boris
More information about the odb-users
mailing list