Using .include(),.where(),.select() for LINQ query - c#

I have a query like this:
var rrx = (from camp in db.Campus
join camproom in db.CampusRooms
on camp.Id equals camproom.CampusId
where (camproom.CampusId == 1) && (camp.BranchId == 10) && (camproom.Status == 0)
select new CampusCampusRoom { CampName = camp.Name, CampusRoomNo = camproom.RoomNo, CampusClassCapacity = camproom.ClassCapacity, CampusExamCapacity = camproom.ExamCapacity }).ToList();
How can I perform this query using .include(), .where(), .select() clauses?

Here is an easy to use filtered projection example. This should provide you with a good example of what you want to do with your query.:
var customersWithRecentReservations =
from c in context.Contacts.OfType<Customer>()
where c.FirstName == p_firstName && c.LastName == p_lastName
select new {Customer = c, Reservations = c.Reservations.Where(r => r.ReservationDate >= p_reservationDate)};
var customers = customersWithRecentReservations.AsEnumerable().Select(p => p.Customer);
Try and adapt this code to your situation or let me know if you need further assistance with it ;)

Related

Conditional retrieval of data through linq in C#

var Getdetails = (from p in XYZDb.tblPulls
join
ro in XYZDb.tblRentalOrders
on p.AffCode equals ro.AffCode.Value
join
tpsb in XYZDb.tblPullSheetBatchProcessings
on p.PullNo.ToString() equals tpsb.PullSheet
select new
{
PullNos = p.PullNo,
AffCode = p.AffCode,
TotalItems = p.TotalItems,
p.PostedOn,
p.UpdatedOn,
p.IsPrinted,
BatchName = tpsb.BatchName
})
.Where(i => i.PostedOn >= from_date && i.PostedOn <= to && i.IsPrinted != null).Distinct();
In the above code only the pullno having BatchName are coming, i want to retrieve all the pullno within that timezone, and if it is batched, then the BatchName will also appear. I am stuck on that. Any kind of help will be appreciated. Feel free to ask any question.
Use left outer join,
var Getdetails = (from p in XYZDb.tblPulls
join
ro in XYZDb.tblRentalOrders
on p.AffCode equals ro.AffCode.Value
join
tpsb in XYZDb.tblPullSheetBatchProcessings
on p.PullNo.ToString() equals tpsb.PullSheet into pt
from batch in pt.DefaultIfEmpty()
select new
{
PullNos = p.PullNo,
AffCode = p.AffCode,
TotalItems = p.TotalItems,
p.PostedOn,
p.UpdatedOn,
p.IsPrinted,
BatchName = (batch == null ? String.Empty : batch.BatchName )
})
.Where(i => i.PostedOn >= from_date && i.PostedOn <= to && i.IsPrinted != null).Distinct();

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.

Method MAX() from SQL to Linq

Hi i'm trying to convert this SQL script in Linq expression
but i donĀ“t know how do the MAX method in Linq
someone can help me?
thank you!
SELECT c.Nome,
c.NumeroRG,
f.Tipo,
f.Descricao,
f.DataHora,
f.IdCliente,
c.IdCliente,
f.IdFrequencia
FROM Cliente c, Frequencia f
WHERE f.Tipo = 1
AND c.IdCliente = f.IdCliente
AND cast(f.DataHora as date) = cast(getdate() as date)
AND f.IdFrequencia = (select MAX(fr.IdFrequencia)
from frequencia fr
where fr.IdCliente =c.IdCliente)
Perhaps something like this:
var query = from client in db.Cliente
join freq in db.Frequencia
on client.IdCliente equals freq.IdCliente
where freq.Tipo == 1
&& freq.DataHora.Date == DateTime.Now.Date
&& freq.IdFrequencia == db.Frequencia.Where(f => f.IdCliente == client.IdCliente)
Max(f => f.IdFrequencia)
select new { .... };
Maybe you need to replace DateTime.Now.Date/DateTime.Today with SqlFunctions.DatePart if you use LINQ-To-Entities, but you haven't mentioned that.
this worked well! thanks
var query = from client in db.Cliente
join freq in db.Frequencia
on client.IdCliente equals freq.IdCliente
where freq.Tipo == true
&& freq.DataHora.Value.Date == DateTime.Today.Date
&& freq.IdFrequencia == db.Frequencia.Where(f => f.IdCliente == client.IdCliente).Max(f => f.IdFrequencia)
select new { Nome = client.Nome, Descricao = freq.Descricao };

Comma separated List in linq select

I have Table HR_Travel(TravelID, TravelCode....) and HR_TravelDocuments(TravelDocID, TravelID, DocUrl)
FromDate = FromDate.AddDays(1);
ToDate = ToDate.AddDays(1);
List<dynamic> Lst = new List<dynamic>();
var queryTravelDetails = from t in db.HR_TravelDetails
where ((t.StatusDate >= FromDate && t.StatusDate <= ToDate)
&& (t.EmpID == EmpID || EmpID == 0) && (t.TravelStatus == TravelStatus || TravelStatus == "All"))
orderby t.StatusDate descending
select new
{
TravelID = t.TravelID,
TravelSubID = db.HR_TravelDetails.Where(i => i.TravelID == 0).FirstOrDefault().TravelID == null ? 0 : db.HR_TravelDetails.Where(i => i.TravelID == 0).FirstOrDefault().TravelID,
t.TravelCode,
t.EmpID,
EmpName = db.EE_Employee.Where(i => i.EmpID == t.EmpID).FirstOrDefault().EmpName,
t.CellNo,
t.BoardingForm,
t.DestinationTO,
t.JournyDate,
t.Purpose,
t.Organization,
t.TravelStatus,
DocUrl = DocUrl = string.Join(",",( db.HR_TravelDocuments.Where(i => i.TravelID == t.TravelID && i.TravelSubID == 0).Select(i => i.DocUrl).ToList()))
};
foreach (var element in queryTravelDetails)
{
Lst.Add(element);
}
Gives the following error:
LINQ to Entities does not recognize the method 'System.String Join[String](System.String, System.Collections.Generic.IEnumerable`1[System.String])' method, and this method cannot be translated into a store expression.
The Join() method can't be used in LINQ expressions, because it cannot translate from CLR to T-SQL. Another example is that you can't use:
var itemCount = db.Table.Count(p => p.Something == SomeFunction(someVariable));
You should move the method call outside the LINQ statement:
var anotherVariable = SomeFunction(someVariable);
var itemCount = db.Table.Count(p => p.Something == anotherVariable);
I hope I explained in a good way.
EDIT: As seen in the comments before, you can also use ToArray() and when the data is loaded locally you can use functions in statements freely.

Dynamic LINQ Multiple Where Clause

Still really struggling with this and appear to be going round in circles.
I have the following code that is driving me nuts. It should populate a list of items to be used in an autocomplete text box:
public string[] GetAutoComplete(string prefixText, int count)
{
string memberid = HttpContext.Current.Session["MemberID"].ToString();
string locationid = HttpContext.Current.Session["LocationID"].ToString();
string inhouse = HttpContext.Current.Session["Inhouse"].ToString();
string supplier = HttpContext.Current.Session["Supplier"].ToString();
string groupw = HttpContext.Current.Session["Group"].ToString();
string external = HttpContext.Current.Session["External"].ToString();
MyEnts autocomplete = new MyEnts();
var r = from p in autocomplete.tblAutoCompletes
where p.MemberId == memberid && p.LocationId == locationid && p.ACItem.Contains(prefixText)
select p.ACItem;
if (inhouse == "Inhouse")
r = r.Where(p => p == inhouse);
if (supplier == "Supplier")
r = r.Where(p => p == supplier);
if (groupw == "Group")
r = r.Where(p => p == groupw);
if (external == "External")
r = r.Where(p => p == external);
r.OrderBy(p => p);
return r.ToArray();
What I am trying to retrieve with the dynamic where clause along the lines of the following.
Should inhouse = "Inhouse", then the list of items should include the word "Inhouse". If inhouse != "Inhouse", the word "Inhouse" should be excluded from the list.
This same logic should then be applied across the different where clauses i.e. Supplier, Group, External.
I genuinely have tried lots of different methods but I cannot for the life of me get the thing to work and it's frustrating me somewhat.
If anyone can suggest a way of doing this, you will either get a big kiss or a big frosty beer should our paths ever cross.
Not exactly sure about your problem here but if you want to exclude then shouldn't the code be something like
if (inhouse == "Inhouse")
r = r.Where(p => p == inhouse);
else
r = r.Where(p => p != inhouse);
Oh! if you want just exclusion then the code should be something like
if (inhouse != "Inhouse")
r = r.Where(p => p != inhouse);
If the set of values to include/exclude is known at compile-time (as appears to be the case in your example), I think this can be managed with one query:
string memberid = HttpContext.Current.Session["MemberID"].ToString();
string inhouse = HttpContext.Current.Session["Inhouse"].ToString();
string supplier = HttpContext.Current.Session["Supplier"].ToString();
bool includeInHouse = (inhouse == "Inhouse");
bool includeSupplier = (supplier == "Supplier");
MyEnts autocomplete = new MyEnts();
var r = from p in autocomplete.tblAutoCompletes
where (p.MemberId == memberid && p.LocationId == locationid && p.ACItem.Contains(prefixText))
&& (includeInHouse || (p.ACItem != "InHouse"))
&& (includeSupplier || (p.ACItem != "Supplier"))
select p.ACItem;
r.OrderBy(p => p.ACItem);
return r.ToArray();
I've eliminated a couple cases for brevity.
Wouldn't each of your Where clauses just need to contain a Contains criteria and some Not Contains?
if (inhouse == "Inhouse")
r = r.Where(p => p.Contains(inhouse) && !p.Contains("Supplier") && !p.Contains("Group") && !p.Contains("External"));
Sorted.
var r = from p in autocomplete.tblAutoCompletes
where p.MemberId == memberid && p.LocationId == locationid && p.ACItem.Contains(prefixText)
select p.ACItem;
if (inhouse != "Inhouse")
r = r.Where(p => p != "Inhouse");
if (supplier != "Supplier")
r = r.Where(p => p != "Supplier");
if (groupw != "Group")
r = r.Where(p => p != "Group");
if (external != "External")
r = r.Where(p => p != "External");
r = r.OrderBy(p => p);
return r.ToArray();
I had to set the exception in quotation marks as the session vlaue was inappropriate and wouldn't have picked out anything from the list.
Thanks to all those contributing and helping me out.

Categories

Resources