Coding Blocks - There’s Something About LINQ
Episode Date: January 25, 2014This week we’re talking about LINQ, what’s so special about .NET, the differences IQueryable and IEnumerable, and another round of “Never Have I Ever”. Oh, and jokes! Download the episode on i...Tunes or Stitcher and make sure to send us your feedback! What is LINQ? Language Integrated Query Common interface for working with data Famous […]
Transcript
Discussion (0)
Knock, knock.
Who's there?
Who's there?
Java.
You're listening to Coding Blocks, Episode 6, Something About Link.
Subscribe to us on iTunes, Stitcher, and more using your favorite podcast apps,
and be sure to give us reviews on iTunes and Stitcher.
Visit us at CodingBlocks.net where you can find show notes, examples, discussions, and more, and send your feedback, questions, and rants and comments to comments at CodingBlocks.net.
And with that, welcome to CodingBlocks. I'm Joe Zek.
I'm Mike Wattlaw.
And I'm Alan Underwood.
Today, we're talking about Link. But first, we got some feedback asking for some additional humor, hence the Java joke.
So in addition to that, we're also going to be playing a little drinking game today.
So every time Alan says, at the end of the day, grab your beer or your coffee,
or if you're Ukrainian, grab your vodka and take a sip.
Right. you know grab your vodka and take a sip right so additionally uh ken wrote in and he asked us if
we could do an episode about link or some other things so here we are uh ken per your request
this whole episode is dedicated to link so with that let's start off with the question of what
is link anybody care to take a gander yeah it's it's that stuff with the arrows and the weird SQL syntax.
It's got the select down at the bottom for no reason.
And the equal sign.
I was trying to get more textbook than that.
But yeah, we can go there, too.
I'm a candid person.
Okay, so I was just going to start off with just a definition of it being the language integrated query.
Ah, that's an acronym.
We can go to funny syntax.
I like the funny syntax.
Yeah, the funny syntax is a little bit more easy to see.
But no, it's actually a common interface for working with data.
It's all about the data.
Yeah, it is all about the data.
And it's kind of a way to be able to write SQL-type statements in C Sharp,
to be able to query things like XML, file system objects, databases.
One expression that I heard that I liked about it referenced it as code as data.
It's also known for being for execution.
It's also got this kind of cool, fluent syntax where you can say stuff like
dot where, dot where, dot take 15.
And it is known, as I hinted at strongly, for its unconventional
syntax.
It's also a very elegant way
to query and then iterate
collections.
While we were coming up with
some research in this episode and coming up with
information for it, I found this great
quote that was on Stack Exchange
that said, link enables
you to write code that expresses
the intent and not the mechanism.
I really liked
that quote because it's so
true if you think about it. When you write your code
in Link,
you don't really care about the behind
the scenes of
some additional types are being created
or storage is being allocated for it or
any delegates are being created and executed.
What you just really care about is I want you to get this data from that data
and return it and return back only this portion of it.
Yeah, and that's really important.
Like Alan said, it really abstracts away your data storage mechanism.
So it provides a common interface, which means when I'm looking at my code,
I don't know whether it's XML or SQL or file system or whatever.
It just kind of looks like this logical, easy-to-read data.
Yeah, in theory, you could actually take the exact same statement and point it to an XML file or point it to a SQL file, assuming that they have the same type entities that live in them, and it would work.
And that's a beautiful thing.
Yeah, and even better, I can actually take some stuff that's in Excel or in XML and join
it or do other stuff in combination with something out of a more traditional database.
Absolutely.
Absolutely.
So along those same veins, you were telling the compiler what to do and not how to do
it.
The implementations, the link to SQLs and that kind of thing, are what tells it how to do it.
You are just telling it what you want it to do.
Very nice.
And it's also hierarchical.
So if you think about a row set from a database, like if you're querying customers and orders and order line items,
typically what you're going to have is one row that has your customer information on it with the order information with a single line item, and that might get repeated for each line item.
Well, with link, a lot of times you actually get a customer object and then dot orders
will give you the order objects and then dot line items will give you those.
So you actually get a hierarchical view of the data, which is very nice.
And it can also be fantastic for also
building collections like XML documents or things like that. And this is probably one of the
lesser thought about features of link because most people think about getting information and
iterating through that information. Well, you can actually create an XML document pretty easily by
creating a list and doing an add to the list and then converting that list into an XML using link.
So it's pretty easy and nice looking syntax to be able to do the same type thing that would have been nasty with like an XML document builder.
Absolutely.
It actually starts looking a lot like regular old English. Depending on who you talk to, there are a few people that aren't too fond of the syntaxes,
but we'll talk about that in a little bit.
You don't actually have to take our word for this.
There are actually some really high-profile projects that make serious usage of LingQ
and would look a lot different if LingQ weren't around.
The big one is probably Entity.
Good luck writing Entity without link.
Also, Mock, which is a library that Ken mentioned
and has messaged us, it's used for testing,
and it makes a big use of link,
and we're going to talk about that later,
in a later episode, actually.
There's also a new aspect-oriented library
that we just got familiar with called Aspectacular,
which makes
a big use of Jlink.
Hold on.
I got to stop saying usage. Hold on here.
So I guess we should drink.
Yeah. Drink.
Whenever Joe wants to start over again, it's time to drink.
Link to SQL, Link to XML.
In addition to those, there's also some cool ones
like Link to S3 and link to Flickr that
lets you treat those just like...
I think link to Flickr is probably the most popular of all, right?
Yeah.
I hear a lot about that one.
Yeah, maybe like 10 years ago.
It's more than entity.
It's big.
I still got a pro account.
So what's so special about.NET to where we get link in.NET?
That's a good question.
I actually spent a lot of time trying to figure this out.
So if Link's so awesome, why doesn't Java have it?
And so I did some researching and tried to figure out what it was exactly about.NET that was so special.
Do I need to go back to my knock-knock trip?
Yeah, we're kind of hating on Java today and other days.
And kind of the parable that I had heard about Link was that someone kind of stood at a whiteboard,
and they're like, this is what I want code to look like.
And they wrote this stuff out, and then they kind of reverse-engineered it from there to figure out how to make it work.
But what I thought was really cool when I was researching this is that there's no one magical cool thing about Link.
It's actually a combination of a bunch of different features,
and you'll probably hear us get a little tied up talking about this on the podcast sometimes
because it's hard to distinguish sometimes between the features that make up Link and Link as a whole.
And so for the next little bit, we're going to talk about the actual parts
independently so so do you mean like for example uh the lambda expressions in link right that is
actually a lambda expression is not link yeah what yeah you can actually do something weird like, say, set var x equals, you know, parentheses, that weird arrow sign, you know, console.writeline.
And what you're really doing is just the C Sharp compiler is providing you a shortcut syntax for writing a delegate.
And that's the real key here is being able to use delegates in C-sharp. And I think that's part of what also makes this conversation, just in general, when you're talking amongst developers,
sometimes it kind of makes the conversation get sidetracked because so often you find when you try to have a conversation about link,
lambdas come into the conversation.
And for those of you who don't know what a lambda is, it's that that and believe me i it was like a black hole the first time i saw one i had no idea what
i was looking at and i got lost for hours trying to figure out what in the world was going on but
it's the equal sign with greater than afterwards and all that means is this goes into so that is
a lambda operation uh so yeah i mean i've tried to like come up with ways to
explain that to people over and over but you know the goes to is one that i've seen over and over
but uh you know another way i've seen is like whatever's on the left is are the you think of
it as if you go back to just a generic uh delegate type right? Whatever's on the left are the parameters
that are going to be passed into the function on the right.
Yep, exactly.
Yep.
It's just a completely new way of looking at it.
It's a totally different syntax.
And it is hard to read at first, I admit.
I love it now because it's so concise,
and like Alan said, it's expressive,
so you can say a lot with a little.
But the first time you're seeing that kind of crazy arrow, it's a bit disjointing.
Yeah.
So then if this is a conversation about link and we're talking about this crazy lambda syntax,
then what exactly is the link part that we're talking about?
That's just the query language, right?
That's your expression in its purest form.
Yeah?
Yeah, so the lambda is the portion.
The lambda is really, I would classify it as the...
You don't actually have to use a lambda
in a regular link expression.
Right.
You can literally say from some collection where this predicate's there and that's it so let's so let's break that
down a little bit more let's say we have a a list type right and uh we'll just say from uh my list from from m in my list select uh yeah some element
right okay so uh so so then it's more like the a sequel like query syntax that's built into it
right and there's no lambda there. There was no equals greater than.
Because I'm trying to be clear about, even when we were
trying to put together some material
for this show, we would come across elements back and forth.
So in that example, there was no lambda in it.
But getting back to the delegate thing that he talked about the important part here is that entire thing is really a delegate
yep and it's funny we are we actually already slipped up because the lambda and query syntax
are specific to the compiler so those aren't features of the clr the common language runtime
delegates yes so f sharp can have access F-sharp can have access to delegates.
Visual Basic can have access to delegates.
But those specific compilers would have to build in the support
for converting that Lambda and query syntax
over to the delegate syntax underneath the covers.
Cool.
And I think what Michael was kind of getting onto there
is that if we didn't have the Lambda and query syntax, we could still
have a link. It would be a little bit uglier, but that is just a small piece of the pie.
So I'll throw this question out there then. Behind the scenes, so you have this from M
in my list example that we gave, right? Behind the the scenes what do you think is happening so uh there's these things called um delegates funk action and predicate these are methods
that are delegates so they act as function pointers and they also take in generic parameters
and output generic parameters so it's a really big abstract way of saying that these are
totally general methods. So we touched on another feature of the CLR there, which is actually just
anonymous types of methods. But really, there's nothing so special about those. Those are really
just kind of delegates. And we also talked about the function action and predicate methods or delegates and
those wouldn't be possible without generics so there is one other thing for the for the clr and
we don't want to talk about too much here because it's kind of a black hole but there's also these
things called expression trees which let you treat your code as data so just to recap for the clr features we've got delegates generics anonymous types and methods
the funk action predicate and then expression trees yep and i don't think that you could have
link without any one of these things no it definitely uses all of them heavily right and
and next up we've got what i kind of categorize as the C-sharp features. And these are things that are nice. This is the sugar.
But you could live without any one of these things.
And the first is the Lambda Creates Blast.
Nope. Can not live without it.
That's true. It would be rough.
I've grown way too attached.
I do have a special fondness in my heart.
I may have fallen in love with the method.
I'm just saying.
And which one would that be?
Is there a song about that?
There's also type inference, which is like basically the var keyword you normally think of it.
But one thing about Java 1.8 that's coming up, they've got some lambda functions coming, but they don't have type inference so whereas we can just say parentheses x arrow
x dot do something they've got to say like string x arrow x dot do something
nice and so it's that big ugly word right there in the middle and so technically we don't need it
but it's really ugly without it yeah it really makes your code a lot more readable when you just put var in there.
There's no doubt.
Well, not only that, but going back to previous shows where we've talked about interfaces and generics
and just the whole concept around just trying to keep your code loose.
Yeah.
Not having to explicitly define that type and just let that be decided at runtime is so much nicer.
Yeah.
Yeah, specific to link, I always end up changing stuff from I list to I enumerable back to list and over and over again.
And it's nice that I don't have to go and change anywhere that I reference it because I'm varring it all over the place
and they've all got pretty much the methods that I need to use anyway.
Right.
Now, there's one other feature of the C Sharp compiler that I identify, which is basically extension methods. Right. sugary way of doing stuff. And the actual major link methods that we think of, like with the.where and the.forEach
are actually all implemented as extension methods, which we could live
without. We could have had an
innumerable class that implemented this stuff, and if you wanted to use link
then you could inherit from that, but then, as we talked about specifically in the interface episode, you only get one parent.
So you really don't want to tie that up if you don't have to.
Yep.
And so the next thing we're going to jump into, like, what are the different types that you can get back from a link query?
And there's really two main ones.
You have IEnumerables and i queryables
ding ding ding weighing in in this corner and a hefty 10 characters i query about so uh this was
this was an interesting topic of discussion before we actually started recording the podcast because
it's it's a little difficult to describe some of these things just outright in words
and and one of the things just outright in words.
And one of the things that we realized pretty quickly.
But we're going to use our words.
We are going to use our words.
And one thing we found real quickly is just saying something slightly different can mean worlds different when we're describing these things.
So we're going to talk about I enumerable first,
and then we'll talk about the difference. We'll kind of compare and contrast what happens. So,
so let's take what he said earlier. So you have from M in my list, and then let's say,
uh, I don't know, let's do orders. Cause that's just easier easier. From O in orders where order total greater than $50.
All right.
So you have that.
You can return that as an I under rule.
You can return it as an I queryable.
On the surface, they both have the same exact syntax.
And essentially, if that was the only thing you were ever going to do with them, they would both act exactly the same. And we're going to talk right now in terms of database because this is where you can really demonstrate the difference between an IEnumerable and an IQueryable.
So if that was your only statement ever from O in orders where order total greater than $50, these are –
What are we selecting?
Huh?
What are we selecting?
We're going to select order, right?
So now pretty much that's going to be deferred.
The first time you go to use that, on either one of those,
if you never had any other statement referencing
other than like maybe doing a to list or something,
then they would both act exactly the same.
Where it gets interesting is when you get into IQueryable.
So let's say 10 lines later.
Yes.
We still have this var that has your from statement.
Mm-hmm.
And –
We'll call that my orders.
Okay.
We have var my orders equals from o in orders where o.order total greater than 50 select order.
Yep.
Right?
Okay. Now, let's say 10 lines later, we want. Yep. Right? Okay.
Now, let's say 10 lines later, we want to reference this my orders var,
and we want to do a.where on it.
This is where IEnumerable versus IQueerable gets interesting.
Absolutely.
Okay.
Okay.
So, in the case of the IEnumerable, like Alan said, it hasn't been executed yet,
but now we do the.where, and however many orders are in that table are going to come back.
Yep.
So if you've got 1,000 of them, you're getting 1,000 rows back.
You're going to execute a SQL statement that's going to get all those orders and bring them back and then in memory whatever your line later
your dot where was that's where that's going to get applied but isn't that one of the big selling
points of entity is that it's supposed to be smarter than that and it's only supposed to
fetch the stuff that it needs well entity actually does return iqueryable so it does that for you
behind the scenes so the difference is if we're talking about link to sequel purely and you're returning you're telling it you want an i numeral back
instead of an i queryable um and you could actually cast it as an i numeral you actually
when you do his next dot where so first we said give me all orders that were what we say greater
than 50 greater than 50 all right so now let's say that out of that subset, we want to say, hey, well, we want to look at all the orders that were just over $100, right?
Or better yet, we want to find the orders that were placed by Alan.
Okay, so now we're going to say from O in my orders where customer name equals Alan.
So the I enumerable at that point is actually going to go get back all the orders
that were greater than $50 from that first statement. So if there were a thousand orders
in the system that were over $50, you just got all thousand of those things back. And now you're
going to loop over all thousand of those to find out where the customer name is on with an I
queryable where this is just beautiful is that is actually going to say, okay, well, they're actually trying
to pull from that original one. And now they're trying to add another, uh, another where clause
to it. I queryable is smart enough to say, okay, I'm not going to go to the database and get those
original thousand orders back. I'm going to say, okay, let's append to this where clause and say,
okay, where it was just order total is greater than $50,
now it's going to be where order total is greater than $50
and customer name equals Allen.
And it's still not going to execute the query until you go to use it.
I mean, if you're lucky, it'll sound that easy.
It'll probably be something like extent one brackets.
Oh, burn.
And that is a good point.
It's really up to the library writer to make that happen.
Yes.
There's no real magic about iQueryable.
And for me, part of the big confusion that comes along is that iQueryable actually implements iEnumerable.
So it's fair for you to say that, hey, entity returns me an iEnumerable, but it's doing the smarter stuff under the cover.
What the heck?
But it's really because i i-crabble implements
but does not extend i-enumerable it seems like it's an insignificant thing but it can have
huge impact on performance at the end of the day it oh jesus everybody drink
so um it is a very important feature to be aware of if If you're doing IEnumerables, just be aware that it is deferred rendering,
but the first time you go to use it, it's going to get back that first result.
With the IQueryable, it'll try and stack on,
and this goes back to what Joe mentioned a minute ago about the expression trees
where IQueryables keep building that expression tree.
The IEnumerables do not.
So if you go to use that variable, it's going to,
it's going to execute the original query. Now, I mean, there was one statement in here that,
that I like to know, you know, you can argue whether or not you agree with it or not, but it
was among the notes that we found, you know, IEnumerable is best to query data from in-memory
collections like lists and arrays, while IQueryable is best to query data from out-of-memory collections like lists and arrays, while iQueryable is best to query data
from out-of-memory collections
like remote databases and services.
Yeah, I think that actually sounds pretty...
I thought that summed it up pretty well.
For the way I've kind of justified it to myself,
which may be wrong,
but the way I think about it is iQueryable,
the point really is to generate a query,
whether it's for SQL or XML or whatever,
it's supposed to generate this thing
that's going to go and get my data.
Whereas IEnumerable,
I tend to think of it more along the building block
kind of level, like this method does this,
this method does that.
And it's all kind of happening in my code,
whereas IQueerable is using these weird expression trees.
Yeah, IQueerable generally builds the statement that's going to be issued to
whatever the remote thing is whether it's a database or whatever that like Joe just said
the other is kind of just going through a step-by-step process right right so like iNumerable
exists to to loop through my stuff and filter it and and do a lot of other stuff but iQueryable
really the point is to do all that other stuff, but also the main deal is really to
generate that SQL query for entity, for example.
Absolutely. So hopefully that isn't
too incredibly confusing and hopefully we've somewhat summarized that
to a point where it at least makes a little bit of sense, especially
if you listen to it like 20 more times.
Yeah, by the fifth time we've talked through this scenario,
we've gotten much more civil about it.
So that's just something.
I'm not saying that anyone threw down.
I'm just saying.
Yeah, I mean.
It might have, you know.
Might have been a little heated.
Not seeing eye to eye.
Actually, the great part is we were all arguing,
but we were all coming to the same exact conclusion.
So it was entertaining.
Sorry you missed it.
It's tough to talk about Link intelligently.
We're proving that.
Speaking of.
Thanks.
We're coming to our tough questions section where we're going to kind of talk about some of the just the kind of the weird little corners of link like deferred execution so what do we mean by deferred execution we kind
of hinted at a little bit where you know you can you can have your your collection and then
kind of say dot where then dot where then. And none of that stuff actually happens until you actually need that data.
So, like, in this example, the first would do it.
But it's not actually going to loop through and do your work until it needs to,
which is really nice in cases where, you know, you don't need that stuff
or you want to keep adding on conditions.
You're not doing anything inefficiently.
But it's also kind of tricky.
Yeah, I mean, if you're not doing anything inefficiently but it's also kind of tricky yeah i mean if you're not aware and aware geez if you're not aware of the deferred then i actually had this happen the
first you know time i was working with link so i'm like why am i not getting data back something's
wrong with this and i didn't realize that that just, you know, it was waiting for me to actually do
something with it. And you'll see a lot of times for better or for worse, a lot of people just
throw a dot to list on the end of a link query so that it forces the eager loading and turns it
into something that you can use. And, you know, maybe that's fine in most cases, but I wasn't
aware of it. And so I'm just over there'm just over there yelling at my computer thinking that there's something absolutely wrong
when I just was not aware that it was not loading it because I hadn't used it yet.
Right, and I actually ran into this just a little bit ago today
because I wrote some code that was doing some stuff,
and I knew that it was the whole point of the code I was trying to check out
was to kind of see what happened when it did evaluate,
and here I am stepping through the debugger like,
what, what?
What the heck?
Nothing wrote off the console.
And it was embarrassing and I shouldn't have shared.
Do you feel better?
Might or might not have been in preparation for this.
Right.
But one thing specifically that was a big help for me researching this episode, whether you can tell or not, was actually the book C sharp in depth. And that was written by the amazing John Skeet. And he gave this awesome
example in the book of streaming. And he talked about sequences. And so what that meant to me,
in reference to deferred execution is, if you see something, you know, my orders dot where today and where order value greater than 500.
Like when you read it, it makes it sound like you take your orders, you get the ones from today, then you get the ones that are greater than 500.
But if that were the case, then deferred execution wouldn't matter.
As soon as you slap that where on, it could happen and the outcome is the same however because of this deferred execution
we can actually do something a little cooler which is basically stream the items which means
we can say take that first order was it today no all right take the next order was it today yes
was it greater than 500 yes so yield that output So it's really this deferred execution that lets us kind of add stuff on later and get the benefit via the streaming.
Oh, you just mentioned something that completely slipped my mind.
The whole reason iQueryable works the way it does is the yield statement.
And I had completely forgotten about this, and it's been quite a while since I even remember looking at yield.
But it basically means return to this after,
or return to the next line after you're done with a chunk of code.
And that is actually how iQueryable functions.
The reason that it doesn't eager load everything
is because it uses that yield statement in its implementation.
Yeah, and the yield's really cool because it kind of keeps track of where it is so it's taking care of a lot
of stuff for you that you don't need to yeah so uh moving on from there sorry about that uh
ah that reminds me so speaking of um these kind of uh greedy operators that actually force the
evaluation and force that execution.
If you guys are using ReSharper, well, first of all, if you guys aren't using ReSharper, you probably ought to be.
I swear I've learned more from ReSharper than I have in a million blog posts and Stack Overflow questions.
But ReSharper is awesome.
But anyway, if you've got ReSharper, sometimes there are some kind of strange little squigglies that will show up when you're dealing with the link.
Particularly the one I'm talking about is the multiple enumerations.
I feel like we've talked about this one before.
I think we have.
We have.
Yeah.
This one will get you.
Right.
And so what that's letting you know is that you could actually be forcing the execution twice.
And I'm really glad that ReSharper lets me know,
even though a lot of times I either don't care or I don't think that's happening.
But it is nice to know that if I do a.count and then a.foreach,
that if I've got a query backing my collection,
then I could be executing that twice.
I am executing that twice.
Or even if you're doing in-memory.
No, actually, if you're only doing the query, that's the only time that happens
because it has to go back and get the data, right?
Well, it'll complain about it.
I mean, if it's an IEnumerable, it doesn't care what the source of that is.
It's just saying, like, hey, it's warning you that there's the possible multiple enumerations.
Right, and so the key takeaway from this is if you need to count,
you should probably go ahead and iterate over that collection one time
and do whatever you need to do to that data and get the count at the same time.
And then that way you're only hitting it once.
Or maybe you shouldn't be using an innumerable if you didn't need to.
Good point there, too.
Was that your case, Jeff?
We'll get to that.
Well, actually, the whole thing with deferred execution,
I see that as being a tradeoff between really great performance and predictability.
There's definitely some weird stuff.
And one of the weirdest things that I remember seeing,
maybe it's not that weird if you know what you're doing,
but is I actually had cleaned up the DB context in an entity situation.
And so I did my open context, I did my get stuff,
and then I closed context and returned my iQueryable.
And then later I tried to use that data.
I tried to loop through it and lo and behold
the contacts had been closed does not exist does not exist and I couldn't figure out what was going
on it's one of the scenes where it's like I know about link I know about deferred execution I know
I know not to do this and then I spent a half hour trying to figure out what the heck was going on
yeah it can be frustrating too I mean if we're specifically talking about entity
the beauty of iqueryable
is also one of the frustrating things is you actually have to have almost like a wrapper db
context to be able to use it properly like if you're trying to return an iqueryable from one
place and then use that in another place you can't throw your iqueryable into a using statement in
your original case because when it gets returned out the context
is gone so you can no longer stack on top of it which is exactly what joe's talking about
but it almost defeats the purpose of using iqueryable in the first place so don't use using
wait what just leave it open um i'm pretty sure that's not the takeaway we said more jokes right
oh okay do we drink?
Well, at the end of the day.
At the end of the day.
So at the end of the day, the Lambda syntax is superior.
It's far superior.
Oh, let's not go there. I think we're onto something there.
All right, so there's definitely going to be a boxing match in this one
because I'm in love with what they call the comprehensive language,
which looks like SQL. You know, I would be love with what they call the comprehensive language, which looks like SQL.
You know, I would be down with the comprehension language
if and only if that select statement could go first like it should.
But no, no, no, no.
It can't.
It can't go first.
It doesn't SQL?
No.
Well, yeah, but you have the same problem in SQL that you have if it went first.
I have no problems.
That's that you would have no type of head support you have to it had the the the compiler needs to know or the the dev environment needs to know what
you're going to be selecting from in order for the type of head to work oh oh yeah fair enough so
select statement has to be last but that still doesn't do anything for the lambda versus
comprehension right that doesn't matter well that's all the more reason why
we're supporting my Lambda case.
We don't have to worry about this crazy sequel syntax.
There's no tab of completion
if we don't know what we're getting it from.
Yeah, I'm on board with that.
I'm with that, but you still don't need Lambda for that.
Well, maybe not, but it's still
my preference.
I mean, it's readable.
I actually do a mixture of the two.
I know Outlaw Simicoe probably has as well.
But I love the whole idea of from O in orders.
And then if I want to do a join, I just say from O I in order items,
and then.where, which is my clause,
and then I say OI.orderid equal o.orderid and then so
basically i've got the best of both worlds now i've got the comprehension syntax mixed in with
my lambda it's just beautiful okay but okay so that's that's fine and great and and i'll i'll
give in on that one that if i am if i'm writing queries that I want to go against database,
so we're talking more entity-related.
No, more links to SQL, because if you're doing true entity,
you should actually just be doing object joins.
You really shouldn't even be doing that much on query language.
Okay, well, let's just put it to,
if I'm doing a query from a database, then fine.
The query syntax, I'm okay with.
But what about if it's not database related?
What if it's just like lists and collections of some types that...
Comprehension with Lambda.
I mean, I'm Lambda all the way.
You know what?
I got to say, you know, Alan may mix his tabs and spaces but uh you know he's got
me on the join joins and link syntax are miserable every once in a while i look them up i'm like
there's got to be a good way of doing this and and i'm just going to uh the dark side writing
the comprehension style but mixing is just weird oh mixing is so beautiful. Yeah. It really is.
I'll tell you what.
In a blog post I'll put up, I'll show you the three different ways to do it, and then you can decide.
And I guarantee you're going to pick mine.
Oh, I've got a feeling I'm going to be wrong here.
Oh, God.
I'm almost afraid.
Yeah, it's beautiful.
It's a thing of art.
All right.
So, well, obviously, you know, we mentioned one downside of link, which was the comprehension syntax.
But are there any other downsides or things you guys should be aware of?
Well, actually, hold up.
Before we move on from there, I will say, though, as much as I love the comprehensive,
there are things that you can't do with that that you can do with lambdas, right? Like if you have a function that's doing some sort of mathematical operator or some sort of needs to return something crazy, you can't do that.
Because with comprehensive syntax, you have select, you have where, you have from, you have various keywords that are baked into it.
But outside of that, if you need to do anything special, you pretty much have to use a lambda.
So I think what you're saying is the lambda syntax is superior.
If you mix it in with comprehensive.
I think that's what I got.
But if you mix it with comprehensive, you can take over the world.
I didn't get that part.
We've got to see the blog post.
Yeah, yeah.
I have to get that together.
So, yes, moving on.
All right, so some downsides.
What might be some downsides? and allusion to this a minute ago, with the entity expression or whatever it spits out in the query.
Oh, the extent?
The extent. Oh, wow.
Extent 1 from extent 2 got joined on extent...
With 20 subqueries. It can be really disgusting.
See, and this is where the comprehension language like like i think that kind of falls apart because like if you write uh well i guess specifically to entity a a from statement and
you try to do a join on that and you use the join keyword yes it's horrible you will get some of the
grossest sequel yes spit out of that thing that you've ever seen. I agree. Now, it may work. I'm not going to argue that it doesn't work.
But is there a more efficient way to write that SQL statement?
Yeah, more often than not, that's not the way you would have written it.
Yeah, it's interesting.
So that's one of the things that really kind of bugged me
and was almost a barrier of entry for me because I'm a fan of SQL
and I love databases.
So when I got into this and I saw the SQL, it was writing out, like, I think I had some short circuits in my
brain. And so I ended up starting doing this like 10 different ways to find out what actually wrote
SQL like I do. And, and so that's one of the big things that I wanted to point out is you can't
just go willy nilly writing this stuff and not
thinking about the impact that it might have. So if you're doing large inserts, like I actually
ran into a problem with this at one point where I was doing an insert where I was moving thousands
of records from one place to another. Depending on how you write your link statement and whatever
extensions that you use at the end of that can really determine whether or not it's doing 2,000 inserts
or it's doing one insert with a bulk copy over.
So you really need to be aware of what you're doing behind the scenes.
So you probably want to run something like SQL Query Profiler behind the scenes if you're doing anything special.
Yeah, I was going to say it almost it like uh you almost really want to run
a profiler or at the bare minimum uh run through the debugger and see what the actual uh query is
going to look like just so you can see like uh does it pass the gross uh you know uh you know
what's the gross factor of the query that it spits out you know absolutely yeah it can be it can be
disgusting and it's something that you need to pay attention to if only there was a tool that of the query that it spits out, you know? Absolutely. Yeah, it can be disgusting,
and it's something that you need to pay attention to.
If only there was a tool that would let me write my SQL syntax,
and then it would convert it over to link syntax.
Ah, yeah.
If you find one.
Yeah.
So one of the other things that is something to be aware of
is if you are working on highly transactional systems like in SQL Server,
one of the things you might use is with no lock on a table so that you're not locking the rows when you're reading, inserting, updating, that kind of thing.
And so that's a nice helper in SQL Server to keep the table from being locked down from doing other reads.
You cannot really control that
at a granular level if you're doing something like link to sequel or entity you might be able
to do it on the entire set but you won't be able to do it on on an individual table basis so i do
find it like it seems and maybe this is just me so you know feel free to write in and and argue
your point if you disagree but like uh if i'm if i'm going to. But if I want to do SQL,
if I want to do some kind of a database query in LingQ,
if they're simple, then it's okay.
But the more complex it gets,
then that's where it seems like it still isn't quite there yet.
Yeah, it can break down.
You got any thoughts on that, Joe?
CTEs.
Yeah, absolutely. Try and do a recursive query in a in a link and don't tell me extension methods because that's cheating
it's not the same thing you're not building a cte you're now basically doing what we said earlier
where you're pulling back data and then you're going back and getting more data and going back
and getting more data so um you can't actually take advantage of
the beauty that is a hierarchical cte in sql server yeah yeah so um uh what do we have oh
another one and this one kind of bit me when i first started doing this so web api uh anything
that's returning stuff uh you pretty much need to be aware of that deferred execution. So if you're not to-listing it
or forcing some sort of eager load like a first,
you're going to get some nasty errors
saying basically, like, you can't do this.
Well, this goes back to Joe's example
of his DB context already being disposed of
by the time he actually wanted to run that Iq variable.
And that's the same exact thing.
That's how you needed that connection.
That's the same exact thing that happens.
You return it, you think it's all good.
You could even call the code within yours and it works fine.
But as soon as that web request is essentially killing that thing.
So it's saying, hey, you can't run this.
You already closed it.
So you will run into many great headaches
if you are not fully aware of your deferred execution.
Yeah, absolutely. And one thing I'm really guilty of with Link is great headaches if you are not fully aware of your deferred execution yeah absolutely and uh
one thing i'm really guilty of with link is um for some reason when i'm doing a for each i don't
have a problem checking if my stuff is null right it just kind of makes sense like loop over something
if it's not null do it whatever but once i start doing that stuff and then like a for each or or
aware suddenly for me those null checks go right out the window.
You'll never see me writing code like my orders dot where x is not null and x dot date is today.
I don't even think about it because I'm starting to think about the code logically
and I'm forgetting about the kind of code underneath it, what kind of crap I might have in my list.
See, I can't say that i've done it
and maybe we'll come back to this in a minute but i definitely have done that a lot checking those
yeah there's there's a lot of and i'll give you some examples in a moment but um specifically as
a downside to link you know there was another example that I've ran into, and this is,
again, you know, we're talking about querying, you know, with entity.
One gotcha that has definitely bitten me is that if you needed to do any kind of date math in your query, it'll compile. You can write it. It'll, it'll look beautiful. It'd be exactly what you want.
But, uh, when you go to run, you'll get a runtime error. And so what I mean by date math is let's say like you were just wanting to get the orders from the last 10 days. And so you did a, a date
time dot now dot add days minus 10, right? It cannot handle that. Now, what you have to do in that situation is have a separate,
uh, variable that has that, uh, you know, that has that expression already saved in that date
already saved in it. And then you could, so like, for example, if you did a, uh, VAR, my date equals
date time dot now dot add days minus 10. And then in your from statement,
from O in orders where O.orderDate greater than my date,
that'll work just fine.
And you can pass that date in and it'll work fine.
But if you want to do any date math in it,
no, you'll get a runtime error.
And that one's bitten me a couple times.
Because it just looks so right.
It does.
Speaking of the kind of null checks and this kind of multi-statement stuff like that,
that Michael was kind of talking about,
one thing I think is gross is if you come in and you've got a statement that's going through
and getting the orders for today,
oh, now I want to add the null check in there.
So I add that there. Oh, now I want to add the null check in there. So I add that there. Oh,
now I want to add some logging. And so now that's when I start adding the brackets in there. So I
can do multiple lines and like a four each or a dot where, and at that point, uh, you know,
I was going for readability and now I've got this kind of like weirdo monster thing with
like brackets and it's not really a loop. It's happening at once,
but it just gets kind of ugly.
And the whole point of link is to deal with this stuff simply.
And so there,
yeah,
Lincoln get pretty nasty,
pretty fast.
Yeah.
That's always,
if you've ever seen like a,
you know,
a four each with like 20 lines in it,
you know what I'm talking about?
And also one thing that kind of gets me sometimes I forget about is
to list creates a copy of the list, which isn't a big deal,
but it's just sometimes it's really convenient.
If you get an IEnumerable back and you want to do something
that's specific to lists on it or IList,
then you end up calling to list pretty often.
And I'm not even sure what function it is in the list that I want so bad,
but it seems like I'm frequently calling to list and creating copies of my
stuff all over the place.
And that is forcing the execution as well.
So with that,
I want to play a little game here.
We've done this once before back in our,
our source control episode.
So now let's do it here.
A never have I ever.
So I'll start it off with my lambda expressions are always just a few lines.
Oh, I think I just admitted to that.
No.
So you're guilty.
What about you, Alan?
Yeah, I've got pages of them.
Yeah.
Nulltex are a slippery slope.
I can definitely think of one as an example where, in my defense, this was a get-only property.
And it, you know, by design, I meant for it to execute some code.
But that Lambda expression definitely was on – it took the screen to basically see the whole thing.
Are we talking about like a 2560 resolution screen?
No, fortunately it wasn't anything crazy like that.
It was just a 1080p screen.
So it's not too insane in terms of computer screens.
But yeah, it took the whole screen to be able to see the entirety of it.
But yeah, I'm bad about that.
All right.
So next, my lambda expressions are never mixed with comprehension and vice versa.
Never.
That should be the rule.
What?
That's crazy talk.
Alan's turning bright red right now.
He's so embarrassed.
Like I said, outside of doing entity, okay, if we're talking entity, okay, fine.
But outside of that, I don't find myself doing that that often.
Because you're not joining enough.
Why even use link at that point, right?
Well, I just find myself using the extension methods in the lambdas more often
that I'm not using the link syntax specifically in that scenario.
Yeah, I feel like I'm setting an artificial boundary for myself there.
You guys will catch on.
Nobody's perfect.
All right.
So, okay.
So now that I have linked to SQL, I never, ever have to write, use SQL directly again.
Ever.
I like SQL.
What's wrong with SQL?
Yeah, I'm a fan of SQL.
So then we all agree we still write SQL even though we've got link to SQL to do it for us.
Those CTEs.
Yeah, especially with the recursive CTEs.
I don't hate data tables, so I'm sorry.
Or even another example that I have here is if you wanted to select into and then query a temp table, that's another problem, problematic area. Yeah.
You know,
where sometimes it's just more efficient and easier to just write the SQL
statement, whether,
whether you do that in your code or whether you have a stored proc that does
it for you.
How are you going to do something like a row number function in SQL server?
Would you even be able to do it? Oh yeah.
I mean like if you're going to try and do a paging data set and you want to
rows 100 through 150, I know you can do, you know, you can say take and all
that, but, you know, CTs and row numbers are pretty effective ways of doing
things.
Is there anyone in our audience who can do this?
We'd love to see it.
Yeah.
I don't think it can be done.
Prove me wrong.
And then we promise we won't copy and paste that code.
All right.
So how about this one?
I've never written my first version of a for each or for loop only to refactor it as a link slash lambda expression.
I've done this and I don't know why.
Oh, I do it all the time.
Oh, my God.
It refactors the reason.
Or resharper. Jeez. Oh, I do it all the time. It refactors the reason. ReSharper, geez.
Oh, yeah.
Well, that happens so often.
Because just in my mind, there will be times where I'll write it out and I'll just think, well, you know what?
I have this.
And for all of these, I just want to loop through these.
And so I'll just kind of write it out the way I'm thinking through it as I'm talking through it in my mind.
And then ReSharper will complain and say, yeah,
you could actually redo this better as a link expression.
Yeah.
And they're right.
Usually they are right.
Yeah.
What's weird about it is like,
if,
if I'm right clicking and like,
what does it say about me?
If I'm refracting,
there's a leak expression.
It's like,
I couldn't think it to make it.
So presumably it's not as readable either.
And here I am doing it.
No,
I will say this though.
On the inverse,
I've definitely taken one
of my comprehension queries and said convert to a lambda and then i'm like undo control z this is
disgusting just just a note i will yeah so uh what about an egregious use of to list? I do it.
I'm really bad.
I'm reaching out to somebody like, hey, this is going to be an innumerable, and I'll do it, and then later I'll need it as a list, and later I'll need it as a list, and later I'll need it as a list.
And I'm just to list crazy all over the place.
Lists are so awesome.
What about if you used a list instead of an innumerable?
Okay, so I do that when I get tired of doing to list to list to list and then i just
feel those guys i'm like so one problem cascades into the other yeah so what is it about list why
do i need a list instead of innumerable what am i doing so wrong i think i think what your
problem could be solved here is that if in your your method declaration if you could use the VAR keyword as the,
as the signature of the method,
then you'd be okay.
Oh yeah.
It's for each.
That's what it is.
I am addicted to for each.
But you can do that with an I enumerable,
but you only want to do it once,
right?
Can you do with I enumerable?
Yeah.
Sorry,
Googling.
I don't understand the difference.
I got lost on what the question was.
Maybe I'm wrong.
If not, I don't need to be doing...
Well, no, the difference, though, is if you have a list and you iterate over it with forEach,
then it's not going to go back to the database if you're using an entity or something.
But if you're using myEnumerable, it will keep pulling from the database.
So it'll keep pulling, but there is no for each method.
You cannot say my enumerable dot for each.
Oh, dot for each.
Yeah, sorry.
I was thinking what Alan was thinking.
I was saying like for each var in blah, blah, blah.
Yeah, okay.
No, I'm talking about the for each method.
I'm addicted to the for each method.
I said it.
Do you feel better?
Yeah.
That's out there now.
That was going to last. So about uh egregious casting so uh this one this one i've done this so many times like i'm also bad like
if i have a okay so here's the example is like i'm i'm working on some uh you know older code and for whatever reason you just can't change the type so
to deep down in it it's using an array of something and uh and i'll do like a dot cast
and then uh you cast it as the actual type that i know that it is in there and then
start doing additional you know run have some big lambda that runs after that.
Yeah, I've actually done some gross stuff where it's like,
I'll just need to do a simple where on like an array list.
And I'm like, I could loop through it and just do it.
Or I could convert it to a list.
And just cast it over to any rule.
I feel like the to list is coming back up.
And all of a sudden, I've done all this extra work,
but I've got it down to one line of code.
All right.
So what about falling in love with a link method?
Default if empty.
Default if empty.
My favorite.
It's like a live join.
That's all it is.
Of course, Alan would bring in a database example.
I love first or default.
I want the first element.
If it's not there, give me null.
I don't want an exception.
I don't want to have to check the link.
Oh, God, I hate that.
Just give me what you got.
But this goes against your null checking principle, though.
Because now if you did a dot first or default and then a dot something else.
It's going to fail.
Oh.
Yeah. That's true, but I'm okay with a fail.
Because I got a try around it.
You just put a try
at the start of your main and then that way
the whole thing is caught.
No problems. Fail safe.
So the deal is
I'm going to end up doing that null check anyway.
So even if I did,
if my orders.
Yeah, but in that example you couldn't though.
I could.
Not if you did a dot first order default dot and first order default returned a null.
Oh, no, I wouldn't do that.
Yeah, that wouldn't work.
No, first order default is.
I like the way you waved your finger when you did it.
No, no, no.
There's a semicolon after your first order default.
Yeah, absolutely, semicolon, and I checked null.
And the thing is, if I said if length, then get element,
I'm still going to do that null check, or I should,
because you can add null elements to a list.
So it saves me that if and the two brackets,
because you should do that all the time.
Three lines of code saved by first or default.
Thank you very much.
So here's an example where earlier I mentioned where a lot of times I am checking for the type, maybe null or empty.
And my favorite, or one of my favorites, is the.aggregate.
And quite often, like, as I'm aggregating through that, I'll check to see what is the current value.
What does its state look like?
And what am I trying to add to it?
What might it look like before I do anything with it?
Aggregate is so cool.
I wish I were better at it.
The few times I've used it, it's been fantastic.
I don't know what it would be.
It would be a real pain to do it otherwise.
But, man, I wish I were fluent.
So how about this one de-anonymize your lambdas no never have i ever no now see this this also brings in the question of when should you
de-anonymize your lambdas like like, okay, that example that I gave, it was
took my screen
to see it, but it
fit. When is the
right point where I should say, okay,
really, this is a lot
of lines of code. It really should belong
in a method that I might want to be able to recall
from something else. Oh, we've all done
it, right? Now, in that example, though,
that I gave, never ever wanted it anywhere else i only needed it right there that's why it was there but it
makes your link statement absolutely disgusting to look at right like you can't even find the
beginning and thought it was beautiful yeah the example i saw in the c-sharp depth book was
actually a place where he was doing the same thing three times so if you can imagine like
you're doing some sort of logging
and you're doing console.out in three different places
and always outputting the value,
then you could set that actual anonymous method to a variable
rather than going through the overhead
of creating three separate but equivalent anonymous methods,
which has a lot of overhead.
Okay, so then we're drawing the line, then,
as if you have to do it a second time.
If it's reusable, yeah.
Now, if you only have to do it one time and it's 1,000 lines long, you're okay with that?
I might put that 1,000 lines in a method.
Actually, I would have a lot of problems with that.
First of all, why is it 1,000 lines?
I love methods of methods.
Methods with nothing but other methods in it.
All right.
And last of our never have I ever cursed, the lack of where not.
Dear God.
Oh, yes.
That one's bad.
I want that N-O-T there.
I know it's the same saying where, parenthesis, exclamation point.
But I keep looking for it, too.
I'm like, where's the where not if you do you think that if you were to continue looking like hard enough like eventually
like oh there it is the documentation well sometimes i'm like maybe it's called without
or maybe it's called except no except it's something different yeah okay Or not contains. Oh, not contains.
Man.
Talk about inverse logic of SQL statement writing.
Oh, it hurts.
All right.
So now we're going to get into the segment of our picks of the week or tips of the week.
And so we kind of alluded to this.
There is a fantastic piece of software out there that you can actually get for free or if you want to upgrade at some point
you can pay a little bit of money for it it's called
LinkPad
L-I-N-K-U-P-A-D
we'll put a link in the show notes
but it's killer you can literally
take a SQL statement and turn it
into link syntax or you
can write link syntax and it'll turn it into query
I think and
i don't remember what the difference between the paid and the free version is but like some of them
will write out your sql statement your c-sharp statement it'll literally write everything out
and you can even operate on on system collections and all kinds of stuff like it's a killer piece
of software well you can actually write you can actually write the code in it. Yes. So you can create a list and then create a select in there, and it'll show you what it'll be.
It's insane.
In addition to, you can actually connect to databases and do selects in it.
And speaking of, if you get that software, I highly recommend taking the time to, I think they have a database SQL script that comes with it.
Take that and put it into a SQL Server Express or whatever you have, because a lot of the
examples in there will not run properly if you don't hook it up to it. And you can gain just a
huge amount of knowledge by just playing with the examples that they already have set up for you.
So definitely check that out.
If you're trying to learn Link and you really want to get into this stuff and believe it can really change the way you code
and it makes it a little bit more elegant and actually easier to follow,
check that stuff out.
It's a killer, killer app.
Yeah, and LinkPad Pro is actually only $39.
So, you know, we developers get a decent hourly rate.
So, you know, this thing's going to pay for itself in no time.
Yeah.
All right.
And my tip of the week, actually,
Alan turned me on to this after I kept running over my headphone cables
with my chair and then failing at fixing them.
So there's a company out there um that actually
makes there's probably more than one but there are companies out there that make headphones with
modular cables so if one cable dies you just swap it out with another one and we'll have a link in
the show notes to the pair i actually really like that alan recommended but this is really fantastic
too because i've got a long cable and a short cable. And if I'm walking around doing laundry with my big-ass headphones on, I'll use that shorter cable down in my pocket.
And then if I'm just kind of wheeling around the office, I'll use that longer cable and run the risk of running over it again.
Yeah, I can't tell you how sad I was.
I had a pair of Shure that I loved, and the cable started to to go and there was nothing i could do about it
break out the soldering iron right could do that yeah i mean at that point i was like it's not even
worth it and they were too far gone yeah yeah so with that uh my pick of the wheat is uh i don't
know how new this one is it was was fairly new to me, at least.
It was an app in the Windows App Store called Tweedium.
It's $2.99, and this is just a fantastic little Twitter client that I found.
If you're a fan of Twitter.
I just really like it.
It kind of had almost a Tweet a tweet deck like feel about it but um
it does uh live uh scrolling of the of the your timeline unlike the official twitter client
and uh so yeah i was i was a big fan of it uh twweedium. Yeah, make sure you follow at CodingBlocks on Twitter.
Yes, yes.
This is why you need this, actually.
Oh, yeah, I forget to mention that.
Hey, Marcus.
You might even go to hear something about the Alan drinking game.
Hey, we've only done one drink to that, by the way.
That's true.
That's only been the one drink?
Yes.
Well, are we counting the day or are we counting just the episode?
The day would be a different story.
I think we've given Alan a complex now.
Yeah, unfortunately.
We've definitely, every now and then,
when he catches himself saying it.
We also wanted to mention
a couple additional resources.
We said there were whole books
written about Link.
The one that I looked at in particular is Link
in Action. We'll have a link to that in
the notes. Also,
I think all of us watched Scott Allen's
set of videos on Pluralsights. He's
actually got two. We'll have the link to those.
Those are fantastic.
Also, I mentioned C-Shot.
One of them was called Link
Fundamentals and the other one was called
Link Architecture.
He did a fantastic job.
He really did.
Four thumbs up.
Yeah.
Link Architecture, yeah, we just mentioned that.
There's also the C Sharp and Neff book, which we've mentioned quite a few times.
There was another great lecture on Plur plural site that was by, uh,
I might mispronounce his name here.
Dan,
uh,
Waylon.
It was a C sharp events,
delegates and lambdas.
And that was a,
another great resource of information there.
Yep.
Fantastic.
And also,
uh,
we mentioned aspectacular a little bit earlier as an example of
link.
So we wanted to pimp that,
uh,
that's a buddy of ours who's,
who's working on that.
And it's a really cool take on aspect-oriented
frameworks so go check that out
and see some really cool
uses of link and expression trees.
Specifically, check that out on GitHub.
That's about it for this week.
We talked about link
quite a bit and we'll be putting
the links to our link stuff in the show notes.
I like how you phrased that.
Link to our link. Not awkward show notes. I like how you phrased that. Link to our link.
Not awkward at all.
Link, link.
And that'll be at www.codingblocks.net
slash episode six.
Yep, and subscribe to us on iTunes, Stitcher,
and more using your favorite podcast app.
Be sure to give us a review on iTunes or Stitcher.
And just like Ken did,
contact us with a question or topic
and leave your name and preferred
method of shout out, whether that be your website, Twitter account, Facebook, whatever.
And if we use your question, we will mention you on the podcast with said information. And if you
do leave us a review on iTunes and we happen to see that your comments there, you'll probably more
than likely make it onto the show because we have a dearth of those right now so visit us at codingblocks.net
where you can find the show notes, examples, discussions
and more and send your feedback
questions and rants to comments Java.