|
That could be an acute problem!
- I would love to change the world, but they won’t give me the source code.
|
|
|
|
|
I'm afraid this TotD is stuck in a circle.
... such stuff as dreams are made on
|
|
|
|
|
Nah. As usual, they're just talking sh1t.
I wanna be a eunuchs developer! Pass me a bread knife!
|
|
|
|
|
If the article includes only the upside of things, it's a haversine of the Times.
Will Rogers never met me.
|
|
|
|
|
|
Learned something new today. I was googling for CRC algorithms and came across this nifty site[^] and started perusing it more generally, then realized I had no idea about let clauses in query expressions![^]
Geez, I've been using LINQ for a while now, and didn't know about that.
Marc
|
|
|
|
|
Cool! I didn't know about it either. Now to find a use for it, just because
|
|
|
|
|
It's a useful tool in your arsenal. So how have you been solving this in the past? Multiple queries chained together?
Just wait until you start using "into[^]".
This space for rent
|
|
|
|
|
Pete O'Hanlon wrote: So how have you been solving this in the past? Multiple queries chained together?
My Linq tends to be rather simple.
Pete O'Hanlon wrote: Just wait until you start using "into[^]".
Though for reporting, yup, been there, done that:
var categoryRanks = (from gs in geekSkills
where (gs.ProfileId == profile.Id)
join s in skills on gs.SkillId equals s.Id
select new { Level = gs.Level, CategoryId = s.CategoryId } into gss
join c in categories on gss.CategoryId equals c.Id
select new { Level = gss.Level, Name = c.Name } into gssc
group gssc by new { gssc.Name, gssc.Level } into g
select new SkillLevelBySkillByCategory() {
SkillLevel = g.Key.Level,
SkillLevelCount = g.Count(x => x.Level == g.Key.Level),
Name = g.Key.Name });
Marc
|
|
|
|
|
Now, if your table have appropriately assigned foreign keys, then your Profile object would have a "geekSkills" collection of Skills object, which in turn would have a Category property which would have a Name property.
Reducing that to :
var categoryRanks = from s in profile.geekSkills
group s by new {Level = s.Level, Name = s.Category.Name} into g
select new SkillLevelBySkillByCategory() {
SkillLevel = g.Key.Level,
SkillLevelCount = g.Count(x => x.Level == g.Key.Level),
Name = g.Key.Name };
Not having the tables (or schema) makes designing that a bit tricky, so that might be off a bit. (like, i"m pretty sure that SkillLevelCount can be just "g.Count()" but I don't know your data)
Now, using LET, we can bring that down to :
var categoryRanks = from s in profile.geekSkills
let sl = new {Level = s.Level, Name = s.Category.Name}
group sl by sl into g
select new SkillLevelBySkillByCategory() {
SkillLevel = g.Key.Level,
SkillLevelCount = g.Count(x => x.Level == g.Key.Level),
Name = g.Key.Name };
Truth,
James
|
|
|
|
|
James Curran wrote: Now, if your table have appropriately assigned foreign keys,
They do, but I haven't set up my models yet with EntityRef and EntitySet. I'll have to do that and then play around with what you're suggesting.
I'll be really curious to log what the DataContext does!
And thank you for the reductions, that was way beyond the call of duty!
Marc
|
|
|
|
|
Marc Clifton wrote: They do, but I haven't set up my models yet with EntityRef and EntitySet.
That shouldn't be necessary. As long as the tables have the foreign keys defined, both Linq2sql & Entity Framework should create the properties automatically.
Truth,
James
|
|
|
|
|
I didn't know that and will probably forget quite soon too. Do people use that sort of syntax still? I never see it, and don't know what its called.
My inclination would be something hideous like this:
var a = strings.SelectMany(x => x.Split(' ')).Select(x => x.ToLower()).Where(x => x[0] == 'a' || x[0] == 'e' || x[0] == 'i' || x[0] == 'o' || x[0] == 'u');
...which I would call Linq, but may not be, or might be just some perverse form of it.
Regards,
Rob Philpott.
|
|
|
|
|
That's the method chaining syntax. The other version is the query syntax.
Query Syntax and Method Syntax in LINQ (C#)[^]
I tend to prefer the method chaining syntax for most queries, but for certain queries, the query syntax looks cleaner.
"These people looked deep within my soul and assigned me a number based on the order in which I joined."
- Homer
|
|
|
|
|
I can't get my head round the Linq syntax, so I always use method chaining. I think it's the way the query is backwards (just like SQL) where method chaining fits C# syntax better (in my mind anyway).
Bad command or file name. Bad, bad command! Sit! Stay! Staaaay...
|
|
|
|
|
Agreed. So my next question would be: Is there anything you can do in one syntax that you can't in the other?
Personally, if it takes more than a moment to figure out what it's trying to do, I revert to pre-2007 methods.
Regards,
Rob Philpott.
|
|
|
|
|
Query syntax is rewritten by the compiler to the same series of method calls as the method chaining syntax, so there's nothing you can do in QS that you can't do in MCS. There are a few things that look a bit neater in QS - let being a prime example - but there's always a way to write the same query in MCS.
There are quite a few extension methods that don't have an equivalent query keyword, so there are things you can do in MCS that you can't do in QS.
LINQPad[^] is probably the best tool to compare the two syntaxes.
"These people looked deep within my soul and assigned me a number based on the order in which I joined."
- Homer
|
|
|
|
|
Splendid, thanks for the info.
Regards,
Rob Philpott.
|
|
|
|
|
Rob Philpott wrote: Is there anything you can do in one syntax that you can't in the other?
Possibly Cast<T>
For example:
T record = mappedRecords[typeof(T)].Cast<T>().Where(r => r.Row == row).Single();
But I'm not sure, I haven't seen any examples using query syntax. I suppose the point though is, you should cast before you query.
Marc
|
|
|
|
|
The Cast<T> part isn't a problem for query syntax - you just declare the type on the variable in the from clause:
from T mappedRecord in mappedRecord[typeof(T)]
...
But there's no query syntax keyword for Single , so you still have to call that as a method:
T record = (from T mappedRecord in mappedRecords[typeof(T)]
where mappedRecord.Row == row
select mappedRecord).Single();
I think the method chaining syntax is much cleaner - especially if you use the overload of Single to eliminate the Where call:
T record = mappedRecords[typeof(T)].Cast<T>().Single(r => r.Row == row);
"These people looked deep within my soul and assigned me a number based on the order in which I joined."
- Homer
|
|
|
|
|
You're not missing anything. I trialled Linq functions extensively a couple of years back and they were always slower (sometimes markedly so) than the traditional methods they 'replace'. It all looks very fancy and sophisticated but it's totally inefficient.
I am not a number. I am a ... no, wait!
|
|
|
|
|
You're missing out on a lot!
LINQ can be a bit slower, but it's awesome for many use cases.
When you really need the milliseconds go for regular ADO.NET, but how often do you really need that?
My experience with LINQ is not that it's slow to use, but that people suddenly forget that their LINQ expression becomes a SQL query and start writing the most horrible, non-indexed queries, now THAT is a performance killer.
What I really like about LINQ is that you can create your own extension methods and use those to create queries that read like regular sentences, or just a lot better than SQL in general (I mean, who remembers why all those WHERE clauses are there?)
|
|
|
|
|
I think you're mistaking Linq with Linq to SQL.
Depending on the use case you might even gain performance, as an Enumerable is only evaluated when it's needed. As long as you're not accessing the items (or converting it into something other than an IEnumberable with "ToList" or "ToArray") the query isn't evaluated.
|
|
|
|
|
Nicholas Marty wrote: I think you're mistaking Linq with Linq to SQL. I know the difference very well.
I was just assuming we were talking about LINQ to SQL/Entities/whatever data source, because if we're talking LINQ to Objects there really isn't any performance issue to talk about
|
|
|
|
|
Depending on what you're doing with Linq, it can be even faster than a loop but it can also be slower by more than 100%.
If the difference matters is really up to the specific case. I'd guess it doesn't really have a noticeable impact in most cases, as a few milliseconds are negligible.
|
|
|
|