- Home
- LLBLGen Pro
- LLBLGen Pro Runtime Framework
FetchEntityCollectionAsync
Joined: 20-Jun-2007
Hi,
I'm using LLBLGen v5.3.
I'm trying to understand how to call FetchEntityCollectionAsync. I don't seem to be able to find any examples, and suspect I'm just missing some syntax.
For example:
Using adapter As SD.LLBLGen.Pro.ORMSupportClasses.IDataAccessAdapter = Grb.Platform.Framework.Business.Lower.FactoryAdapter.FactoryAdapter.GetDataAccessAdapter(m_adapterConnection)
'adapter.FetchEntityCollection(empGeneralEntityCollection, filter, maxNum, orderBy, preFetchPath, includedFieldList)
Dim qp As SD.LLBLGen.Pro.ORMSupportClasses.QueryParameters = New SD.LLBLGen.Pro.ORMSupportClasses.QueryParameters()
qp.CollectionToFetch = empGeneralEntityCollection
qp.RelationsToUse = filter.Relations
qp.SorterToUse = orderBy
qp.ExcludedIncludedFields = includedFieldList
Dim getTask As Threading.Tasks.Task = adapter.FetchEntityCollectionAsync(qp, New System.Threading.CancellationToken())
End Using
Seems to compile ok
But returns nothing (as I don't have an await...so I'd expect no result).
But when I try to add an await:
Using adapter As SD.LLBLGen.Pro.ORMSupportClasses.IDataAccessAdapter = Grb.Platform.Framework.Business.Lower.FactoryAdapter.FactoryAdapter.GetDataAccessAdapter(m_adapterConnection)
'adapter.FetchEntityCollection(empGeneralEntityCollection, filter, maxNum, orderBy, preFetchPath, includedFieldList)
Dim qp As SD.LLBLGen.Pro.ORMSupportClasses.QueryParameters = New SD.LLBLGen.Pro.ORMSupportClasses.QueryParameters()
qp.CollectionToFetch = empGeneralEntityCollection
qp.RelationsToUse = filter.Relations
qp.SorterToUse = orderBy
qp.ExcludedIncludedFields = includedFieldList
Dim getTask As Threading.Tasks.Task = Await adapter.FetchEntityCollectionAsync(qp, New System.Threading.CancellationToken())
End Using
I get a compile time error: 'Await' can only be used within an Async method. Consider marking this method with the "Async' modifier and changing its return type to 'Task(Of EntityCollection(Of EmpGeneralEntity))'
So a few questions if I may...
1.) Thoughts on what I'm doing wrong?
2.) Would you be able to point me to a full sample code that uses the FetchEntityCollectionAsync?
3.) I was looking at: https://www.llblgen.com/Documentation/4.2/LLBLGen%20Pro%20RTF/Using%20the%20generated%20code/Async/gencode_async_gettingstarted.htm, but this seemed to take me down the into the QuerySpec...and not sure if that's where I really wanted to go down that path anyway. So maybe there's some other info on using just the FetchEntityCollectionAsync that I might be able to use?
Thanks!
fetching a collection asynchronously is implemented through either linq or queryspec. these end up in the method you're trying to call. We didn't ship async overloads for the normal fetchentitycollection method as that would bloat the API a lot and create a lot of redundant code.
Also, this method returns a task but that's not something you need to store in a variable. If the method returns e.g. an int, you can simply do:
Dim intVar = Await <asyncmethod>()
Also, no need to specify the full interface of a class in the Using, and you have a very deep namespace hierarchy for the adapter which obtains an adapter for a shared connection. That doesn't look right: never share a connection object nor an adapter instance. Always create new instances!
About the error: your code itself has to be in an async method too. You can't start calling async methods in the middle of the codebase, you can do that only from within an async method, which is then called from async code etc. So it bleeds through. This is a side effect of the way Microsoft designed async, and not something we can do something about.
Joined: 20-Jun-2007
Joined: 20-Jun-2007
I see this example of how to fetch using adapter QuerySpec adapter.FetchQuery(): https://www.llblgen.com/Documentation/4.1/LLBLGen%20Pro%20RTF/Using%20the%20generated%20code/Adapter/gencode_usingcollectionclasses_adapter.htm
// QuerySpec, C#, uses EXISTS query.
using(var adapter = new DataAccessAdapter())
{
var qf = new QueryFactory();
var q = qf.Order
.Where(qf.Customer
.CorrelatedOver(OrderEntity.Relations.CustomerEntityUsingCustomerId)
.Contains(myCustomer));
adapter.FetchQuery(q, myCustomer.Orders);
}
However, when I try:
Using adapter As SD.LLBLGen.Pro.ORMSupportClasses.IDataAccessAdapter = Framework.Business.Lower.FactoryAdapter.FactoryAdapter.GetDataAccessAdapter(m_adapterConnection)
Dim qf2 As New Framework.Business.Lower.FactoryClasses.QueryFactory
Dim q2 As SD.LLBLGen.Pro.QuerySpec.EntityQuery(Of Framework.Business.Lower.EntityClasses.EmpGeneralEntity) = qf2.EmpGeneral
adapter.FetchQuery(Of Framework.Business.Lower.EntityClasses.EmpGeneralEntity)(q2, Nothing)
End Using
The adapter.FetchQuery seems to be looking for a string as it's first argument, not a EntityQuery. There doesn't seem to be an implementation of the function to take an SD.LLBLGen.Pro.QuerySpec.EntityQuery
I think I'm looking at something just wrong. Can you help put me on the path?
namespace Framework.Business.Lower.FactoryAdapter
{
public static class FactoryAdapter
{
static public SD.LLBLGen.Pro.ORMSupportClasses.IDataAccessAdapter GetDataAccessAdapter(AdapterConnection connection)
{
SD.LLBLGen.Pro.ORMSupportClasses.IDataAccessAdapter returnValue = null;
SD.LLBLGen.Pro.ORMSupportClasses.CatalogNameOverwriteHashtable catalogNameOverwrite = new SD.LLBLGen.Pro.ORMSupportClasses.CatalogNameOverwriteHashtable();
SD.LLBLGen.Pro.ORMSupportClasses.SchemaNameOverwriteHashtable schemaNameOverwrite = new SD.LLBLGen.Pro.ORMSupportClasses.SchemaNameOverwriteHashtable();
try
{
if (connection == null)
{
throw new Core.Exceptions.FrameworkException(ExceptionMessage.NullConnection);
}
string databaseType = GetDatabaseProviderNameFromDatabaseType(connection.ProviderName);
if (string.IsNullOrEmpty(connection.FrameworkSchema) == true)
{
throw new Core.Exceptions.FrameworkException(string.Format(System.Globalization.CultureInfo.InvariantCulture,
ExceptionMessage.InvalidFrameworkSchemaName1, databaseType, connection.FrameworkSchema));
}
if(string.IsNullOrEmpty(connection.PlatformSchema) == true)
{
throw new Core.Exceptions.FrameworkException(string.Format(System.Globalization.CultureInfo.InvariantCulture,
ExceptionMessage.InvalidPlatformSchemaName1, databaseType, connection.PlatformSchema));
}
if (string.Equals(connection.ProviderName, Core.StringConstantConfiguration.DatabaseProviderSql, System.StringComparison.InvariantCultureIgnoreCase))
{
System.Data.Common.DbConnectionStringBuilder builder = new System.Data.Common.DbConnectionStringBuilder();
builder.ConnectionString = connection.ConnectionString;
string sqlDatabaseName = string.Empty;
if (builder.ContainsKey(Constants.ConnectionStringDatabaseKey))
{
sqlDatabaseName = builder[Constants.ConnectionStringDatabaseKey].ToString();
}
else
{
throw new Core.Exceptions.FrameworkException(ExceptionMessage.SqlServerConnectionStringMissingDatabaseKey);
}
if (string.IsNullOrEmpty(sqlDatabaseName) == true)
{
throw new Core.Exceptions.FrameworkException(string.Format(System.Globalization.CultureInfo.InvariantCulture,
ExceptionMessage.InvalidSqlServerDatabaseName1, sqlDatabaseName));
}
else
{
catalogNameOverwrite.Add(Constants.SqlServerDefaultCatalogName, sqlDatabaseName);
schemaNameOverwrite.Add(Constants.DefaultFrameworkSchemaName, connection.FrameworkSchema);
schemaNameOverwrite.Add(Constants.DefaultPlatformSchemaName, connection.PlatformSchema);
SD.LLBLGen.Pro.ORMSupportClasses.IDataAccessAdapter adapter = new
Framework.Business.Lower.SqlServer.DatabaseSpecific.DataAccessAdapter(connection.ConnectionString, false, catalogNameOverwrite, schemaNameOverwrite);
adapter.CommandTimeOut = connection.CommandTimeOut;
returnValue = adapter;
}
}
else if (string.Equals(connection.ProviderName, Core.StringConstantConfiguration.DatabaseProviderOracleUnmanaged, System.StringComparison.InvariantCultureIgnoreCase)
|| string.Equals(connection.ProviderName, Core.StringConstantConfiguration.DatabaseProviderOracleManaged, System.StringComparison.InvariantCultureIgnoreCase))
{
schemaNameOverwrite.Add(Constants.DefaultFrameworkSchemaName, connection.FrameworkSchema);
schemaNameOverwrite.Add(Constants.DefaultPlatformSchemaName, connection.PlatformSchema);
SD.LLBLGen.Pro.ORMSupportClasses.IDataAccessAdapter adapter = new
Framework.Business.Lower.Oracle.DatabaseSpecific.DataAccessAdapter(connection.ConnectionString, false, null, schemaNameOverwrite);
adapter.CommandTimeOut = connection.CommandTimeOut;
returnValue = adapter;
}
else if (string.Equals(connection.ProviderName, Core.StringConstantConfiguration.DatabaseProviderPostgres, System.StringComparison.InvariantCultureIgnoreCase))
{
schemaNameOverwrite.Add(Constants.DefaultFrameworkSchemaName.ToLower(System.Globalization.CultureInfo.InvariantCulture), connection.FrameworkSchema);
schemaNameOverwrite.Add(Constants.DefaultPlatformSchemaName.ToLower(System.Globalization.CultureInfo.InvariantCulture), connection.PlatformSchema);
SD.LLBLGen.Pro.ORMSupportClasses.IDataAccessAdapter adapter = new
Framework.Business.Lower.PostgreSql.DatabaseSpecific.DataAccessAdapter(connection.ConnectionString, true, null, schemaNameOverwrite);
adapter.CommandTimeOut = connection.CommandTimeOut;
returnValue = adapter;
}
else
{
throw new Core.Exceptions.FrameworkException(string.Format(System.Globalization.CultureInfo.InvariantCulture,
ExceptionMessage.InvalidDatabaseProviderInvariantName1, connection.ProviderName));
}
}
catch (System.Exception ex)
{
throw new Core.Exceptions.FrameworkException(ExceptionMessage.ErrorInGetDataAccessAdapter, ex);
}
return returnValue;
}
Add Imports SD.LLBLGen.Pro.QuerySpec.Adapter at the top of your code file where you use FetchQuery(). It's an extension method, so you have to add the namespace of the extension method to the code file.