LINQ query syntax with comparator - c#

Consider this code:
var files = Directory.GetFiles(filePath);
var dataFiles = from file in files
where System.IO.Path.GetExtension(file) == extension
orderby file.Length
select file;
I've been looking for a string comparator that will do "natural sort". Sadly, there is no build-in functionality for this common task. I found this post and it looks good.
Can I use NaturalStringComparer with LINQ query syntax? I am aware of the solution with lambdas.

Unfortunately this is not possible since the overload of OrderBy with a custom comparer is not supported in query syntax - only method syntax makes it accessible:
var comparer = new NaturalStringComparer();
var dataFiles = files.Where(f => System.IO.Path.GetExtension(f) == extension)
.OrderBy(f => f, comparer);

You need to use the extension method syntax:
files.OrderBy(file => file.Length, new NaturalStringComparer())

var files = Directory.GetFiles("C:\\");
var dataFiles = from file in files
where System.IO.Path.GetExtension(file) == extension
orderby file
select file;
this might help you.

Related

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));

Grab a List item based on newest datetime

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();

Using the linq search option in enumerate files

Quick one here. I am trying to EnumerateFiles in a C# application and I want to find all the files in a directory that do not match a given pattern. So I would have something like this:
var files = Directory.EnumerateFiles("MY_DIR_PATH", "NOT_MY_FILE_NAME");
Can someone help me out with the not part?
I don't think you can use that overload of EnumerateFiles for this, but you can use linq:
Directory.EnumerateFiles("MY_DIR_PATH").Where(s => s != "NOT_MY_FILE_NAME");
or in query syntax:
var files = from f in Directory.EnumerateFiles("MY_DIR_PATH")
where f != "NOT_MY_FILE_NAME"
select f;
You can do something like that:
var files = Directory.EnumerateFiles("MY_DIR_PATH")
.Where(fileName => fileName != "MY_FILE_NAME");
How about
var files = Directory.GetFiles("MY_DIR_PATH")
.Where(f => !f.Contains("NOT_MY_FILE_NAME"));

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.

What is the LINQ to XML equivalent for this XPath

I wondering what the "best practice" way (in C#) is to implement this xpath query with LINQ:
/topNode/middleNode[#filteringAttribute='filterValue']/penultimateNode[#anotherFilterAttribute='somethingElse']/nodesIWantReturned
I would like an IEnumerable list of the 'nodesIWantReturned', but only from a certain section of the XML tree, dependent on the value of ancestor attributes.
In addition to the Linq methods shown, you can also import the System.Xml.XPath namespace and then use the XPathSelectElements extension method to use your XPath query directly.
It is noted in the class that these methods are slower than 'proper' Linq-to-XML, however a lot of the time this isn't too important, and sometimes it's easier just to use XPath (it's certainly a lot terser!).
var result = doc.XPathSelectElements("your xpath here");
var result = root.Elements("topNode")
.Elements("middleNode")
.Where(a => (string)a.Attribute("filteringAttribute") == "filterValue")
.Elements("penultimateNode")
.Where(a => (string)a.Attribute("anotherFilterAttribute") == "somethingElse")
.Elements("nodesIWantReturned");
A more verbal solution:
var nodesIWantReturned = from m in doc.Elements("topNode").Elements("middleNode")
from p in m.Elements("penultimateNode")
from n in p.Elements("nodesIWantReturned")
where m.Attribute("filteringAttribute").Value == "filterValue"
where p.Attribute("anotherFilterAttribute").Value == "somethingElse"
select n;

Categories

Resources