I am working on a project for an Event application. My task is to create a partial view and show any events that are within the next two days.
I am getting an error:
Operator <= cannot be applied to operands of type string and DateTime
I am unsure how to fix this issue.
Here is my code:
public ActionResult GetLastMinuteDeals()
{
DateTime futureDate = DateTime.Today.AddDays(2);
var LastMinuteDeal = db.Events
.Where(a => a.EventStartDate <= DateTime.Today)
.Where(a => a.EventStartDate <= futureDate);
return LastMinuteDeal;
}
The member EventStartDate is likely a string type. To compare them to a DateTime, you will need to create another DateTime object, like so:
var LastMinuteDeal = db.Events
.Where(a => DateTime.Parse(a.EventStartDate) <= DateTime.Today)
.Where(a => DateTime.Parse(a.EventStartDate) <= futureDate);
Related
I have a database table AdvisorComments where I have advisorID and studentID along with other columns. There can be multiple records for same advisorID and studentID. Also, an advisorID can have different studentIds and vice versa.
I have another table Students where I have stored only current advisorId which can be updated to different advisor.
I want to get all the students (current: Students table; previous: AdvisorComments table) for a particular advisor from Students table.
Here's what I have tried:
this.advisorID = 1;
var advisorComments = _context.AdvisorComments.Where(x => x.advisorID == this.advisorID).GroupBy(x=>x.studentID).Select(m => new { m.First().studentID}).ToList();
/* output:
0: studentID 1
1: studentID 4
*/
var studentList = _context.Students.Where(x => x => x.advisorID == this.advisorID || advisorComments.Any(a => a.studentID== x.studentID)).ToList();
/*output:
Getting error
System.InvalidOperationException: 'The LINQ expression 'a => a.studentID == EntityShaperExpression:
Project.Models.Student
ValueBufferExpression:
ProjectionBindingExpression: EmptyProjectionMember
IsNullable: False
.studentID' could not be translated. Either rewrite the query in a form that can be translated, or switch to client evaluation explicitly by inserting a call to 'AsEnumerable', 'AsAsyncEnumerable', 'ToList', or 'ToListAsync'.
*/
Declared advisorComments as List type and it's working.
List<int> advisorComments = _context.AdvisorComments.Where(x => x.advisorID == this.advisorID).Select(m => studentID).Distinct().ToList();
this.advisorID = 1;
var advisorComments = _context.AdvisorComments
.Where(x => x.advisorID == this.advisorID)
.DistinctBy(z => z.studentID)
.Select(m => new { m.studentID}).ToList();
/* output:
0: studentID 1
1: studentID 4
*/
var studentList = _context.Students
.Where(x => x.advisorID == this.advisorID ||
advisorComments.Any(z => z.studentID == x.studentID))
.ToList();
DistinctBy is not standard linq but a helper function -- here is the code
public static IEnumerable<TSource> DistinctBy<TSource, TKey>
(this IEnumerable<TSource> source, Func<TSource, TKey> keySelector)
{
HashSet<TKey> seenKeys = new HashSet<TKey>();
foreach (TSource element in source)
{
if (seenKeys.Add(keySelector(element)))
{
yield return element;
}
}
}
hat tip > https://stackoverflow.com/a/489421/215752
I have a model with startDate and endDate Property.
When inserting the model to mongo, the datetime is translated to ISO format datetime string.
I am trying to get document by dates range properties using LINQ on collection as documented at mongodb documentation https://mongodb-documentation.readthedocs.io/en/latest/ecosystem/tutorial/use-linq-queries-with-csharp-driver.html#gsc.tab=0
My C# code model relevant props:
public DateTime StartWorkDate { get; set; }
public DateTime FinishWorkDate { get; set; }
mongodb document relevant props:
My code where i try to get document by dates range
GetRecordsByDate(DateTime start,DateTime end){
...
var collection = _db.GetCollection<TestModel>("TestCollection");
var query = from test in collection.AsQueryable<TestModel>()
where (DateTime.Compare(test.StartWorkDate, start) > 0 || DateTime.Compare(test.StartWorkDate, start) == 0) &&
(DateTime.Compare(test.FinishWorkDate, end) < 0 || DateTime.Compare(test.FinishWorkDate, end) == 0)
select test;
return query.ToList();
}
I get the following exception:
Message:System.InvalidOperationException: 'Compare({document}{StartWorkDate}, 01/01/2019 00:00:00) is not supported
If i try get all documents and then run the same query on the result it works perfect:
GetRecordsByDate(DateTime start,DateTime end){
...
var collection = _db.GetCollection<TestModel>("TestCollection");
var resTemp = collection.Find(Builders<TestModel>.Filter.Empty).ToList();
var collectionResult = resTemp.Where(test =>
(DateTime.Compare(test.StartWorkDate, start) > 0 || DateTime.Compare(test.StartWorkDate, start) == 0) &&
(DateTime.Compare(test.FinishWorkDate, end) < 0 || DateTime.Compare(test.FinishWorkDate, end) == 0)
).ToList();
}
Which brings me to my other question (its just a good to know question):
I know its better using query on the mongo because its querying system is very efficient, But what is the difference between running the query on mongo then getting all documents and then running linq on them as i did at my working code
Managed to solve it using filters, Im sure someone will find it usefull
var collection = _db.GetCollection<TestModel>("TestCollection");
var builder = Builders<TestModel>.Filter;
var filter = builder.Gt(t => t.StartWorkDate, start) & builder.Lt(t => t.FinishWorkDate, end);
var res = collection.Find(filter).ToList();
I am currently building an angular website and using Web Api 2 as my data service.
I have encountered a issue with populating child entities when i call a http get method. The child entities (fields) does not appear in the Json response.
//Fetch records by page size
public ICollection<CompanyStatDomainModel> GetRecordsByPageSize(int page)
{
const int pgeSize = 20;
var result = _companyStatRepo.AllIncluding(c => c.CompanyDomainModel, c => c.RatingDomainModels)
.OrderBy(c => c.CompanyStatId).Skip(page * pgeSize).Take(pgeSize).ToList();
return result;
}
CONTROLLER
public ICollection<CompanyStatDomainModel> GetRecordsByPageSize(int page)
{
var companyStatService = new CompanyStatService();
return companyStatService.GetRecordsByPageSize(page);
}
WebApiConfig.cs
var json = config.Formatters.JsonFormatter;
json.SerializerSettings.PreserveReferencesHandling = Newtonsoft.Json.PreserveReferencesHandling.Objects;
config.Formatters.Remove(config.Formatters.XmlFormatter);
The easiest way to solve this kind of problem is by manually projecting the results of the EF query to the desired structure, something like
var result = _companyStatRepo
.AllIncluding(c => c.CompanyDomainModel, c => c.RatingDomainModels)
.OrderBy(c => c.CompanyStatId).Skip(page * pgeSize)
.Take(pgeSize).Select(csr => new CompanyStatRepo {
prop1 = csr.prop1,
prop2 = csr.prop2,
...
RatingDomainModels = csr.RatingDomainModels.ToList()
}).ToList();
I don't know the real structure of your classes, but this is the basic idea.
I would like a lambda expression to get all my posts with a PublishDate in a specific month / year range (like 10/2011).
public IEnumerable<Post> SearchPosts(string periode)
{
// periode may be 10/2011 so I would like all posts from 10/01/2011 to 10/31/2011
return m_PostRepository.GetPosts().Where(x => x.PublishDate...?
}
Description
You can do this using the DateTime properties Year and Month in your Where Filter.
Sample
return m_PostRepository.GetPosts().Where(x => x.PublishDate.Year == 2011 &&
x.PublishDate.Month == 10).ToList();
More Information
MSDN - DateTime.Month Property
MSDN - DateTime.Year Property
Update after a comment from Bronzato
DateTime? date;
// does date has a value ? If yes, apply the filter. If not return everything.
if (date.HasValue)
{
return m_PostRepository.GetPosts().Where(x => x.PublishDate.Year == date.Value.Year &&
x.PublishDate.Month == date.Value.Month).ToList();
} else return return m_PostRepository.GetPosts();
You can also try it like this (working with PublishDate as Nullable<DateTime>):
DateTime date;
if (DateTime.TryParseExact(value, "MM/yyyy", CultureInfo.InvariantCulture, DateTimeStyles.None, out date))
{
var result = m_PostRepository.GetPosts().Where(x => x.PublishDate.HasValue &&
x.PublishDate.Value.Month == date.Month &&
x.PublishDate.Value.Year == date.Year).ToList();
}
public IEnumerable<Post> SearchPosts(string periode){
string[] _periode = periode.Split("/");
return m_PostRepository.GetPosts().Where(x => x.PublishDate.year = convert.ToInt16(_periode[1])).Where(x => x.PublishDate.Month= convert.ToInt16(_periode[0]))}
I have a C#-4 MVC3 RC test-application which is using Entity Framework 4.
I have this method:
public static List<Content> FetchMenu(int websiteID) {
return (from w in ContextHelper.Current.Websites
where w.WebsiteID == websiteID
select w.Contents).ToList();
}
The objects involved here (Content and Website) are of type EntityObject.
The above function gives compilation error:
Cannot implicitly convert type 'System.Linq.IQueryable<System.Collections.Generic.List<Manager.Models.Content>>' to 'System.Collections.Generic.List<Manager.Models.Content>'. An explicit conversion exists (are you missing a cast?)
w.Contents is an EntityCollection<Content> type collection.
How do I defer the Linq.IQueryable type to return a generic List of type Content?
You need to use parentheses, so that you apply ToList() to the whole query (an object of type IQueryable):
public static List<Content> FetchMenu(int websiteID) {
return (from w in ContextHelper.Current.Websites
where w.WebsiteID == websiteID
select w.Contents).ToList();
}
Otherwise you are calling ToList() on w.Contents only and the select is applied afterwards. It might be clearer if I show the method chaining syntax.
Your version:
ContextHelper.
Current.
Websites.
Where(w => w.WebsiteID == websiteID).
Select(w => w.Contents.ToList());
Correct version:
ContextHelper.
Current.
Websites.
Where(w => w.WebsiteID == websiteID).
Select(w => w.Contents).
ToList();
Edit:
Since w.Contents is a collection, you need to flatten it out by using SelectMany:
public static List<Content> FetchMenu(int websiteID) {
return ContextHelper.
Current.
Websites.
Where(w => w.WebsiteID == websiteID).
SelectMany(w => w.Contents).
ToList();
}
var query = (from w in ContextHelper.Current.Websites
where w.WebsiteID == websiteID
select w.Contents).First();
return query.ToList();
The .First() seems to do the trick... thanks.
Yakimych's answer using SelectMany() is corret. For completeness, here it is using "query comprehension" syntax:
public static List<Content> FetchMenu(int websiteID) {
return (from w in ContextHelper.Current.Websites
where w.WebsiteID == websiteID
from c in w.Contents
select c).ToList();
}