Grab a List item based on newest datetime - c#

Im grabing articles with this code.
List<view_M04FrontpagesEntity> fList = new view_M04FrontpagesService().GetByCategoryId(0);
var article = new M02ArticlesService().GetById(fList.First<view_M04FrontpagesEntity>().M02ArticleId);
I want to grab the article with the newest article.UpdatedDate how can a best do this with linq or other method?

Use MaxBy method provided my MoreLinq
List<view_M04FrontpagesEntity> fList = new view_M04FrontpagesService().GetByCategoryId(0);
var newest = fList.MaxBy(article => article.UpdatedDate);

you can Use OrderByDescending in LInQ.
var query = myList.Where(x =>x=="somePredicate")
.OrderByDescending(x => x.UpdatedDate ).FirstOrDefault();
Returns the first element of a sequence, or a default value if the sequence contains no elements.

var first = articles.OrderByDescending( a => a.UpdateDate ).First();
Generally speaking, this is it. You need to transfer this to your code yourself, because none of the code you posted helped.

var result = (from article in fList
orderby article.UpdatedDate descending
select article).First();

This is working as intended.
var m04FrontpagesEntities = new view_M04FrontpagesService().GetByCategoryId(0).ToList().Select(x => new M02ArticlesService().GetById(x.M02ArticleId)).ToList().OrderByDescending(x => x.UpdatedDate); ;
var article = m04FrontpagesEntities.First();

Related

convert the for loop with index using LINQ

I am new to C# language, I have started learning LINQ in that
So I just want to convert the code using linq. Is there any way to do. The current implementation is not a stylish one.
var list = new List<int>();
for (int index = 0; index < contentList.Count; index++)
{
list.Add(MyClass.GetCorrespondence(module, index));
}
return list;
You could write it like this:
var list = contentList.Select((_, i) => MyClass.GetCorrespondence(module, i)).ToList();
or like this
var list = Enumerable.Range(0,contentList.Count).Select(i => MyClass.GetCorrespondence(module, i)).ToList();
But, honestly, dont do either! Your code is perfectly readable as it is.
If you must use LINQ for this then you can use the overload for Select which "projects each element of a sequence into a new form by incorporating the element's index." e.g:
list.AddRange(contentList.Select((c, index) => MyClass.GetCorrespondence(c, index));
https://learn.microsoft.com/en-us/dotnet/api/system.linq.enumerable.select?view=netframework-4.8
this method work:
var result= contentList.Select((paramter,index)=>MyClass.GetCorrespondence(module,index)).ToList();
If you're desperate to do it with Linq then you could try:
list.AddRange(Enumerable.Range(0, contentList.Count).Select(index => MyClass.GetCorrespondence(module, index)))
or:
list = Enumerable.Range(0, contentList.Count).Select(index => MyClass.GetCorrespondence(module, index)).ToList();
You could also use the ForEach LINQ statement.
contentList.ForEach(x => list.Add(MyClass.GetCorrespondence(module, x)));
EDIT: Any reason why this was down voted?

How do I select several ids?

There is a list List<string> list
How to build a query using LINQ, which repeat the query "Select * FROM a Where id IN(...)"
Use LINQ and Contains method:
var result = a.Where(c => list.Contains(c.Id)).ToList();
You could use Any as well:
var result = source.Where(item => list.Any(element => element == item.Id)).ToList();
Btw if you're using the list only to check if a given element is present or not, I'd suggest using a HashSet<string> as you may gain better performance:
HashSet<string> container = ....
Then use as follows:
var result = source.Where(item => container.Contains(item.Id));

Is there any benefits to using List.AddRange over a LINQ.ToList()?

I was working through an MVC4 tutorial today and saw the user implemented a select in a different manner than I'm used to. His code was:
var GenreLst = new List<string>();
var GenreQry = from d in db.Movies
orderby d.Genre
select d.Genre;
GenreLst.AddRange(GenreQry.Distinct());
ViewBag.movieGenre = new SelectList(GenreLst);
I looked at it and rewrote it in my own way as:
var genres = db.Movies
.OrderBy(m => m.Genre)
.Select(m => m.Genre)
.Distinct()
.ToList();
ViewBag.MovieGenre = new SelectList(genres);
His GenreList variable isn't used elsewhere, so I got rid of it. My main question is how he uses the AddRange. Is it any better to AddRange than ToList?
Thanks for reading!
e.ToList<T>() is implemented under the hood as:
return new List<T>(e);
And the List<T>(IEnumerable<T> e) constructor actually just calls this.AddRange(e) internally.
In other words, the two bits of code will do the exact same thing, in the exact same way.

Using SelectMany() or matching elements of two sequences with LINQ (dot syntax)

I need select all elements from a set whose Id property is contained within a second set. Can "SelectMany()" be used to accomplish this? What is the most efficient / best solution for this type of matching problem.
Example:
Select all DateRangeIds for a given ReportId by way of a joining entity set.
Sets:
Reports {ReportId, ReportName}
ReportDateRanges {DateRangeId, ReportId, ReportDateRangeId}
DateRanges {DateRangeId, DateRangeName}
Here is my solution's code. I am unsure if this is the proper approach, but this does solve the problem I've described:
var report = Reports.Take(1).FirstOrDefault();
int reportId = Convert.ToInt32(report.Id);
var dateRangeIds = ReportDateRanges.Where(rdr => rdr.ReportId == reportId).OrderBy(it => it.DateRangeId).Select(it => it.DateRangeId);
var dateRanges = DateRanges.Where(dateRange => dateRangeIds.Contains(dateRange.Id));
LINQ experts, please feel free to critique this code and offer any suggestions. Thanks for the help!
Well, you can use an Enumerable.Intersect(Of TSource) Method (IEnumerable(Of TSource), IEnumerable(Of TSource), IEqualityComparer(Of TSource))
for example:
var list1 = new List<int> {1,2,3,4,5,6,7,8};
var list2 = new List<int> {9,10,11,12,13,4,5};
list1.Intersect(list2);
result
4,5
Using overload specified in link, you can specify EqualityComparer for your custom object in order to find intersection of both enumerations.
Hope this helps.
I think your code is simple and readable but there are something which is not good:
var report = Reports.Take(1).FirstOrDefault();
you can write:
var report = Reports.FirstOrDefault();
And in this line:
var dateRangeIds = ReportDateRanges.Where(rdr => rdr.ReportId == reportId)
.OrderBy(it => it.DateRangeId)
.Select(it => it.DateRangeId);
you used orderby but you don't need this.
You can join the collections.
Given that you have the reportId you can issue this query.
Reports
.Where(report => report.ReportId == reportId)
.Join(ReportDateRanges,
report => report.ReportId,
rdr => rdr.ReportId,
(report, reportDateRange) => reportDateRange)
.Join(DateRanges,
rdr => rdr.DateRangeId,
dateRange => dateRange.DateRangeId,
(reportDateRange, dateRange) => dateRange);
Here's one way to do it:
IEnumerable<SomeTypeWithAnIDProperty> sourceSequence = //whatever
IEnumerable<TypeOfTheIDProperty> ids = //whatever
var selectedItems =
from sourceObject in sourceSequence
join id in ids
on sourceObject.ID equals id
select sourceObject;
Or, to use your example
var dateRangeIds = ReportDateRanges
.Where(rdr => rdr.ReportId == reportId)
.OrderBy(it => it.DateRangeId)
.Select(it => it.DateRangeId);
var dateRanges = DateRanges.Join(dateRangeIds, dateRange => dateRange.Id, id => id, (dateRange, id) => dateRange);

How to specify an Order or Sort using the C# driver for MongoDB?

I'm trying to figure out how to sort a collection of documents server side by telling the C# driver what the sort order is, but it appears not to support that construct yet.
Is it possible to do this any other way?
You can also do it using the SetSortOrder method on the MongoCursor class:
db["collection"].Find().SetSortOrder(SortBy.Ascending("SortByMe"));
Just to add to Chris's answer, in C# Driver 2.x it is now done with SortBy, SortByDescending, ThenBy & ThenByDescending
collection.Find(bson => true).SortBy(bson => bson["SortByMeAscending"]).ThenByDescending(bson => bson["ThenByMeDescending"]).ToListAsync()
Now it resembles Linq even more.
http://mongodb.github.io/mongo-csharp-driver/2.0/reference/driver/crud/reading/#sort
For async methods:
var filter = Builders<BsonDocument>.Filter.Empty;
var sort = Builders<BsonDocument>.Sort.Ascending("time");
collection.FindAsync(filter, new FindOptions<BsonDocument, BsonDocument>()
{
Sort = sort
});
Simple usage of api in MongoDB.Driver 2.5.0
var client = new MongoClient("mongodb://localhost:27017");
var database = client.GetDatabase("Blog");
var list = database.GetCollection<BlogPost>("BlogPost")
.Find(e => e.Deleted == false)
.SortByDescending(e => e.CreatedOn)
.Limit(20)
.ToList();
Note that to sort on multiple fields use this:
db["collection"].Find().SetSortOrder(SortBy.Ascending("SortByMe").Descending("An‌​dByMe");
If you want to use linq:
From the documentation: (http://docs.mongodb.org/ecosystem/tutorial/use-linq-queries-with-csharp-driver/)
var query=
(from c in collection.AsQueryable<C>()
orderby c.X
select c)
foreach (var d in query)
{
// process your documents
}
If you want you can also limit the results:
var query=
(from c in collection.AsQueryable<C>()
orderby c.X descending
select c).Take(1);
Just remember to have an index on the field you are sorting by : ]
It seems the way to do this using the existing C# driver is as follows:
db["collection"].Find(new Document().Append("query",
new Document()).Append("orderby",
new Document().Append(name:1).Append(age,-1)));
Which I was turned on to by Sam Corder here
You can apply sort with SortDefinition like this:
FilterDefinition<User> filter = Builders<User>.Filter.Eq(a => a.Deleted , false);
SortDefinition<User> sort = Builders<User>.Sort.Descending(a => a.Id);
List<User> result = _dbContext.Users.Find(filter).Sort(sort).Limit(10).ToList();
#DmitryZyr's answer for FindAsync was not working. This one did however.
var sortDefinition = new SortDefinitionBuilder<ImmutableLog>().Descending("date");
var findOptions = new FindOptions<ImmutableLog>() {Sort = sortDefinition};
await this.Collection.FindAsync(new BsonDocument(), findOptions);
I'm currently using the API version MongoDB.Driver 2.8.1.
Here is my method that I call to return a list of objects with Descending sorting, if it is required:
public static IEnumerable<TEntity> GetDocumentsForCollection(
IMongoDatabase database,
string collectionName,
FilterDefinition<TEntity> query,
string databaseCollectionKeyToSortOnDescending)
{
var _mongoSettings = new MongoCollectionSettings();
_mongoSettings.GuidRepresentation = GuidRepresentation.Standard;
var _collection = database.GetCollection<TEntity>(collectionName, _mongoSettings);
if (string.IsNullOrEmpty(databaseCollectionKeyToSortOnDescending))
{
return _collection.Find(query).ToList();
}
return _collection.Find<TEntity>(query).Sort(Builders<TEntity>.Sort.Descending(databaseCollectionKeyToSortOnDescending)).ToList();
}
I'm doing this in JavaScript since I don't know C#, but it should have equivalent syntax with the C# driver.
If your query looked like:
db.c.find({"foo" : "bar"})
and you want to sort by "baz" ascending, wrap your query in a "query" field and add an "orderby" field:
db.c.find({"query" : {"foo" : "bar"}, "orderby" : {"baz" : 1}})
For descending sort, use -1.

Categories

Resources