LINQ - DateTime to String again - linq

I have the following code:
result = from i in _dbContext.Meetings
where i.UserInvitedID == CurrentUserID && i.MeetingStatus == null && i.AllowedTime.AllowedDate.Day >= date
//where i.UserInvitedID == CurrentUserID && i.MeetingStatus == null && EntityFunctions.TruncateTime(i.AllowedTime.AllowedDate.Day) >= date
select new ITW2012Mobile.Core.DataTable.MeetingModel2()
{
Name = i.UserInviter.FirstName + " " + i.UserInviter.LastName,
Company = i.UserInviter.Company,
MeetingID = i.MeetingID,
Time = EntityFunctions.AddMinutes(EntityFunctions.AddHours(i.AllowedTime.AllowedDate.Day, i.AllowedTime.Hour).Value, i.AllowedTime.Minute).Value.ToString("0:dddd, MMMM d, yyyy 0:t"),
Image = i.UserInviter.ProfileImage,
Username = i.UserInviter.aspnet_User.UserName
};
Time is string. Of course, I get
Exception error: {"LINQ to Entities does not recognize the method
'System.String ToString()' method, and this method cannot be
translated into a store expression."}
but how to write correctly in my case?

You can't use .ToString in L2E at all. That's an EF limitation.
You have to do that in object space -- e.g., after an .AsEnumerable()

Related

LINQ EF AND VS2017

I wrote a query and worked on LINQPAD
from x in FacilityData
from y in FavInformation
where y.UserID == 1 && x.ID == y.FacilityID
select new
{
xID = x.ID,
xDistrictName = (from y in _Ilcelers
where y.ID == x.DistrictID
select y.IlceAd).FirstOrDefault(),
xName = x.Name,
Value = (from o in Tags
from p in Table_tags
where o.Prefix != null && o.Prefix == p._NAME && o.Facility == y.FacilityID
orderby p.İd descending
select new
{
FType = o.TagType,
Name = o.TagsName,
Value = p._VALUE,
Time = p._TIMESTAMP
}).Take(Tags.Count(h => h.Facility == y.FacilityID))
}
result
the result is perfect
but does not work in visual studio,
Value = (from o in DB.Tags
from p in DB.table_tags
where o.Prefix != null && o.Prefix == p.C_NAME && o.Facility == 11
orderby p.id descending
select new
{
FType=o.TagType,
Name = o.TagsName,
Value = p.C_VALUE,
Time = p.C_TIMESTAMP
}).Take(Tags.Count(h => h.Facility == y.FacilityID))
and it gives an error.
I guess the part with .Take() doesn't work because it's linq to EF.
error:
Limit must be a DbConstantExpression or a Db Parameter Reference Expression. Parametre name: count]
error image
thank you have a good day
Not sure but I will just throw it in. If you are talking about linq to ef/sql, it is possible they dont know a thing about C#. If take() would be the problem try to get the select result local first by doing .tolist(). Afterwards use your take funtion.
.ToList().Take(Tags.Count(h => h.Facility == y.FacilityID))

Performing a date comparison with a date field stored in the database

I am trying to compare todays date with a date in the database.
Todays date is saved in the database like this : 2016-06-14 00:00:00.000
dtTodaysDate is generated like this: 6/14/2016 11:51:09 AM
Here is the method
public string CheckCreateOneProjectReportPerDay(string strprojectId)
{
string checkReturnValue = "DoesNotExist";
DateTime dtTodaysDate = DateTime.Now;
var checkProjectRec =
_objContext.tbl_Project_Status_MSTR.Where(
s => s.ProjectID == strprojectId && s.StatusDate == dtTodaysDate);
if (checkPrjDate.Any())
{
checkReturnValue = "RecordExist";
}
return checkReturnValue;
}
I tried to use the keyword contains in the query below but no luck
var checkProjectRec =
_objContext.tbl_Project_Status_MSTR.Where(
s => s.ProjectID == strprojectId && s.StatusDate == dtTodaysDate);
The query above will always return nothing because they don't match. Is there a better way
of doing this comparison ?
It looks like your database column StatusDate only stores the Day, Month, and Year of its DateTime object.
I would recommend altering your linq query to search for only those values of dtTodaysDate.
Give this a try:
var checkProjectRec =
_objContext.tbl_Project_Status_MSTR.Where(
s => s.ProjectID == strprojectId
&& s.StatusDate.Year == dtTodaysDate.Year
&& s.StatusDate.Month == dtTodaysDate.Month
&& s.StatusDate.Day == dtTodaysDate.Day);
Linq-to-SQL: DateTime Methods might be worth looking into as well.

Using case statement in linq query

I have a linq query like this :
var trfplanList = (from at in entities.tdp_ProviderAccomodationType
join ap in entities.tdp_ProviderAccomodationTariffPlan on at.PATID equals ap.FK_PATID
join ac in entities.tdp_ProviderAccomodationCategory on ap.FK_PACID equals ac.PACID
where at.FK_ProviderID == CityID && at.IsApproved == 0 && ap.IsApproved == 0 && ac.AccomodationCategory == "Double Occupy"
orderby at.AccomodationType,ap.FromDate,ap.SType
select new AccomodationTariff
{
AccomodationType = at.AccomodationType,
SType = ap.SType,
FromDate = Convert.ToDateTime(ap.FromDate),
ToDate = Convert.ToDateTime(ap.ToDate),
RoomTariff = Convert.ToDecimal(ap.Rate),
ExPAXRate = Convert.ToDecimal(at.PerPaxRate)
}).ToList();
I have two questions:
Can't I convert value while assigning in the select new {} block ? it is giving me an error in project.
I want use 'case' while selecting ExPAXRate from the database for example in SQL I used to write :
CASE ap.SType WHEN 'Off Season' THEN at.PerPaxRateOS ELSE at.PerPaxRate END AS ExPAXRate
Can I use something like this in linq query ?
Can't I convert value while assigning in the select new {} block
No, you can't (sadly). EF doesn't know how to translate it into SQL.
I want use 'case'
You can use the ternary operator (?):
ExPAXRate = at.OffSeason ? at.PerPaxRateOS : at.PerPaxRate
(assuming that at.OffSeason exists).
A solution for the conversion issue could be to project into an anonymous type first and then, in memory, to AccomodationTariff:
...
select new
{
AccomodationType = at.AccomodationType,
SType = ap.SType,
FromDate = ap.FromDate,
ToDate = ap.ToDate,
RoomTariff = ap.Rate,
ExPAXRate = at.PerPaxRate
}).AsEnumerable()
.Select(x => new AccomodationTariff
{
AccomodationType = x.AccomodationType,
SType = x.SType,
FromDate = Convert.ToDateTime(x.FromDate),
ToDate = Convert.ToDateTime(x.ToDate),
RoomTariff = Convert.ToDecimal(x.Rate),
ExPAXRate = Convert.ToDecimal(x.PerPaxRate)
}).ToList();

Linq using nullable datetime field

I have a problem with LINQ (using EF - 4.3.1.0) using the following:
DateTime? dtcollected = DateTime.TryParse(dateCollected, out dateVal) ? dateVal : (DateTime?)null;
DateTime? dtanalyzed = DateTime.TryParse(dateanalyzed, out dateVal) ? dateVal : (DateTime?)null;
var doesexist = (from pw in dbContext.WtTbl
where pw.CompanyId == 13
&& pw.DateCollected == dtcollected
&& pw.DateAnalyzed == dtanalyzed
select pw).Any();
Note that dateCollected came in as a string so I had to convert it to a nullable DateTime. Same goes for dateanalyzed.
What I am struck at is that I have a companyId of 13. A null value of dtcollected. And a value for dtanalyzed already in the table so I would expect doesexist to return true, but it returns false.
If I comment out
var doesexist = (from pw in dbContext.WtTbl
where pw.CompanyId == 13
// && pw.DateCollected == dtcollected
&& pw.DateAnalyzed == dtanalyzed
select pw).Any();
or put:
var doesexist = (from pw in dbContext.WtTbl
where pw.CompanyId == 13
&& pw.DateCollected == null
&& pw.DateAnalyzed == dtanalyzed
select pw).Any();
Then I get a true. How come it is not able to comprehend null value of dtcollected?
Am I doing something wrong.
In most database systems (definitely SQL Server), if one side of the comparison is null, then the result of the comparison is unknown, and therefore not included in the result set (or, for all intents and purposes, false).
That said, you need to perform a check for null against your variables, only checking against the database field if the parameter is non-null, like so:
var doesexist = (
from pw in dbContext.WtTbl
where
pw.CompanyId == 13 &&
(dtcollected == null || pw.DateCollected == dtcollected) &&
(dtanalyzed == null || pw.DateAnalyzed == dtanalyzed)
select pw).Any();
This translates roughly to:
declare #dtcollected date = null
declare #dtanalyzed date = null
select
*
from
Table as t
where
(#dtcollected is null or t.DateCollected = #dtcollected) and
(#dtanalyzed is null or t.DateAnalyzed = #dtanalyzed)

date difference with linq

With this code:
i.SpesaAlloggio = db.TDP_NotaSpeseSezB.Sum(p => p.Costo / (((DateTime)p.DayEnd)
.Subtract((DateTime)p.DayStart).Days + 1));
I receive this error:
LINQ to Entities does not recognize the method
'System.TimeSpan Subtract(System.DateTime)' method, and this method cannot be
translated into a store expression.
How can I do this?
Use a calculated DB field and map that. Or use SqlFunctions with EF 4 as LukLed suggested (+1).
I wrote a function for removing time:
public static DateTime RemoveHours(DateTime date)
{
int year = date.Year;
int month = date.Month;
int day = date.Day;
return new DateTime(year, month, day);
}
and changed filtering condition:
var query =
from trn in context.IdentityTransactions
where trn.ClientUserId == userId && trn.DateDeleted == null
orderby trn.DateTimeCreated
select new
{
ClientServerTransactionID = trn.ClientServerTransactionID,
DateTimeCreated = trn.DateTimeCreated,
ServerTransDateTime = trn.ServerTransDateTime,
Timestamp = trn.Timestamp,
Remarc = trn.Remarc,
ReservedSum = trn.ReservedSum,
};
if (dateMin.HasValue && dateMin.Value > DateTime.MinValue)
{
DateTime startDate = Converters.RemoveHours(dateMin.Value);
query = from trn in query
where trn.DateTimeCreated >= startDate
select trn;
}
if (dateMax.HasValue && dateMax.Value > DateTime.MinValue)
{
var endDate = Converters.RemoveHours(dateMax.Value.AddDays(1.0));
query = from trn in query
where trn.DateTimeCreated < endDate
select trn;
}
dateMin and dateMax are nullable types and may be not set in my case.
Try (it is not very efficient, but it will work):
i.SpesaAlloggio = db.TDP_NotaSpeseSezB.ToList()
.Sum(p => p.Costo / (((DateTime)p.DayEnd)
.Subtract((DateTime)p.DayStart).Days + 1));
EDIT : This will be extremely slow for large tables, because it transfers whole table content form server
Entity Framework tries to translate your expression to SQL, but it can't handle ((DateTime)p.DayEnd).Subtract((DateTime)p.DayStart). You have to make it simpler. ToList() gets all rows and then makes the calculation on application side, not in database.
With EF4, you could use SqlFunctions DateDiff
With EF1, you could create calculated field or view with this field and make calculation based on this field.

Resources