Entity Framework Pagination (Select records using string datetime column) - linq

I have a table which has startdate (in format "yyyymmddhhss")and the corresponding entity attribute is string type. I would like to use LINQ To SQL get all the records with StartDate >= SelectedStartDate. Since this table has more than 10 million records, I need to use pagination as well.
Could anyone please suggest on how to implement this/
Regards,
Raaj

The best solution would be of course to migrate the string values to a DATETIME column and query the data from that column.
But if you don't have enough privileges to do that, you're lucky you have the format yyyymmddhhss in your table because that preserves the natural order of dates; all you have to do is to convert the parameter to a string in the required format:
public IEnumerable<YourDataObject> GetData(DateTime date, PageInfo pageInfo)
{
var startDate = date.ToString("yyyyMMddHHss");
return _dbContext.Table
.OrderBy(x => x.StartDate)
.Where(x => String.Compare(x.StartDate, startDate) >= 1)
.Skip(pageInfo.PageSize * pageInfo.PageIndex)
.Take(pageInfo.PageSize)
.Select(x => new YourDataObject
{
//
});
}
Here is a sample output in LINQPad:

Related

linq Command not getting the answer for DB

i have a table(UserQuestions) in my DB(WebSiteUsers) which contains QuestionID field as a Primary key and QuestionContext field which holds the Questions that are asked as its value.
Now i want to have a textBox that show me the QuestionContext Value by getting QuestionID.
I used these linq commands and none of them bring me the correct answer :
string Questioncontext = new WebSiteUsersEntities().UserQuestions.Where(p => p.QuestiuonID.ToString() == QuestionID).Select(p => new { p.QuestionContext}).ToString();
string Questionx = (from q in new WebSiteUsersEntities().UserQuestions where q.QuestiuonID.ToString() == QuestionID select q.QuestionContext).ToString();
QuestionCntxt.Text = Questionx;
the outcome is like this :
SELECT
[Extent1].[QuestionContext] AS [QuestionContext]
FROM [dbo].[UserQuestion] AS [Extent1]
WHERE CAST( [Extent1].[QuestiuonID] AS nvarchar(max)) = #p__linq__0
I guess your QuestionID variable is of type string, while the database column is of type int.
So rather than using
q.QuestiuonID.ToString() == QuestionID
criteria inside the query, convert the variable to int and use that as criteria.
Also ToString just gives you the SQL query text, not the result. Use ToList if you expect more than one result or FirstOrDefault if you expect zero or one results:
var questionID = int.Parse(QuestionID);
string Questioncontext = new WebSiteUsersEntities().UserQuestions
.Where(p => p.QuestiuonID == questionID)
.Select(p => p.QuestionContext)
.FirstOrDefault();
Note that I also changed the select to return directly QuestionContext string rather than anonymous object having QuestionContext property.

Bltoolkit oracle clob type

I use bltoolkit as orm and i had a problem with clob type.
I have a long string value and i got error while update operation.
Error: ORA01704 - String literal too long.
Checked table and my column type is clob.
There is no clob option in bltoolkit table class design.
I set this column like that:
[MapField("MSG_BODY")]
public string MsgBody { get; set; }
What is wrong ?
I find a solution, post only clob columns and it works !
//update only body
value = db.Schedule
.Where(x => x.Rowversion == _zaman
&& x.ScheduleId == this.ScheduleId)
.Set(x => x.Rowversion, x => _zaman)
.Set(x => x.MsgBody, x => this.MsgBody)
.Update();

How to convert a string into a datetime in Linq to Entities query?

My Linq to entities query is written as below.
The datatype of DATECOLUMN1 in my ORACLE database is of string.
Datetime FilterStartDate = DateTime.Now;
var query = from c in db.TABLE1
join l in db.TABLE2 on c.FK equals l.PK
where (FilterStartDate >= DateTime.ParseExact(l.DATECOLUMN1, "dd/MM/yyyy", CultureInfo.InvariantCulture) : false) == true
select c;
Writing above query gives me an error of not supported. How can I convert DATECOLUMN1 into a datetime to compare it.
P.S. I do not have control over database schema, so changing datatype of column in Oracle database is not a feasible solution for me.
In you Model, add the following property to your partial class TABLE2:
public DateTime DATECOLUMN1_NEW
{
get
{
return DateTime.ParseExact(DATECOLUMN1, "dd/MM/yyyy", CultureInfo.InvariantCulture);
}
set { }
}
Then, in you LINQ query, use DATECOLUMN1_NEW (it's already in DateTime format) in place of DATECOLUMN1.
Erm.. I think the problem you are having is that you are putting ": false" in there.
It looks like you are trying to use a condtional operator (?:) but you forgot the "?".
I don't think you actually need this as you are just trying to determine if the date is greater or not. Also if ParseExact fails it will throw an exception (not what you want) so you should use TryParse instead and handle the true/false returned and the out value to determine whether or not the date is (a) Actually a date (b) less then FilterStartDate.
You can use two alternatives:
Use the function described in the answer here: How to I use TryParse in a linq query of xml data?
Use the following fluent syntax version which I think is more readable.
var query = db.Table1.Join(db.Table2, x => x.FK, y => y.PK, (x, y) => x).Where(x =>
{
DateTime Result;
DateTime.TryParse(x.Date, out Result);
return DateTime.TryParse(x.Date, out Result) && FilterStartDate >= Result;
});

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.

Linq to EF Expression Tree / Predicate int.Parse workaround

I have a linq Entity called Enquiry, which has a property: string DateSubmitted.
I'm writing an app where I need to return IQueryable for Enquiry that have a DateSubmitted within a particular date range.
Ideally I'd like to write something like
IQueryable<Enquiry> query = Context.EnquirySet.AsQueryable<Enquiry>();
int dateStart = int.Parse("20090729");
int dateEnd = int.Parse("20090930");
query = (from e in query
where(enq => int.Parse(enq.DateSubmitted) < dateEnd)
where(enq => int.Parse(enq.DateSubmitted) > dateStart)
select e);
Obviously Linq to EF doesn't recognise int.Parse, so I think I can achieve what I want with an Expression method that returns a predicate???
I've been playing around with PredicateBuilder and looking all over but I've successfully fried my brains trying to work this out. Sure I could add another property to my Entity and convert it there but I'd really like to understand this. Can anyone explain or give an example/link that doesn't fry my brains?
Thanks in advance
Mark
If you know your date strings are valid, and they're really in that order (which is a natural sort order) you might be able to get away with string comparisons:
IQueryable<Enquiry> query = Context.EnquirySet.AsQueryable<Enquiry>();
string dateStart ="20090729";
string dateEnd = "20090930";
query = (from e in query
where(enq => enq.DateSubmitted.CompareTo(dateEnd)) < 0)
where(enq => enq.DateSubmitted.CompareTo(dateStart)) > 0)
select e);

Resources