Below is a piece of code that I do in a loop:
At the beginning, in the first query, I get a list of location IDs. The list can be long.
Ultimately, I need to find for which LocationId FamiliId > 0
I have it done in a loop but I would like to do it in one question. Is it possible and if so how?
var locationIds = context.TblUsersDistricts
.Where(d => d.UserId == userId && d.ValidityTo == null)
.Select(x => x.LocationId).ToList();
int familyId = 0;
foreach(var item in locationIds) {
familyId = (from I in context.TblInsuree
join F in imisContext.TblFamilies on I.FamilyId equals F.FamilyId
join V in imisContext.TblVillages on F.LocationId equals V.VillageId
join W in imisContext.TblWards on V.WardId equals W.WardId
join D in imisContext.TblDistricts on W.DistrictId equals D.DistrictId
where(I.Chfid == chfid &&
D.DistrictId == item &&
F.ValidityTo == null &&
I.ValidityTo == null &&
V.ValidityTo == null &&
W.ValidityTo == null &&
D.ValidityTo == null)
select F.FamilyId)
.FirstOrDefault();
if (familyId > 0) break;
};
It sounds like you want:
var familyId = (
from item in locationIds
from I in context.TblInsuree
// ... etc
&& D.ValidityTo == null)
select F.FamilyId)
.FirstOrDefault();
?
Related
In my query I am getting records based on RoleId and LocationId, some times the user may not pass location in that case I want to remove that filter and get information from all locations.
Currently I am doing this way
if(loc > 0)
{
var myResult = (from x in CSDB.Allocations
join s in CSDB.Managers
on x.ManagerId equals s.Id
Where x.RoleId == 2 && s.LocationId == loc
select new
{
x.name,
x.Date
}).ToList();
}
else
{
var myResult = (from x in CSDB.Allocations
join s in CSDB.Managers
on x.ManagerId equals s.Id
Where x.RoleId == 2
select new
{
x.name,
x.Date
}).ToList();
}
I am seeing if I can check if loc is null or not inside the query instead of using if else.
You can do something like this:
Where x.RoleId == 2 && (loc == null || s.LocationId == loc)
Also, you can do smth like this.
Where x.RoleId == 2 && (loc?.Equals(s.LocationId) ?? true)
If loc just int I would prefer to use a little bit changed #Salah Akbari answer:
Where x.RoleId == 2 && (loc == 0 || s.LocationId == loc)
Simply extract your managers and filter them if needed. That way you can as well easily apply more filters and code readability isn't hurt.
var managers = CSDB.Managers.AsQueryable();
if(loc > 0)
managers = managers.Where(man => man.LocationId == loc);
var myResult = from allocation in CSDB.Allocations
join manager in managers on allocation.ManagerId equals manager.Id
where allocation.RoleId == 2
select new
{
allocation.name,
allocation.Date
};
How to change this SQL query to LINQ? I've tried it several times, but it didn't work
SELECT Payment.ID, Payment.TotalGroupID, PaymentTrans.PaymentID, PaymentTrans.TotalGroupID as TotalGroupID1, PaymentTrans.TransferStatus
FROM PaymentTrans INNER JOIN Payment
ON (PaymentTrans.PaymentID = Payment.ID OR PaymentTrans.TotalGroupID = payment.TotalGroupID)
WHERE (PaymentTrans.TransferStatusis NULL OR (PaymentTrans.TransferStatus <> '01' and PaymentTrans.TransferStatus <> '02'))
and this is my try
var a= (from x in db.PaymentTransactions
join p in db.Payments
on
x.PaymentID equals p.ID
where x.TransferStatus== null || (x.TransferStatus!= "01" && x.TransferStatus!= "02")
select new { x, p }).ToList();
but it still wrong LINQ, because in my query I have 2 conditions in ON Clause. thanks
try this
var query = (from x in db.PaymentTransactions
join p in db.Payments
on x.PaymentID equals p.ID //main condition of join
where ((x.TransferStatus == null ||
(x.TransferStatus != "01" && x.TransferStatus!= "02")) //your `where` condition
|| x.TotalGroupID == p.TotalGroupID) //your second or join
select new {x,p})
.ToList();
The answers above filter on both conditions, they should filter one of the conditions according to the question (PaymentID or TotalPaymentID). You can either write two seperate queries and use a union or use a Cartesian product before filtering.
var result = (from paymentTransaction in db.PaymentTransactions
join payment in db.Payments on paymentTransaction.PaymentID equals payment.ID
where paymentTransaction.TransferStatus == null || (paymentTransaction.TransferStatus != "01" && paymentTransaction.TransferStatus != "02")
select new { paymentTransaction, payment }).Union
(from paymentTransaction in db.PaymentTransactions
join payment in db.Payments on paymentTransaction.TotalGroupID equals payment.TotalGroupID
where paymentTransaction.TransferStatus == null || (paymentTransaction.TransferStatus != "01" && paymentTransaction.TransferStatus != "02")
select new { paymentTransaction, payment });
var cartResult = from paymentTransaction in db.PaymentTransactions
from payment in db.Payments
where paymentTransaction.PaymentID == payment.ID || paymentTransaction.TotalGroupID == payment.TotalGroupID
where paymentTransaction.TransferStatus == null || (paymentTransaction.TransferStatus != "01" && paymentTransaction.TransferStatus != "02")
select new { paymentTransaction, payment };
You cannot add multiple ON in LINQ. the solution of your problem above can be solved like this.
Hint: just use multiple Where.
var result =
(
from trans in db.PaymentTransactions
join payment in db.payments
on trans.PaymentID equals payment.ID
where trans.TotalGroupID == payment.TotalGroupID
where x.TransferStatus== null || (x.TransferStatus!= "01" && x.TransferStatus!= "02")
select new
{
//your properties
}
).ToList();
i am trying to convert the following SQL into LINQ and need some assistance with the nested select clauses for the paid_amount and paid_vat and also for the select within the where clause. Ignore the index things.
here is the SQL
SELECT
tramps.gl_transaction.debtor_uri,
tramps.debtor.account_no,
tramps.gl_transaction.uri as transaction_uri,
tramps.gl_transaction.base_currency_amount,
tramps.gl_transaction.base_currency_vat_amount,
(select IsNull(sum(gltr.base_currency_amount), 0.00)
from tramps.gl_transaction gltr
where gltr.sibling_uri = tramps.gl_transaction.uri) * (-1) as Paid_Amount ,
(select IsNull(sum(gltr.base_currency_vat_amount), 0.00)
from tramps.gl_transaction gltr
where gltr.sibling_uri = tramps.gl_transaction.uri) * (-1) as Paid_Vat ,
tramps.account.property_ref,
tramps.account.sub_ledger_code,
tramps.gl_transaction.transaction_type_code,
tramps.gl_transaction.transaction_description,
tramps.gl_transaction.effective_date
FROM tramps.account, tramps.chart WITH (INDEX (PK_CHART)), tramps.gl_transaction WITH (INDEX (glt_debtor_gen)) ,tramps.debtor, tramps.receivables_register , tramps.bank_account
WHERE tramps.chart.code = tramps.account.chart_code
AND tramps.gl_transaction.debtor_uri = tramps.debtor.uri
AND tramps.gl_transaction.account_uri = tramps.account.uri
AND tramps.receivables_register.uri = tramps.gl_transaction.receivables_register_uri
AND tramps.receivables_register.bank_account_uri = tramps.bank_account.uri
AND tramps.chart.control_account = 'Debtor'
AND tramps.gl_transaction.status = 'L'
AND tramps.gl_transaction.process_status = 'Released'
AND ( (tramps.gl_transaction.generated = 'C' AND tramps.gl_transaction.sibling_uri IS NULL AND tramps.gl_transaction.written_off <> 'Y')
OR (tramps.gl_transaction.generated = 'N' AND tramps.gl_transaction.sibling_uri IS NULL) )
AND (tramps.gl_transaction.base_currency_amount +
(select IsNull(sum(gltr.base_currency_amount), 0.00)
from tramps.gl_transaction gltr
where gltr.sibling_uri = tramps.gl_transaction.uri) <> 0.00 )
this is the LINQ i have managed to create so far, but i am struggling with the nested selects, the sum and the where clause
from acc in Accounts
join chart in Charts on acc.Chart_code equals chart.Code
join gltrans in Gl_transactions on acc.Uri equals gltrans.Account_uri
join debt in Debtors on gltrans.Debtor_uri equals debt.Uri
join recreg in Receivables_registers on gltrans.Receivables_register_uri equals recreg.Uri
join bankacc in Bank_accounts on recreg.Bank_account_uri equals bankacc.Uri
let paidcurrency = from gltrns in Gl_transactions
where gltrns.Sibling_uri == gltrans.Uri
select gltrns.Base_currency_amount
where
chart.Control_account == "Debtor"
&& gltrans.Status == "L"
&& gltrans.Process_status == "Released"
&& acc.Property_ref == 102979
&& ((gltrans.Generated == "C" && gltrans.Sibling_uri == null && gltrans.Written_off != "Y")
|| (gltrans.Generated == "N" && gltrans.Sibling_uri == null) )
select new
{
gltrans.Debtor_uri,
debt.Account_no,
gltrans.Uri,
gltrans.Base_currency_amount,
gltrans.Base_currency_vat_amount,
er = (decimal?)paidcurrency.Base_currency_vat_amount.Sum() ?? 0,
acc.Property_ref,
acc.Sub_ledger_code,
gltrans.Transaction_type_code,
gltrans.Transaction_description,
gltrans.Effective_date
}
This might help out a little. I blended in some fluent syntax to help translate the Sum functions. Let me know if some of these translations help as I can't check it directly without your schema and some data.
var result =
from acc in Accounts
join chart in Charts on acc.Chart_code equals chart.Code
join gltrans in Gl_transactions on acc.Uri equals gltrans.Account_uri
join debt in Debtors on gltrans.Debtor_uri equals debt.Uri
join recreg in Receivables_registers on gltrans.Receivables_register_uri equals recreg.Uri
join bankacc in Bank_accounts on recreg.Bank_account_uri equals bankacc.Uri
// query expression
//let paidcurrency = from gltrns in Gl_transactions
// where gltrns.Sibling_uri == gltrans.Uri
// select gltrns.Base_currency_amount
// change to fluent..
let paid_Amount = gltrans.Where(g => g.Sibling_uri == g.Uri)
.Select(g => g.Base_currency_amount * -1 ?? 0.00M).Sum()
// same for Vat..
let paid_Vat = gltrans.Where(g => g.Sibling_uri == g.Uri)
.Select(g => g.Base_currency_vat_amount * -1 ?? 0.00M).Sum()
// added another 'let' to use in the where clause..
let base_Currency = gltrans.Where(g => g.Sibling_uri == g.Uri)
.Select(g => g.Base_currenct_amount ?? 0.00M).Sum()
where
chart.Control_account == "Debtor"
&& gltrans.Status == "L"
&& gltrans.Process_status == "Released"
&& acc.Property_ref == 102979
&& (
(
gltrans.Generated == "C" &&
gltrans.Sibling_uri == null &&
gltrans.Written_off != "Y"
)
||
(
gltrans.Generated == "N" &&
gltrans.Sibling_uri == null
)
)
&& gltrans.Base_currency_amount + base_Currency != 0.00M
select new
{
gltrans.Debtor_uri,
debt.Account_no,
gltrans.Uri,
gltrans.Base_currency_amount,
gltrans.Base_currency_vat_amount,
//er = (decimal?)paidcurrency.Base_currency_vat_amount.Sum() ?? 0,
paid_Amount,
paid_Vat,
acc.Property_ref,
acc.Sub_ledger_code,
gltrans.Transaction_type_code,
gltrans.Transaction_description,
gltrans.Effective_date
};
How can I rewrite this using a condition in LINQ?
If the selectID = zero, I want this to run :
var products = from p in product.Table
orderby p.Name
where (p.stock == stockId)
select p;
If the selectID NOT zero, I want this to run :
var products = from p in product.Table
orderby p.Name
where (p.stock == stockId) &&
(p.Id == selectID)
select p;
This below works, but I have to use a "dummy" second condition (p.hidden == false)
for the ternary operator to work :
var products = from p in product.Table
orderby p.Name
where (p.stock == stockId) &&
(selectID != 0 ? p.Id == selectID : p.hidden == false)
select p;
Is there a way to get rid of (p.hidden == false) because it is not required in the logic and is just there to get the operator to work. thanks
You could use the same Id as the record as fallback value:
var products = from p in product.Table
orderby p.Name
where p.stock == stockId &&
p.Id == (selectID == 0 ? p.Id : selectID)
select p;
However, since that could lead to a less efficient query plan i would simply use an if-else:
var products = product.Table.Where(p => p.stock == stockId);
if(selectID != 0)
products = products.Where(p => p.Id == selectID);
products = products.OrderBy(p=> p.Name);
You could also write it like this:
var products = from p in product.Table
orderby p.Name
where (p.stock == stockId) &&
(p.Id == selectID || selectID == 0)
select p;
The || selectID == 0 just returns true if the ID isn't supplied and still allows the query to run as you intended. The link below was how I learned this simple trick.
http://www.sommarskog.se/dyn-search-2008.html
I'm trying to return a result and a nested result in a linq to entities query.
Orders[] orderlist =
(from m in db.Orders.Include("OrderLines")
where
areas.Contains(m.Area)
&& m.Branch == branch
&& (m.OrderStatus == "1" || m.OrderStatus == "4")
&& m.SpecialInstrs == string.Empty
select m
HOW??---> m.OrderLines = m.OrderLines.Where(p => (p.LineType == "1" || p.LineType == "7") && p.MBomFlag != "C").ToArray()
).ToArray();
The problem is that the include returns all the FK'd OrderLines for each order when I really only want certain order lines.
How do I do this?
Orders and OrderList are both POCO entities generated by L2E and the poco entity generator.
You can manually join them:
Orders[] orderlist = (from m in db.Orders
join p in db.Orderlines
on p.OrderId = m.Id
where areas.Contains(m.Area)
&& m.Branch == branch
&& (m.OrderStatus == "1" || m.OrderStatus == "4")
&& m.SpecialInstrs == string.Empty
&& (p.LineType == "1" || p.LineType == "7")
&& p.MBomFlag != "C"
select m).ToArray();