In the below code:
var results = from service
in LogisticsService.GetTransportationModes<CarrierTransportationMode>
(
x => x.CarrierId == carrierRoleId &&
x.ParentTransportationModeId != null &&
!(x is LoadCarrierMode) &&
(x.ParentTransportationMode.TransportationModeStatus != null) &&
x.ParentTransportationMode.TransportationModeStatus.Value != TransportationModeStatus.Inactive
)
//.OrderByDescending(o => o.IsDefault)
//.ThenBy(t => t.ParentTransportationMode.Name)
orderby service.IsDefault descending, service.ParentTransportationMode.Name
select new
{
text = service.ParentTransportationMode.Name,
value = service.ParentTransportationMode.Id
};
If service.IsDefault is null, I need to skip orderby / thenby completely. So the code would execute as if there was no orderby present in the linq like below:
var results = from service
in LogisticsService.GetTransportationModes<CarrierTransportationMode>
(
x => x.CarrierId == carrierRoleId &&
x.ParentTransportationModeId != null &&
!(x is LoadCarrierMode) &&
(x.ParentTransportationMode.TransportationModeStatus != null) &&
x.ParentTransportationMode.TransportationModeStatus.Value != TransportationModeStatus.Inactive
)
select new
{
text = service.ParentTransportationMode.Name,
value = service.ParentTransportationMode.Id
};
I tried to modify the query with conditions like below:
.OrderByDescending(o => o.IsDefault.HasValue ? o.IsDefault : null)
.ThenBy(t => t.IsDefault.HasValue ? t.ParentTransportationMode.Name : null)
orderby !service.IsDefault.HasValue ? null: service.IsDefault descending, service.ParentTransportationMode.Name
But that didn't help.
Do I need to pass any special parameter in the orderby so that the ordering will never happen at all conditionally? any keyword like 'case' or so can be used? If so, how?
Would appreciate any help!.
Thanks!.
As you need to keep the order of the elements with service.IsDefault == null, an easy solution is to split your dataset into two parts (first service.IsDefault == null, second: service.IsDefault != null) sort the second part, then, concat:
var transportationModes = LogisticsService.GetTransportationModes<CarrierTransportationMode>(x =>
x.CarrierId == carrierRoleId &&
x.ParentTransportationModeId != null &&
!(x is LoadCarrierMode) &&
(x.ParentTransportationMode.TransportationModeStatus != null) &&
x.ParentTransportationMode.TransportationModeStatus.Value != TransportationModeStatus.Inactive)
var services = (from service in transportationModes
where service.IsDefault == null
select service).Concat
(from service in transportationModes
where service.IsDefault != null
orderby service.IsDefault descending, service.ParentTransportationMode.Name
select service);
var results = from service in services
select new
{
text = service.ParentTransportationMode.Name,
value = service.ParentTransportationMode.Id
};
Related
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 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);
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))
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();