Session: Loading Entities
There are various methods with many overloads that allow users to download documents from a database and convert them to entities. This article will cover the following methods:
Load
The most basic way to load a single entity is to use one of the Load
methods.
TResult Load<TResult>(string id);
Task<TResult> LoadAsync<TResult>(string id);
Parameters | ||
---|---|---|
id | string | Identifier of a document that will be loaded. |
Return Value | |
---|---|
TResult | Instance of TResult or null if a document with a given ID does not exist. |
Example
Employee employee = session.Load<Employee>("employees/1");
Employee employee = await asyncSession.LoadAsync<Employee>("employees/1");
Note
In 4.x RavenDB, only string identifiers are supported. If you are upgrading from 3.x, this is a major change, because in 3.x non-string identifiers are supported.
Load with Includes
When there is a 'relationship' between documents, those documents can be loaded in a single request call using the 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 the server should look for 'referenced' documents. |
Return Value | |
---|---|
ILoaderWithInclude | The Include method by itself does not materialize any requests but returns loader containing methods such as Load . |
Example I
We can use this code to also load an employee which made the order.
// 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
// loading 'products/1'
// including document found in 'Supplier' property
Product product = await asyncSession
.Include("Supplier")
.LoadAsync<Product>("products/1");
Supplier supplier = await asyncSession.LoadAsync<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
// loading 'products/1'
// including document found in 'Supplier' property
Product product = await asyncSession
.Include<Product>(x => x.Supplier)
.LoadAsync<Product>("products/1");
Supplier supplier = await asyncSession.LoadAsync<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);
Task<Dictionary<string, TResult>> LoadAsync<TResult>(IEnumerable<string> ids);
Parameters | ||
---|---|---|
ids | IEnumerable |
Multiple document identifiers to load |
Return Value | |
---|---|
Dictionary<string, TResult> | Instance of Dictionary which maps document identifiers to TResult or null if a document with given ID doesn't exist. |
Dictionary<string, Employee> employees = session.Load<Employee>(new[]
{
"employees/1",
"employees/2",
"employees/3"
});
Dictionary<string, Employee> employees = await asyncSession.LoadAsync<Employee>(new[]
{
"employees/1",
"employees/2",
});
LoadStartingWith
To load multiple entities that contain a common prefix, use the LoadStartingWith
method from the 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);
Task<T[]> LoadStartingWithAsync<T>(
string idPrefix,
string matches = null,
int start = 0,
int pageSize = 25,
string exclude = null,
string startAfter = null);
Task LoadStartingWithIntoStreamAsync(
string idPrefix,
Stream output,
string matches = null,
int start = 0,
int pageSize = 25,
string exclude = null,
string startAfter = null);
Parameters | ||
---|---|---|
idPrefix | string | prefix for which the documents should be returned |
matches | string | pipe ('|') separated values for which document IDs (after 'idPrefix') 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 |
exclude | string | pipe ('|') separated values for which document IDs (after 'idPrefix') should not be matched ('?' any single character, '*' any characters) |
skipAfter | string | skip document fetching until given ID is found and return documents after that ID (default: null ) |
Return Value | |
---|---|
TResult[] | Array of entities matching given parameters. |
Stream | Output entities matching given parameters as a stream. |
Example I
// return up to 128 entities with Id that starts with 'employees'
Employee[] result = session
.Advanced
.LoadStartingWith<Employee>("employees", null, 0, 128);
// return up to 128 entities with Id that starts with 'employees'
Employee[] result = (await asyncSession
.Advanced
.LoadStartingWithAsync<Employee>("employees", null, 0, 128))
.ToArray();
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);
// 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 = (await asyncSession
.Advanced
.LoadStartingWithAsync<Employee>("employees/", "1*|2*", 0, 128))
.ToArray();
Stream
Entities can be streamed from the server using one of the following Stream
methods from the Advanced
session operations.
Streaming query results does not support the include
feature.
Learn more in How to Stream Query Results.
Information
Entities loaded using Stream
will be transient (not attached to session).
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);
Task<IAsyncEnumerator<StreamResult<T>>> StreamAsync<T>(IQueryable<T> query);
Task<IAsyncEnumerator<StreamResult<T>>> StreamAsync<T>(IQueryable<T> query, out StreamQueryStatistics streamQueryStats);
Task<IAsyncEnumerator<StreamResult<T>>> StreamAsync<T>(IDocumentQuery<T> query);
Task<IAsyncEnumerator<StreamResult<T>>> StreamAsync<T>(IRawDocumentQuery<T> query);
Task<IAsyncEnumerator<StreamResult<T>>> StreamAsync<T>(IRawDocumentQuery<T> query, out StreamQueryStatistics streamQueryStats);
Task<IAsyncEnumerator<StreamResult<T>>> StreamAsync<T>(IDocumentQuery<T> query, out StreamQueryStatistics streamQueryStats);
Task<IAsyncEnumerator<StreamResult<T>>> StreamAsync<T>(string startsWith, string matches = null, int start = 0, int pageSize = int.MaxValue, string startAfter = null);
Parameter | Type | Description |
---|---|---|
startsWith | string |
prefix for which documents should be streamed |
matches | string |
pipe ('|') separated values for which document IDs 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 |
skipAfter | string |
skip document fetching until a given ID is found and returns documents after that ID (default: null ) |
StreamQueryStats | streamQueryStats (out parameter) |
Information about the streaming query (amount of results, which index was queried, etc.) |
Return Type | Description |
---|---|
IEnumerator< StreamResult> |
Enumerator with entities. |
streamQueryStats (out parameter) |
Information about the streaming query (amount of results, which index was queried, etc.) |
Example I
Stream documents for a ID prefix:
IEnumerator<StreamResult<Employee>> enumerator = session
.Advanced
.Stream<Employee>("employees/");
while (enumerator.MoveNext())
{
StreamResult<Employee> employee = enumerator.Current;
}
Raven.Client.Util.IAsyncEnumerator<StreamResult<Employee>> enumerator = await asyncSession
.Advanced
.StreamAsync<Employee>("employees/");
while (await enumerator.MoveNextAsync())
{
StreamResult<Employee> employee = enumerator.Current;
}
Example 2
Fetch documents for a ID prefix directly into a stream:
using (var outputStream = new MemoryStream())
{
session
.Advanced
.LoadStartingWithIntoStream("employees/", outputStream);
}
using (var outputStream = new MemoryStream())
{
await asyncSession
.Advanced
.LoadStartingWithIntoStreamAsync("employees/", outputStream);
}
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.
IsLoaded
checks if you've already tried to load a document during the current session.
If you try to load a document that no longer exists with the Load
method (perhaps it has been deleted),
IsLoaded
will then return true
because IsLoaded
shows that you've already tried to load the non-existent document.
bool IsLoaded(string id);
Parameters | ||
---|---|---|
id | string | Entity ID for which the check should be performed. |
Return Value | |
---|---|
bool | Indicates if an entity with a 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
bool isLoaded = asyncSession.Advanced.IsLoaded("employees/1"); // false
Employee employee = await asyncSession.LoadAsync<Employee>("employees/1");
isLoaded = asyncSession.Advanced.IsLoaded("employees/1"); // true