|
One thing I see often in code is people creating the SqlCommand and SqlParameter objects each time they need to make a call. Isn't this wasteful? You can reuse the existing command and parameter objects just fine as far as I know. I do it for SQLite at least. It bothers me because it seems like more unnecessary GC pressure which isn't what you need for a webapp. This is what I did with SQLite: code:
Inverness fucked around with this message at 02:43 on Jan 16, 2015 |
# ? Jan 16, 2015 02:36 |
|
|
# ? May 17, 2024 04:06 |
|
Inverness posted:One thing I see often in code is people creating the SqlCommand and SqlParameter objects each time they need to make a call. SqlCommands hold on to SqlConnections, which hold on to unmanaged resources. That's why they should be disposed and recreated as necessary. I don't know if you necessarily need to dispose SqlCommands, but it's easier to manage if you just instantiate both a command and a connection as needed in a using block.
|
# ? Jan 16, 2015 02:44 |
|
bpower posted:Ok there's nothing inherently wrong with the UoW pattern or the repository pattern, but a lot of people, you included, have pointed out its a needless abstraction of EF. Right, basically isn't the DbContext a Repository and a Unit of Work already?
|
# ? Jan 16, 2015 02:47 |
|
Pretty much. If you're using your own Repository/UoW on top of EF just because you think they're good data access patterns then you've taken a wrong turn. Implementing your own will make some things easier and 'nicer' I suppose.
|
# ? Jan 16, 2015 03:33 |
|
Space Whale posted:I'll give an example: Yeah, that's pretty much the same as EF. Malcolm XML posted:Please use attribute based routing and have your controllers use reasonable method names. Why is that better than configuring it to use MVC-style routing, exactly?
|
# ? Jan 16, 2015 03:57 |
|
RICHUNCLEPENNYBAGS posted:Yeah, that's pretty much the same as EF. There's no second guessing what the url of an action is when they're on top of each other.
|
# ? Jan 16, 2015 06:35 |
|
kingcrimbud posted:There's no second guessing what the url of an action is when they're on top of each other. Yeah, instead, just an extra opportunity to gently caress up naming it.
|
# ? Jan 16, 2015 07:58 |
|
RICHUNCLEPENNYBAGS posted:Yeah, instead, just an extra opportunity to gently caress up naming it. Hey, ~/Catalog/Porducts/105 is a perfectly legitimate route and won't make people think less of your business at all!
|
# ? Jan 16, 2015 09:48 |
|
RICHUNCLEPENNYBAGS posted:Yeah, instead, just an extra opportunity to gently caress up naming it. as opposed to having it implicitly generated by some weird convention based thing that is impossible to control?
|
# ? Jan 16, 2015 12:22 |
|
Ithaqua posted:SqlCommands hold on to SqlConnections, which hold on to unmanaged resources. That's why they should be disposed and recreated as necessary. I don't know if you necessarily need to dispose SqlCommands, but it's easier to manage if you just instantiate both a command and a connection as needed in a using block. Also the System.Data.SqlClient related stuff isn't thread safe, which can lead to some bizarre errors with DataReaders trying read data from the wrong command.
|
# ? Jan 16, 2015 15:56 |
|
Ithaqua posted:SqlCommands hold on to SqlConnections, which hold on to unmanaged resources. That's why they should be disposed and recreated as necessary. I don't know if you necessarily need to dispose SqlCommands, but it's easier to manage if you just instantiate both a command and a connection as needed in a using block. PhonyMcRingRing posted:Also the System.Data.SqlClient related stuff isn't thread safe, which can lead to some bizarre errors with DataReaders trying read data from the wrong command. Inverness fucked around with this message at 16:13 on Jan 16, 2015 |
# ? Jan 16, 2015 16:11 |
|
Inverness posted:This makes more sense as to why you would need to remake connections. Pooling means actual connections can be handed out to the threads that need them, yes? Right, and the framework handles that for you in the background.
|
# ? Jan 16, 2015 17:30 |
|
PhonyMcRingRing posted:Right, and the framework handles that for you in the background. Exactly. There is no reason to manually worry about your resources with a SqlConnection since the framework does all of the pooling for you. Spin up a new one as necessary and make sure it's in a using{} block. bpower posted:Pretty much. If you're using your own Repository/UoW on top of EF just because you think they're good data access patterns then you've taken a wrong turn. Using a repository pattern is good in a couple of cases. It isolates the rest of your code from Entity Framework, so just your data access layer has to know about it. This helps immensely, for example, when you run into situations where EF generates a terrible ill-performing query and you need to drop down to SQL. If your data access code is hidden behind a repository, you can change the code in one place and not worry about affecting callers. This inherently gives you a second benefit of testability, assuming you are referencing your repository by its interface, since you can provide a mock implementation for your repository to test the rest of your code without hitting the database. However, implementing UoW on top of EF is just a pitfall in my opinion. A guy here at work has tried to do it a couple of times over the years and it's always turned into an over-complicated mess that doesn't buy you any actual benefit. Maybe I just haven't seen it done properly, but until I do I will remain unconvinced.
|
# ? Jan 16, 2015 20:05 |
|
Speaking of using{}, if a using (foo) {} block lasts until the end of the method, is it in any way different from just declaring foo as a local variable?
|
# ? Jan 16, 2015 20:24 |
|
NihilCredo posted:Speaking of using{}, if a using (foo) {} block lasts until the end of the method, is it in any way different from just declaring foo as a local variable? Yes, if foo has a Dispose defined and an exception is thrown in that block/scope, the using version will invoke the Dispose method and the other will not. Conceptually speaking (and maybe in actual compiler mojo), using is syntactic sugar for: code:
|
# ? Jan 16, 2015 20:27 |
|
Malcolm XML posted:as opposed to having it implicitly generated by some weird convention based thing that is impossible to control? If configuring it doesn't count as "controlling" it then I don't think we're in agreement about what "control" means. Bognar posted:Exactly. There is no reason to manually worry about your resources with a SqlConnection since the framework does all of the pooling for you. Spin up a new one as necessary and make sure it's in a using{} block. The problem is that, inevitably, you're going to end up wanting to do more stuff that requires talking directly to EF (like, say, doing some Include statements) and eventually it's not really much an abstraction at all (it's half talking to EF and half to the wrapper and your wrapper gradually accumulates the same list of methods as DbContext). I kind of regret doing this even though it does make testing a bit easier. RICHUNCLEPENNYBAGS fucked around with this message at 02:28 on Jan 17, 2015 |
# ? Jan 17, 2015 02:25 |
|
bpower posted:Ok there's nothing inherently wrong with the UoW pattern or the repository pattern, but a lot of people, you included, have pointed out its a needless abstraction of EF. Well, why stop at repository http://java.dzone.com/articles/orm-offensive-anti-pattern
|
# ? Jan 17, 2015 03:10 |
|
RICHUNCLEPENNYBAGS posted:If configuring it doesn't count as "controlling" it then I don't think we're in agreement about what "control" means. The whole "testable" thing really bugs me as a reason to go through all these double-abstraction-layer gymnastics. I have an MVC project where I have a service (the generic, business-logic-goes-here form of the word, not a web service or something) that gets the DbContext passed to it through its constructor. The service does a thing with the database. I want to unit test the functionality of the service methods without needing that database. My DbContext looks like this: C# code:
C# code:
I'm really, really not an expert at any of this; if someone notices that this code will do something horrifying, please speak up. The tests appear to work doing things this way, and operate only on the test data I've given them, but they could be touching things they aren't supposed to (one specific concern I have is if mocking a concrete DbContext class, as in new Mock<MyDbContext>(); still expects a database to be there, even if all of its IDbSets are mocked. This is just me not knowing enough about how EF works under the hood).
|
# ? Jan 17, 2015 04:02 |
|
Yeah, but at this point it's pretty difficult for me to undo that for a year-old project and has rather limited benefits. Anyway I've inserted some other behaviors like tenant filtering that might be tricky to get just overriding DbContext, anyway.
|
# ? Jan 17, 2015 06:00 |
|
quote://Create the mock sets (using Moq) Is the bolded stuff some internal methods needed to call add and remove? If so, aren't you heavily coupling the test to the implementation? I'm learning about TDD at the moment. There seems be be no consensus on really fundamental issues. Consider these videos Beck, Flower and David Heinemeier Hansson (DHH) discuss his (DHH's) blog post "tdd is dead" in the video below. The whole thing is fascinating. https://www.youtube.com/watch?v=z9quxZsLcfo Heres another Ian Cooper: TDD, where did it all go wrong http://vimeo.com/68375232 DHH thinks testing has gone wrong and needs a reboot. The idea that TDD inevitably leads to good design is a myth. Infact some times it leads to bad design, his prime example is "Hexagonal Architecture " Beck thinks testing has not gone wrong but some people may need to go back to first principles. He has never seen "test induced bad design" or what ever DHh is calling it. He fully believes ,if done correctly, tdd leads to good design. Ian Cooper thinks testing has gone wrong and needs a reboot. He has seen loads of "test induced bad design".We need to go back to first principles. His prime example of TDD done correctly , in its purest form, as Beck intended, is "Hexagonal Architecture". The very thing DHH held up as the worst consequence of TDD. What do you guy think? Am I even understanding the points at issue? A lot of the discussion went over my head. My solution is to create a local test version of my db. I fill it with test data in a similar way to the Seed method in EF migration. All my tests assume the db is in exactly its starting state. they can add data and read it back if they want, but they must try to delete that data first and at the end o ensure the tests are atomic. The test db is pretty empty, its has all the lookups , a few users of each type needed in the tests. a few typical entities that can be reused for many tests. Its working well so far. Its not perfect, spinning up the db takes about 2 seconds and then about 40 tests that hit take 2 seconds.Thats probably a deal breaker for many, but like your solution it keeps the ugliness outside of production code. I have 8 year old hardware but getting upgraded soon. Like Che Delilas I welcome all criticism.
|
# ? Jan 17, 2015 08:43 |
|
Forgall posted:Well, why stop at repository I dot know anything about that guy, but the bolded part is utterly false. He picked java and Hibernate the two most boilerplate heavy examples he could think of to demonstrate his point. Why not Dapper ? It seems intellectually dishonest. that dudes blog posted:First, let's see how ORM works, by example. Let's use Java, PostgreSQL, and Hibernate. Let's say we have a single table in the database, called post:
|
# ? Jan 17, 2015 09:02 |
|
bpower posted:Is the bolded stuff some internal methods needed to call add and remove? If so, aren't you heavily coupling the test to the implementation? I'm learning about TDD at the moment. There seems be be no consensus on really fundamental issues. I'm pretty sure that the code you bolded is what is necessary to perform LINQ queries on an IDbSet if you want the IDbSet to point to somewhere other than where the DbContext specifies (in this case I'm pointing to the in-memory testboats List that I created for this test method, instead of a database somewhere). It still feels hinky, especially since I'm not mocking out every method in the interface. http://msdn.microsoft.com/en-us/library/gg679233%28v=vs.113%29.aspx I really wish there was an obvious approach to this whole repository/uow + unit testing thing, because it really makes me scratch my head. quote:My solution is to create a local test version of my db. I fill it with test data in a similar way to the Seed method in EF migration. All my tests assume the db is in exactly its starting state. they can add data and read it back if they want, but they must try to delete that data first and at the end o ensure the tests are atomic. The test db is pretty empty, its has all the lookups , a few users of each type needed in the tests. a few typical entities that can be reused for many tests. This idea just rubs me the wrong way. There just has to be a decent way to completely short-circuit the need for a database at all for the purposes of unit testing, but without having an otherwise completely redundant abstraction on top of your DbContext.
|
# ? Jan 17, 2015 09:37 |
|
Che Delilas posted:I'm pretty sure that the code you bolded is what is necessary to perform LINQ queries on an IDbSet if you want the IDbSet to point to somewhere other than where the DbContext specifies (in this case I'm pointing to the in-memory testboats List that I created for this test method, instead of a database somewhere). Me too! But I don't know why. If speed was no issue whatsoever whats the difference between creating an in memory mock and having a test db on disk, or more likely several dbs on disk that the relevant tests point at. We both have to maintain test data. EF can keep all dbs structurally in sync. What about tests involving data access to text files? They're just data on disk right? This seems like a widely accepted solution. http://stackoverflow.com/questions/1805012/unit-testing-how-to-access-a-text-file It points to this http://msdn.microsoft.com/en-us/library/ms182475.aspx You end up with this code:
These are not rhetorical questions btw.
|
# ? Jan 17, 2015 10:10 |
|
Che Delilas posted:This idea just rubs me the wrong way. There just has to be a decent way to completely short-circuit the need for a database at all for the purposes of unit testing, but without having an otherwise completely redundant abstraction on top of your DbContext. Not until EF 7 there isn't!
|
# ? Jan 17, 2015 19:17 |
|
How well supported will TypeConverter be with .NET Core and other platforms going forward? There isn't any other generic way of specifying how types can be converted for things like serialization yet this is not supported on other platforms. The IValueConverter you find on other platforms is much more limited and situational for things like data binding.
|
# ? Jan 17, 2015 19:39 |
|
Tests are good but TDD is stupid. That's my take.
|
# ? Jan 17, 2015 20:20 |
|
bpower posted:Me too! But I don't know why. If speed was no issue whatsoever whats the difference between creating an in memory mock and having a test db on disk, or more likely several dbs on disk that the relevant tests point at. We both have to maintain test data. EF can keep all dbs structurally in sync. I mean, the point of unit testing is to test something in isolation. I want to be able to test some complicated algorithm on its own whether I have access to a database or not; I care about the operation of the algorithm and nothing else. But you make a good point; I mean in what situation, realistically, are we going to have access to our development machine, the source code we're testing, and our unit testing project and code, but not have access to at least some kind of database system that EF can connect to to get dummy data? Any dev box or CI server worth the name is going to have something available to serve that function. Maybe this is one of those cases of everyone (okay, me) getting caught up in the ~perfect theoretical form~ of a thing, when a little bit of concession to reality would make things a lot simpler for the vast majority of cases. (As an aside, anyone else ever find themselves wishing that Microsoft had called their stupid Access program anything else at all? Every time I have a conversation that involves databases, my brain twitches just a little bit when the inevitable phrase "access to the database" comes up. They could called it anything else that doesn't imply "availability and permission," but nooOOOooo.) quote:Why aren't we mocking System.IO.File? Well, I wouldn't mock this one specifically, because if I had a method that created a file as part of its operation, I would want to make sure that file actually got created. I've had enough minor trouble caused by file permissions issues, thanks very much . But I know that's sort of beside the point you're making.
|
# ? Jan 18, 2015 00:37 |
|
Ideally a unit test suite should create whatever environment it needs to operate and that includes a test database.
|
# ? Jan 18, 2015 08:39 |
|
Continuing the mvc / web api chat... So right now I have controllers named after resources: DocumentController, DocumentsController, FolderController, FoldersController etc. They have methods like below, comments are for this example, I've actually got an mvc help area in-app that displays the xml help on the web api controller methods. ApiControllerBase has some common stuff over the top of the normal web api controller thing, like logging object etc. code:
|
# ? Jan 18, 2015 22:15 |
|
I tend to have one controller per entity type, regardless of plurality. Otherwise, looks fairly standard layout to me.
|
# ? Jan 18, 2015 23:02 |
|
fleshweasel posted:Ideally a unit test suite should create whatever environment it needs to operate and that includes a test database. I disagree. Most unit tests should never hit the database. Mock the results of your query and test the logic of your method alone. No need for an actual db. I only hit a database (in-memory) when writing integration tests, I use Highway.Data to put a decent abstraction layer on my queries. Plays well with EF and NHibernate.
|
# ? Jan 19, 2015 02:19 |
|
EssOEss posted:I tend to have one controller per entity type, regardless of plurality. Otherwise, looks fairly standard layout to me. Ditto on one controller per entity type. It would drive me nuts to have a [Type]Controller and [Type]sController for every entity.
|
# ? Jan 19, 2015 02:32 |
|
Dromio posted:I disagree. Most unit tests should never hit the database. Mock the results of your query and test the logic of your method alone. No need for an actual db. I only hit a database (in-memory) when writing integration tests, Yes and the stored procedures would benefit from tests too.
|
# ? Jan 19, 2015 02:54 |
|
fleshweasel posted:Yes and the stored procedures would benefit from tests too. There are tools for testing stored procedures. SSDT has database tests.
|
# ? Jan 19, 2015 03:45 |
|
Bognar posted:Ditto on one controller per entity type. It would drive me nuts to have a [Type]Controller and [Type]sController for every entity. True, I guess when you're using [Http*] attribs and not naming the methods like "Get", "Put", but "SearchByContact", then you're not bound to return the same datatype for both singular and plural. Thanks for clearing things up, I've been writing mvc apps for ages, but I'm still fairly new to the whole REST and web api thing.
|
# ? Jan 19, 2015 06:42 |
|
mortarr posted:True, I guess when you're using [Http*] attribs and not naming the methods like "Get", "Put", but "SearchByContact", then you're not bound to return the same datatype for both singular and plural. Thanks for clearing things up, I've been writing mvc apps for ages, but I'm still fairly new to the whole REST and web api thing. I think if you use HTTP verb routing the convention is to do multiple/all entities if you don't provide an ID and one if you do.
|
# ? Jan 19, 2015 06:47 |
|
If I call ToDictionary() on a ParallelQuery, do the key-generating projections happen in parallel? It would make sense for them to, but I can't find any documentation of which operations are actually parallelized and which aren't.
|
# ? Jan 19, 2015 19:27 |
|
GrumpyDoctor posted:If I call ToDictionary() on a ParallelQuery, do the key-generating projections happen in parallel? It would make sense for them to, but I can't find any documentation of which operations are actually parallelized and which aren't. The results in ParallelQuery are iterated after the tasks are merged, so no it doesn't happen in parallel. You can view the reference source here: http://referencesource.microsoft.com/#System.Core/System/Linq/ParallelEnumerable.cs,dcdd1c9b4c10ea06
|
# ? Jan 19, 2015 20:21 |
|
[plug] The WPF team wants to get the message out about work they're doing for WPF. In this case, they've brought the XAML-performance-analysis tools from WinRT XAML (VS2013) to also now work with desktop WPF XAML (VS2015 CTP5): http://blogs.msdn.com/b/wpf/archive/2015/01/16/new-ui-performance-analysis-tool-for-wpf-applications.aspx
|
# ? Jan 19, 2015 20:39 |
|
|
# ? May 17, 2024 04:06 |
|
we were passing around some of those screenshots excitedly at work today actually, i spent some time installing VS2015 in a vm to try and try it out - unfortunately it won't build our main solution yet, something about the package-restore-less workflow is upsetting to it. these perf tools are a great carrot to keep trying!
|
# ? Jan 19, 2015 20:47 |