Querying by type in DB4O
-
06-07-2019 - |
Question
How do you pass a class type into a function in C#?
As I am getting into db4o and C# I wrote the following function after reading the tutorials:
public static void PrintAllPilots("CLASS HERE", string pathToDb)
{
IObjectContainer db = Db4oFactory.OpenFile(pathToDb);
IObjectSet result = db.QueryByExample(typeof("CLASS HERE"));
db.Close();
ListResult(result);
}
Solution
There are two ways. The first is to explicitly use the Type type.
public static void PrintAllPilots(Type type, string pathToDb)
{
...
IObjectSet result = db.QueryByExample(type);
}
PrintAllPilots(typeof(SomeType),somePath);
The second is to use generics
public static void PrintAllPilots<T>(string pathToDb)
{
...
IObjectSet result = db.QueryByExample(typeof(T));
}
PrintAllPilots<SomeType>(somePath);
OTHER TIPS
The answers given by by Jon, Jared, and yshuditelu use query-by-example which is largely unused DB4o querying mechanism, and could potentially be deprecated in the future.
The preferred methods of querying on DB4O for .NET is native queries and LINQ.
// Query for all Pilots using DB4O native query:
var result = db.Query<Pilot>();
Or alternatively using Linq-to-DB4O:
// Query for all Pilots using LINQ
var result = from Pilot p in db
select p;
Both of these work provided you know the type (e.g. Pilot) at compile time. If you don't know the type at compile time, you can instead use a DB4O SODA query:
var query = db.Query();
query.Constrain(someObj.GetType());
var results = query.Execute();
edit Why use LINQ instead of SODA, Query-by-Example (QBE), or Native Query (NQ)? Because LINQ makes it very natural to do query expressions. For example, here's how you'd query for pilots named Michael:
var michaelPilots = from Pilot p in db
where p.Name == "Michael"
select p;
And LINQ is composable, meaning you can do things like this:
var first20MichaelPilots = michaelPilots.Take(20);
And you'll still get an efficient query executed in DB4O when you iterate over the results. Doing the same in SODA or QBE or NQ is ugly at best.
I think this is what you want:
public static void PrintAllPilots(Type classType, string pathToDb)
{
IObjectContainer db = Db4oFactory.OpenFile(pathToDb);
IObjectSet result = db.QueryByExample(classType);
db.Close();
ListResult(result);
}
You can either do it manually by using Type
:
public static void PrintAllPilots(Type type, string pathToDb)
Or you could use generics to infer the type:
public static void PrintAllPilots<T>(string pathToDb)
{
//...
var result = db.QueryByExample(typeof(T));
}