|
For anyone working on .NET / WebAPI Projects I highly suggest trying out Glimpse. It's like the Chrome DevTools but with more insight into your code.
|
# ? Apr 27, 2015 17:36 |
|
|
# ? Jun 6, 2024 13:54 |
|
The Wizard of Poz posted:I also have a more general question around dependency injection. I have a controller action that looks like this: ReSharper supports "go to implementation" (I think this is ReSharper and not Visual Studio anyway), and if you've got multiple implementations it'll ask which one. Bognar posted:I don't have much time at the moment to elaborate, but I will say I strongly disagree with the general patterns described here. If you need a context, then instantiate one - don't keep the same one around for the lifetime of a request. Due to the way EF handles object caching, strange and unexpected things can happen. Similarly, you shouldn't just automatically set up a transaction per request. Even if you ignore the performance concerns, you still should reason about which requests actually require a transaction and only use one where it's necessary. EF does a transaction every time you call SaveChanges, doesn't it? Anyway, if you're running into problems with object caching I think you're doing some strange things in a single request. I don't think performance concerns are seriously worth worrying about unless you're doing a bulk insert of thousands of records -- in which case more contexts will help but you'll still have serious performance issues with EF. RICHUNCLEPENNYBAGS fucked around with this message at 23:57 on Apr 27, 2015 |
# ? Apr 27, 2015 23:54 |
|
RICHUNCLEPENNYBAGS posted:ReSharper supports "go to implementation" (I think this is ReSharper and not Visual Studio anyway), and if you've got multiple implementations it'll ask which one. Thanks guys for the ReSharper suggestion - I'll give their free trial a shot and see how I go. Edit: Already super-impressed, lots of cool stuff in this add-on. Thanks again. putin is a cunt fucked around with this message at 05:25 on Apr 28, 2015 |
# ? Apr 28, 2015 00:32 |
|
Does anyone know why Visual Studio would do this? I'm referring to the first incidence of panelProducts being highlighted like that. It's a local variable, passed in to the Sub as a parameter, and that's the first time it's references in the method. At first I thought I must have accidentally clashed with a class name or something, but as you can see, subsequent references aren't highlighted, and it does it no matter what I call it.
|
# ? Apr 28, 2015 15:15 |
|
Funking Giblet posted:I don't use EF, but NHibernate, which will always create a transaction no matter what, and it's bad for performance to not handle it yourself as it will create one per modification, so you might get a few transactions per action. Ah, I can't say much for NHibernate - most of the advice I was giving was EF specific. RICHUNCLEPENNYBAGS posted:EF does a transaction every time you call SaveChanges, doesn't it? It does, which is why it's very likely unnecessary for you to start one for each request. RICHUNCLEPENNYBAGS posted:Anyway, if you're running into problems with object caching I think you're doing some strange things in a single request. It doesn't have to be strange, or even complicated. This example is inspired by something we ran into trying to do one context per request. Lets say you have these models: C# code:
C# code:
C# code:
C# code:
C# code:
What happened was that when Susie called GetFarts() and got the user to name and shame them, the user was already loaded in the context due to the call in GetButts(). Entity Framework automatically saw that the Farts UserId match the loaded User, so it automatically wired them up. It tries to connect the object graph to what's already loaded. When Johnny removed the User from GetButt(), it affected one tiny far away section of code in non-obvious ways. It's hard to catch because it's hard to know what's already been loaded into the context or what callers are expecting to be loaded into the context. You could say the root of the problem was bad developers not being careful, and to some extent that's true, but this was just a simple example. Add a few developers to a non-trivial project and tons of code can be accidentally written that is dependent on previous queries. Now it's a mine-field if you try to optimize queries by removing unnecessary includes, because you can't just test where that query is used, you have to test every thing that happens after that query is used in each request. Another thing that makes this particularly hard to protect against is that Includes are one of the hardest things to unit test. EF's in-memory database in the next version may make this easier, but as of now there's no great way to test object caching and includes without touching the database. I've harped on the Include aspect of object caching, but there's another slightly less disruptive issue. If you query the database and load a value into EF, something changes in the database, then you re-query the database with the same context, EF will NOT overwrite your previous values with the new changed values from the database. It will look at the Id, see that the object is already loaded, then ignore all the new values. This is not as big of an issue with web requests where the context lifetime should be short, but it is definitely a problem if you have anything with a long-running context. In all, it's easier to just instantiate the context where you need it. You gain greater control over the semantics of how and when a context should be opened, and you don't run into nasty object caching issues.
|
# ? Apr 28, 2015 15:52 |
|
This might be a bit of a long shot, but has anyone here worked with DbGeomatry, specifically the functions that create shapes from WKT. I'm wanting to create a point with WKT from user input lat/long, but the values have to be transformed to represent a datum that I am unfamiliar with. Anyone have any experience with transforming lat/long to WGS84 in a .Net language?
|
# ? Apr 28, 2015 16:43 |
|
Bognar posted:Ah, I can't say much for NHibernate - most of the advice I was giving was EF specific. Wait, so EF uses query caching? This is optional in NHib (and should be off for most cases). It should use entity caching per id, so queries skip it. Includes would hit it if only id's are used for the joins, but the above example should lazy load the users if they aren't in the query so nothing should break, And the second example shouldn't work because the transaction should be isolated away from change in the first place. Does EF support clearing the cache before a query in that case? I'm just trying to wrap my NHib knowledge around EF because the above sounds bad.
|
# ? Apr 28, 2015 17:19 |
|
Everything Bognar said I learned about the hard way learning EF. I handle my contexts in my service and use a CleanUp() method like so: code:
code:
When a view is destroyed, the ViewModel will call the services CleanUp(). I can then hang on to the ViewModel for a longer period if needed but, any reference to the original context's objects leaves when the View is garbage collected. The trouble I run into is using it in something like a TabControl or where there is navigation. My Tab Views hang on to references of the cleaned up context and it takes a complete refresh to tell it to grab the services "new" objects. I remedy this as best as possible by using Messaging with Navigation to do a complete PropertyChanged event which then Inits the new context in the service, grabs the "new" references, and releases the old references. Still trying to figure out a better way to do that... e: posted before finishing crashdome fucked around with this message at 18:28 on Apr 28, 2015 |
# ? Apr 28, 2015 18:17 |
|
AuxPriest posted:Anyone have any experience with transforming lat/long to WGS84 in a .Net language? I've stumbled through the Esri ArcGIS SDK in .Net, but I'm not sure how much that can help you. It's a loving mess.
|
# ? Apr 28, 2015 18:21 |
|
Funking Giblet posted:Includes would hit it if only id's are used for the joins, but the above example should lazy load the users if they aren't in the query so nothing should break This is true, and I didn't consider it in my post since I haven't used EF with lazy loading in years. I've seen it cause way too many performance problems to even consider using it again. It turns idiomatic C# code that looks like it's just in-memory into code that touches the database, which inevitably leads to round trip DB calls in a foreach. Nasty. Funking Giblet posted:And the second example shouldn't work because the transaction should be isolated away from change in the first place. Does EF support clearing the cache before a query in that case? I'm just trying to wrap my NHib knowledge around EF because the above sounds bad. I don't think EF has any support for query caching, all the caching is done by entity Id. The specific example I was talking about is where you'd *want* to get the newer values. There's no implicit transaction in EF until you call SaveChanges(), so the queries are returning new values but the context is ignoring them. You'd have to instantiate a new context to get the new values. To my knowledge, there's not a way to clear the entire cache for each context. You *are* able to specify that a specific query should return results without checking the cache, but it also bypasses the entity cache entirely so those objects aren't change tracked.
|
# ? Apr 28, 2015 18:26 |
|
This brings me back to my original point, don't encapsulate queries at all, and use projections only, even using those projections directly if possible. (Can't believe I'm about to do this..) code:
Nhibernate can actually batch multiple queries in one round trip like this if you use the Future modifer, which acts like a promise for all other queries marked with future within the same transaction, which is why reusing the transaction and session actually helps. Funking Giblet fucked around with this message at 19:09 on Apr 28, 2015 |
# ? Apr 28, 2015 19:05 |
|
chippy posted:Does anyone know why Visual Studio would do this? Yes, that's been an irritating bug in VB syntax highlighting for a while. There are some patterns of "chains of dots" that cause it. I never figured out why. We fixed it in VS2015. However, sorry to say we don't have plans to port the fix to older versions of VS.
|
# ? Apr 28, 2015 19:09 |
|
-Dethstryk- posted:I've stumbled through the Esri ArcGIS SDK in .Net, but I'm not sure how much that can help you. It's a loving mess. I just wrote my own functions to do the transformations after doing a bunch of math. Surprised these things don't already exist in an easy to use format :\.
|
# ? Apr 28, 2015 22:15 |
|
Bognar posted:This is true, and I didn't consider it in my post since I haven't used EF with lazy loading in years. I've seen it cause way too many performance problems to even consider using it again. It turns idiomatic C# code that looks like it's just in-memory into code that touches the database, which inevitably leads to round trip DB calls in a foreach. Nasty. As long as you're using some profiling tool in conjunction it's no problem. MiniProfiler for MVC.NET will even alert in red at the highest level to indicate a duplicated query, which usually means an N+1 EF lazy-loading issue.
|
# ? Apr 28, 2015 23:53 |
|
Bognar posted:I don't think EF has any support for query caching, all the caching is done by entity Id. It's only cached if you use Find; you can avoid the cache, if you want, by using Single or First or SingleOrDefault or FirstOrDefault. Then none of the problems you're talking about even come up. If you do use Find I'm pretty sure no query is run if the thing is already cached. (Or maybe not? I don't know; that was my understanding and nothing's made me question it so far but I guess it could be wrong) Funking Giblet posted:This brings me back to my original point, don't encapsulate queries at all, and use projections only, even using those projections directly if possible. Anyway, projections are great, but in EF at least they're not really helpful if you want to mutate stuff. If you just want to do read-only queries, absolutely. Since we're all yammering on about Entity, what's the best way to do mapping of this sort: View model contains a collection of some other view model. These each correspond to some database entity. Based on what's in the collection, you need to modify existing entries, add new ones, and drop existing ones that aren't in the view model collection. I've done this a few ways but none of them has really satisfied me as being not noisy/technically slow if you had large inputs. I guess maybe it would be best to sort both by ID and then go incrementing each collection? That'd avoid multiple loops at least. RICHUNCLEPENNYBAGS fucked around with this message at 04:15 on Apr 29, 2015 |
# ? Apr 29, 2015 04:09 |
|
If any of you are going to Build, be sure to check out the Xamarin talk on Friday. I did most of the web infrastructure for our demo (If we manage to finish it. It should be done tomorrow, but building it at all was a split second decision and we started the project three weeks ago ), so you may be able to see it explode in real time! Or if it works live, see some pretty cool Azure and Xamarin app interaction. At least that's the hope. We'll see! Except for me, I couldn't go . Drastic Actions fucked around with this message at 04:39 on Apr 29, 2015 |
# ? Apr 29, 2015 04:23 |
|
RICHUNCLEPENNYBAGS posted:It's only cached if you use Find; you can avoid the cache, if you want, by using Single or First or SingleOrDefault or FirstOrDefault. Then none of the problems you're talking about even come up. If you do use Find I'm pretty sure no query is run if the thing is already cached. (Or maybe not? I don't know; that was my understanding and nothing's made me question it so far but I guess it could be wrong) Find searches the cache for an entity, then queries the database if it's not in the cache. No surprises happen in this use case. FirstOrDefault will execute the query no matter what, check the Id of the result returned in the query, check the cache for the Id, then return the cached object if found. If not found in the cache it will deserialize the results then cache the entity. It will also magically hook up any navigation properties if they, too, are loaded in the cache.
|
# ? Apr 29, 2015 05:11 |
|
Drastic Actions posted:Or if it works live, see some pretty cool Azure and Xamarin app interaction. Go on...
|
# ? Apr 29, 2015 14:00 |
|
I sometimes write a quick program to help a client get a specific piece of work done. I don't want to mess with installers, I really just want to hand over the program and tell them to run it. Let's say a Console (or WPF, or WinForms) project has a few dependencies, which end up as dll files in the Release folder. I have to hand-pick the executable, the config file, and the dll files, move them to a new folder, zip the folder, and transfer it to the client. Then I have to help them unzip it, and tell them which file to run, or help them create a shortcut to the executable. This has many error prone steps, considering the target audience has trouble with the difference between single- and double-clicking the mouse. I've used ILMerge to bundle the whole application into one executable, but I can never get all the arguments right the first time, and it's generally a painful process. What would be great is a one-click "bundle all dependencies into an executable" button in Visual Studio. Does VS have such an extension I'm not aware of? Or are future VS versions considering adding this feature?
|
# ? Apr 29, 2015 16:44 |
|
Malcolm XML posted:Unfortunately no one actually cares about windows phone or tablet so idk why they kept pushing universal apps so hard What's exciting to me is that universal apps will run as resizable windowed apps on Desktop (yay! huge audience, and at last something I'm happy to switch to after Winforms), as well as on tablet and phone and IOT and HoloLens. Also, with them, you can offer your windowed apps for download via the Store. Nicer than having to download apps from download.com. (edit: I guess that store stuff is being opened up to regular desktop apps as well). ljw1004 fucked around with this message at 18:27 on Apr 29, 2015 |
# ? Apr 29, 2015 18:21 |
|
epalm posted:I sometimes write a quick program to help a client get a specific piece of work done. I don't want to mess with installers, I really just want to hand over the program and tell them to run it. Let's say a Console (or WPF, or WinForms) project has a few dependencies, which end up as dll files in the Release folder. I have to hand-pick the executable, the config file, and the dll files, move them to a new folder, zip the folder, and transfer it to the client. Then I have to help them unzip it, and tell them which file to run, or help them create a shortcut to the executable. This has many error prone steps, considering the target audience has trouble with the difference between single- and double-clicking the mouse. You can output click once projects to disk.
|
# ? Apr 29, 2015 18:45 |
|
Exciting stuff going on at Build: Microsoft Launches Visual Studio Code, A Free Cross-Platform Code Editor For OS X, Linux And Windows Microsoft Launches Its .NET Distribution For Linux And Mac
|
# ? Apr 29, 2015 18:49 |
|
RICHUNCLEPENNYBAGS posted:You can output click once projects to disk. I get a publish folder with files in it. I want to generate exactly 1 file, transfer it, double click it.
|
# ? Apr 29, 2015 19:58 |
|
I forgot Build was going on. Maybe we'll get a VS 2015 release date? Since reading the C# 6 features list, I've had several "man I wish I was using C# 6" moments lately.
|
# ? Apr 29, 2015 19:59 |
|
epalm posted:I get a publish folder with files in it. I want to generate exactly 1 file, transfer it, double click it. Set up ILMerge as a build step? http://www.hanselman.com/blog/MixingLanguagesInASingleAssemblyInVisualStudioSeamlesslyWithILMergeAndMSBuild.aspx Embed all your assemblies? http://blogs.msdn.com/b/microsoft_press/archive/2010/02/03/jeffrey-richter-excerpt-2-from-clr-via-c-third-edition.aspx
|
# ? Apr 29, 2015 20:14 |
|
My thoughts on the use of EF as discussed below: (for the vast majority of projects) - let DI create a new DbContext per request - you have simplified your code a little - just write queries directly in your controllers rather than creating a new layer that all queries must be written in - you have simplified your codebase a lot - put common queries into helper classes returning IQueryables - when sharing code for something more complicated, return a custom object rather than an EF object - don't use Include
|
# ? Apr 29, 2015 22:46 |
|
epalm posted:I've used ILMerge to bundle the whole application into one executable, but I can never get all the arguments right the first time, and it's generally a painful process. I use the Fody plugin Costura to do the same sort of thing. You'd still need to distribute the config file if you have config specific settings. https://github.com/Fody/Costura
|
# ? Apr 29, 2015 23:06 |
|
Dreadrush posted:My thoughts on the use of EF as discussed below: (for the vast majority of projects) lol. Thank you for the absolutely insane advice.
|
# ? Apr 30, 2015 00:32 |
|
RICHUNCLEPENNYBAGS posted:lol. Thank you for the absolutely insane advice. Care to elaborate? In my experience following this advice results in simple and flexible code.
|
# ? Apr 30, 2015 01:18 |
|
Bognar posted:Exciting stuff going on at Build: VSCode is pretty sweet. I've been playing around with it on a Ubuntu machine at work.
|
# ? Apr 30, 2015 01:25 |
|
Dreadrush posted:Care to elaborate? I can't see any good reason to have a ton of data access and mapping code in your controller instead of in a separate class (I usually have one mapper to one controller but whatever). In fact I've done it that way and learned the hard way that it eventually grows unmanageable and changed it. Avoiding includes is not a good idea because then you're relying on lazy loads. Why? Yes, the code is simpler, but in exchange you have code that is slow as hell.
|
# ? Apr 30, 2015 02:34 |
|
I'm kind of in a daze about where Microsoft is going with .NET Core. I used to be big into C# back in the early 2000s, having done a lot of ASP.NET. These days two things have happened: I find myself wanting to re-learn C#, and all of the development I do is small console utilities that I want portable across Win/Lin/Mac, with Mac and Linux being the big hitters. It sounds like .NET Core should be right up my alley, but somehow I find myself incredibly lost when it comes to moving C# dev off of Windows with VS2013. It's mostly my fault, but I think there's also a bit of information overload here. Admittedly I am jumping back on the ship just as Microsoft is radically shifting the paradigm, but I guess it leaves me wondering what the next step for picking up C# again should be. I'm probably going to just install the Mono package for Mac and MonoDevelop and just stop worrying about it and start learning rather than trying to figure out every new thing or second guessing whether I should be doing this or that. Analysis paralysis.
|
# ? Apr 30, 2015 03:13 |
|
Martytoof posted:I find myself wanting to re-learn C#, and all of the development I do is small console utilities that I want portable across Win/Lin/Mac, with Mac and Linux being the big hitters. It sounds like .NET Core should be right up my alley, but somehow I find myself incredibly lost when it comes to moving C# dev off of Windows with VS2013. Another option: watch this talk tomorrow at 2pm Pacific time: quote:Taking .NET Cross-Platform: Building .NET Applications on Linux and Mac
|
# ? Apr 30, 2015 03:29 |
|
amotea posted:I wish they'd just fix and improve WPF, and not reinvent the wheel over and over again. There is no viable alternative for desktop applications right now. I also wish WPF would become less bad, so we agree on that point. However, you can take your xaml & data binding & mvvm principles and use them to build universal apps which are now much more integrated with the desktop. And man you are behind the times wrt Silverlight. Browser plugins are dead, completely. Much better js runtimes & mobile killed it. It was a neat idea in its time but c'mon.
|
# ? Apr 30, 2015 03:30 |
|
ljw1004 posted:Another option: watch this talk tomorrow at 2pm Pacific time: Or I could do that, thanks
|
# ? Apr 30, 2015 03:35 |
|
RICHUNCLEPENNYBAGS posted:I can't see any good reason to have a ton of data access and mapping code in your controller instead of in a separate class (I usually have one mapper to one controller but whatever). In fact I've done it that way and learned the hard way that it eventually grows unmanageable and changed it. Things become unmanageable when classes take on too much responsibility and become too large. This can also happen by moving this code down a layer into another class. If each controller represents a different http resource, then your controllers will not get too large. At this point, it is most manageable to include data access code directly in the controller. If I write this code in a separate class in another layer, then I have unnecessarily added more work and more complexity to my project. I am not relying on lazy loading by avoiding Includes. I suggest ending queries with a Select to retrieve only the fields needed for your query.
|
# ? Apr 30, 2015 03:40 |
|
Dreadrush posted:Things become unmanageable when classes take on too much responsibility and become too large. This can also happen by moving this code down a layer into another class. If each controller represents a different http resource, then your controllers will not get too large. OK, that's what we were all talking about a few posts ago when we mentioned "projection," but that doesn't help if you want to mutate data. For read-only queries projection is the way to go (even if you aren't going after navigation properties you will select the entire row without it). As for your point about controllers: no, I entirely disagree. The purpose of the controller is not to do data access. I have no idea what it means for "each controller to represent a different HTTP resource." RICHUNCLEPENNYBAGS fucked around with this message at 04:09 on Apr 30, 2015 |
# ? Apr 30, 2015 04:07 |
|
Factor Mystic posted:I also wish WPF would become less bad, so we agree on that point. However, you can take your xaml & data binding & mvvm principles and use them to build universal apps which are now much more integrated with the desktop. Weeeell.. the Windows 10 desktop. Windowed WinRT isn't being backported to even 8, is it? That means a lot of us are stuck with WPF for many years to come. Originally, when .NET came out and took over the LOB world, it was at least in part because it supported platforms that were currently in use, not just ones that would likely eventually get some.
|
# ? Apr 30, 2015 08:49 |
|
Visual Studio Code is a really interesting idea which got less interesting when it was revealed that a) it's an Atom-like html app which can't open large files, and b) it doesn't have as much intellisense support as even OmniSharp provides.
|
# ? Apr 30, 2015 08:51 |
|
|
# ? Jun 6, 2024 13:54 |
|
https://github.com/jbogard/MediatR This is what I use to simplify controllers. The added benefit is you could mix NHib and EF and NoSql behind the scenes, you only expose IMediator to the controllers. This also helps in horrible cases such as code:
This could be changed to the following. code:
Now each of thesse requests/commands has an associated handler, they themselves are simple pocos. The handler looks like this. code:
This is obviously getting complex, but this is the next step whenever a controller becomes complicated. You quickly see that controllers become nothing more than wrappers around these commands, which with some clever ActionInvoker implementation, might not even need to exist at all... I would even call my queries directly inside the command handlers, no repos or services. Funking Giblet fucked around with this message at 08:58 on Apr 30, 2015 |
# ? Apr 30, 2015 08:53 |