FetchEntityCollectionAsync

Posts   
 
    
greenstone
User
Posts: 132
Joined: 20-Jun-2007
# Posted on: 24-Jan-2018 19:10:06   

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!

Otis avatar
Otis
LLBLGen Pro Team
Posts: 39614
Joined: 17-Aug-2003
# Posted on: 25-Jan-2018 11:21:43   

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.

Frans Bouma | Lead developer LLBLGen Pro
greenstone
User
Posts: 132
Joined: 20-Jun-2007
# Posted on: 25-Jan-2018 17:59:38   

Thanks for the thorough explanation!

greenstone
User
Posts: 132
Joined: 20-Jun-2007
# Posted on: 29-Jan-2018 20:45:04   

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;
    }

Otis avatar
Otis
LLBLGen Pro Team
Posts: 39614
Joined: 17-Aug-2003
# Posted on: 30-Jan-2018 12:03:25   

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.

Frans Bouma | Lead developer LLBLGen Pro