Session: Loading entities
There are various methods with many overloads that allow user to download a documents from database and convert them to entities. This article will cover following methods:
Load
The most basic way to load single entity is to use one of Load
methods.
TResult Load<TResult>(string id);
Parameters | ||
---|---|---|
id | string or ValueType | Identifier of a document that will be loaded. |
transformer or transformerType | string or Type | Name or type of a transformer to use on a loaded document. |
configure | Action<ILoadConfiguration> | Additional configuration that should be used during operation e.g. transformer parameters can be added. |
Return Value | |
---|---|
TResult | Instance of TResult or null if document with given Id does not exist. |
Example I
Employee employee = session.Load<Employee>("employees/1");
Example II
// loading 'employees/1'
// and transforming result using 'Employees_NoLastName' transformer
// which returns 'LastName' as 'null'
Employee employee = session.Load<Employees_NoLastName, Employee>("employees/1");
Non string identifiers
The above examples show how to load a document by its string key. What if a type of your entity's identifier is not a string? You need to use an overload of the Load
method that takes a parameter which type is ValueType
.
Example III
If you have an entity where an identifier is an integer number:
public class EntityWithIntegerId
{
c int Id { get; set; }
/*
...
*/
}
you can load it by specifying an integer value as the identifier:
EntityWithIntegerId entity = session.Load<EntityWithIntegerId>(1);
Converting to string identifier
Even if the identifier is a string, you can use the Load<T>(ValueType)
overload. The client is aware of the ID generation conventions (collectionName/number),
so you could load the entity with key employees/1
by using the code:
Employee employee = session.Load<Employee>(1);
Load with Includes
When there is a 'relationship' between documents, then those documents can be loaded in a single request call using Include + Load
methods.
ILoaderWithInclude<object> Include(string path);
ILoaderWithInclude<T> Include<T>(Expression<Func<T, string>> path);
ILoaderWithInclude<T> Include<T>(Expression<Func<T, IEnumerable<string>>> path);
ILoaderWithInclude<T> Include<T, TInclude>(Expression<Func<T, string>> path);
ILoaderWithInclude<T> Include<T, TInclude>(Expression<Func<T, IEnumerable<string>>> path);
Parameters | ||
---|---|---|
path | string or Expression | Path in documents in which server should look for a 'referenced' documents. |
Return Value | |
---|---|
ILoaderWithInclude | Include method by itself does not materialize any requests, but returns loader containing methods such as Load . |
Example I
// loading 'products/1'
// including document found in 'Supplier' property
Product product = session
.Include("Supplier")
.Load<Product>("products/1");
Supplier supplier = session.Load<Supplier>(product.Supplier); // this will not make server call
Example II
// loading 'products/1'
// including document found in 'Supplier' property
Product product = session
.Include<Product>(x => x.Supplier)
.Load<Product>("products/1");
Supplier supplier = session.Load<Supplier>(product.Supplier); // this will not make server call
Example III
// loading 'products/1'
// including document found in 'Supplier' property
// transforming loaded product according to Products_Transformer
Product product = session
.Include<Product>(x => x.Supplier)
.Load<Products_Transformer, Product>("products/1");
Supplier supplier = session.Load<Supplier>(product.Supplier); // this will not make server call
Load - multiple entities
To load multiple entities at once use one of the following Load
overloads.
Dictionary<string, TResult> Load<TResult>(IEnumerable<string> ids);
Parameters | ||
---|---|---|
ids | IEnumerable<string> or IEnumerable<ValueType> or ValueType[] | Enumerable or array of Ids that should be loaded. |
transformer or transformerType | string or Type | Name or type of a transformer to use on a loaded documents. |
configure | Action<ILoadConfiguration> | Additional configuration that should be used during operation e.g. transformer parameters can be added. |
Return Value | |
---|---|
TResult[] | Array of entities in the exact same order as given ids. If document does not exist, value at the appropriate position in array will be null . |
Example I
Dictionary<string, Employee> employees = session.Load<Employee>(new[]
{
"employees/1",
"employees/2",
"employees/3"
});
Example II
// loading 'employees/1' and 'employees/2'
// and transforming results using 'Employees_NoLastName' transformer
// which returns 'LastName' as 'null'
Employee[] employees = session
.Load<Employees_NoLastName, Employee>(new List<string> { "employees/1", "employees/2" });
Employee employee1 = employees[0];
Employee employee2 = employees[1];
LoadStartingWith
To load multiple entities that contain common prefix use LoadStartingWith
method from Advanced
session operations.
T[] LoadStartingWith<T>(
string idPrefix,
string matches = null,
int start = 0,
int pageSize = 25,
string exclude = null,
string startAfter = null);
void LoadStartingWithIntoStream(
string idPrefix,
Stream output,
string matches = null,
int start = 0,
int pageSize = 25,
string exclude = null,
string startAfter = null);
Parameters | ||
---|---|---|
keyPrefix | string | prefix for which documents should be returned |
matches | string | pipe ('|') separated values for which document keys (after 'keyPrefix') should be matched ('?' any single character, '*' any characters) |
start | int | number of documents that should be skipped |
pageSize | int | maximum number of documents that will be retrieved |
pagingInformation | RavenPagingInformation | used to perform rapid pagination on server side |
exclude | string | pipe ('|') separated values for which document keys (after 'keyPrefix') should not be matched ('?' any single character, '*' any characters) |
configure | Action<ILoadConfiguration> | Additional configuration that should be used during operation e.g. transformer parameters can be added. |
skipAfter | string | skip document fetching until given key is found and return documents after that key (default: null ) |
Return Value | |
---|---|
TResult[] | Array of entities matching given parameters. |
Example I
// return up to 128 entities with Id that starts with 'employees'
Employee[] result = session
.Advanced
.LoadStartingWith<Employee>("employees", null, 0, 128);
Example II
// return up to 128 entities with Id that starts with 'employees/'
// and rest of the key begins with "1" or "2" e.g. employees/10, employees/25
Employee[] result = session
.Advanced
.LoadStartingWith<Employee>("employees/", "1*|2*", 0, 128);
Example III
// return up to 128 entities with Id that starts with 'employees/'
// and rest of the Id have length of 3, begins and ends with "1"
// and contains any character at 2nd position e.g. employees/101, employees/1B1
// and transform results using 'Employees_NoLastName' transformer
Employee[] result = session
.Advanced
.LoadStartingWith<Employees_NoLastName, Employee>("employees/", "1?1", 0, 128);
Stream
Entities can be streamed from server using one of the following Stream
methods from Advanced
session operations.
IEnumerator<StreamResult<T>> Stream<T>(IQueryable<T> query);
IEnumerator<StreamResult<T>> Stream<T>(IQueryable<T> query, out StreamQueryStatistics streamQueryStats);
IEnumerator<StreamResult<T>> Stream<T>(IDocumentQuery<T> query);
IEnumerator<StreamResult<T>> Stream<T>(IRawDocumentQuery<T> query);
IEnumerator<StreamResult<T>> Stream<T>(IRawDocumentQuery<T> query, out StreamQueryStatistics streamQueryStats);
IEnumerator<StreamResult<T>> Stream<T>(IDocumentQuery<T> query, out StreamQueryStatistics streamQueryStats);
IEnumerator<StreamResult<T>> Stream<T>(string startsWith, string matches = null, int start = 0, int pageSize = int.MaxValue, string startAfter = null);
Parameters | ||
---|---|---|
fromEtag | Etag | ETag of a document from which stream should start (mutually exclusive with 'startsWith') |
startsWith | string | prefix for which documents should be streamed (mutually exclusive with 'fromEtag') |
matches | string | pipe ('|') separated values for which document keys (after 'keyPrefix') should be matched ('?' any single character, '*' any characters) |
start | int | number of documents that should be skipped |
pageSize | int | maximum number of documents that will be retrieved |
pagingInformation | RavenPagingInformation | used to perform rapid pagination on server side |
skipAfter | string | skip document fetching until given key is found and return documents after that key (default: null ) |
Return Value | |
---|---|
IEnumerator<StreamResult> | Enumerator with entities. |
Example I
IEnumerator<StreamResult<Employee>> enumerator = session
.Advanced
.Stream<Employee>("employees/");
while (enumerator.MoveNext())
{
StreamResult<Employee> employee = enumerator.Current;
}
Remarks
Entities loaded using Stream
will be transient (not attached to session).
fromEtag does not do any filtrations on server-side based on the specified in streaming function return type (e.g. Employee
) and will return all documents from given Etag even if their Raven-Clr-Type
does not match the return type, which may cause potential casting errors. Set return type to object
, dynamic
or RavenJObject
to address situation when documents with different types might be returned.
IsLoaded
To check if an entity is attached to a session, e.g. it has been loaded previously, use the IsLoaded
method from the Advanced
session operations.
If you try to load a document that does not exist with the Load
method, IsLoaded
will return true
because that document load has already been attempted.
bool IsLoaded(string id);
Parameters | ||
---|---|---|
id | string | Entity Id for which check should be performed. |
Return Value | |
---|---|
bool | Indicates if entity with given Id is loaded. |
Example
bool isLoaded = session.Advanced.IsLoaded("employees/1"); // false
Employee employee = session.Load<Employee>("employees/1");
isLoaded = session.Advanced.IsLoaded("employees/1"); // true