Help troubleshooting LINQ query - c#

I have this LINQ query:
var returnList = from TblItemEntity item in itemList
join TblClientEntity client in clientList
on item.ClientNo equals client.ClientNumber
join TblJobEntity job in jobList
on item.JobNo equals job.JobNo
where item.ClientNo == txtSearchBox.Text //Is this filter wrong?
orderby client.CompanyName
select new { FileId = item.FileId, CompanyName = client.CompanyName, LoanStatus = item.LoanStatus, JobNo = job.JobNo, JobFinancialYE = job.JobFinancialYE, VolumeNo = item.VolumeNo };
Why doesn't this return anything?
P/S : All of them are of string datatype.

Have you tried to remove parts of the join to figure out where the problem is and then add those removed parts back again one after one? Start with:
var returnList = from TblItemEntity item in itemList
where item.ClientNo == txtSearchBox.Text //Is this filter wrong?
select new { FileId = item.FileId };
Since you're doing inner joins there could be that one of the joins filters out all the items.
EDIT: When debugging don't expand the return type, the select new {FileId = item.FileId} is all you need to debug.

Still waiting on that sample data.
You say you're getting results filtering by other attributes so why should this be any different? Assuming the user-input txtSearchBox has a reasonable value, try printing the values out onto the debug console and see if you're getting reasonable results. Look at the output window. Try this version of your query:
Func<string,bool> equalsSearch = s =>
{
var res = s == txtSearchBox.Text;
Debug.WriteLine("\"{0}\" == \"{1}\" ({2})", s, txtSearchBox.Text, res);
return res;
};
var returnList = from TblItemEntity item in itemList
join TblClientEntity client in clientList
on item.ClientNo equals client.ClientNumber
join TblJobEntity job in jobList
on item.JobNo equals job.JobNo
//where item.ClientNo == txtSearchBox.Text //Is this filter wrong?
where equalsSearch(item.ClientNo) //use our debug filter
orderby client.CompanyName
select new { FileId = item.FileId, CompanyName = client.CompanyName, LoanStatus = item.LoanStatus, JobNo = job.JobNo, JobFinancialYE = job.JobFinancialYE, VolumeNo = item.VolumeNo };

Why doesn't this return anything?
There two possibilites:
1) The join is empty, that is, no items, clients and jobs have matching ID's.
2) The where clause is false for all records in the join.
To troubleshoot this you will have to remove the where clause and/or some of the joined tables to see what it takes to get any results.

Related

Linq count and sum in join

I want to get rows with the count column and sum column like in the SQL command ... count(column1.table1) as countname, sum(column2.table1) as sumname ..., but I don't know the right way to write it in Linq, for the example:
var get = (from dbrg in db.data_barangs
join pbrg in db.pengiriman_barangs
on dbrg.kode_barang equals pbrg.kode_barang
join jdkp in db.jadwal_kapals
on pbrg.id_jadwal equals jdkp.id_jadwal
join dplb in db.data_pelabuhans
on jdkp.kode_pelabuhan equals dplb.kode_pelabuhan
join drdp in db.data_redpacks
on dbrg.kode_barang equals drdp.kode_barang
select new
{
KodeBarang = dbrg.kode_barang,
TanggalKedatangan = jdkp.tgl_kedatangan,
WaktuKedatangan = jdkp.waktu_kedatangan,
NamaPelabuhan = dplb.nama_pelabuhan,
Kota = dplb.kota,
Provinsi = dplb.provinsi,
NamaKapal = jdkp.kapal,
JumlahPacking = drdp.id_jadwal.Count(),
TotalBerat = drdp.total_berat_packing.Sum()
}).ToList();
Do you guys know the correct way?
The comments above correctly saying that group by should be used.
It is also good to know what keys should be used in the group by. In the select above you are listing a lot of properties and two of them should be grouped. Please take consider adding and removing some columns.
Why remove columns? Because of performance. If more columns used to group id_jadwal and total_berat_packing that has a cost at database level.
You may ask why add more columns? This can be because of correct functionality. Right now you have seven classic property, these are enough for correct summation? If not add more columns and create index for those
I did modify the query to fulfil grouping if you have question please let me know in the comment section.
var result = (from dbrg in db.data_barangs
join pbrg in db.pengiriman_barangs
on dbrg.kode_barang equals pbrg.kode_barang
join jdkp in db.jadwal_kapals
on pbrg.id_jadwal equals jdkp.id_jadwal
join dplb in db.data_pelabuhans
on jdkp.kode_pelabuhan equals dplb.kode_pelabuhan
join drdp in db.data_redpacks
on dbrg.kode_barang equals drdp.kode_barang
group new { JumlahPacking = drdp.id_jadwal, TotalBerat = drdp.total_berat_packing }
by new {
KodeBarang = dbrg.kode_barang,
TanggalKedatangan = jdkp.tgl_kedatangan,
WaktuKedatangan = jdkp.waktu_kedatangan,
NamaPelabuhan = dplb.nama_pelabuhan,
Kota = dplb.kota,
Provinsi = dplb.provinsi,
NamaKapal = jdkp.kapal,
}
into beratAndPackingSumGroup
select new
{
KodeBarang = beratAndPackingSumGroup.Key.KodeBarang,
TanggalKedatangan = beratAndPackingSumGroup.Key.TanggalKedatangan,
WaktuKedatangan = beratAndPackingSumGroup.Key.WaktuKedatangan,
NamaPelabuhan = beratAndPackingSumGroup.Key.NamaPelabuhan,
Kota = beratAndPackingSumGroup.Key.Kota,
Provinsi = beratAndPackingSumGroup.Key.Provinsi,
NamaKapal = beratAndPackingSumGroup.Key.NamaKapal,
JumlahPacking = beratAndPackingSumGroup.Select(x => x.JumlahPacking).Count(),
TotalBerat = beratAndPackingSumGroup.Sum(x => x.TotalBerat)
});
If JumlahPacking property is not correct you can call a distinction on it: beratAndPackingSumGroup.Select(x => x.JumlahPacking).Distinct().Count() this is require more performance.

LINQ query works on LINQPAD throws Error on Visual Studio

var data = (from prod in db.ref_ProductAvail
group prod by new { prod.storeOfAccount, prod.serviceName } into g
orderby g.Key.storeOfAccount
join branch in db.ref_Branch
on g.Key.storeOfAccount equals branch.code
select new
{
branchCode = g.Key.storeOfAccount,
branchName = branch.description,
serviceName = g.Key.serviceName,
svcCount = g.Key.serviceName.Count()
}).ToList();
My Query works on LINQPAD but throws this error on C# >
DbExpressionBinding requires an input expression with a collection ResultType.Parameter name: input,
as I've searched for a solution I failed to found the exact solution to my problem, also removing ToList or using IEnumerable does work but I cannot use foreach.
Yes, you got it right. the error should be in g.Key.serviceName.Count() because this expression is trying to count number of characters in serviceName string. which is not convertible to sql. If you want to achieve the same thing, you can try something like
var data = (from prod in db.ref_ProductAvail
group prod by new { prod.storeOfAccount, prod.serviceName } into grouping
orderby grouping.Key.storeOfAccount
from g in grouping
join branch in db.ref_Branch
on g.Key.storeOfAccount equals branch.code
select new
{
branchCode = g.Key.storeOfAccount,
branchName = branch.description,
serviceName = g.Key.serviceName,
svcCount = grouping.Select(x=>x.Key.serviceName).Distinct().Count()
}).ToList();
Haven't tested it though

Returning List<string> from Linq query returns query syntax not values

I have the below code to return a list of strings.
public List<string> Top5CodesForToday()
{
var date = DateTime.Now;
var resultList = new List<string>();
using (var db = new PillowContext())
{
var qry = (from d in db.DownTimes
where DbFunctions.TruncateTime(d.DateTime) == DbFunctions.TruncateTime(date)
group d by new {d.Code}
into g
let total = g.Sum(x => x.Amount)
orderby total descending
let top5 = g.Take(5).ToList()
select new {g.Key.Code, Total = total});
foreach (var item in qry)
{
int x = item.Code;
var results = from r in db.DownTimeCodes
where r.Code == x
select r.Description;
resultList.Add(results.ToString());
}
}
return resultList;
}
When I look at the contents of returnList I am seeing the correct number of items however each item is made up of the actual query syntax, not the data itself. I have seen this before and usually solve it by doing .ToList() however I am unsure how I could change my code to solve this
The problem here is that when you are calling ToString the query is not executed yet, so essentially you are calling ToString on a IQueryable object, receiving the query instead of results. You need to call something to execute the query.
You can call ToList() still:
var results = (from r in db.DownTimeCodes
where r.Code == x
select r.Description).ToList();
resultList.AddRange(results);
Or, if you expect just one result, call FirstOrDefault()/SingleOrDefault():
var results = (from r in db.DownTimeCodes
where r.Code == x
select r.Description).FirstOrDefault();
resultList.Add(results);
You are calling ToString() on List<>. As default for most complex types, it just writes out type name not the data.
This line
resultList.Add(results.ToString());
should be changed to
resultList.AddRange(results);

Linq to SQL joining two tables and populate GridView

I have two tables in my database, Building and Town. They look like this:
Building:
buildingid
buildingname
Town:
id
userid
buildingid
In Town there is one entry for each building a user has.
What i want is to populate a GridView for a user with a given userid. This GridView should include the buildingname and the number of buildings.
Building. I have tried this:
var buildings = (from Town in dc.Towns
join Building in dc.Buildings
on Town.buildingid equals Building.buildingid
select Building.buildingname);
gvBuildings.DataSource = buildings;
gvBuildings.DataBind();
But I don't know how to get the numbers for each building.
I have now been working on this for a while and a couple of your answers work. I have used this code:
var buildings = dc.Towns
.Where(t => t.userid == userid)
.GroupJoin(dc.Buildings,
t => t.buildingid,
b => b.buildingid,
(Town, Buildings) => new
{
BuildningName = Buildings.First().buildingname,
Count = Buildings.Count()
});
gvBuildings.DataSource = buildings.ToList();
gvBuildings.DataBind();
When i run this code my GridView ends up looking like this:
I need the buildings to be shown in groups, grouped by the buildingname. I have tried all of the suggestions but i cant get it to work.
Try grouping:
var buildings = dc.Towns
.Where(t => t.UserId == userId)
.GroupJoin(dc.Buildings,
t => t.BuildingId,
b => b.BuildingId,
(town, buildings) => new
{
BuildingName = buildings.First().BuildingName,
Count = buildings.Count
});
Keep in mind that when binding to a control you must supply a collection of type (or implementing) IList. This can be accomplished by calling ToList() on the buildings collection:
gvBuildings.DataSource = buildings.ToList();
gvBuildings.DataBind();
check linq differed execution
and than try the blow code might work for you
var buildings =
(from j in dc.Town
join i in dc.Buildings
on j.buildingId equals i.buildingId
where j.Userid = varUSerid
group new {i, j}
by new
{ i.BuildingID }
into
g
select new {
BuildingName = g.First<k=>k.BuildingName)
, count = g.Count() } ).ToList();
gvBuildings.DataSource = buildings;
gvBuildings.DataBind();
var buildings = (from Town in dc.Towns
join Building in dc.Buildings
on Town.buildingid equals Building.buildingid
into results
from r in results.DefaultIfEmpty()
group Town by new
{
r.BuildingId
} into groupedResults
where Town.UserID == parameteruserId
select new
{
BuildingName = Building.buildingname,
BuildingCount = groupedResults.Count()
});
Try this.. it should work.. i have a similar requirement..
manDbDataContext db = new DbDataContext();
var estimatedTotal = ( from est in db.AssignmentEstimatedMaterials
where est.assignment_id == Convert.ToInt32(Label_assignmentId.Text)
join materialdetail in db.Materials on est.material_id equals materialdetail.material_id
select new { est.qty,est.total_amount, materialdetail.material_name}).ToList();
GridView_estiamte_material.DataSource = estimatedTotal;
GridView_estiamte_material.DataBind();
Note, you should select individual data and it works.

Problem with order by in LINQ

I'm passing from the controller an array generated by the next code:
public ActionResult GetClasses(bool ajax, string kingdom)
{
int _kingdom = _taxon.getKingdom(kingdom);
var query = (from c in vwAnimalsTaxon.All()
orderby c.ClaName
select new { taxRecID = c.ClaRecID, taxName = c.ClaName }).Distinct();
return Json(query, JsonRequestBehavior.AllowGet);
}
The query List should be ordered, but it doesn't work, I get the names of the classes ordered wrong in the array, because I've seen it debugging that the names are not ordered.The view is just a dropdownbox loaded automatically, so I'm almost sure the problem is with the action. Do you see anything wrong?Am I missing something?
I think gmcalab is almost there. The reason it's not working is that Distinct blows away the ordering. So you need Distinct THEN OrderBy. But this means you have to sort by the new attribute name:
var query = (from c in vwAnimalsTaxon.All()
select new { taxRecID = c.ClaRecID, taxName = c.ClaName }
).Distinct().OrderBy(t => t.taxName);
Give this a try:
var query = (from c in vwAnimalsTaxon.All()
select new { taxRecID = c.ClaRecID, taxName = c.ClaName }
).Distinct().OrdeyBy(c => c.ClaName);
In LINQ the Distinct method makes no guarantees about the order of results. In many cases the Distinct causes the OrderBy method to get optimized away. So it's necessary to do the OrderBy last, after the Distinct.
var query = (from c in vwAnimalsTaxon.All()
select new { taxRecID = c.ClaRecID, taxName = c.ClaName })
.Distinct()
.OrderBy(c => c.ClaName);
The select will also blow away the sorting. So either Distinct or Select needs orderby after.

Categories