LINQ - using a query expression to calculate data time difference - linq

I use EntityFramework 4, LINQ, and C#.
I need display data in a GridView from a query expression using Linq; I need project as anonymous type a value calculate on fly DateTime.UtcNow - cl.DateLocked Note: cl.DateLocked is of type DateTime and I need to know how many days of difference between this two dates.
With this query I receive an error:
DbArithmeticExpression arguments must have a numeric common type.
Any idea how to do it in Linq? If Linq does not allow it how to do it in a different way?
Thanks for your time
var queryContentsLocked = from cl in context.CmsContentsLockedBies
join cnt in context.CmsContents
on cl.ContentId equals cnt.ContentId
join u in context.aspnet_Users
on cl.UserId equals u.UserId
select new
{
cl.DateLocked,
cnt.ContentId,
cnt.Title,
u.UserName,
u.UserId,
TimePan = DateTime.UtcNow - cl.DateLocked // Problem here!!!
};

var queryContentsLocked = from cl in context.CmsContentsLockedBies
join cnt in context.CmsContents
on cl.ContentId equals cnt.ContentId
join u in context.aspnet_Users
on cl.UserId equals u.UserId
select new
{
cl.DateLocked,
cnt.ContentId,
cnt.Title,
u.UserName,
u.UserId,
Days = SqlFunctions.DateDiff("day", cl.DateLocked, DateTime.UtcNow)
};

Without using any SqlFunction
var grandTotalWork = (from t in db.AssignmentHandymandetails
join ad in db.AssignmentDetails on t.assignment_detail_id equals ad.assignment_detail_id
where ad.assignment_id == Convert.ToInt32(Label_assignmentId.Text)
select new { startTime = t.started_time.Value.TimeOfDay, endTime = t.end_time.Value.TimeOfDay, TotalWorkTime = (t.started_time.Value.TimeOfDay.Duration() - t.end_time.Value.TimeOfDay.Duration()).Duration()});
then you can bind the result in GridView you wish

Try this:
DateTime.UtcNow.Subtract(cl.DateLocked).TotalDays

Related

Insert records using select in LINQ

How can we convert following query to LINQ
INSERT INTO License (PersonID, LicenseState, LicenseNumber, LicenseYear)
SELECT p.PersonID,
s.LicenseState,
s.LicenseNumber,
s.LicenseYear
FROM SourceData s
JOIN Person p
ON s.UserID = p.DomainAccountName
WHERE s.isActive = 1
var query = from s in db.SourceData
join p in db.Person on s.UserId equals p.DomainAccountName
where s.IsActive
select new License
{
PersonID = p.PersonID,
LicenseState = s.LicenseState,
LicenseNumber = s.LicenseNumber,
LicenseYear = s.LicenseYear
};
db.Licenses.AddRange(query);
That will actually give you one SQL query, and a bunch of individual SQL INSERTS. Alternately, you could use the Z.EntityFramework.Plus.EFCore nuget package, and use the code
var query = ... (same)...
db.Licenses.InsertFromQuery(query);
which should use the single SQL statement you posted.
UPDATE: I originally confused the retail/licensed Z.EntityFramework.Extensions.EFCore with the free/open-source Z.EntityFramework.Plus.EFCore package. Code above has been updated.
If you care about performance, you don't have to load anything to the client. It is how EF Core works right now, if you want to insert something - you have to feed ChangeTracker with new records.
I would suggest EF Core extension linq2db.EntityFrameworkCore which generates exactly the same query as in question but via LINQ. Note that I'm one of the creators.
Then you can do the following:
var query =
from s in db.SourceData
join p in db.Person on s.UserId equals p.DomainAccountName
where s.IsActive
select new License
{
PersonID = p.PersonID,
LicenseState = s.LicenseState,
LicenseNumber = s.LicenseNumber,
LicenseYear = s.LicenseYear
};
await query.InsertAsync(db.License.ToLinqToDBTable(), x => x);

How do I outer join and group by in Entity framework Linq?

I'm having trouble getting my Linq statemnt to work when doing an outer join and a group by. Here's a SQL version of what I'm trying to accomplish:
select p.PRIMARY_KEY, min(p.EFFECTIVE_DATE), sum(IsNull(c.PAID_INDEMNITY, 0))
from PRMPOLCY p
left outer join CLMMAST c on p.PRIMARY_KEY = c.POLICY_NO
where p.UNDERWRITER_UID = 93
GROUP BY p.PRIMARY_KEY
Here's what I have in Linq (which doesn't work):
var result = from p in context.PRMPOLCies
join c in context.CLMMASTs on p.PRIMARY_KEY equals c.POLICY_NO into polClm
where (p.UNDERWRITER_UID == underwriter)
from grp in polClm.DefaultIfEmpty()
group grp by p.PRIMARY_KEY into g
select new PolicySummation()
{
PolicyNo = g.Key,
Incurred = g.Sum(grp => grp.PAID_INDEMNITY ),
EffDate = g.Min(grp => grp.PRMPOLCY.EFFECTIVE_DATE
};
Beating my head against the wall trying to figurwe this out!
Assuming you have a navigation property set up between PRMPOLCY and CLMMAST, you shouldn't need to specify the join explicitly. It's much easier to express most queries in linq without explicit joins, but rather treating your structures as a hierarchy. I don't know the specifics of your model property names, but I'd take a guess that something like this would work.
var result =
from p in context.PRMPOLCies
where (p.UNDERWRITER_UID == underwriter)
select new PolicySummation {
PolicyNo = p.PRIMARY_KEY,
Incurred = p.CLMASTs.Select(c => c.PAID_INDEMNITY).DefaultIfEmpty().Sum(),
EffDate = p.EFFECTIVE_DATE,
};
You need to include both your tables in the group clause like this:
group new { p, grp } by p.PRIMARY_KEY into g
Then in your Sum / Min
g.Sum(grp => grp.grp == null ? 0 : grp.grp.PAID_INDEMNITY )
g.Min(grp => grp.p.PRMPOLCY.EFFECTIVE_DATE)

LINQ Error when using multiple JOIN in same statement on CRM 2011 Plug-in

Hi I am trying to join multiple entities in CRM 2011 but I get and error saying: {"'xrmsm_sessionEnrollments' entity doesn't contain attribute with Name = 'xrmsm_termsid'."}. That is correct but I am joining the entity that have that attribute.
My Linq Query:
var query2 = from e in svsContext.xrmsm_sessionEnrollmentsSet
join s in svsContext.xrmsm_sessionsSet on e.xrmsm_SessionLookup.Id equals s.xrmsm_sessionsId
join ic in svsContext.xrmsm_institutionCoursesSet on s.xrmsm_institutionCourseLookup.Id equals ic.xrmsm_institutionCoursesId
join ts in svsContext.xrmsm_term_sessionsSet on e.xrmsm_termSessionLookup.Id equals ts.xrmsm_term_sessionsId
join t in svsContext.xrmsm_termsSet on ts.xrmsm_TermLookup.Id equals t.xrmsm_termsId
where (e.xrmsm_StudentLookup.Equals(studentlookup)
&& e.xrmsm_YearLookup.Equals(entity.GetAttributeValue("xrmsm_studentlookup"))
&& ic.xrmsm_institutionCoursesId == institutionCourseGuid
&& t.xrmsm_termsId == termGuid)
select new { sessionName = s.xrmsm_sessionsName, StudentName = e.xrmsm_studentsName, StudentId = e.xrmsm_StudentLookup.Name };
My original SQL query that works on SQL Server:
SELECT en.xrmsm_currentsessionenrollmentsname
,en.xrmsm_isreadonlyname
,en.xrmsm_sessionenrollmentsaverage
,en.xrmsm_sessionenrollmentsgrade
,en.xrmsm_sessionenrollmentsid
,en.xrmsm_sessionenrollments_id
,en.xrmsm_sessionlookup as sessionid
,en.xrmsm_sessionlookupname
,en.xrmsm_sessionsname
,en.xrmsm_studentlookup AS studentid
,en.xrmsm_studentlookupname
,en.xrmsm_studentsname
,en.xrmsm_termsessionlookup
,en.xrmsm_termsessionlookupname
,en.xrmsm_withdrawal
,en.xrmsm_yearaverage
,en.xrmsm_yeargrade
,en.xrmsm_yearlookup
,en.xrmsm_yearlookupname
FROM CoseyTest_MSCRM.dbo.Filteredxrmsm_sessionEnrollments as en INNER JOIN
CoseyTest_MSCRM.dbo.Filteredxrmsm_sessions crmsessions ON
(en.xrmsm_sessionlookup = crmsessions.xrmsm_sessionsid AND en.xrmsm_yearlookup = crmsessions.xrmsm_yearlookup)
INNER JOIN Filteredxrmsm_institutionCourses institutionCourses
on crmsessions.xrmsm_institutioncourselookup = institutionCourses.xrmsm_institutioncoursesid
Inner Join Filteredxrmsm_term_sessions as termsession
on en.xrmsm_termsessionlookup = termsession.xrmsm_term_sessionsid
Inner Join Filteredxrmsm_terms as terms
on termsession.xrmsm_termlookup = terms.xrmsm_termsid
where en.xrmsm_yearlookup = '4BA07BED-3F51-E211-8359-00155D004403'
and en.xrmsm_studentlookup = 'C844AF65-5B51-E211-8359-00155D004403'
and terms.xrmsm_termsid = 'D1D107B7-4551-E211-8359-00155D004403'
and institutionCourses.xrmsm_institutioncoursesid = '2121914E-4551-E211-8359-00155D004403'
Linq provider for CRM has some limitations. You can fount it here. Check if your query violates limitations.
Try having a look at the actual query that it is generating and run that in SQL, it may help understand what is going on.
It could be that something your doing in LINQ is not available in CRM as paramosh mentioned but I can't see anything that jumps out at me.
Thanks for all your responses. I did the following workaround.
Make a query that retrieve a list of all the Student enrollments
Use the Find method of the List<T> class to find if a record exist with the conditions I am searching for.
var query2 = (from e in svsContext.xrmsm_sessionEnrollmentsSet
join s in svsContext.xrmsm_sessionsSet on e.xrmsm_SessionLookup.Id equals s.xrmsm_sessionsId
join ic in svsContext.xrmsm_institutionCoursesSet on s.xrmsm_institutionCourseLookup.Id equals ic.xrmsm_institutionCoursesId
join ts in svsContext.xrmsm_term_sessionsSet on e.xrmsm_termSessionLookup.Id equals ts.xrmsm_term_sessionsId
join t in svsContext.xrmsm_termsSet on ts.xrmsm_TermLookup.Id equals t.xrmsm_termsId
where (e.xrmsm_StudentLookup.Equals(studentlookup))
select new
{
EnrollmentId = e.xrmsm_sessionEnrollments_id,
SessionId = s.xrmsm_sessions_id,
EnrollmentYear = e.xrmsm_YearLookup,
InstitutionCourseId = (Guid)ic.xrmsm_institutionCoursesId,
TermId = (Guid)t.xrmsm_termsId,
Student = e.xrmsm_StudentLookup
}).ToList();
var q = query2.Find(r => r.EnrollmentYear.Id == entity.GetAttributeValue<EntityReference>("xrmsm_yearlookup").Id
&& r.InstitutionCourseId == institutionCourseGuid
&& r.TermId == termGuid);

Outer Join statement in LINQ

I am trying to create an outer join statement in LINQ and am not having much luck. I know that Performing an outer join requires two steps:
(1) Convert the join into a group join with into
(2) Use DefaultIfEmpty() on the group to generate the null value you expect if the joined result set is empty.
I have been using this code as an example:
var query = (from p in dc.GetTable<Person>()
join pa in dc.GetTable<PersonAddress>() on p.Id equals pa.PersonId into tempAddresses
from addresses in tempAddresses.DefaultIfEmpty()
select new { p.FirstName, p.LastName, addresses.State });
So I tried to do this:
var outerJoin =
from h in resultHours
join u in results on h.Key equals u.Key into outer
from dictionary in outer.DefaultIfEmpty()
select new {
The problem is that intellisense doesn't recognize anything in the select new {} statement. I've tried u. and h., even dictionary.
The problem I may be running into is that I'm trying to outer join two dictionaries. It doesn't seem to like that, although this is what I was told I need to do. I am obviously doing something wrong or not understanding something.
I need to join the dictionary results.Unit with the dictionary resultHours.Hours because my output is missing unitId fields under certain conditions. Doing an outer join is supposed to clear this up.
Here is the code for results:
var results =
(from v in VDimUnit
join vf in VFactEnergyAllocation on v.UnitKey equals vf.UnitKey
join vd in VDimGadsEvent on vf.GadsEventKey equals vd.GadsEventKey
join vt in VDimTime on vf.TimeKey equals vt.TimeKey
where typeCodes.Contains(vd.GadsEventTypeCode)
&& vt.YearNum >= (year - 3) && vt.YearNum <= year
group vf by new {v.PlantId, v.PhysicalUnitId, v.NetDependableCapacity, v.NetMaximumCapacity,
vt.MonthNum} into groupItem
select new {groupItem.Key.PlantId, groupItem.Key.PhysicalUnitId, groupItem.Key.NetMaximumCapacity,
groupItem.Key.MonthNum, PO_HRS = groupItem.Sum(
x=> (float)x.AllocatedEnergyMwh / groupItem.Key.NetDependableCapacity),
UO_HRS = groupItem.Sum(x=> (float)x.AllocatedEnergyMwh / groupItem.Key.NetDependableCapacity),
Unit = groupItem.Count(), groupItem.Key}).ToDictionary(x=> x.Key, x=> x);
Here is the code for resultHours:
var resultHours =
(from vt in VDimTime
join vf in VFactEnergyAllocation on vt.TimeKey equals vf.TimeKey
join vd in VDimGadsEvent on vf.GadsEventKey equals vd.GadsEventKey
join v in VDimUnit on vf.UnitKey equals v.UnitKey
group vt by new {v.PlantId, v.PhysicalUnitId, v.NetDependableCapacity, v.NetMaximumCapacity,
vt.MonthNum} into groupItem
select new {groupItem.Key.PlantId, groupItem.Key.PhysicalUnitId, groupItem.Key.NetMaximumCapacity,
Hours = groupItem.Count(), groupItem.Key}).ToDictionary(x=> x.Key.ToString(), x=> x.Hours);
This is presently how I have my output. It will change after I figure out how to do the outer join.
var finalResults =
(from r in results
orderby r.Key.MonthNum, r.Key.PlantId, r.Key.PhysicalUnitId
select new {Site = r.Key.PlantId, Unit = r.Key.PhysicalUnitId, r.Key.MonthNum, Numerator = r.Value.PO_HRS, Denominator =
resultHours[r.Key.ToString()], Weight = r.Key.NetMaximumCapacity, Data_Indicator = DATA_INDICATOR,
Budgeted = budgetedPlannedOutageHrs, Industry_Benchmark = INDUSTRY_BENCHMARK, Comments = comments,
Executive_Comments = executiveComments, Fleet_Exec_Comments = fleetExecComments});
I'm at a loss. The LINQ outer join examples I have found apaprently do not apply when joining dictionaries.

Help for translate c# Linq query with 2 group by into vb.net linq query

Hello everyone,
I tried and tried to make this query in vb.net, but I can not.
I do not understand if I have to use two groups, and if so, how do I use them.
This is a query that is in the project - tutorial Tailspin SpyWorks
and should serve to show the 5 most popular products.
I do not understand really how to do.
var query = (from ProductOrders in db.OrderDetails
join SelectedProducts in db.Products on ProductOrders.ProductID
equals SelectedProducts.ProductID
group ProductOrders by new
{
ProductId = SelectedProducts.ProductID,
ModelName = SelectedProducts.ModelName
} into grp
select new
{
ModelName = grp.Key.ModelName,
ProductId = grp.Key.ProductId,
Quantity = grp.Sum(o => o.Quantity)
} into orderdgrp
where orderdgrp.Quantity > 0
orderby orderdgrp.Quantity descending
select orderdgrp).Take(5);
I tried to do the translation but I can not find documentation that helps me understand how do I manage two groups.
Dim query = (From ProductOrders in db.OrderDetails
Join SelectedProducts in db.Products On
ProductOrders.ProductID Equals SelectedProducts.ProductID
Group ProductOrders By New With
{
.ProductId = SelectedProducts.ProductID,
.ModelName = SelectedProducts.ModelName
} into grp
In fact from now on I can not go on
If someone can please help me out
Thanks a lot
Fabrizio
Im not an expert of VB language, but the following code is syntactically correct:
Dim query = (From ProductOrders In Products
Join SelectedProducts In SelProducts On ProductOrders.ProductId Equals SelectedProducts.ProductId
Group ProductOrders By Key = New With {
.ProductId = SelectedProducts.ProductId,
.ModelName = SelectedProducts.ModelName
} Into grp = Group
Select orderdgrp = New With
{
.ModelName = Key.ModelName,
.ProductId = Key.ProductId,
.Quantity = grp.Sum(Function(o) o.Quantity)
}
Where orderdgrp.Quantity > 0
Order By orderdgrp.Quantity Descending
Select orderdgrp).Take(5)
Verify that the query is also semantically correct.

Resources