Adding a calculated field in LINQ select results? - c#

I have a LINQ query (using with EF)
Basically I want to add a column in Select results based on value of another column.
I have PaymentDate column in DB table but not Paid column. If there is null in PaymentDate column it also shows payment is false and if it has some date in it means paid is true.
Here is my query, please guide me how to do that.
var selectedResults=
from InvoiceSet in Invoices
join BookedAreasSet in BookedAreas
on InvoiceSet.InvoiceID equals BookedAreasSet.InvoiceID
join AreaSet in Areas on BookedAreasSet.AreaID equals AreaSet.AreaID
select new {InvoiceSet.InvoiceNumber,InvoiceSet.Amount,InvoiceSet.TotalDiscount,InvoiceSet.GST, InvoiceSet.PaymentDate,InvoiceSet.ShoppingCentreID,BookedAreasSet.BookedAreaID,
AreaSet.Name,Here I want to add calculated value column based on InvoiceSet.PaymentDate value}

I think you should be able to do something like this
var selectedResults=
from InvoiceSet in Invoices
join BookedAreasSet in BookedAreas
on InvoiceSet.InvoiceID equals BookedAreasSet.InvoiceID
join AreaSet in Areas on BookedAreasSet.AreaID equals AreaSet.AreaID
select new { InvoiceSet.InvoiceNumber,InvoiceSet.Amount,InvoiceSet.TotalDiscount,InvoiceSet.GST,
InvoiceSet.PaymentDate,InvoiceSet.ShoppingCentreID,BookedAreasSet.BookedAreaID,
AreaSet.Name,Paid = (InvoiceSet.PaymentDate == null) }

Related

Apache Ignite Group By Linq Query Issue

i'm trying to join three caches with two of them are left outer joined,also has group by clause. With the below query i ran into strange issue, the generated sql was not correct.
var query = (from service in serviceCache
join meetingService in meetingServiceCache.DefaultIfEmpty() on service.Value.ServiceId equals meetingService.Value.ServiceId
join meeting in meetingCache.DefaultIfEmpty() on meetingService.Value.MeetingId equals meeting.Value.MeetingId
group new { service, meeting } by service.Value.ServiceId into g
select new {
service.Value.ServiceId,
lastMeeting = g.Select(x=>x.meeting.Value.CreatedDate).Max()
}).ToCacheQueryable().GetFieldsQuery.Sql;
The generated query looks like below
select _T0.SERVICEID,min(_T0.CreatedDate) from MEETINGSCHEMA.SERVICES as _T0
left outer join (select _T1.*,_T1.KEY,_T1.VAL from MEETINGSCHEMA.MEETINGSERVICE as _T1) as _T2 on (_T2.SERVICEID= _T0.SERVICEID)
left outer join (select _T3.*,_T3.KEY,_T3.VAL from MEETINGSCHEMA.MEETINGS as _T3) as _T4 on (_T4.MEETINGID= _T3.MEETINGID)
group by (_T0.SERVICEID)
In selected columns the createdDate should be selected from _T4 reference,But it's always selected from first table alias thus the query was failing always reporting CreatedDate as invalid column.I Suspect something wrong with linq to sql translation.
Please let me know if i'm doing any mistake. Also the code snippet was typed by hand with out intellisense, pardon me incase of typos.
After grouping you can select only Key property or aggregation functions. Also LEFT JOIN should be written in different way.
var query =
from service in serviceCache
join meetingService in meetingServiceCache on service.Value.ServiceId equals meetingService.Value.ServiceId into j
from meetingService in j.DefaultIfEmpty()
join meeting in meetingCache on meetingService.Value.MeetingId equals meeting.Value.MeetingId into j
from meeting in j.DefaultIfEmpty()
group new { service, meeting } by service.Value.ServiceId into g
select new
{
ServiceId = g.Key,
lastMeeting = g.Max(x => x.meeting.Value.CreatedDate)
};
This seems to be a bug in Ignite, I've filed a ticket.
The workaround is to reorder the joined tables and put meeting first, something like this:
var query = (from meeting in meetingCache
join meetingService in meetingServiceCache.DefaultIfEmpty() on meeting.Value.MeetingId equals meetingService.Value.MeetingId
join service in serviceCache service.Value.ServiceId equals meetingService.Value.ServiceId
group new { service, meeting } by service.Value.ServiceId into g
select new {
service.Value.ServiceId,
lastMeeting = g.Select(x=>x.meeting.Value.CreatedDate).Max()
}).ToCacheQueryable().GetFieldsQuery.Sql;
Another workaround is to use raw SQL for this query.

Select all columns from one table and 1 column from another

I have the following query in linq:
(from creditCard in DbSet
join rank in base.dataContext.ProductVerticalRanks on creditCard.ProductVerticalReferenceId equals rank.ProductVerticalReferenceId
where rank.ClientId == clientId
orderby rank.PreferredOrder
select creditCard)
.Include(creditCard => creditCard.ProductVerticalCompany)
.Include(creditCard => creditCard.Labels);
But now I have a new requirement, I need to add a column 'rank.PreferredOrder' from table 'rank' into the result, is there an easy way of doing this without making a massive 'select' statement, because there are around 20-30 fields in creditCard alone.
I dont have your model in front of me, so can't confirm this or not, but you can use an anonymous object like this:
from creditCard in DbSet
join rank in base.dataContext.ProductVerticalRanks on
creditCard.ProductVerticalReferenceId equals rank.ProductVerticalReferenceId into g
where rank.ClientId == clientId
orderby rank.PreferredOrder
select new {Card = creditCard, Ranks = g}

Join two tables with key in common and show on a datagrid c# linq

I need to join the two tables of a DataGrid, but I only want the values with the same id (idviagem is pk in table idviagem and is fk in table idpassageiro)
I don't know how to do the query, in that moment I only take the table tbpassageiro on the grid, and I want to join them on DataGrid when the keys are equals
using (checkinEntities1 db = new checkinEntities1())
{
var qcheckin = (from c in db.tbpassageiro
join g in db.tbviagem on c.idviagem equals g.idviagem
where c.idviagem == g.idviagem
select c).ToList();
gridpass.ItemsSource = qcheckin;
}
The binding I know 100% is correct (some values from table passageiro and the other Biding values from table tbviagem)
This what I want to do:
If you want columns from both tables, then you have to create a view model for the columns which you want from both tables.
using (checkinEntities1 db = new checkinEntities1())
{
var qcheckin = (from c in db.tbpassageiro
join g in db.tbviagem on c.idviagem equals g.idviagem
where c.idviagem == g.idviagem
select new viewModelName()
{
//get the column values here like
Hora = c.Hora,
Partida = g.Partida
}).ToList();
gridpass.ItemsSource = qcheckin;
}
Hope this will give you the answer you are looking for.

Conversion of Sql query to linq

I am trying to convert sql query for select to linq query using EF in MVC but really got stuck with an error.
In SQL I'm able to get 6 records for my query,similarly when I try to convert this to linq it shows some error.
Following is my query in SQL:
SELECT
PurchaseOrderMaster.*, PurchaseOrderDetails.*, Vendor.*,
BusinessUnit.*, InvoiceMaster.*, TenantEmployee.*
FROM
PurchaseOrderMaster
INNER JOIN
PurchaseOrderDetails ON PurchaseOrderMaster.TenantID = PurchaseOrderDetails.TenantID
AND PurchaseOrderMaster.PurchaseOrderNumber = PurchaseOrderDetails.PurchaseOrderNumber
AND PurchaseOrderMaster.PurchaseOrderDate = PurchaseOrderDetails.PurchaseOrderDate
INNER JOIN
InvoiceMaster ON PurchaseOrderMaster.TenantID = InvoiceMaster.TenantID
AND PurchaseOrderMaster.PurchaseOrderNumber = InvoiceMaster.PurchaseOrderNumber
AND PurchaseOrderMaster.PurchaseOrderDate = InvoiceMaster.PurchaseOrderDate
INNER JOIN
BusinessUnit ON PurchaseOrderMaster.TenantID = BusinessUnit.TenantID
AND PurchaseOrderMaster.BusinessUnitID = BusinessUnit.BusinessUnitID
INNER JOIN
TenantEmployee ON PurchaseOrderMaster.TenantID = TenantEmployee.TenantID
INNER JOIN
Vendor ON PurchaseOrderMaster.TenantID = Vendor.TenantID
AND PurchaseOrderMaster.VendorID = Vendor.VendorID
For this query I am able to get 6 records .
And my linq query is:
return (from pom in db.PurchaseOrderMaster
join pod in db.PurchaseOrderDetails on pom.TenantID equals pod.TenantID
where pom.PurchaseOrderNumber == pod.PurchaseOrderNumber && pom.PurchaseOrderDate == pod.PurchaseOrderDate
join inv in db.InvoiceMaster on pom.TenantID equals inv.TenantID
where pom.PurchaseOrderNumber == inv.PurchaseOrderNumber && pom.PurchaseOrderDate == inv.PurchaseOrderDate
join bu in db.BusinessUnit on pom.BusinessUnitID equals bu.BusinessUnitID
join te in db.TenantEmployee on pom.TenantID equals te.TenantID
join v in db.Vendor on pom.TenantID equals v.TenantID
where pom.VendorID == v.VendorID
orderby pom.PurchaseOrderNumber ascending, pom.PurchaseOrderDate descending
select new { pom, pod, inv, bu, te, v }).ToList();
At the time of debugging,following is the error that I'm getting:
{"Invalid column name 'invoiceMasterModel_TenantID'.\r\nInvalid column name 'invoiceMasterModel_PurchaseOrderNumber'.\r\nInvalid column name 'invoiceMasterModel_PurchaseOrderDate'.\r\nInvalid column name 'invoiceMasterModel_InvoiceNumber'.\r\nInvalid column name 'invoiceMasterModel_InvoiceDate'.\r\nInvalid column name 'tenantEmployeeModel_TenantID'.\r\nInvalid column name 'tenantEmployeeModel_EmployeeID'."}
Inside Invoice Table it is not able to find some of the columns and hence throwing the error according to me..
I tried with many possible ways but was unable to solve this.
Any ideas..?
Problem was with my Entity.
What I did is,I added my entity again and according to that I recreated models for the associated tables removing the earlier ones.
It solved my problem finally .
I found this link Entity Framework 5 Invalid Column Name error related to somewhat similar problem.
Here also similar kind of error happened after the date time field. Check if your datetime field PurchaseOrderDate is nullable.
Many tools exist that can convert your sql queries to linq, in case you don't wanna write it urself. Try the following sites, works well in my case:
http://www.sqltolinq.com/
http://www.linqpad.net/

LINQ Joining multiple tables using row index/number

I have an excel template for uploading records to database and it has multiple sheets.
I am able to join the sheets' data on upload using LINQ and this is my code:
var query = from component in ds.Tables[0].AsEnumerable()
join componenthazardous in ds.Tables[1].AsEnumerable()
on component.Field<string>("PartNumber")
equals componenthazardous.Field<string>("PartNumber")
join manufacturers in ds.Tables[2].AsEnumerable()
on component.Field<string>("PartNumber")
equals manufacturers.Field<string>("PartNumber")
join vendorinfo in ds.Tables[3].AsEnumerable()
on component.Field<string>("PartNumber")
equals vendorinfo.Field<string>("PartNumber")
join crossreference in ds.Tables[4].AsEnumerable()
on component.Field<string>("PartNumber")
equals crossreference.Field<string>("PartNumber")
select new {
PartNumber = component["PartNumber"].ToString(),
Description = component["Description"].ToString(),
Hazardous = componenthazardous["Hazardous"].ToString(),
M_MfgrCode = manufacturers["MfgrCode"].ToString(),
M_MfgrName = manufacturers["MfgrName"].ToString(),
M_Status = manufacturers["Status"].ToString(),
M_AsOf = manufacturers["AsOf"].ToString(),
M_Remarks = manufacturers["Remarks"].ToString()
};
Now, my problem is that my boss suddenly changed the requirements. On excel template, the key I used to join the tables are duplicated. Its uniqueness will be based on the combination of PartNumber and MfgrName. How can I join the tables using this combination as key if only one sheet has these rowcolumns?
My idea is that I'll use row number as my key for joining since the partnumber column on other sheets is referenced from the first sheet/datatable but I don't know how. Any idea or any other way to solve this?
Thanks.

Categories