LINQ Where instead of Select - c#

I need to do this:
if(...)
{
var query2 = query.Select(i => new { Balance = i.Balance * i.RateValue, Date = i.Date });
}
Of course I may do it, but then I'll have a problem:
var list = query2.ToList();
How I can implement this? Maybe something like this:
if(accountName == "Safe" && currency == "Br")
{
query = query.Where(i => new { Balance = i.Balance * i.RateValue, Date = i.Date });
}
But this doesn't work.

Your question is lacking context. What is the type of i and which properties does it have more? Do you want to filter on account name and currency? Also Where and Select are completely different functions.
Or did you mean something like this?
var query = query.Where(i => i.AccountName == "Safe" && i.Currency == "Br")
.Select(i => new { Balance = i.Balance * i.RateValue, Date = i.Date });

Related

Aggregate of string on anonymous type

I want to concat multiple string value into single string with comma separated,i tried using aggregate function but it shows cannot convert string to how to fix this issue,
I tried below code
var res = (from e in WYNKContext.SurgeryAssigned.Where(x => x.CmpID == cmpid && x.IsCancelled == false)
select new
{
ID = e.SAID,
UIN = e.UIN,
SurgeryDate = e.SurgeryDate,
SurgeryID = e.SurgeryID,
Surgery = ((from st in WYNKContext.SurgeryTran.
Where(x => x.SurgeryID == e.SurgeryID)
select new
{
desc = icdmaster
.Where(x => x.ID ==
st.IcdSpecialityCode).Select(x =>
x.SpecialityDescription).FirstOrDefault(),
}).ToList()).Aggregate((a, b) => a.desc + "," + b.desc),
}).ToList();
I want Output like inside surgery property like = string1,string 2 ,etc....
without using aggregate i am getting as count in Surgery Property
var res = (from e in WYNKContext.SurgeryAssigned.Where(x => x.CmpID == cmpid && x.IsCancelled == false)
select new
{
ID = e.SAID,
UIN = e.UIN,
SurgeryDate = e.SurgeryDate,
SurgeryID = e.SurgeryID,
Surgery = (from st in WYNKContext.SurgeryTran.Where(x => x.SurgeryID == e.SurgeryID)
select new
{
icd = icdmaster.Where(x => x.ID == st.IcdSpecialityCode).Select(x => x.SpecialityDescription).FirstOrDefault(),
}).ToList(),
}).ToList();
also tried string join :
Surgery = string.Join(",", (from st in WYNKContext.SurgeryTran.Where(x => x.SurgeryID == e.SurgeryID)
select new
{
icd = icdmaster.Where(x => x.ID == st.IcdSpecialityCode).Select(x => x.SpecialityDescription).FirstOrDefault(),
}).ToList()),
but in output i am getting like this
Surgery ={ icd = CORNEA },{ icd = CATARACT/IOL }
can some one tell what i did wrong in string.join.....
The string class has a static method named Join, which takes in a collection of items and a string to join them with, which should work for you here.
If I'm reading your code correctly, it would look something like this:
Surgery = string.Join(",", WYNKContext.SurgeryTran
.Where(surgTran => surgTran.SurgeryID == e.SurgeryID)
.Select(surgTran => icdmaster
.Where(icd => icd.ID == surgTran.IcdSpecialityCode)
.Select(icd => icd.SpecialityDescription)
.FirstOrDefault())),

How to add serial no in IQueryable query in LinQ?

This is my method that returns IQueryable query. I want to generate serial no based on number of records.
public IQueryable<CompanyModel> GetCompanyData()
{
var query = (from e in Context.tblCompany
where e.Cmp_Id == this.CompanyId
&& e.TenantId == this.TenantId
select new CompanyModel()
{
CmpId = e.Cmp_Id,
SrNo = 0,
});
return query;
}
You can try below code may it help you
public IQueryable<CompanyModel> GetCompanyData()
{
List<CompanyModel> query = (from e in Context.tblCompany
where e.Cmp_Id == this.CompanyId
&& e.TenantId == this.TenantId
select new CompanyModel()
{
CmpId = e.Cmp_Id,
SrNo = 0,
}).ToList();
int counter=0;
query.Foreach(x=>x.SrNo = counter++);
return query;
}
As far as I am aware, the only way to have sequence number generated by the query itself is using "Select" method overload with 2 parameters, however it doesn't work with IQueryable, so your query will look like:
Context.tblCompany.Where(e => e.Cmp_Id == this.CompanyId && e.TenantId == this.TenantId)
.Select(e => new { CmpId = e.Cmp_Id })
.AsEnumerable()
.Select((e, i) => new CompanyModel { CmpId = e.CmpId, SrNo = i });
Obviously, this sequence number will be generated on the client and the resulting expression can't be treated as IQueryable anymore. At the same time, the part before "AsEnumerable" will be successfully translated into SQL.

multiple Search parameters in Multiple joined tables using LINQ in DBML

I want to build an advanced multiple parameters search for a website.
This is my DBML and ORM schema:
In this advanced multiple parameters search user can search through Estates with multiple parameters as like size, floor, city, price and so on.
This is the function that I coded to handle this part.
private DataTable linq_search_by_details()
{
myDBMLDataContext ctx = new myDBMLDataContext(address);
var query = ctx.Estates.AsQueryable();
query = query.Where(c => c.eshId == int.Parse(ddlEshape.SelectedValue.ToString()));
query = query.Where(c => c.cityId == int.Parse(ddlcity.SelectedValue.ToString()));
query = query.Where(c => c.ETId == int.Parse(ddlType.SelectedValue.ToString()));
query = query.Where(c => c.dealingId == int.Parse(ddldeal.SelectedValue.ToString()));
query = query.Where(c => c.deedId == int.Parse(ddldeed.SelectedValue.ToString()));
if (!string.IsNullOrEmpty(txtPrepaymentFrom.Value.Trim()))
{
query = query.Where(c => int.Parse(c.prepayment) <= int.Parse(txtPrepaymentFrom.Value));
}
if (!string.IsNullOrEmpty(txtPrepaymentTo.Value.Trim()))
{
query = query.Where(c => int.Parse(c.prepayment) >= int.Parse(txtPrepaymentTo.Value));
}
if (!string.IsNullOrEmpty(txtPrepaymentFrom.Value.Trim()) && !string.IsNullOrEmpty(txtPrepaymentTo.Value.Trim()))
{
query = query.Where(c => int.Parse(c.prepayment) <= int.Parse(txtPrepaymentFrom.Value) && int.Parse(c.prepayment) >= int.Parse(txtPrepaymentTo.Value));
}
if (!string.IsNullOrEmpty(txtPriceFrom.Value.Trim()))
{
query = query.Where(c => int.Parse(c.price) <= int.Parse(txtPriceFrom.Value));
}
if (!string.IsNullOrEmpty(txtPriceTo.Value.Trim()))
{
query = query.Where(c => int.Parse(c.price) >= int.Parse(txtPriceTo.Value));
}
if (!string.IsNullOrEmpty(txtPriceFrom.Value.Trim()) && !string.IsNullOrEmpty(txtPriceTo.Value.Trim()))
{
query = query.Where(c => int.Parse(c.price) <= int.Parse(txtPriceFrom.Value) && int.Parse(c.price) >= int.Parse(txtPriceTo.Value));
}
if (!string.IsNullOrEmpty(txtFloor.Value.Trim()))
{
query = query.Where(c => c.eFloor == short.Parse(txtFloor.Value));
}
if (chbExchange.Checked)
{
query = query.Where(c => c.exchange == true);
}
var final = query.Select(c => new { c.esId,c.owId, c.City.cityName, c.EstateShape.eshName, c.EstateType.ETName, c.owner.owFname, c.owner.owLname, c.esSize, c.prepayment, c.price });
return Special.LINQResultToDataTable(final.ToList());
}
This function works perfectly but now I want more to add some parameres from EstateEquipment and EstateFacility.
As you can see in ORM the relation between Estate and EstateEquipment (also Estate and EstateFacility) is one to many.
Now I want to user can search through Estate in cityId = 1, size around 400m which has for example eqId = 1 and 2 from EstateEquipment then which has for example fId = 1 and 2 from EstateFacility.
This is how I tried to handle last part.
foreach (ListItem item in cblEquipment.Items)
{
if (item.Selected)
{
eq = true;
}
}
if(eq)
{
var eqQuery = ctx.EstateEquipments.AsQueryable();
foreach (ListItem item in cblEquipment.Items)
{
if (item.Selected)
{
eqQuery = eqQuery.Where(c => c.eqId == int.Parse(item.Value.ToString()));
}
}
var eqFinal = eqQuery.Select(c => new { c.Estate.esId, c.Estate.owner.owId, c.Estate.City.cityName, c.Estate.EstateShape.eshName, c.Estate.EstateType.ETName, c.Estate.owner.owFname, c.Estate.owner.owLname, c.Estate.esSize, c.Estate.prepayment, c.Estate.price });
DataTable dtEq = Special.LINQResultToDataTable(eqFinal.ToList());
if(dtEq.Rows.Count>0)
{
this.Build_search(dtEq);
}
else
{
msg = "No record found";
sysMsg.Attributes["class"] = "";
sysMsg.Attributes["class"] = "alert alert-warning";
}
}
Here, First I check which equipment is selected from the list. Then extended the query accordance with Items selected. But I don't know how to join this new result with last result and even EstateFacility result.
Thanks for any help.
Without being able to test my solution because of your rather complex case, I hope it at least puts you in the right direction.
I'd say try something like this:
if (cblEquipment.Items.Any(item => item.Selected))
{
var selectedEquipmentIds = cblEquipment.Items.Where(item => item.Selected).Select(item => int.Parse(item.Value.ToString()));
query = query.Where(c => ctx.EstateEquipments.Any(eq => eq.esId == c.esId && selectedEquipmentIds.Contains(eq.eqId)));
}
This goes in your first code snippet just before var final .... Second snippet will then not be used and therefore your error handling over there will also need to move...

LINQ to Entities does not recognize the method

This is my Code where I am fetching data.
var list = (from u in _dbContext.Users
where u.IsActive
&& u.IsVisible
&& u.IsPuller.HasValue
&& u.IsPuller.Value
select new PartsPullerUsers
{
AvatarCroppedAbsolutePath = u.AvatarCroppedAbsolutePath,
Bio = u.Bio,
CreateDateTime = u.CreationDate,
Id = u.Id,
ModifieDateTime = u.LastModificationDate,
ReviewCount = u.ReviewsReceived.Count(review => review.IsActive && review.IsVisible),
UserName = u.UserName,
Locations = (from ul in _dbContext.UserLocationRelationships
join l in _dbContext.Locations on ul.LocationId equals l.Id
where ul.IsActive && ul.UserId == u.Id
select new PartsPullerLocation
{
LocationId = ul.LocationId,
Name = ul.Location.Name
}),
Rating = u.GetPullerRating()
});
Now Here is my Extension.
public static int GetPullerRating(this User source)
{
var reviewCount = source.ReviewsReceived.Count(r => r.IsActive && r.IsVisible);
if (reviewCount == 0)
return 0;
var totalSum = source.ReviewsReceived.Where(r => r.IsActive && r.IsVisible).Sum(r => r.Rating);
var averageRating = totalSum / reviewCount;
return averageRating;
}
I have check this Post LINQ to Entities does not recognize the method
And I come to know I need to use
public System.Linq.Expressions.Expression<Func<Row52.Data.Entities.User, int>> GetPullerRatingtest
But how ?
Thanks
You can use conditionals inside LINQ to Entity queries:
AverageRating = u.ReviewsReceived.Count(r => r.IsActive && r.IsVisible) > 0 ?
u.ReviewsReceived.Where(r => r.IsActive && r.IsVisible).Sum(r => r.Rating) /
u.ReviewsReceived.Count(r => r.IsActive && r.IsVisible)
: 0
This will be calculated by the server, and returned as part of your list. Although with 10 million rows like you said, I would do some serious filtering before executing this.
Code within LINQ (to Entities) query is executed within database, so you can't put random C# code there. So you should either use user.GetPullerRating() after it is retrieved or create a property if you don't want to do the calculation every time.
You can also do:
foreach (var u in list)
u.Rating = u.GetPullerRating()
By the way, why is it extension method.

Issue with LINQ group by with count

I'm trying to run the following query but for some reason MemberTransactionCount and NonMemberTransactionCount are coming back as the exact same values. It seems that the .Where() clauses aren't working as we'd expect them to.
Hoping someone can point out where I might be going wrong.
from trans in transactions
orderby trans.TransactionDate.Year , trans.TransactionDate.Month
group trans by new {trans.TransactionDate.Year, trans.TransactionDate.Month}
into grp
select new MemberTransactions
{
Month = string.Format("{0}/{1}", grp.Key.Month, grp.Key.Year),
MemberTransactionCount =
grp.Where(x => x.Account.Id != Guid.Empty || x.CardNumber != null)
.Sum(x => x.AmountSpent),
NonMemberTransactionCount =
grp.Where(x => x.Account.Id == Guid.Empty && x.CardNumber == null)
.Sum(x => x.AmountSpent)
}
EDIT
I've verified in the database that the results are not what they should be. It seems to be adding everything together and not taking into account the Account criteria that we're looking at.
I ended up solving this with two separate queries. It's not exactly as I wanted, but it does the job and seems to just as quick as I would have hoped.
var memberTrans = from trans in transactions
where trans.Account != null
|| trans.CardNumber != null
orderby trans.TransactionDate.Month
group trans by trans.TransactionDate.Month
into grp
select new
{
Month = grp.Key,
Amount = grp.Sum(x => x.AmountSpent)
};
var nonMemberTrans = (from trans in transactions
where trans.Account == null
&& trans.CardNumber == null
group trans by trans.TransactionDate.Month
into grp
select new
{
Month = grp.Key,
Amount = grp.Sum(x => x.AmountSpent)
}).ToList();
var memberTransactions = new List<MemberTransactions>();
foreach (var trans in memberTrans)
{
var non = (from nt in nonMemberTrans
where nt.Month == trans.Month
select nt).FirstOrDefault();
var date = new DateTime(2012, trans.Month, 1);
memberTransactions.Add(new MemberTransactions
{
Month = date.ToString("MMM"),
MemberTransactionCount = trans.Amount,
NonMemberTransactionCount = non != null ? non.Amount : 0.00m
});
}
I think the main problem here is that you doubt the result, though it might be correct.
Add another property for verification:
TotalAmount = grp.Sum(x => x.AmountSpent)

Categories

Resources