Invalid cast exception UnaryExpression to EntityFieldExpression

Posts   
 
    
arjanv
User
Posts: 512
Joined: 15-Nov-2006
# Posted on: 19-Apr-2008 14:48:53   

Hi,

I get an InvalidCastException when I call the ToList() method of a query.

This is the code I'm using where sourceApplicationID is an int.

                LinqMetaData meta = new LinqMetaData(dataAccessAdapter);
                var query = (from r in meta.RedirectRequest
                            where r.OriginalApplicationID == sourceApplicationID
                            select r).IncludeFields(r=> r.ID, r=> r.OriginalApplicationID, r=> r.DestinationApplicationID);

                List<RedirectRequestEntity> redirects = query.ToList();

Stacktrace

[InvalidCastException: Unable to cast object of type 'System.Linq.Expressions.UnaryExpression' to type 'SD.LLBLGen.Pro.LinqSupportClasses.ExpressionClasses.EntityFieldExpression'.]
   SD.LLBLGen.Pro.LinqSupportClasses.ExpressionHandlers.QueryExpressionBuilder.HandleExcludeIncludeFieldsExpression(ExcludeIncludeFieldsExpression expressionToHandle) +208
   SD.LLBLGen.Pro.LinqSupportClasses.ExpressionHandlers.GenericExpressionHandler.HandleExpression(Expression expressionToHandle) +728
   SD.LLBLGen.Pro.LinqSupportClasses.ExpressionHandlers.QueryExpressionBuilder.HandleExpression(Expression expressionToHandle) +110
   SD.LLBLGen.Pro.LinqSupportClasses.ExpressionHandlers.GenericExpressionHandler.HandleSelectExpression(SelectExpression expressionToHandle, SelectExpression newInstance) +239
   SD.LLBLGen.Pro.LinqSupportClasses.ExpressionHandlers.GenericExpressionHandler.HandleSelectExpression(SelectExpression expressionToHandle) +111
   SD.LLBLGen.Pro.LinqSupportClasses.ExpressionHandlers.QueryExpressionBuilder.HandleSelectExpression(SelectExpression expressionToHandle) +98
   SD.LLBLGen.Pro.LinqSupportClasses.ExpressionHandlers.GenericExpressionHandler.HandleExpression(Expression expressionToHandle) +1514
   SD.LLBLGen.Pro.LinqSupportClasses.ExpressionHandlers.QueryExpressionBuilder.HandleExpression(Expression expressionToHandle) +110
   SD.LLBLGen.Pro.LinqSupportClasses.LLBLGenProProviderBase.HandleExpressionTree(Expression expression) +848
   SD.LLBLGen.Pro.LinqSupportClasses.LLBLGenProProviderBase.Execute(Expression expression) +33
   SD.LLBLGen.Pro.LinqSupportClasses.LLBLGenProProviderBase.System.Linq.IQueryProvider.Execute(Expression expression) +29
   SD.LLBLGen.Pro.LinqSupportClasses.LLBLGenProQuery`1.Execute() +32
   SD.LLBLGen.Pro.LinqSupportClasses.LLBLGenProQuery`1.System.Collections.Generic.IEnumerable<T>.GetEnumerator() +53
   System.Collections.Generic.List`1..ctor(IEnumerable`1 collection) +369
   System.Linq.Enumerable.ToList(IEnumerable`1 source) +54
   Orangehill.Cal.BusinessLogic.LinqSO.GetRedirectsViaLinq2(Int32 sourceApplicationID) in C:\Projects\CAL\Linq2LLBLGen\Solution\Orangehill.Cal.BusinessLogic\LinqSO.cs:43
   Orangehill.Cal.Backend.Login.OnInit(EventArgs e) in C:\Projects\CAL\Linq2LLBLGen\Solution\Orangehill.Cal.Backend\public\Login.aspx.cs:38
   System.Web.UI.Control.InitRecursive(Control namingContainer) +321
   System.Web.UI.Page.ProcessRequestMain(Boolean includeStagesBeforeAsyncPoint, Boolean includeStagesAfterAsyncPoint) +834

Any suggestions?

T.i.a. Arjan Vermunt

Otis avatar
Otis
LLBLGen Pro Team
Posts: 39903
Joined: 17-Aug-2003
# Posted on: 19-Apr-2008 16:04:14   

Is any of these fields specified in the includefields call a nullable type?

Frans Bouma | Lead developer LLBLGen Pro
arjanv
User
Posts: 512
Joined: 15-Nov-2006
# Posted on: 19-Apr-2008 20:37:40   

No, they are all integer fields. The ID field is an identity field.

Otis avatar
Otis
LLBLGen Pro Team
Posts: 39903
Joined: 17-Aug-2003
# Posted on: 19-Apr-2008 21:32:32   

arjanv wrote:

No, they are all integer fields. The ID field is an identity field.

Yes, but a nullable<int> or not? (i.e. are they nullable in the DB) ?

Frans Bouma | Lead developer LLBLGen Pro
arjanv
User
Posts: 512
Joined: 15-Nov-2006
# Posted on: 19-Apr-2008 21:43:03   

All fields of the table are not nullable

Otis avatar
Otis
LLBLGen Pro Team
Posts: 39903
Joined: 17-Aug-2003
# Posted on: 19-Apr-2008 22:23:55   

arjanv wrote:

All fields of the table are not nullable

Ok thanks simple_smile

Still weird where the unary comes from though. Could you enable tracing on the linq provider? (at level 3 !) ? You'll then get the expression as it is fed to the linq provider in text. Could you paste it here please?

Frans Bouma | Lead developer LLBLGen Pro
arjanv
User
Posts: 512
Joined: 15-Nov-2006
# Posted on: 19-Apr-2008 22:35:12   

Hope this is what you asked for. I used this value in de config file.

<add name="LinqExpressionHandler" value="3"/>

output

: Initial expression to process:
value(SD.LLBLGen.Pro.LinqSupportClasses.DataSource2`1[Orangehill.Cal.LLBL.EntityClasses.RedirectRequestEntity]).Where(r => (r.OriginalApplicationID = value(Orangehill.Cal.BusinessLogic.LinqSO+<>c__DisplayClass2).sourceApplicationID)).ExcludeFields( value(System.Linq.Expressions.Expression`1[System.Func`2[ Orangehill.Cal.LLBL.EntityClasses.RedirectRequestEntity,System.Object]][]))
A first chance exception of type 'System.InvalidCastException' occurred in SD.LLBLGen.Pro.LinqSupportClasses.NET35.DLL
Otis avatar
Otis
LLBLGen Pro Team
Posts: 39903
Joined: 17-Aug-2003
# Posted on: 20-Apr-2008 11:01:55   

Yes that's what I was looking for simple_smile It would reveal if there were unexpected unaryexpressions somewhere, which isn't the case. so I've to look elsewhere simple_smile

Frans Bouma | Lead developer LLBLGen Pro
arjanv
User
Posts: 512
Joined: 15-Nov-2006
# Posted on: 20-Apr-2008 11:07:45   

Do you need something from me, generated code or the project file? if so, I would prefer to send it via email, because it's a spin off from a live application.

Otis avatar
Otis
LLBLGen Pro Team
Posts: 39903
Joined: 17-Aug-2003
# Posted on: 20-Apr-2008 11:19:58   

arjanv wrote:

Do you need something from me, generated code or the project file? if so, I would prefer to send it via email, because it's a spin off from a live application.

If you could re-create the error in a northwind based query it would be great (you can just post the query here). I haven't tried reproducing it yet, I'll try on monday (with the other issue still open, the prefetch path error).

Frans Bouma | Lead developer LLBLGen Pro
arjanv
User
Posts: 512
Joined: 15-Nov-2006
# Posted on: 20-Apr-2008 11:27:14   
If you could re-create the error in a northwind based query it would be great

Does it really has to be reproducable against the northwind database? A database connection isn't necessary, because it's not getting there.

arjanv
User
Posts: 512
Joined: 15-Nov-2006
# Posted on: 21-Apr-2008 10:08:46   

Found out what causes the Exception simple_smile .

Tables containing bit fields cause the exception to occur. I reproduced it on the Products table of the Northwind database.

Otis avatar
Otis
LLBLGen Pro Team
Posts: 39903
Joined: 17-Aug-2003
# Posted on: 21-Apr-2008 10:43:36   

arjanv wrote:

Found out what causes the Exception simple_smile .

Tables containing bit fields cause the exception to occur. I reproduced it on the Products table of the Northwind database.

as in: excluding 'Discontinued' or including 'Discontinued' caused it? That would explain why our unittests work but you ran into this issue: we don't use a bitfield in these tests.

Frans Bouma | Lead developer LLBLGen Pro
arjanv
User
Posts: 512
Joined: 15-Nov-2006
# Posted on: 21-Apr-2008 10:51:17   

No, as in: when the entity contains a bit field wink

arjanv
User
Posts: 512
Joined: 15-Nov-2006
# Posted on: 21-Apr-2008 11:21:41   

Sorry, spoke too soon. had it working for employee's added products entity and got the Unary cast exception. Concluded too soon. I attach a test case against the northwind database.

Otis avatar
Otis
LLBLGen Pro Team
Posts: 39903
Joined: 17-Aug-2003
# Posted on: 21-Apr-2008 11:24:05   

I can repro it when I add a bitfield to the IncludeFields list:


[Test]
public void GetAllProductsWithJustAFewFieldsIncluded()
{
    using(DataAccessAdapter adapter = new DataAccessAdapter())
    {
        LinqMetaData metaData = new LinqMetaData(adapter);
        var q = (from p in metaData.Product
                 select p).IncludeFields(p => p.ProductName, p => p.QuantityPerUnit, p=>p.Discontinued);

        int count = 0;
        foreach(var v in q)
        {
            count++;
            Assert.IsFalse(v.ReorderLevel.HasValue);
            Assert.IsTrue(v.ProductName.Length > 0);
            Assert.IsTrue(v.QuantityPerUnit.Length > 0);
        }
        Assert.AreEqual(77, count);
    }
}

When I remove p=>p.Discontinued from the IncludeFields() call, the query works fine (on the latest codebase). Looking into it

Frans Bouma | Lead developer LLBLGen Pro
arjanv
User
Posts: 512
Joined: 15-Nov-2006
# Posted on: 21-Apr-2008 11:29:24   

Including or excluding value types are the problem. Try adding an int field in the excluding list. The same result.

Otis avatar
Otis
LLBLGen Pro Team
Posts: 39903
Joined: 17-Aug-2003
# Posted on: 21-Apr-2008 11:30:14   

It happens with any entity field which is of a valuetype (e.g. int, bool, etc.). -> an extra convert is added by the C#/VB.NET compiler to convert the field expression to the 'object' type.

(edit) heh, I didn't saw your previous post flushed simple_smile

Frans Bouma | Lead developer LLBLGen Pro
Otis avatar
Otis
LLBLGen Pro Team
Posts: 39903
Joined: 17-Aug-2003
# Posted on: 21-Apr-2008 11:51:20   

Fixed in next build!

Frans Bouma | Lead developer LLBLGen Pro