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..
If my EF tables are correct and the query is correct, why does it return wrong result?
Is it because the
MergeAs(AppendOnly)
? because the only thing that different is that.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..