wrong result possibly because MergeAs(AppendOnly) LINQ - linq

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..

Related

Distinct on two columns with same data type

In my game application I have a combats table:
id player_one_id player_two_id
---- --------------- ---------------
1 1 2
2 1 3
3 3 4
4 4 1
Now I need to know hoy many unique users played the game. How can I apply distinct, count on both columns player_one_id and player_two_id?
Many thanks.
By using union you can get unique distinct value.
$playerone = DB::table("combats")
->select("combats.player_one_id");
$playertwo = DB::table("combats")
->select("combats.player_two_id")
->union($playerone)
->count();

How do i resolve conflict when selecting productid whose product visit have same occurences

My Database Table Contain Records Like this:
ID ProductId Occurences
1 1 1
2 2 5
3 3 3
4 4 3
5 5 5
6 6 8
7 7 9
Now i want to get top 4 ProductId with the highest Occurences.
This is my Query:
var data = (from temp in context.Product
orderby temp.Occurences descending
select temp).Take(4).ToList();
Now here as because ProductId 2 and 5 have same occurences and ProductId 3 and 4 also have same occurences then here I am not getting that how to resolve this means which product id should i take as because they are having same occurences.
Basically i am selecting this productid to display this products on my website.i will display those products which are return by this query.
So can anyone please give me some idea like how to resolve this ???
Expected Output:
ID ProductId Occurences
1 7 9
2 6 8
so Now for 3rd position Which ProductId i should select as because both ProductId 2 and 5 have same Occurences and for 4th position which ProductId i should select among 3 and 4 as because they both too have same occurences.
can I suggest you to use group by technique and pick the first one
context.Product.GroupBy(p => p.Occurance)
.Select(grp => grp.FirstOrDefault())
.Take(4)ToList();
Sorry, I have not tested this but it should do the job. You just need to add OrderBy along with it.

Where returns object reference not set to an instance of object

I'm new to Linq. I've 2 tables Table 1 and Table 2. They are related by Id1.
Table 1 Table2
------- ------
Id1 Id2 RId1 (reference key from TAble 1)
1 1 1
2 1
2 3 2
4 2
5 Null
3 6 .
. 7 .
.
When I use the Where clause to query data from table 2, I get error Object reference not set to an instance of object
var result = db.Table2.Where(i => i.Rid1 == 1);
Even this code doesn't help
if (result != null)
Please help me.
In this case it appears that Rid1 is a nullable. Comparing a null against an integer may result in that error. Try changing it to the following:
db.Table2.Where(i => i.Rid1.GetValueOrDefault(0) == 1);

linq group by First()

I have the following list
ID Counter SrvID FirstName
-- ------ ----- ---------
1 34 66M James
5 34 66M Keith
3 55 45Q Jason
2 45 75W Mike
4 33 77U Will
What I like to do is to order by ID by ascending and then get the first value of Counter, SrvID which are identical (if any).
So the output would be something like:
ID Counter SrvID FirstName
-- ------ ----- ---------
1 34 66M James
2 45 75W Mike
3 55 45Q Jason
4 33 77U Will
Note how ID of 5 is removed from the list as Counter and SrvID was identical to what I had for ID 1 but as ID 1 came first I removed 5.
I tried the following but not working:
var query = from record in list1
group record by new {record.Counter, record.SrvID }
into g
let winner = (from groupedItem in g
order by groupedItem.ID
select groupedItem ).First()
select winner;
I get the followng message:
The method 'First' can only be used as a final query operation.
The funny thing is the full error message is:
"NotSupportedException: The method 'First' can only be used as a final query operation. Consider using the method 'FirstOrDefault' in this instance instead."
I have had a problem with using First in Entity Framework, have you tried changing to FirstOrDefault ?

Linq query to retrieve: Customers, Orders and OrderLineItems

I have a table containing a list of customers, a second table containing orders placed by my customers and a third table containing the line items for the orders.
I would like to be able to use a Linq query to get the customer name, the number of orders and the total value of all the orders placed by this customer.
Assuming the following data:
[Customers]
CustomerId Name
---------------------
1 Bob Smith
2 Jane Doe
[Orders]
OrderId CustomerId
---------------------
1 1
2 1
3 2
[OrderLineItems]
LineItemId OrderId UnitPrice Quantity
--------------------------------------------
1 1 5 2
2 1 2 3
3 2 10 10
4 2 4 2
5 3 2 5
I would like the following result:
Name OrdersCount TotalValue
--------------------------------------------
Bob Smith 2 124
Jane Doe 1 10
What would be the Linq query to get this result?
If you presume that you have a strongly typed datacontext and a partial class Customer that you are free to add to, I would solve this problem like this:
public partial class Customer {
public int NumberOfOrders {
get { return Orders.Count(); }
}
public int TotalValue {
get { return Orders.OrderLineItems.Sum( o => o.UnitPrice * o.Quantity); }
}
}
YourDataContext db = new YourDataContext();
var query = from c in db.Customers
select new {c.Name, c.NumberOfOrders,
c.TotalValue}
This would project a new anonymous type with the data you requested.

Resources