query only returning one result - c#

Hey, I am pretty certain I am doing something incorrectly with my lambda expression and that is making it so that I only return a single result. If there is nothing wrong with my query (it has the ability to return multiple results), then I must have an error elsewhere and I should be able to find it. If my results should return more than one result for the third part of the or, only one is being returned. Am I doing something wrong here?
var proQuery = from a in solutionContext.Products
where a.ID == solutionID ||
(a.ParentID == solutionID && a.Versions.All(c => c.VersionNumber == activeNumber)) ||
(a.Product2.ParentID == solutionID &&
a.Versions.All(c => c.VersionNumber == activeNumber))
select a;
If there is anymore information you need, I would be happy to help.

There isn't really enough here for us to go on, but are you sure that the Alls are correct and shouldn't be Anys? Absent additional information, that's one thing to look at.

Related

Difference between these 2 LINQ queries using Azure mobile client

So I'm having issues with this LINQ query I had been using for some time, and now it seems to not be working as expected.
messagesWithoutConditional =
await
MobileServiceInstance.GetSyncTable<Messages>()
.OrderByDescending(key => key.SentDate)
.Take(50)
.Where(
p =>
(p.Uuid == myUuid && p.RecipientUuid == otherUuid) ||
(p.Uuid == otherUuid && p.RecipientUuid == myUuid))
.ToListAsync();
So lets say I have this query that simply returns the last 50 messages sent between 2 parties. Now if I want to add an additional condition that the 50 messages should also be before a certain date I would expect to do something like this
messagesWithConditional =
await
MobileServiceInstance.GetSyncTable<Messages>()
.OrderByDescending(key => key.SentDate)
.Take(50)
.Where(
p =>
((p.Uuid == myUuid && p.otherUuid == recipientUuid) ||
(p.Uuid == otherUuid && p.RecipientUuid == myUuid))
&& p.SentDate < 'some date')
.ToListAsync();
Lets suppose I should expect this to return 40 messages, but it returns 0. However, if I alternate the query into this
messagesWithConditional = messagesWithoutConditional.Where(p => p.SentDate < 'some date').ToList();
then I will receive the 40 expected messages by querying the result of my original expression.
How is the second approach any different from the first? Ideally I would like to use the && operator to add a new conditional expression rather than break off into a second where clause
Edit
I should also note that the times are in UTC, and the SentDate attribute is of type DateTimeOffset
As of right now it appears to be a bug, unless some other insight is made. Please refer to the bug report for more information
.Where should be put before the .OrderByDescending and .Take(50)

Determine if record exists where two fields must match in MVC

I have a table (and a corresponding class) for this solution that has only two fields a UserId and a TicketId. Now I need to test if a record exists in this table where the UserId matches the logged in individual and TicketId matches the passed value. This is the code I tried:
bool subscriptionExists = db.TicketSubscriptions.Any(ts => ts.TicketId.Equals(db.Tickets.FirstOrDefault(t => t.TicketNumber == ticketNumber).TicketId))
.Where(ts => ts.UserId == db.Users.FirstOrDefault(u => u.NTUserName.Equals(User.Identity.Name)).UserId);
However, I am getting the following error:
'bool' does not contain an extension method for 'where' and no
extension method 'where' accepting a first argument of type 'bool'
could be found (are you missing a using directive or an assembly
reference?
Am I on the right track? or is there a much better way to test this?
You are using Where on a bool value instead of a List. Any() returns bool. You can try like following. Hope this will help you.
var ticketId=db.Tickets.FirstOrDefault(t =>t.TicketNumber==ticketNumber).TicketId;
var userId=db.Users.FirstOrDefault(u=>u.NTUserName.Equals(User.Identity.Name)).UserId;
bool subscriptionExists = db.TicketSubscriptions.
Any(ts => ts.TicketId.Equals(ticketId) && ts.UserId == userId);
You're calling the .Where on the result of the .Any, which is a boolean value. Try combining your clauses and then calling .Any on the whole thing:
bool subscriptionExists = db.TicketSubscriptions.Any(
ts => ts.TicketId.Equals(db.Tickets.FirstOrDefault(t => t.TicketNumber == ticketNumber).TicketId) &&
ts.UserId == db.Users.FirstOrDefault(u => u.NTUserName.Equals(User.Identity.Name)).UserId);
TicketSubscriptions.Any() returns a Bool.
It is result is a True or False. So you cannot continue to query with a where. Write the code more readable. You can see mistakes easier. In any() function you need a boolean statement like if statements. You can use || or && signs simply.
var userId = User.Identity.Name;
var passedValue = ... // I dont know if it is from a parameter.
bool subscriptionExists = TicketSubscriptions.Any(ts => ts.NTUserName == userId && ts.TicketId == passedValue );
your problem is that Any() returns a bool, so you can't call Where() on it.
Where, returns another IEnumerable, so if you put Where before Any(), you won't have that problem.
You can also put both conditions inside the Any() I.E. someEnumerable.Any(/*condition1*/ && /*condition1*/);
on another note, I'd make use of Navigation Properties if I were you. You can google search for "navigation properties" and the name of whatever database framework you're using(like entity framework or linq to sql) to find more information.
That will let you do things like
subscriptionExists = db.TicketSubscriptions
.Any(ts => ts.Ticket.TicketNumber == ticketNumber
&& ts.User.NTUserName == User.Identity.Name);
on yet another note, I believe that User.Identity is going to have the user id, so you don't even have to bother accessing the users table like that. Intellisence can help you find out how to access that.
Complementing the #Azim answer
When you use .FirstOrDefault must verify returned values. Otherwise if you have sure that the return value never is null must use .First
var ticketId=db.Tickets.FirstOrDefault(t =>t.TicketNumber==ticketNumber).TicketId;
varuserId=db.Users.FirstOrDefault(u=>u.NTUserName.Equals(User.Identity.Name)).UserId;
if(ticketId != null && userId != null)
{
bool subscriptionExists = db.TicketSubscriptions.
Any(ts => ts.TicketId.Equals(ticketId) && ts.UserId == userId)
}

Is this the correct way to return this data using LINQ

I have the following linq statement, however I'm not convinced its the best way of achieving the goal (but I'm not sure):
return
Buyer.Where(x =>
x.OperatingCalendar.BankHolidays.Any(y => y.OccursOn == today.Date)) ??
Buyer.Where(x =>
x.OperatingCalendar.DayOfWeek.DayID == (int)today.DayOfWeek);
The idea is to query Buyer.OperatingCalendar to find a row indicating that today a public holiday, and if its not a public holiday a row indicating the day of week. Some buyers do not have any rows.
The key is that OperatingCalendar can potentially contain a row for both scenarios for each buyer, but if a public holiday exists it must override day of the week. If no rows exist Buyer would return null.
Can't use OR - due to unique data requirements. The diagram below should explain the situation.
Where will never return null so the ?? operator is useless here. Assuming you only want to ever pull a single result anyway then you should use SingleOrDefault instead of Where, this should allow you to use ?? correctly
return
Buyer.SingleOrDefault(x =>
x.OperatingCalendar.BankHolidays.Any(y => y.OccursOn == today.Date)) ??
Buyer.SingleOrDefault(x =>
x.OperatingCalendar.DayOfWeek.DayID == (int)today.DayOfWeek);
You can, however, do this in one query which would save you an extra trip to the DB
return Buyer.SingleOrDefault(x =>
x.OperatingCalendar.BankHolidays.Any(y => y.OccursOn == today.Date) ||
x.OperatingCalendar.DayOfWeek.DayID == (int)today.DayOfWeek)

LINQ query, ignoring results with certain decimal points

I need to perform a LINQ query on a large database in C#. One of the columns I need to use in the query is a double. I need to omit results that have more than 4 decimal places in this column. The database can't be changed as other programs need to use it and make use of what I don't want. The results are then added to a list to use later. I thought that this would work.
where fun.Units != '*.?????*'
However it returns the error that too many characters are in the character literal.
The whole query looks like this so far
var clientQuery1 = from cli in main1.Clients
from pol in main1.Policies
from fun in main1.FundHoldings
from uni in main1.UnitPrices
where cli.AccountNumber == accNum
&& pol.ClientRef == cli.ClientRef
&& fun.FKeyRef == pol.PolicyRef
&& uni.UnitPriceRef == fun.UnitPriceRef
&& fun.Units != '*.?????*'
select uni.UnitName;
Can you please try with this below query and let me know.
var clientQuery1 = from cli in main1.Clients
from pol in main1.Policies
from fun in main1.FundHoldings
from uni in main1.UnitPrices
where cli.AccountNumber == accNum
&& pol.ClientRef == cli.ClientRef
&& fun.FKeyRef == pol.PolicyRef
&& uni.UnitPriceRef == fun.UnitPriceRef
&& fun.Units == Math.Round(Convert.ToDouble(fun.Units),4)
select uni.UnitName;
Well you can solve that particular error using:
&& fun.Units != "*.?????*"
Note the change from single quotes to double quotes. However, that's not going to help you overall. What's the type of fun.Units in LINQ? If it's decimal, you might be able to use:
&& decimal.Round(fun.Units, 4) == fun.Units
... but it's not clear to me what that will do in the generated SQL. It's worth a try, but even if it works you should see what the SQL looks like.

Possible to do this in linq?

I am wondering if something like this could be done(of course what I have written does not work but that's what I am essentially trying to achieve) .
var test = u.Owner;
a.Table.Where(u => test == true)
I have a linq query that I want to reuse(basically I got a query that I use 5 times) and the only thing that changes is what I am comparing against.
So in the above u.Owner is compared against true. In another query it would look the same but instead of u.Owner I might have u.Add == true or u.Edd == true.
So is there a way I can sort of reuse what I have. Of course in my code the query is a bit longer but I just shortened down.
Edit
Basically the whole query
List<Permission> clearence = user.PermissionLevels.Where(u => u.Id == Id &&( u.Add == permissionNeeded || u.Permission.Name == PermissionTypes.Owner)).ToList();
permissionNeeded == Enum
So my orignal way of doing it was u.Permission.Name == permissionNeeded so I compared the enum value to a string.
Now my db model has change and I need to check against 5 different permissions separately that are bools and not strings.
u.Add = true || u.Owner == true;
u.Edit = true || u.Owner == true;
u.Delete= true || u.Owner == true;
u.View= true || u.Owner == true;
Thats all changes for the entire query so that's why I am trying to make it into one query(just like I had it before).
So I am thinking of having a switch statement. The method still takes in a permissionNeeded(enum) I then go through and determine what clause I need and some how insert it into the query.
switch(PermssionNeeded)
{
case PermissionTypes.Add:
u.Add;
break;
// all other cases here.
}
Take advantage of the fact that Where can have any function taking type Table as a parameter and returning a boolean to create a function like:
public IQueryable<Table> QueryTables(Func<Table, bool> testFunction)
{
return a.Table.Where(testFunction).AsQueryable<Table>();
}
Edit: (in addition to edit to add AsQueryable above, which I earlier forgot)
If all you want to do is vary the boolean field used in the test, and you don't want to have to specify an entire function (which you're about to find out is much easier), you would need to use some reflection:
using System.Reflection;
public IQueryable<Table> QueryTables(PropertyInfo pi)
{
return a.Table.Where(t => (bool)(pi.GetGetMethod().Invoke(t, null))).AsQueryable<Table>();
}
To construct the PropertyInfo object, use something like:
PropertyInfo pi = typeof(Table).GetProperty("Owner");
I prefer the earlier method, but I did want to show that something like this is at least possible.
If you only want to specify the property you are checking you can do
public IEnumerable<Table> GetTables(Func<Table,bool> getValue)
{
return a.Table.Where(table => /*some common filter*/)
.Where(table => getValue(table))
}
var query = from u in uSrc join v in vSrc on u.ID equals v.RelatedUID
where v.Valid && u.Created < DateTime.UtcNow.AddDays(-365)
select u; // relatively complicated starting point.
var q1 = query.Where(u => u.Add); // must also have Add true
var q2 = query.Where(u => u.Test); // must also have Test true
var q3 = query.Where(u => u.ID < 50); // must also have ID < 50
And so on.
Edit:
Okay, so your starting query is:
List<Permission> clearence = student.PermissionLevels.Where(u => u.Id == Id &&( u.Add == permissionNeeded || u.Permission.Name == PermissionTypes.Owner)).ToList();
However, note that this creates a list, so any further work done on it will be a matter of Linq-to-objects. We'll come back to that in a minute, as it's sometimes good and sometimes not.
Now, if I understand you correctly, you need different sets for different cases, which you can do with your query as per:
var set0 = clearance.Where(u.Add = true || u.Owner == true);
var set1 = clearance.Where(u.Edit = true || u.Owner == true);
var set2 = clearance.Where(u.Delete= true || u.Owner == true);
var set3 = clearance.Where(u.View= true || u.Owner == true);
Now, this will work, but may not be the best approach. If we go back to the original query, we don't have to do ToList(), but can have:
IQueryable<Permission> clearence = student.PermissionLevels.Where(u => u.Id == Id &&( u.Add == permissionNeeded || u.Permission.Name == PermissionTypes.Owner));
Now, in the first case because we built a list we first got all values that matched the critera backed, and then stored it in memory, in clearance.
In the second case, clearance doesn't store any values at all, but instructions on how to get them.
The question is which is better to use. In the case where we are going to end up using the vast majority of the objects returned by the first query on its own, then there is a performance boost in using the list version, because they are loaded into memory only once, and then taken from memory without hitting the database again.
However, in most cases, it's better to do the second version for two reasons:
We hit the database in each case, but only retrieve the objects needed in that case.
We don't store anything in memory longer than necessary. Above a certain amount this is an important performance matter in itself.
The time to first item is faster this way.
We can further refine, for example if we do the following:
var trimmed = from set0 select new{u.Id, u.Permission.Name};
The we retrieve anonymous objects with Id and Name properties that are all we care about for a particular case, and not all of the relevant fields are retrieved from the database, or other source.
I've recently come to prefer a Dictionary over switch statements. You could store all your lambas in a Dictionary<PermissionNeeded, Func<User, bool>> that would look like this:
Dictionary<PermissionNeeded, Func<User, bool>> Permissions =
new Dictionary<PermissionNeeded, Func<User, bool>> {
{ PermissionNeeded.Add, u => u.Add }, // don't need to specify == true
{ PermissionNeeded.Edit, u => u.Edit },
...
etc
};
And you would call it like this:
var clearance = Permissions[PermissionNeeded.Add](user);
or maybe
var clearance = Permissions[PermissionNeeded.Add](user) && Permissions[PermissionNeeded.Edit](user);
or perhaps
var clearance = Permission[PermissionNeeded.Add](user) || Permissions[PermissionNeeded.View](user);
and so on. Even if you don't have a user object, I think this would still be valid and make the code pretty easy to read, and if you have to modify your functions, its all in the dictionary...

Categories