linq using IN Operator in split comma values - c#

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))

Related

Check if parameter value is null or not inside query

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
};

Difference between LINQ Lambda and SQL statement

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 };

Linq to Entities conditional WHERE

I'm currently running the following query:
var results = from c in _context.Cs
join a in _context.Ca on c.Id equals a.CId
where c.Status == "A"
where c.CtId == ctId
where c.FY == fYear
where (a.PMId == lUserId || a.TLId == lInUserId)
select new { c.Id, c.T, c.C, c.S } into x
group x by new {x.Id, x.T, x.C, x.S} into g
orderby g.Key.T, g.Key.C, g.Key.S
select new { Id = g.Key.Id, T = g.Key.T, C = g.Key.C, S = g.Key.S}
Now I need to make the where (a.PMId == lUserId || a.TLId == lInUserId) line conditional on if lUserId != 0 (use it if not 0, ignore it if 0).
Normally, I would declare the variable results then set it in an if statement, but I have no idea how to define this data structure. It shows as being defined as:
IQueryble<'a>
'a is new { int Id, string T, string C, string S}
Whats the best way to accomplish this?
You can use || operator in the query so if first condition is true, the second will not be evaluated and if first is false that is not equal to 0 second will be evaluated:
where lUserId ==0 || (a.PMId == lUserId || a.TLId == lInUserId)
What I understand is:
use the condition a.PMId == lUserId || a.TLId == lInUserId if and only if UserId != 0
Ignore that condition if lUserId ==0
If I understand the requirement correctly, then && will be the operator that you have to use here. since it will skip checking the second condition if the first condition is false(that is UserId == 0).
I think you are looking for this:
where (UserId != 0 && a.PMId == lUserId || a.TLId == lInUserId)

Summing a column gives null in C#/ASP.NET

I have the following sql statement that calculate the sum of the column:
select coalesce(SUM(cdin_ActMortgageAmnt),0)
from CDIndex,company
where comp_companyid=cdin_companyid and comp_idcust like '%10319%'
and cdin_Deleted is null and cdin_startunstufdate is not null
and cdin_Status='InProgress'
gives me the output like this:
I tried to convert it to LINQ like this:
var sumation = (from com in db.Companies
join cd in db.CDIndexes on com.Comp_CompanyId equals cd.cdin_CompanyId
where
cd.cdin_Status == "InProgress" &&
cd.cdin_startunstufdate == null &&
cd.cdin_Deleted == null
select new {
sum = cd.cdin_ActMortgageAmnt
}
);
var summ = sumation.Sum(x => x.sum);
When I put tracePoint beside var summ in debug mode it gives me null when i point to it.
What is the problem?
On your case you are using coalesce(SUM(cdin_ActMortgageAmnt),0) because some values of cdin_ActMortgageAmnt can be null and you are giving the default value of 0, you need to do the same in your final query. Something like this when you do the select
cd.cdin_ActMortgageAmnt ?? 0
this query is appropriate your sql query
var sumation =db.Companies.Join(db.CDIndexes,
com=>com.Comp_CompanyId,
cd=>cd.cdin_companyid,
(com,cd)=>new {com,cd})
.Where(x=>x.com.comp_idcust.Contains("10319") && x.cd.cdin_Status== "InProgress" &&
cd.cdin_startunstufdate != null &&
cd.cdin_Deleted == null)
.Select(x=>new
{
sum=x.cd.cdin_ActMortgageAmnt ?? 0
}).ToList()
Here is one way:
var summ = db.Companies.Join(
db.CDIndexes,
cd => cd.cdin_CompanyId,
com => Comp_CompanyId,
(com, cd) => new { com, cd })
.Where(z=>z.com.comp_idcust.Contains("10319")) // Added "LIKE"
.Where(z=>z.cd.cdin_Status == "InProgress")
.Where(z=>z.cd.cdin_startunstufdate != null) // Reversed your condition
.Where(z=>z.cd.cdin_Deleted == null)
.Sum(z=>z.cd.cdin_ActMortgageAmnt);
You can also combine all the Wheres together, but I prefer not to in most cases like this:
var summ = db.Companies.Join(
db.CDIndexes,
cd => cd.cdin_CompanyId,
com => Comp_CompanyId,
(com, cd) => new { com, cd })
.Where(z=>z.com.comp_idcust.Contains("10319") // Added "LIKE"
&& z.cd.cdin_Status == "InProgress"
&& z.cd.cdin_startunstufdate != null // Reversed your condition
&& z.cd.cdin_Deleted == null)
.Sum(z=>z.cd.cdin_ActMortgageAmnt);

Linq sum and null

I have the query:
var qq = (from c in db.tblArcadeGames
where
c.IsDeleted == false &&
c.ParentGameID == 0 &&
c.Approved == true
let aggPlays = c.Plays + db.tblArcadeGames.Where(v => v.ParentGameID == c.ID).Sum(v => (int?)v.Plays)
orderby aggPlays descending
select new { c, aggPlays })
.Skip(Skip)
.Take(Fetch);
foreach (var g in qq)
{
HttpContext.Current.Response.Write("{" + g.aggPlays + "}\n");
}
When I print out aggPlays in the loop above they come out as:
{21}
{}
{}
{}
The problem seems to be that the Sum() returns null if no records exist. I'm not sure how to get around this so that c.Plays + null wont equal null but just c.Plays.
You can correct this by not returning int?, but rather convert to an int directly:
.Sum(v => v.Plays ?? 0)
int response =
(from p in data.tbHoraires
where p.eid == eid && p.annee == annee && p.obligatoire == true
select (int?)p.nbminute ?? 0).Sum();

Categories