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
};
Related
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();
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();
?
I have the following lambda statement:
var resources = Db.Resource.Where(w => w.ResValue.Any(a => a.ApplicationFk == applicationPk) && w.CategoryFk == (categoryId ?? w.CategoryFk ) && w.IsEditable);
if (cultureIdsMissing!= null)
{
resources = resources.Where(w => w.ResValue.Any(a => cultureIdsMissing.Any(aa => aa == a.CultureFk) && a.Value == string.Empty));
}
This is not returning the result which I want, which is returned by:
SELECT Resource.ResourcePk, Resource.CategoryFk, Resource.Name, Resource.IsEditable, ResValue.ApplicatieFk, ResValue.CultureFk, ResValue.Value
FROM Resource
INNER JOIN ResValue ON Resource.ResourcePk = ResValue.ResourceFk
WHERE (ResValue.ApplicatieFk = 6)
AND (Resource.IsEditable = 1)
AND (ResValue.Value = '')
AND (ResValue.CultureFk = 1 OR ResValue.CultureFk = 2)
Not that cultureIdsMissing is a List containing both the numbers 1 and 2.
What am I missing or doing wrong with the lambda query?
I think you have to remove && w.CategoryFk == (categoryId ?? w.CategoryFk ) from your linq lemda expression. if categoryId = 1 then it will take only records with value 1. So try after remove that. Your linq code should be this.
var resources = Db.Resource.Where(w => w.ResValue.Any(a => a.ApplicationFk == applicationPk)&& w.IsEditable);
if (cultureIdsMissing!= null)
{
resources = resources.Where(w => w.ResValue.Any(a => cultureIdsMissing.Any(aa => aa == a.CultureFk) && a.Value == string.Empty));
}
You should take it from your sql statement :
Db.Resource
.Join(Db.ResValue
, rs => rs.ResourcePk
, resV => resv.resourceFk
, (rs, resv) => new { res = rs, resV = resV })
.Where(w => w.resv.ApplicatieFk == 6
&& w.res ==1
&& resv.Value == string.empty()
&& (resv.CultureFk == 1 || resv.CultureFk == 2))
It's not tested so maybe it won't work on first try.
I would translate the SQL to query comprehension syntax. In general, convert phrases in query comprehension order, use table aliases as range variables (or create range variables), and put unary/overall aggregate functions (such as TOP, DISTINCT or SUM) as function calls outside the whole query. For your SQL,
var ans = from r in Resource
where r.IsEditable == 1
join rv in ResValue on r.ResourcePk equals rv.ResourceFk
where rv.ApplicatieFk == 6 && rv.Value == "" && (rv.CultureFk == 1 || rv.CultureFk == 2)
select new { r.ResourcePk, r.CategoryFk, r.Name, r.IsEditable, rv.ApplicatieFk, rv.CultureFk, rv.Value };
I am getting the following results for
string[] proj = Pid.Split(',');
"1032,1222" --> [0]=1032,[1]=1222
but I want to use in LINQ query. This is my LINQ query. Where to use it and how to use it?
string[] proj = Pid.Split(',');
var data2 = (from p in Db.emp.AsEnumerable()
join r in Db.use on p.EmployeeId equals r.EmployeeId
join q in Db.proo on p.EmployeeId equals q.EmpId
where (q.IsDelete == false && p.IsDelete == false && p.RoleID != 1 && p.RoleID != 2 && q.ProId == Convert.ToInt32(Pid))
select new GroupSelectedModel {
Text = CultureInfo.CurrentCulture.TextInfo.ToTitleCase(p.FirstName + " " + p.LastName),
Value = r.UserId.ToString(),
StatusId = Convert.ToInt32(p.Status)
})
.Distinct().ToList().OrderBy(r => r.Text);
return data2.OrderBy(p => p.StatusId).ToList();
Please check above mentioned code.
When you need IN, you have to invert it, and use Contains(). Your post is not very clear, but I think you're asking for something like this (note you need to use a List instead of an array):
List<string> proj = new List<string>(Pid.Split(','));
where (q.IsDelete == false && p.IsDelete == false && p.RoleID != 1 && p.RoleID != 2 && proj.Contains(q.ProId))
How can I build the where clause dynamically, Some time the OwnerID will be zero only itemID and LocationIDwill be provided as the search criteria, in that case the LINQ should be
(from s in repository.ItemOwners.Include("OwnerDetails")
where s.ItemId == searchCriteria.ItemID &&
s.OwnerDetails.LocationId == searchCriteria.LocationID
select new { s.OwnerDetails.OwnerName, s.OwnerDetails.MobNumber }).ToList();
Some time the OwnerID and ItemId will be zero then only the LocationID will be provided as the search criteria, in that case the LINQ should be
(from s in repository.ItemOwners.Include("OwnerDetails")
where s.OwnerDetails.LocationId == searchCriteria.LocationID
select new { s.OwnerDetails.OwnerName, s.OwnerDetails.MobNumber }).ToList();
Some time the whole OwnerID, ItemID and LocationID will be provided as the search criteria, then the LINQ will be like this
(from s in repository.ItemOwners.Include("OwnerDetails")
where s.OwnerId == searchCriteria.OwnerID &&
s.ItemId == searchCriteria.ItemID &&
s.OwnerDetails.LocationId == searchCriteria.LocationID
select new { s.OwnerDetails.OwnerName, s.OwnerDetails.MobNumber }).ToList();
Here only the where clause is changing, Please help me to solve. How I can I build the where clause dynamically (Please note, here I am having a navigation property which is OwnerDetails.LocationId).
You can easily do it by using method-based query. You can add the conditions one at a time and call Select and ToList at the end:
// Where(x => true) might not be necessary, you can try skipping it.
var query = repository.ItemOwners.Include("OwnerDetails").Where(x => true);
if (searchCriteria.OwnerID != null)
query = query.Where(s => s.OwnerID == searchCriteria.OwnerID);
if (searchCriteria.ItemID != null)
query = query.Where(s => s.ItemID == searchCriteria.ItemID);
if (searchCriteria.OwnerID != null)
query = query.Where(s => s..OwnerDetails.LocationId == searchCriteria.LocationID);
var results = query.Select(s => new { s.OwnerDetails.OwnerName, s.OwnerDetails.MobNumber }).ToList();
Simplest is just check the zero condition in the Where clause:
(from s in repository.ItemOwners.Include("OwnerDetails")
where (searchCriteria.OwnerID == 0 || s.OwnerId == searchCriteria.OwnerID) &&
(searchCriteria.ItemID == 0 || s.ItemId == searchCriteria.ItemID) &&
s.OwnerDetails.LocationId == searchCriteria.LocationID
select new { s.OwnerDetails.OwnerName, s.OwnerDetails.MobNumber }).ToList();