Comparing 2 strings in a linq to sql statement - c#

var j = from c in User.USERs
where (c.USER_NAME.Equals(tempUserName))
select c;
this keeps on giving me an empty sequence
both are just strings im comparing user input with database

Do something like this:
var j = User.USERs.First(c => c.USER_NAME == tempUserName)
or
var j = User.USERs.Single(c => c.USER_NAME == tempUserName)
or just take j[0] from the result your own query gives you.
P.S. - both First or Single will throw an exception if no item matched the query, if you want to get null returned if nothing was found use FirstOrDefault respectively SingleOrDefault.
to broaden the spectrum try something like this:
string userToSearchFor = tempUserName.Trim().ToLower();
var j = User.USERs.FirstOrDefault(c => c.USER_NAME.ToLower() == userToSearchFor);
if (j != null)
{
//found something
}

If it is returning an empty sequence then your where clause is evaluating to false, check what SQL it is generating if you need to solve that problem first.
To answer your question, to get a single element you usually use
.Single()
.SingleOrDefault()
.First()
.FirstOrDefault()

I would do it like this:
var result = User.USERs.SingleOrDefault(x => x.USER_NAME.Equals(tempUserName));
if (result != null)
{
//do your thing
}

Related

Linq query in next line

Why line 2 of mycode can not be read :
var allResarchs = db.Researchs;
allResarchs.Where(a => a.ChiefManagerId == 1);
allResarchs.ToList();
You never set the value of Where statement to the variable.
var allResarchs = db.Researchs.Where(a => a.ChiefManagerId == 1).ToList();
You should assign results of LINQ queries:
var allResarchs = db.Researchs;
var filtered = allResarchs.Where(a => a.ChiefManagerId == 1);
var list = filtered.ToList();
Also you can do it in simplier way (if you do not need intermediate results):
var list = db.Researchs.Where(a => a.ChiefManagerId == 1).ToList();
Linq never changes the input sequence!
allResearches.Where(research => research.ChiefManagerId == 1);
This statement won't change allResearches. You could do the following. (by the way, I've changed the var into the actual returned types, so you understand better what is going on.)
IQueryable<Research> queryResearches = db.Researches;
IQueryable<Research> queryResearchesWithId1 = queryResearches
.Where(research => research.ChiefManagerId == 1);
List<Research> researchesWithId1 = queryResearchedWithId1.ToList();
Be aware, that until the last statement the query is not executed, there is no communication with the database yet. Only the last statement will actually contact the database.
Of course you can write it all in one statement. However, this won't improve performance very much:
var researchesWithId1 = db.Researches
.Where(research => research.ChiefManagerId == 1)
.ToList();

Linq Query to check if the records are all the same

I am very much new to the Linq queries. I have the set of records in the csv which is like below
ProdID,Name,Color,Availability
P01,Product1,Red,Yes
P02,Product2,Blue,Yes
P03,Product1,Yellow,No
P01,Product1,Red,Yes
P04,Product1,Black,Yes
I need to check for the Names of the each product and if its is not the same in all the records then I need to send an error message.I know the below query is used to find the duplicates in the records but not sure how can I modify it check if it all has the same values.
ProductsList.GroupBy(p => p.Name).Where(p => p.Count() > 1).SelectMany(x => x);
var first = myObjects.First();
bool allSame = myObjects.All(x=>x.Name == first.Name);
Enumerable.All() will return true if the lambda returns true for all elements of the collection. In this case we're checking that every object's Name property is equal to the first (and thus that they're all equal to each other; the transitive property is great, innit?). You can one-line this by inlining myObjects.First() but this will slow performance as First() will execute once for each object in the collection. You can also theoretically Skip() the first element as we know it's equal to itself.
if I understand correctly you want to check if product exists in the list
using System.Linq;
private bool ItemExists(string nameOfProduct) {
return ProductsList.Any(p=> p.Name== nameOfProduct);
}
UPD after author comment:
To know all the records that are not having the same name as the first record:
var firstName = ProductsList[0].Name;
var differentNames = ProductsList.Where(p => p.Name != firstName);
Another option (just to have all other names): ProductsList.Select(p => p.Name).Where(n => n != firstName).Distinct()
Old version
So, if there are at least two different names then you should return an error?
LINQ way: return ProductsList.Select(p => p.Name).Distinct().Count() <= 1
More optimizied way:
if (ProductsList.Count == 0)
return true;
var name = ProductsList[0].Name;
for (var i = 1; i < ProductsList.Count; i++)
{
if (ProductsList[i].Name != name)
return false;
}
return true;

How do I Take everything in a collection using Linq?

I've got a method which can accept an optional int? value as a number of items to Take from a collection. I want to return all items if a null value is passed. Right now I have to duplicate my query to accomplish this
if(take == null)
{
x = db.WalkingDeadEps.Where(x => x.BicyclesCouldHaveSavedLives == true).ToList()
}
else
{
x = db.WalkingDeadEps.Where(x => x.BicyclesCouldHaveSavedLives == true).Take(take).ToList()
}
Is there a simpler way? Something like this?
.Take(take != null ? take : "all")
with Linq you have the option to store your query in variables. it will not be executed until you call ToList or equivalent methods on it.
var query = db.WalkingDeadEps.Where(x => x.BicyclesCouldHaveSavedLives == true);
x = take.HasValue ? query.Take(take.Value).ToList() : query.ToList();

LINQ Filtering - Optimization

I make one database trip to get a list of entities.
I then would like to separate this list into 2 lists, one for the entities that have not expired (using a start and end) which i call TopListings and another which are regular listings, those that have expired or have start/end date as null (the ones that are not TopListings)
I am not entirely sure which filtering is fasted to separate into 2 lists, should I get the toplist first, then filter second list based on what is NOT in the top list for second?
var listings = ListingAdapter.GetMapListings(criteria);
var topListings = listings.Where(x => x.TopStartDate >= DateTime.Now && x.TopExpireDate >= DateTime.Now);
//I AM NOT SURE WHAT THIS LINE SHOULD BE
var regularListings = listings.Where(x => x.TopStartDate < DateTime.Now || x.TopExpireDate < DateTime.Now || x.TopStartDate == null || x.TopExpireDate == null );
Thank you
You might want to use a LookUp
like this:
var lookup = listings.ToLookup(x => x.TopStartDate >= DateTime.Now && x.TopExpireDate >= DateTime.Now);
var topListings = lookup[true];
var regularListings = lookup[false]; // I assume everything not a topListing is a regular listing.
If this isnt enough, you could create an enum
enum ListingType { Top, Regular, WhatEver };
...
var lookup = listings.ToLookUp(determineListingType); // pass a methoddelegate that determines the listingtype for an element.
...
var topListings = lookup[ListingType.Top];
var regularListings = lookup[ListingType.Regular];
var whateverListings = lookup[ListingType.WhatEver];
In this case, it would probably be easier to use a loop, instead of Linq operators:
var topListings = new List<Listing>();
var regularListings = new List<Listing>();
foreach (var x in listings)
{
if (x.TopStartDate >= DateTime.Now && x.TopExpireDate >= DateTime.Now)
topListings.Add(x);
else
regularListings.Add(x);
}
This is also more efficient, because the list is enumerated only once.
Take a look at the 'Except' operator to make things a little easier. You might have to add a .ToList() on topListings first though.
var regularListings = listings.Except(topListings);
http://blogs.msdn.com/b/charlie/archive/2008/07/12/the-linq-set-operators.aspx
Make use of regular foreach loop that's straight forward. You can iterate through listing with one go and add items to appropriate collections. If you are LINQ kind of guy, ForEach extension is what you are looking for:
var topListings = new List<Listing>();
var regularListings = new List<Listing>();
listing.ForEach(item=>{
if (x.TopStartDate < DateTime.Now
|| // I've inverted the condition, since it is faster-one or two conditions will be checked, instead of always two
x.TopExpireDate < DateTime.Now)
regularListings.Add(x);
else
topListings.Add(x);
});

Foreach loop problem for IQueryable object

Can we use foreach loop for IQueryable object?
I'd like to do something as follow:
query = IQueryable<Myclass> = objDataContext.Myclass; // objDataContext is an object of LINQ datacontext class
int[] arr1 = new int[] { 3, 4, 5 };
foreach (int i in arr1)
{
query = query.Where(q => (q.f_id1 == i || q.f_id2 == i || q.f_id3 == i));
}
I get a wrong output as each time value of i is changed.
The problem you're facing is deferred execution, you should be able to find a lot of information on this but basically none of the code s being executed until you actually try to read data from the IQueryable (Convert it to an IEnumerable or a List or other similar operations). This means that this all happens after the foreach is finished when i is set to the final value.
If I recall correctly one thing you can do is initialize a new variable inside the for loop like this:
foreach (int i in arr1)
{
int tmp = i;
query = query.Where(q => (q.f_id1 == tmp || q.f_id2 == tmp || q.f_id3 == tmp));
}
By putting it in a new variable which is re-created each loop, the variable should not be changed before you execute the IQueryable.
You dont need a for each, try it like this:
query = objDataContext.Myclass.Where(q => (arr1.Contains(q.f_id1) || arr1.Contains(q.f_id2) || arr1.Contains(q.f_id3));
this is because "i" is not evaluated until you really use the iterate the query collectionif not by that time I believe "i" will be the last.

Categories