3

NOTE

This might be a dup of this. But I don't get a clear answer from that.

The problem

I got wrong result from linq.

EXAMPLE

id     groupid   status     name
------------------------------------
guid1  guidA     reserved   truck1
guid2  guidA     reserved   truck2
guid3  guidA     reserved   truck3
guid4  guidA     reserved   truck4

*assume all guids are guids.. 
**id is a primary key (unique)

CASE

If I put only where groupid == guidA the result is correct (4 rows)

but, if I put where groupid == guidA && status == reserved the result is wrong (3 rows)

EXPLANATION

The query built with expression tree. From the debug watch, the query (that return wrong the result) is like this

query.Expression:
-----------------
Convert(value(System.Data.Objects.ObjectSet`1[myEFTable]))
.MergeAs(AppendOnly)
.Where(m => ( m.groupId == value(myFilterClass).groupId))
.Where(m => m.status.Contains(value(myFilterClass).statusStr))
.Select(m => new myViewClass() 
{
    Id = m.id, GroupId = m.groupid, Status = m.status, Name = m.name
})
.OrderBy(o => o.Name).Skip(0).Take(10)

Then I tried to run a similar query and it returns correct result

assume e is ObjectSet<myEFTable> and strGuid is guidA

Guid grId = new Guid(strGuid);
e.AsQueryable()
.Where(m => m.status.Contains("reserved"))
.Where(m => m.groupId == grId)
.Select(m => new myViewClass()
{
    Id = m.id, GroupId = m.groupid, Status = m.status, Name = m.name
}).OrderBy(o => o.Name).Skip(0).Take(10);

QUESTION

I'm completely clueless about this error..

  1. If my EF tables are correct and the query is correct, why does it return wrong result?

  2. Is it because the MergeAs(AppendOnly) ? because the only thing that different is that.

  3. If this is about unique key, what should I do with myViewClass to ensure that every row is unique and should not be merged (if that was the case) ?

    ---------------------------------------------------------------------

UPDATE 2013/08/29

The result is incorrect because I have a typos in one of my query..

So, after changing few lot of here and there, try and error, till I almost lost the trace of whatever that changed, commented, erased, suddenly it works.. EUREKA!! what?

what I did is not really change everything, it's just a lot of changes but doesn't really end up so much different than where I was starting.. so there's that!

then that EUREKA moment ends and leave me tracing my way back to find out what is actually wrong, simply because I don't believe in miracles..

so here it is..

The tables is actually similar to this:

 PartsGroups   
 -----------
 id  name   
 -----------
 1   Nails  
 -----------

 Items
 -----------------
 id  name   status
 -----------------
 2  Table  Empty
 5  Table  Indent
 6  Door   Empty
 3  Sofa   Empty

 PartsGroupPairs      
 ------------------   
 id  groupId partId   
 ------------------   
 1       1       4    
 2       1       7    
 3       1       8    
 4       1      15    
 -------------------  

 Parts                      
 ------------------------   
 id  name  itemId  status   
 ------------------------   
  4  XNail      2  Empty    
  7  SNail      5  Empty    
  8  UNail      6  Empty    
 15  ZNail      3  Empty    
 ------------------------   

The relationships is like this

 PartsGroups   PartsGroupPairs      Parts                      Items
 -----------   ------------------   ------------------------   -----------------
 id  name      id  groupId partId   id  name  itemId  status   id  name   status
 -----------   ------------------   ------------------------   -----------------
 1   Nails     1       1       4     4  XNail      2  Empty     2  Table  Empty
 1   Nails     2       1       7     7  SNail      5  Empty     5  Table  Indent
 1   Nails     3       1       8     8  UNail      6  Empty     6  Door   Empty
 1   Nails     4       1      15    15  ZNail      3  Empty     3  Sofa   Empty
 -----------   -------------------  ------------------------   -----------------
       One <---> Many       Many <---> One           Many <------> One 

 PartsGroup.pairs is a collection of PartsGroupPairs 
 PartsGroupPair.group is a PartsGroup 
 PartsGroupPair.part is a Part
 Part.item is an Item
 Item.parts is a collection of Parts

So when I select PartsGroup where name == 'Nails' it works perfectly, it returns 4 rows

But why when I select PartsGroup where name == 'Nails' and Status == 'Empty' it returns 3 rows?? (see below)

 PartsGroups   PartsGroupPairs      Parts                      Items
 -----------   ------------------   ------------------------   -----------------
 id  name      id  groupId partId   id  name  itemId  status   id  name   status
 -----------   ------------------   ------------------------   -----------------
 1   Nails     1       1       4     4  XNail      2  Empty     2  Table  Empty
 1   Nails     3       1       8     8  UNail      6  Empty     6  Door   Empty
 1   Nails     4       1      15    15  ZNail      3  Empty     3  Sofa   Empty
 -----------   -------------------  ------------------------   -----------------

this row didnt get selected..

 PartsGroups   PartsGroupPairs      Parts                      Items
 -----------   ------------------   ------------------------   -----------------
 id  name      id  groupId partId   id  name  itemId  status   id  name   status
 -----------   ------------------   ------------------------   -----------------
 1   Nails     2       1       7     7  SNail      5  Empty     5  Table  Indent
 -----------   -------------------  ------------------------   -----------------

the mistake I made is at the Where part. The query itself built at the runtime coz I separate entities, filters, views and paging modules. So mostly I just passing IQueryable here and there.

In the case for filter, every time I filter, I'll add another Where. So in this case it went like this below:

using(var DB = new databaseContext()) 
{
    ObjectSet<PartsGroupPair> d = 
        DB.CreateObjectSet<PartsGroupPair>("partsGroupPair");

    int searchGroupId = 1; // int instead of guid for example
    int searchStatus = "Empty"; 

    // filter by specific PartsGroup    
    IQueryable<PartsGroupPair> e = d.Where(m => m.group.id == searchGroupId);

    // then if I want to filter by the status
    e = e.Where(m => m.part.item.status == searchStatus));  // WRONG!! 
    // I want to filter by part.status, not item.status
    // so instead, it should be 
    e = e.Where(m => m.part.status == searchStatus));  // RIGHT!! 

    // view 
    IQueryable<PartsGroupPairView> f = 
        e.Select(m => new PartsGroupPairView()
        {
            Id = m.id, GroupId = m.groupid, 
            Status = m.part.status, Name = m.part.name 
            // etc..
        });

    // paging
    f = f.OrderBy(o => o.Name).Skip(0).Take(10);  
}

The wrong filtering makes LINQ ignore the other Parts, and returns 3 rows instead of 4 because it found only one Item instead of 2 Parts.

So in my case, it's a silly typo with a quite complex data..

It's really frustrating when nothing works while everything seems to be okay..

4

0 回答 0