Reputation: 131
I am new to LINQ query expressions that use a lambda expression. I have one method by which I want to update the value in a different table. It is working fine in single or default, but not when I use a Where condition.
public static void UpdateData(int UserID)
{
using (var objEntity = new DataContext())
{
UserMaster objUser = objEntity.UserMasters.SingleOrDefault(TBL => TBL.UserID == UserID);
UserOfferUsed objUserUsed = objEntity.UserOfferUseds.Where(TBL => TBL.UserID == UserID);
objUser.Purchaseon = DateTime.Now.ToString("dd MMMM yyyy");
objUserUsed.UsedCoupon = 0;
objEntity.SaveChanges();
objData = null;
}
}
Error :Cannot implicitly convert type 'System.Linq.IQueryable' to 'Database.UserOfferUsed'. An explicit conversion exists (are you missing a cast?)
Upvotes: 1
Views: 2961
Reputation: 30502
A linq statement acts on sequences that are enumerable. This means that you can say: give me the first one. and: I've got this one, give me the next one.
Most linq operators return an IEnumerable < T >, meaning, it returns another sequence. The sequence is not enumerated until you perform something like foreach or until you perform a linq statement that doesn't return en IEnumerable < T > but a T
In other words: as long as your statements return sequences the code is not really enumerated.
If you look up SingleOrDefault, you'll see that the return value is a T. To calculate the return value the sequence is enumerated.
The return value of Enumerable.Where is not a T, but IEnumerable < T >. The compiler says so.
To get the same result as your first statement you'll need the parameterless SingleOrDefault:
IEnumerable<UserOfferUsed> mySequence = objEntity.UserOfferUseds
.Where(TBL => TBL.UserID == UserID);
UserOfferUsed objUserUsed = mySequence.SingleOrDefault();
Or if you want to do it in one statement:
UserOfferUsed objUserUsed = objEntity.UserOfferUseds
.Where(TBL => TBL.UserID == UserID)
.SingleOrDefault();
If you look up functions like First / Single / Any / All, Linq functions that don't return a sequence but one element of the sequence, you'll find a version with a parameter and a parameterless version. The function with the parameter has the same effect as using Where with the parameter followed by the parameterless function:
var result = SomeSequence.Last( x => SomeFunction(x))
returns the same item of the sequence as:
var result = SomeSequence.Where( x => SomeFunction(x)).Last();
Upvotes: 1
Reputation: 29036
.Where
will return an IQueryable
here, use .SingleOrDefault
or .FirstOrDefault
to get the result(if the required result is only a single item). or you can use .ToList()
if the result will contains more than one element. If so you have to change objUserUsed
as List<UserOfferUsed>
That is, Your code will be Like this:
UserOfferUsed objUserUsed = objEntity.UserOfferUseds.FirstOrDefault(TBL => TBL.UserID == UserID);
Or Like this
List<UserOfferUsed> objUserUsed = objEntity.UserOfferUseds.Where(TBL => TBL.UserID == UserID).ToList();
You can choose one of the above according to your requirement;
Update: If the UserID
is unique for each element in the list then .FirstOrDefault()
will be the best option since the query will not give more than one result( you have to consider null
too, Since FirstOrDefault()
will give null if there is no specified match found). If you Go with the List and you want to update those values means you can do like the following:
foreach(var objUserUsed in objEntity.UserOfferUseds.Where(TBL => TBL.UserID == UserID))
{
objUserUsed.UsedCoupon = 0;
}
Upvotes: 4