I have using a basic DataContext to create objects then submit these into a database.
Have written a couple of tests myself to see which is fast but just wondering which method is considered best practice out of the following.
Code iterates through a loop and instantiates an object which is to be persisted to the database. Is it better to:
1.) Create a list of objects then and assign each created object to the list then at the end use
MyDataContext.InsertAllOnSubmit(ListOfObjects)
2.) Assign each created object directly into the DataContext using
MyDataContext.InsertOnSubmit(Object)
Hope this makes sense, if anyone needs more information let me know!
Thanks
I assume we're talking about the performance impact on the submit event - there is no database connection opened immediately when these methods are called.
Since each implementation will only update the database on Submit, they are both very similar.
Any performance difference will be marginal (and will be countered by whatever processing you do to put the objects into the List or enumerate the List), so go with whichever fits better into your design.
You might find this page about premature optimization interesting - http://c2.com/cgi/wiki?PrematureOptimization
Premature optimization is the root of
all evil -- Donald Knuth.
I guess for the second option, you'll need to re-open the connection for each operation. Using a list is cleaner and a better option.
Related
I am trying to rewrite extremely ugly class in one application at work. In one of our classes, there are hundreds of lines of code that ensure initialization and re-initialization of some classes. Currently, this is done in the awful brute force-y way, where you write your init code and manually copy it to re-init part (as they are very similar).
Because of this , I started to rewrite it to a form of a list of delegates which are then called with a parameter in both places (bool isReinit). Then I noticed that most of the delegates are also identical, as the initialization process of 90 percent of the classes is identical. This means that I should be able to create some default initialization function to simplify the code drastically. Currently I created something like this :
https://dotnetfiddle.net/RVS5UT
I also created class CustomInitializer which implements IInitializer and only takes one Func as a parameter and runs it in Initialize, for the cases where the initialization is a lot different.
Now, this simplified and anonymized piece of working code, but it works. The problem is that the whole approach is very awkward and the constructor signature is ugly as hell. Is there some way to simplify this ? I can't find any pattern or approach that would help me ? Any step towards better code is welcome and maybe I am just missing something.
There is also another catch. One solution I figured out would be to store the property pairs (var1a + var1b, var2a+var2b, ..) in an object and pass it directly to Initialize method. But this would mean moving the properties, which is sadly not possible at the moment, because the file has over 18k lines and code reviewers would kill me for changing third of them because of refactoring of one method (even if its a long one). I need to leave the target properties (var1a, var1b, var2a, ..) where they are now. This could also mean that there is no elegant way to solve this.
I am using .NET 4.0, C# 5.0
EDIT: I have no access to the initialized types (another stupid catch)
Thanks for your help.
the file has over 18k lines
Wow, looks like a lot of fun.
It is absolutely good to try to improve it. And believe me, whatever your co-workers may think, there is nothing else to do than refactoring here, unless this code does not need to evolve.
But, it seems to me you go on the path of complexity, trying to be DRY instead of trying to be expressive. The idea of having StandardInitializer and CustomInitializer managing lambdas is extremely complex. The initialization of a class should be in the class it is responsible to initialize. If some behaviors are really shared, they may share a base class or a collaboration class.
I recommend you this discussion on Working Effectively With Legacy Code. As you'll see and probably already know, the first key point is to have tests.
Please don't try to refactor such a class without a test harness. Otherwise you'll introduce regression, you'll be frustrated, and your co-workers will be comforted in their vision that nothing can be done here without breaking everything.
And don't forget if tests are hard to create, it's because of bad code, not because tests are expensive. Bad code is expensive.
After some tests protect you, try to think in terms of responsibility and life cycle. For example in a WPF application, it is a common issue to have "initializable" ViewModel because they do some async web service call to initialize themselves.
In this case, the object with the responsibilty of lifecycle for a given ViewModel, has also the responsibility to init it. If it manages several Initializable view models, then this kind of code is fine:
foreach (var initializable in initializables)
{
initializable.Initialize();
}
But please, whatever solution you choose, keep a clear separation between Initialize and Reinitialize (if they have things in common, make them call an internal shared function). It is a very bad idea to write stuff like:
init.Initialize(true);
It clearly states that the behavior of your Initialize function will change depending of a boolean value. If you have 2 behaviors, you should have 2 functions with clear naming.
There's a lot of code like this in company's application I'm working at:
var something = new Lazy<ISomething>(() =>
(ISomething)SomethingFactory
.GetSomething<ISomething>(args));
ISomething sth = something.Value;
From my understanding of Lazy this is totally meaningless, but I'm new at the company and I don't want to argue without reason.
So - does this code have any sense?
Code that is being actively developed is never static, so one possibility of why they code it this way is in case they need to move the assignment to another place in the code later on. However, it sounds as if this is occurring within a method, and normally I would expect Lazy initialization to occur most often for class fields or properties, where it would make more sense (because you may not know which method in the class would first use it).
Unfortunately, it could just as likely be more a lack of knowledge of how the Lazy feature works in C# (or lazy init in general), and maybe they are just trying to use the latest "cool feature" they found out about.
I have seen weird or odd things proliferate in code at a company, simply because people saw it coded one way, and then just copied it, because they thought the original person knew what they were doing and it made sense. The best thing to do is to ask why it was done that way. Worst case, you'll learn something about your company's procedures or coding practices. Best case, you may wind up educating them if they say "gee, I don't know".
Well, in this case is meaningless of course because you are getting the value right after creating the object but maybe this is done to follow a standard or something like that.
At my company we do similar things registering the objects in the Unity container and calling Unity to create the instance just after registering it.
Unless they are using something multiple times in the method, it seems pretty useless, and slightly less efficient than just performing the action immediately. Otherwise, Lazy<T> is going through the Value get and checking to see if the value has been materialized yet, and performing a Func call.. Usefull for deferred loading, but pointless if it is just used once in a method immediately..
Lazy<T> however is usually really helpful for Properties on a class
It can be useful if the Lazy.Value is going to be moved out of the method in the future, but anyway it can be considered as overengineering, and not the best implementation as the Lazy declaration seemed to be extracted to a property in this case.
Thus shortly - yes, it's useless.
I like to implement a collection (something like List<T>) which would hold all my objects that I have created in the entire life span of my application as if its an array of pointers in C++. The idea is that when my process starts I can use a central factory to create all objects and then periodically validate/invalidate their state. Basically I want to make sure that my process only deals with valid instances and I don't re-fetch information I already fetched from the database. So all my objects will basically be in one place - my collection. A cool thing I can do with this is avoid database calls to get data from the database if I already got it (even if I updated it after retrieval its still up-to-date if of course some other process didn't update it but that a different concern). I don't want to be calling new Customer("James Thomas"); again if I initted James Thomas already sometime in the past. Currently I will end up with multiple copies of the same object across the appdomain - some out of sync other in sync and even though I deal with this using timestamp field on the MSSQL server I'd like to keep only one copy per customer in my appdomain (if possible process would be better).
I can't use regular collections like List or ArrayList for example because I cannot pass parameters by their real local reference to the their existing Add() methods where I'm creating them using ref so that's not to good I think. So how can this be implemented/can it be implemented at all ? A 'linked list' type of class with all methods working with ref & out params is what I'm thinking now but it may get ugly pretty quickly. Is there another way to implement such collection like RefList<T>.Add(ref T obj)?
So bottom line is: I don't want re-create an object if I've already created it before during the entire application life unless I decide to re-create it explicitly (maybe its out-of-date or something so I have to fetch it again from the db). Is there alternatives maybe ?
The easiest way to do what you're trying to accomplish is to create a wrapper that holds on to the list. This wrapper will have an add method which takes in a ref. In the add it looks up the value in the list and creates it when it can't find the value. Or a Cache
But... this statement would make me worry.
I don't want re-create an object if
I've already created it before during
the entire application life
But as Raymond Chen points out that A cache with a bad policy is another name for a memory leak. What you've described is a cache with no policy
To fix this you should consider using for a non-web app either System.Runtime.Caching for 4.0 or for 3.5 and earlier the Enterprise Library Caching Block. If this is a Web App then you can use the System.Web.Caching. Or if you must roll your own at least get a sensible policy in place.
All of this of course assumes that your database's caching is insufficient.
Using Ioc will save you many many many bugs, and make your application easier to test and your modules will be less coupled.
Ioc performance are pretty good.
I recommend you to use the implementation of Castle project
http://stw.castleproject.org/Windsor.MainPage.ashx
maybe you'll need a day to learn it, but it's great.
I have a windows form app written in C#. the main_form class instantiates an AccessProcess named AccessProcessWorker which is a class that inherits from BackgroundWorker, then main_form then initializes Process with the following code
AccessProcessWorker.DoWork += new DoWorkEventHandler(processWorker.worker_DoWork);
AccessProcessWorker.RunWorkerCompleted += new RunWorkerCompletedEventHandler(processWorkerCompleted);
AccessProcessWorker.ProgressChanged += new ProgressChangedEventHandler(processProgressChanged);
this application has just gone from POC to "make it work fast".
I wrote this app to work against an Access database but now want to make it go against MS Sql, but leave the option to work against access also. So, I could do something ugly like instantiate and initialize a SqlProcessWorker or AccessProcessWorker based on some UI selection made by the user. But what I'd like to do is make it so main_form always creates something like an IProcess so I didn't have to add logic to main_form every time there is a new ProcessWorker. The problem in my design is that the initializing breaks when I do it the way I described.
If anyone has any ideas, or need further clairification please let me know.
What you look for is called "dependency injection".
At some point you will need to instantiate the correct type, but The Factory Pattern is usually to the goto here. Now, that may be a bit much if you will only ever have one of two types to 'new' in order to get your IProcess object.
In the interests of keeping it simple, I would actually just go with the "ugly" approach.
You've mentioned Access and SQL Server as the two current databases, but how many do you realistically believe your app is needing to support? In my experience an application's database platform is very rarely changed and not without serious thought.
If there were a large set of database platforms to support and you can't predict which in advance, then maybe a decoupled design would be useful. Otherwise KISS.
If both of the database are the same layout and structure, you can just use EntitySpaces and change the default connection of the application. I.e. you have one code base when it comes to data access and then you just set the current connection based on whether you want the Access or SQL Database.
I would wrap the "ugly" bits of code in a separate method, or preferably a class which takes care of choosing which DB to talk to and the synchronization with the actual BackgroundWorker instances. The important point here is to adhere to the DRY principle: Don't Repeat Yourself.
I think that for a work project, you should do it as fast as possible, without thinking of future databases, because it's probably not gonna happen.
Are you sure there's not, somewhere, a class which already works with both Sql Server and MS Access? For example, OleDbConnection, OleDbCommand?
For simple SQL, all you need is to change the connection string and you can work with both databases.
If you haven't coded the rest of the application yet, you should take a day or two to look for some frameworks, compare and choose one of your liking. It'll make you write less code, and in future apps you'll be spared most of the database plumbery code. I guarantee that the time invested will be returned to you manyfold (if you work with databases once in a while, that is).
I've run into this issue quite a few times and never liked the solution chosen. Let's say you have a list of States (just as a simple example) in the database. In your code-behind, you want to be able to reference a State by ID and have the list of them available via Intellisense.
For example:
States.Arizona.Id //returns a GUID
But the problem is that I don't want to hard-code the GUIDS. Now in the past I've done all of the following:
Create class constants (hard-coding of the worst kind.. ugh!)
Create Lookup classes that have an ID property (among others) (still hard-coded and would require a rebuild of the project if ever updated)
Put all the GUIDS into the .config file, create an enumeration, and within a static constructor load the GUIDS from the .config into a Hashtable with the enumeration item as the key. So then I can do: StateHash[StatEnum.Arizona]. Nice, because if a GUID changes, no rebuild required. However, doesn't help if a new record is added or an old one removed, because the enumeration will need to be updated.
So what I'm asking is if someone has a better solution? Ideally, I'd want to be able to look up via Intellisense and not have to rebuild code when there's an update. Not even sure that's possible.
EDIT: Using states was just an example (probably a bad one). It could be a list of widgets, car types, etc. if that helps.
Personally, I would store lookup data in a database, and simply try to avoid the type of hard coding that binds rules to things like individual states. Perhaps some key property of those states (like .ApplyDoubleTax or something). And non-logic code doesn't need to use intellisense - it typically just needs to list them or find by name, which can be done easily enough however you have stored it.
Equally, I'd load the data once and cache it.
Arguably, coding the logic against states is hard coding - especially if you want to go international anytime soon - I hate it when a site asks me what state I live in...
Re the data changing... is the USA looking to annex anytime soon?
I believe that if it shows up in Intellisense, then, by definition, it is hard-coded into your program.
That said, if your goal is make the hard-coding as painless as possible, on thing you might try is auto-generating your enumeration based on what's in the database. That is, you can write a program that reads the database and creates a FOO.cs file containing your enumeration. Then just run that program every time the data changes.
This cries out for a custom MSBuild task. You really want an autogenerated enum or class in this case; if the IDs are sourced from a database and can/will change, and are not easily predicted. You could then put the task in your project and it would run before each build updating as necessary.
Or start looking at ORMs :)