Weird Formatting of LINQ/Entity Framework Chains
Related to #1130. This is a particular nuisance when using Entity Framework where all of the collections are nested within a DbContext instance.
The current behavior violates the general "one dot per line" rule. Additionally, this is the primary reason that I have not introduced CSharpier into my team's project.
Input:
public List<ThingDto> GetThingsCreatedAtOrAfter(DateTimeOffset timestamp)
{
return _db.Things.Where(x => x.CreatedAt >= timestamp).Select(x => new ThingDto
{
Id = x.Id,
Name = x.Name,
Description = x.Description,
Quantity = x.Quantity,
}).ToList();
}
Output:
public List<ThingDto> GetThingsCreatedAtOrAfter(DateTimeOffset timestamp)
{
return _db
.Things.Where(x => x.CreatedAt >= timestamp)
.Select(x => new ThingDto
{
Id = x.Id,
Name = x.Name,
Description = x.Description,
Quantity = x.Quantity,
})
.ToList();
}
Expected behavior:
public List<ThingDto> GetThingsCreatedAtOrAfter(DateTimeOffset timestamp)
{
return _db.Things
.Where(x => x.CreatedAt >= timestamp)
.Select(x => new ThingDto
{
Id = x.Id,
Name = x.Name,
Description = x.Description,
Quantity = x.Quantity,
})
.ToList();
}
I have the same problem when using the formatter and it frustrates me a lot.
Same problem
the same
The formatting of member chains is based on prettier. The rules prettier followed are found here.
It boils down to - break after each method or indexer. Group properties with a method/indexer. I don't recall if I ever tried to track down how prettier decided on that style.
That said - it doesn't appear to be difficult to change this formatting. But I'd want to dig into this more before commiting to making the change.
I formatted a whole lot of code using a quick POC here but haven't spent a lot of time reviewing all the changes yet.
One possible exception would be keeping the old formatting on this. A chain with several properties followed by one method call would be treated as a group.
// current formatting
string method = Encoding.UTF8.GetString(
buffer,
segmentStart,
bytesConsumed - segmentStart
);
// vs with this change
string method = Encoding
.UTF8
.GetString(buffer, segmentStart, bytesConsumed - segmentStart);
Especially in the case where the method call is going to break either way
request.Properties.Add(
HttpPropertyKeys.RetrieveClientCertificateDelegateKey,
_retrieveClientCertificate
);
// vs
request
.Properties
.Add(
HttpPropertyKeys.RetrieveClientCertificateDelegateKey,
_retrieveClientCertificate
);
Looking at these examples, I think we might be on the wrong track and that there needs to be a more fine-grained solution to this. The first thing I notice is that the provided examples show the first MemberExpression being placed on its own line, but those should be on the same line as the Identifier in these cases since that would still be 1 dot per line. Obviously though, in the provided examples, the current formatting is more readable.
My initial thought is that there may need to be a distinction depending on the number of MemberExpression's and CallExpression's in a single statement.
Similar issue: https://github.com/belav/csharpier/issues/1108