Microsoft Access

Posts   
 
    
loren
User
Posts: 14
Joined: 29-Jul-2006
# Posted on: 11-Aug-2008 07:19:10   

I've been working on a different project and am just coming back to this, but this appears to be a continuation of http://www.llblgen.com/tinyforum/Messages.aspx?ThreadID=13893 (which I thought I'd resolved.)

When I apply filters to my TypedLists, I consistently get the following error message:

InvalidComObjectException: COM object that has been separated from its underlying RCW cannot be used

I've tried several different things, but believe I've isolated this exclusively to filtering requests for TypedLists. There are no problems accessing either Entities or Collections for the same data I have these problems with for TypedLists. Additionally, if I do a try/catch and ignore the Exception, the TypedList is populated as expected.

Also, I have already tried refreshing the project and regenerated code.

// These fail for TypedLists, but work for Collections.
//IPredicate filter = new FieldCompareValuePredicate(ProductFields.ProductId, ComparisonOperator.Equal, 100);
//IPredicate filter = new FieldBetweenPredicate(ProductFields.ProductId, 100, 200);
//IPredicate filter = new FieldLikePredicate(ProductFields.ProductDescription, "something");

// This works for TypedLists and Collections.
IExpression productExpression = new Expression(ProductFields.ProductId);
IPredicate filter = new FieldCompareExpressionPredicate(ProductFields.ProductId, ComparisonOperator.Equal, productExpression);

// However, this fails for TypedLists, but works for collections
//IExpression productExpression = new Expression(ProductFields.ProductId, ExOp.Add, 0);
//IPredicate filter = new FieldCompareExpressionPredicate(ProductFields.ProductId, ComparisonOperator.Equal, productExpression);

//-----------------------------------------------------

// Executable TypedList lines
LlblGen.TypedListClasses.ProductTypedList productList = new LlblGen.TypedListClasses.ProductTypedList();
productList.Fill(0, null, true, filter);

// Executable Collection lines (always successful)
LlblGen.CollectionClasses.ProductCollection productList = new LlblGen.CollectionClasses.ProductCollection();
productList.GetMulti(filter);

From my previous post:

  • LLBLGen version/release: v2.6 Final, June 6, 2008
  • SD.LLBLGen.Pro.ORMSupportClasses.NET20.dll: 2.6.08.0624
  • Template: Self-Servicing, General2005 Presets
  • Database: Microsoft Access 2003
  • Connection String: "Provider=Microsoft.Jet.OLEDB.4.0;Data Source=C:\Project\Database\Main.mdb;User Id=;Password=;Jet OLEDB:System Database=;Jet OLEDB:Database password="
  • Exception: System.Runtime.InteropServices.InvalidComObjectExceptionStack Trace:
   at System.Data.Common.UnsafeNativeMethods.IAccessor.ReleaseAccessor(IntPtr hAccessor, Int32& pcRefCount)
   at System.Data.OleDb.RowBinding.Dispose()
   at System.Data.OleDb.Bindings.Dispose()
   at System.Data.OleDb.OleDbCommand.CloseInternal()
   at System.Data.OleDb.OleDbCommand.ResetConnection()
   at System.Data.OleDb.OleDbCommand.Dispose(Boolean disposing)
   at System.ComponentModel.Component.Dispose()
   at SD.LLBLGen.Pro.ORMSupportClasses.Query.Dispose(Boolean isDisposing)
   at SD.LLBLGen.Pro.ORMSupportClasses.Query.Dispose()
   at SD.LLBLGen.Pro.ORMSupportClasses.DaoBase.PerformGetMultiAsDataTableAction(IEntityFields fieldsToReturn, DataTable tableToFill, Int64 maxNumberOfItemsToReturn, ISortExpression sortClauses, IPredicate selectFilter, IRelationCollection relations, Boolean allowDuplicates, IGroupByCollection groupByClause, ITransaction transactionToUse, Int32 pageNumber, Int32 pageSize)
   at LlblGen.DaoClasses.TypedListDAO.GetMultiAsDataTable(IEntityFields fieldsToReturn, DataTable tableToFill, Int64 maxNumberOfItemsToReturn, ISortExpression sortClauses, IPredicate selectFilter, IRelationCollection relations, Boolean allowDuplicates, IGroupByCollection groupByClause, ITransaction transactionToUse, Int32 pageNumber, Int32 pageSize) in C:\Projects\LLBLGen\DaoClasses\TypedListDAO.cs:line 49
   at LlblGen.TypedListClasses.EmployeeTypedList.Fill(Int64 maxNumberOfItemsToReturn, ISortExpression sortClauses, Boolean allowDuplicates, IPredicate selectFilter, ITransaction transactionToUse, IGroupByCollection groupByClause, Int32 pageNumber, Int32 pageSize) in C:\Projects\LLBLGen\TypedListClasses\EmployeeTypedList.cs:line 198
   at LlblGen.TypedListClasses.EmployeeTypedList.Fill(Int64 maxNumberOfItemsToReturn, ISortExpression sortClauses, Boolean allowDuplicates, IPredicate selectFilter) in C:\Projects\LLBLGen\TypedListClasses\EmployeeTypedList.cs:line 146
   at Windows.Program.Main(String[] args) in C:\Projects\Windows\Program.cs:line 53
Walaa avatar
Walaa
Support Team
Posts: 14994
Joined: 21-Aug-2005
# Posted on: 11-Aug-2008 09:31:12   

Please check these: http://osdir.com/ml/log.log4net.user/2006-06/msg00010.html http://osdir.com/ml/log.log4net.user/2006-11/msg00027.html

Would create a new project in VS and try using ADO.NET to access your MS Access database? (no LLBLGen Pro stuff) And see if the problem re-appear there.

loren
User
Posts: 14
Joined: 29-Jul-2006
# Posted on: 11-Aug-2008 18:35:08   

Wow. Those links are more advertising than content. simple_smile

I'm not sure if this is what you were looking for, but I tested OleDb data retrieval in a separate project and it worked so I moved the code into my current project for testing as follows:

// Use direct connection to fill a DataTable.
using (OleDbConnection connection = new OleDbConnection(@"Provider=Microsoft.Jet.OLEDB.4.0;Data Source=MyDatabase.mdb"))
{
    OleDbCommand command = new OleDbCommand("SELECT * FROM Invoice WHERE InvoiceId<200000", connection);

    connection.Open();
    using (OleDbDataReader reader = command.ExecuteReader())
    {
        DataTable dataTable = new DataTable();
        dataTable.Load(reader);
    }
    connection.Close();
}

// Create a predicate filter.
IPredicate filter = new FieldCompareValuePredicate(InvoiceFields.InvoiceId, ComparisonOperator.LesserThan, 200000);

// Retrieve a filtered InvoiceCollection.
InvoiceCollection collection = new InvoiceCollection();
collection.GetMulti(filter);

// Retrieve a filtered InvoiceTypedList.
InvoiceTypedList typedList = new InvoiceTypedList();
typedList.Fill(0, null, true, filter);

The direct data retrieval and the InvoiceCollection retrieval worked as expected. InvoiceTypedList triggered the exception above.

daelmo avatar
daelmo
Support Team
Posts: 8245
Joined: 28-Nov-2005
# Posted on: 12-Aug-2008 07:11:31   

Reproduced. (RTL: 2.6.8.804).

ProductTypedList products = new ProductTypedList();

IPredicateExpression filter = new PredicateExpression();
filter.Add(ProductsFields.ProductName ==  "Ikura");

products.Fill(0, null, false, filter);

Exception and stack trace: same as above

Combinations LLBLGen Pro v2.5 + MSAccess + Adapter = OK LLBLGen Pro v2.5 + MSAccess + SelfServicing = OK LLBLGen Pro v2.6 + MSAccess + Adapter = OK LLBLGen Pro v2.6 + MSAccess + SelfServicing = Issue reproduced LLBLGen Pro v2.6 + MSAccess + SelfServicing (no filter) = OK LLBLGen Pro v2.6 + SQLServer + Adapter = OK LLBLGen Pro v2.6 + SQLServer + SelfServicing = OK

So the problem seems to be on LLBLGen Pro v2.6 + MSAccess + SelfServicing combination, filtering on a TypedList.

We will look into it.

David Elizondo | LLBLGen Support Team
Otis avatar
Otis
LLBLGen Pro Team
Posts: 39882
Joined: 17-Aug-2003
# Posted on: 12-Aug-2008 10:19:05   

Extremely odd... I get: "Attempted to read or write protected memory. This is often an indication that other memory is corrupt." frowning

Also from the dispose method. Apparently a second dispose takes place somewhere, and the code in the OleDb provider isn't seeing this and tries to re-release the native elements.

(edit) Looks like a bug in the Microsoft OleDb crap (which won't be a first). The problem is this: we fetch the data with a datareader, the datareader gets disposed after it's done reading. (first closed, then disposed). Then the routine exists and the query is disposed. This dispose routine calls dispose on the command, which resets the connection (which is already closed) and there it tries to dispose the bindings of rows read by the command again...

I tracked it down to the following: the connection was closed before the reader was disposed. All other providers deal with this properly, but the OleDb one gets itself into trouble. Anyway, I have reversed the calls (first reader cleanup, then connection close) and it now works.

I've attached a new build which should correct the problem.

Frans Bouma | Lead developer LLBLGen Pro
loren
User
Posts: 14
Joined: 29-Jul-2006
# Posted on: 12-Aug-2008 17:44:34   

Works great! As always, LLBLGen support is phenomenal! Thanks for the quick response.