Wrong field returned

Posts   
 
    
AlexanderM
User
Posts: 41
Joined: 18-May-2012
# Posted on: 11-Dec-2014 22:03:02   

Hello,

Running this query on Northwind ProductId has the value of CategoryId. Based on the results of my business code it looks like it gets the value of the first Id/long in the table, but I also noticed that a boolean got the wrong value and I didn't really understand where the value was getting from.


var products =
    (
    from p in Product
    select new
    {
        Product = p,
        ProductId = p.ProductId, //This one is wrong
    }
    )
    .ToList();
products.Dump();

Renaming the returned field to something else (ProductId => ProductId2) fixes this:


var products =
    (
    from p in Product
    select new
    {
        Product = p,
        ProductId2 = p.ProductId, //Now this is correct
    }
    )
    .ToList();
products.Dump();

Btw for the sake of short code I use anonymous types but in my original code I used normal classes and that also fails. This happened in the same statement of the other forum thread, but I think it is not related, just my bad luck cry

daelmo avatar
daelmo
Support Team
Posts: 8245
Joined: 28-Nov-2005
# Posted on: 12-Dec-2014 06:16:08   
David Elizondo | LLBLGen Support Team
Otis avatar
Otis
LLBLGen Pro Team
Posts: 39590
Joined: 17-Aug-2003
# Posted on: 12-Dec-2014 10:49:23   

For projecting entities as references in a custom type we use a trick to make this work (as we have two pipelines: one for projections and one for entities as entity fetches can use a shortcut and thus are faster that way), it seems this falls apart when you reference the same fields again in the projection. Any reason for that? It should work though, I agree.

Frans Bouma | Lead developer LLBLGen Pro
Otis avatar
Otis
LLBLGen Pro Team
Posts: 39590
Joined: 17-Aug-2003
# Posted on: 12-Dec-2014 11:30:47   

I can reproduce it. The reason for why it goes wrong is that the 'ProductId' field is already in the list of fields, exactly how it is defined, and therefore it's skipped. The engine makes a mistake there, as the row fetched is used as input into the lambda, but it is 1 field short: it should reference the ProductId field from the one that's already in the projection. We replace the fields in the lambda with array read expressions so they obtain the values from the row read from the DB, before the lambda is executed to produce the end instance. Skipping a field as it's already in the resultset, and it would otherwise cause a problem. It goes ok in non-entity fetches properly: This produces a proper query with 1 field which is read two times. The same should happen in the situation where the field is actually used for producing an entity.


[Test]
public void MultipleTimesSameFieldInProjectionTest3()
{
    using(var adapter = new DataAccessAdapter())
    {
        var metaData = new LinqMetaData(adapter);

        var q = from p in metaData.Product
                select new
                {
                    P1 = new { ProductId = p.ProductId },
                    P2 = new {  ProductId = p.ProductId}

                };

        foreach(var v in q)
        {
            Assert.AreEqual(v.P1.ProductId, v.P2.ProductId);
        }
    }
}

Will look into what we can do about this.

Frans Bouma | Lead developer LLBLGen Pro
Otis avatar
Otis
LLBLGen Pro Team
Posts: 39590
Joined: 17-Aug-2003
# Posted on: 12-Dec-2014 15:19:52   

Fixed. There was a problem with the bookkeeping of indices where which value was located as some values were used to produce an entity. This has been fixed now: indices are properly kept and duplicates now get the proper values. Also we fixed a related issue with where the entity instance was placed in the raw value list which was projected: no longer can it overwrite a field value which is projected directly into the custom type (like ProductId here).

Frans Bouma | Lead developer LLBLGen Pro
AlexanderM
User
Posts: 41
Joined: 18-May-2012
# Posted on: 16-Dec-2014 10:56:25   

Reopened because we noticed problems with the new DLL and our exisitng code. It crashes on statements with contains. We use the DLL mentioned in the thread: Linq to llblgen Expression tree for Contains limitation

Is the fix you metioned there also present in the DLL in this thread?

Otis avatar
Otis
LLBLGen Pro Team
Posts: 39590
Joined: 17-Aug-2003
# Posted on: 16-Dec-2014 17:09:31   

all fixes are cumulative, so a new dll contains all previous fixes. This thread you mean? http://www.llblgen.com/tinyforum/Messages.aspx?ThreadID=22781 Yes that fix is in the dll attached to this thread. (and the test related to that thread works OK)

Could you give a repro case for the situation which crashes with the fixed version of this thread as we don't have a failing test (all our contains queries succeed)

Frans Bouma | Lead developer LLBLGen Pro
AlexanderM
User
Posts: 41
Joined: 18-May-2012
# Posted on: 19-Dec-2014 13:58:15   

I will look into it, my colleagues got an error on a contains which looked the same. So they reverted my change and we're using the old DLL. I haven't seen the error. Because of the holiday season it will take some time.

Otis avatar
Otis
LLBLGen Pro Team
Posts: 39590
Joined: 17-Aug-2003
# Posted on: 19-Dec-2014 14:18:49   

AlexanderM wrote:

I will look into it, my colleagues got an error on a contains which looked the same. So they reverted my change and we're using the old DLL. I haven't seen the error. Because of the holiday season it will take some time.

No worries, we're not exactly operating at full speed this time of year as well wink

I double checked the other thread and the Contains issue and our test code to see whether the feature works did contain the same code and works OK (produces a proper contains query).

I also don't think this fix has any relation to the other thread (as the change is only in effect during materialization), it might be some change later than the one of the other thread might have caused a problem but that needs more research.

Frans Bouma | Lead developer LLBLGen Pro