LINQ to Dataset SELECT NOT IN to a table? - c#

Here is my working LINQ to dataset query. I have added a fourth table and I want to add a NOT IN type filter to the query where query1.dedpk NOT IN deduct.dedpk. Not sure how to do it.
var main = dsTemp.Tables["Maindata"].AsEnumerable();
var pg = dsTemp.Tables["pgto"].AsEnumerable();
var py = dsTemp.Tables["pyto"].AsEnumerable();
var deduct = dsTemp.Tables["Deduct"].AsEnumerable();
var query1 = from mainrow in main
join pgrow in pg on mainrow.Field<string>("pgpk") equals pgrow.Field<string>("pgpk")
join pyrow in py on mainrow.Field<string>("pypk") equals pyrow.Field<string>("pypk")
into griddata
select new
{
lastname = mainrow.Field<string>("lastname"),
firstname = mainrow.Field<string>("firstname"),
dedpk = mainrow.Field<string>("dedpk"),
};
Thanks

var query1 = from mainrow in main
join pgrow in pg on mainrow.Field<string>("pgpk") equals pgrow.Field<string>("pgpk")
join pyrow in py on mainrow.Field<string>("pypk") equals pyrow.Field<string>("pypk")
into griddata
where
!deduct.Any(x => x.Field<string>("dedpk") == mainrow.Field<string>("dedpk"))
select new
{
lastname = mainrow.Field<string>("lastname"),
firstname = mainrow.Field<string>("firstname"),
dedpk = mainrow.Field<string>("dedpk"),
};

Related

Linq query does not return data

I have the following query in SQL which returns 5 rows of data:
SELECT DISTINCT c.Id, c.FirstName, c.LastName, c.PhoneNumber, 'Waiting to be sent'
FROM DistributionGroupMembers dgm
JOIN Contacts c on dgm.ContactId = c.Id
JOIN DistributionGroups dg on dgm.DistributionGroupId = dg.Id
WHERE dg.Id IN (
SELECT DistributionGroupId
FROM DistributionGroupInSms
WHERE SmsId = 40
)
When I try to run the adequate query in C# using LINQ it won't return anything:
int[] groupIDs = await _db.DistributionGroupInSms.Where(dgis => dgis.SmsId == message.Id).Select(g => g.Id).ToArrayAsync();
var recipients = await (from dgm in _db.DistributionGroupMembers
join c in _db.Contacts on dgm.ContactId equals c.Id
join dg in _db.DistributionGroups on dgm.DistributionGroupId equals dg.Id
where groupIDs.Contains(dg.Id)
select new
{
ID = c.Id,
FN = c.FirstName,
LN = c.LastName,
PN = c.PhoneNumber,
SR = "Waiting to be sent"
}).Distinct().ToListAsync();
What am I doing wrong?
Can you simply do a join:
int[] groupIDs = await _db.DistributionGroupInSms.Where(dgis => dgis.SmsId == message.Id).Select(g => g.Id).ToArrayAsync();
var recipients = await (from dgm in _db.DistributionGroupMembers
join c in _db.Contacts on dgm.ContactId equals c.Id
join dg in _db.DistributionGroups on dgm.DistributionGroupId equals dg.Id
join gIds in groupIDs on gIds equals dg.Id
select new
{
ID = c.Id,
FN = c.FirstName,
LN = c.LastName,
PN = c.PhoneNumber,
SR = "Waiting to be sent"
}).Distinct().ToListAsync();
I figured it out, in the select clause by getting the groupIDs I selected Id instead of another field in the table called DistributionGroupId. Thanks everyone for the input

How to convert to Linq

How to convert the following query into linq
SELECT
a.ProductId,
a.Name,
a.Description,
b.Quoteid,
b.Productid,
b.Quantity,
b.OriginalPrice
FROM
Products AS a
LEFT JOIN
QuoteDtails AS b
ON a.ProductId = b.ProductId
AND b.QuoteId = 200;
Don't know where to add the AND condition.
Thanks and regards
You can try this linq if you want to write LEFT JOIN of linq, you need to add
into [temp collection] from [Left join talbe collection] in [temp collection].DefaultIfEmpty()
after Linq join
look like this.
from ss in Products
join aa in QuoteDtails
on ss.ProductId equals aa.ProductId into temp
from ds in temp.DefaultIfEmpty()
where ds.QuoteId = 200
select new
{
ProductId_P = ss.ProductId,
Name = ss.Name,
Description = ss.Description,
Quoteid = ds.Quoteid,
Productid_Q = ds.Productid,
Quantity = ds.Quantity,
OriginalPrice = ds.OriginalPrice
}
You can add AND condition in your LINQ query like this :
var res = from p in products
join q in quoteDtails on new { Criteria1 = p.ProductID, Criteria2 = 200 } equals new { Criteria1 = q.Productid, Criteria2 = q.Quoteid }
select new
{
ProductId_P = p.ProductID,
Name = p.Name,
Description = p.Description,
Quoteid = q.Quoteid,
Productid_Q = q.Productid,
Quantity = q.Quantity,
OriginalPrice = q.OriginalPrice
};

linq query to return a string from a list

I have a products table and an activities table.Each product is made up of different activities.What i want is to display a product name,price,etc and the all the activities (i.e all the activities in one column) which are part of that product in a datagrid using linq
Below is my query
using (bungeedbEntities context = new bungeedbEntities())
{
var bookingData = from con in context.bookings
join agn in context.agents on con.main_agent_id equals agn.code
select new POS_LINK.BusinessObjects.Bookings
{
Product = con.product_name,
Activity = String.Join(",", (from con1 in context.bookings
join acp in context.booking_activity on con1.code equals acp.booking_code
join agn in context.agents on con1.main_agent_id equals agn.code
join act in context.activities on acp.activity_code equals act.code
select act.name).ToArray()),
ReservationCode = con.main_agent_voucher,
CostOfSale = 0.00M,
DateOfActivity = (DateTime)con.date_of_activity,
Notes = con.notes,
Quantity = (int)con.pax,
Child_quantity = 0,
Child_cost_percentage = 0,
CostPerPerson = 0.00M,
SubAgentRef = "56789",
SubAgentName = con.sub_agent_name,
ClientName = con.client_name,
MainAgent = agn.agent_name,
Consultant2 = con.sub_agent_consultant
};
return bookingData.ToList();
On running i get the following error- LINQ to Entities does not recognize the method 'System.String Join(System.String, System.String[])' method, and this method cannot be translated into a store expression.
I seem to have run out of ideas anyone with a better solution to this would save me from a lot of head scratching
You need to do it in two steps: first step selects the data, while the second step translates it to a string with string.Join:
var bookingData = (from con in context.bookings
join agn in context.agents on con.main_agent_id equals agn.code
select new { // Construct an anonymous type with the relevant parts
Product = con.product_name,
ActivityData = (from con1 in context.bookings
join acp in context.booking_activity on con1.code equals acp.booking_code
join agn in context.agents on con1.main_agent_id equals agn.code
join act in context.activities on acp.activity_code equals act.code
select act.name),
ReservationCode = con.main_agent_voucher,
DateOfActivity = (DateTime)con.date_of_activity,
Notes = con.notes,
Quantity = (int)con.pax,
SubAgentName = con.sub_agent_name,
ClientName = con.client_name,
MainAgent = agn.agent_name,
Consultant2 = con.sub_agent_consultant
}).AsEnumerable() // Bring this into memory
.Select(p => new POS_LINK.BusinessObjects.Bookings {
Product = p.Product,
Activity = string.Join(", ", p.ActivityData.ToArray()),
ReservationCode = p.ReservationCode,
CostOfSale = 0.00M,
Notes = p.Notes,
Quantity = p.Quantity,
Child_quantity = 0,
Child_cost_percentage = 0,
CostPerPerson = 0.00M,
SubAgentRef = "56789",
SubAgentName = p.SubAgentName,
ClientName = p.ClientName,
MainAgent = p.MainAgent,
Consultant2 = p.Consultant2
});
return bookingData.ToList();
The idea here is simple: first, you construct an anonymous type that has all relevant information, including an enumeration of acc.names, then you force it into memory by calling AsEnumerable(), and finally construct your POS_LINK.BusinessObjects.Bookings objects using LINQ-to-Object, which understands string.Join.

Getting a field value from a LINQ query without Iteration

I have the following query in controller and I want to store a column value in a variable but I am not being able to iterate it. Here is my code:
var srmas = (
from SRMAs in db.SRMAs
join SRMAStatus in db.SRMAStatus on SRMAs.Status equals SRMAStatus.Id
join PurchaseOrders in db.PurchaseOrders on SRMAs.PONumber equals PurchaseOrders.PONumber
join Suppliers in db.Suppliers on PurchaseOrders.SupplierID equals Suppliers.SupplierID
join SRMADetails in db.SRMADetails on SRMAs.Id equals SRMADetails.SRMAId
where(SRMAs.Id == srmaid)
group SRMADetails by new
{
SRMADetails.Id,
SRMADetails.SRMAId,
SRMADetails.SupplierPartNum,
SRMAs.PONumber,
SRMAs.ActualAmount,
SRMAs.ApprovedOn,
SRMAs.Status,
SRMAs.TrackingNumber,
SRMAs.SupplierRMANumber,
SRMAs.RequestedFromSupp,
SRMAs.CreatedOn,
Suppliers.SupplierName,
SRMAStatus.StatusName,
PurchaseOrders.PODate,
PurchaseOrders.suppliersOrderNumber
} into grp
select new
{
grp.Key.Status,
grp.Key.SRMAId,
grp.Key.Id,
grp.Key.PONumber,
grp.Key.SupplierRMANumber,
grp.Key.ActualAmount,
grp.Key.SupplierPartNum,
grp.Key.RequestedFromSupp,
grp.Key.TrackingNumber,
grp.Key.ApprovedOn,
grp.Key.SupplierName,
grp.Key.StatusName,
grp.Key.PODate,
grp.Key.suppliersOrderNumber,
grp.Key.CreatedOn,
Sum = grp.Sum(SRMADetails => SRMADetails.Cost * SRMADetails.QtyReturned)
}
).ToList();
System.Collections.IEnumerable et = (System.Collections.IEnumerable)srmas;
IEnumerator it = et.GetEnumerator();
while (it.MoveNext())
{
SRMA current = (SRMA)it.Current;
Response.Write(current.Status);
}
ViewBag.SRMAs = srmas.Select(srma => new IndexViewModel
{
Id = srma.SRMAId,
SupplierRMANum = srma.SupplierRMANumber,
SRMADetailsID = srma.Id,
PONumber = srma.PONumber,
CreatedOn = srma.CreatedOn,
SupplierName = srma.SupplierName,
SRMAStatus = srma.StatusName,
Status = srma.Status,
suppliersOrderNumber = srma.suppliersOrderNumber,
PODate = srma.PODate,
Sum = srma.Sum,
TrackingNumber = srma.TrackingNumber,
ActualAmount = srma.ActualAmount
}).ToList();
I just want to get Status value of first record. How do I do it?

C# LINQ: Get count for each row

Here the query for retrieving all the comptes in my base.
I would like to add a number within the object GridCompte in order to count the element inside the list (1,2,3...):
var comptes = (from c in Comptes
join s in Societies on c.IdSoc equals s.IdSoc
select new GridCompte
{
SocCompteId = c.IdCompte,
Name = c.Name,
Nb = ??? COUNT ???,
.....
SocName = s.Name
}).ToList();
I tried using the group statement, but i didn't manage to achieve my goal.
Any suggestions?
First prepare your linq only for the fields you want to get
var comptes = from c in Comptes
join s in Societies on c.IdSoc equals s.IdSoc
select new
{
SocCompteId = c.IdCompte,
Name = c.Name,
.....
SocName = s.Name
};
Now use index option that is available in Select
var finalComptes = (comptes.AsEnumerable()
.Select((comptes, index) => new GridCompte()
{
SocCompteId = c.IdCompte,
Name = c.Name,
Nb = index + 1,
.....
SocName = s.Name
}).ToList();

Categories

Resources