James Craig
Where coding practices come to die.
2021-09-15T00:00:00Z
http://www.gutgames.com/
James Craig
Optimize All The Things
2021-09-15T00:00:00Z
http://www.gutgames.com/post/Optimize-All-The-Things/
<p>I have to say that I love listening to other devs argue about really obscure things. Most of it is bluster and can be ignored but every once in a while you hear about some optimization technique or something that is interesting. My favorites are the times where people claim that X is always faster than Y, so never do Y. The reason that I love them is because some of the claims are just bizarre. The funny bit is usually the conversation ends and that bizarre bit of advice is then past on again and again. No one ever seems to follow up on these with any tests. No one benchmarks.</p>
<p>One time I was told to never use foreach with arrays. It's horrible for performance was what I was told. I asked how he came by this knowledge and his response was that he read it online. I asked if they could send me the source and they threw up their hands and simply changed the subject. After they had walked away, I decided that I was actually going to test what the person said. It took all of 5 minutes to write the benchmark code and another 5 minutes to run it but after that, I discovered that they were wrong. foreach and for are about the same when dealing with arrays.</p>
<p>After that I wondered all of the other instances where I just took a person's word for these optimizations. How many of them were accurate? Or if they WERE accurate all those years ago, how many of them still held up? With that idea in mind, any time I was bored and had nothing to do I created a new benchmark to test some preconceived idea that I had. Eventually I started to pull some of them together and <a href="https://github.com/JaCraig/I-Got-Bored">gathered them together into a repo</a>. Now every time I hear a new speed trick or optimization technique that someone mentions, I add a test for it to see if it's remotely accurate. Much of the time, they aren't but with some I've been amazed at the speed gains that can be made. Also with each new version of .Net, I test to see what still holds true. For instance, with .Net 5 I've found the following seems to be the case:</p>
<ol>
<li>
<p>When dealing with arrays of data inside of a method, use ArrayPool to allocate.</p>
</li>
<li>
<p>Array.Copy is generally better for smaller arrays. Larger arrays (100,000+), Buffer.MemoryCopy seems to be a better option.</p>
</li>
<li>
<p>For arrays, just treat them as arrays when iterating over them. IEnumerable, etc. slow them down.</p>
</li>
<li>
<p>For arrays, foreach and for have no difference at this point in time.</p>
</li>
<li>
<p>If you can, use Array.Sort and List.Sort. They're much faster than the alternatives.</p>
</li>
<li>
<p>The various old optimizations like bitwise math are no longer effective.</p>
</li>
<li>
<p>Unchecked math no longer seems to be substantially faster.</p>
</li>
<li>
<p>Structs are much faster to create than classes. Setting or getting values is about the same though.</p>
</li>
<li>
<p>For ConcurrentDictionary, use TryGetValue over an index or key lookup.</p>
</li>
<li>
<p>For Dictionary, the type of the key matters. Long, uint, ulong, etc. are much faster than string.</p>
</li>
<li>
<p>Dictionary is much faster than ConcurrentDictionary. Only use ConcurrentDictionary when you need to.</p>
</li>
<li>
<p>Dynamic vs static typing, static is about 10x faster.</p>
</li>
<li>
<p>Byte packing is faster than using an enum but it's about 4ns vs 2ns...</p>
</li>
<li>
<p>Fields are slightly faster than properties in certain circumstances.</p>
</li>
<li>
<p>Dictionary is generally faster than Hashtable if using an int as the key. Hashtable seems slightly faster when dealing with string as the key.</p>
</li>
<li>
<p>Array.Copy and List.CopyTo are much faster at copying data over than other options.</p>
</li>
<li>
<p>Arrays are much faster than alternatives for iteration.</p>
</li>
<li>
<p>++x or x++ makes no difference.</p>
</li>
<li>
<p>Use 'is' instead of any of the clever other options if you can for determining the type of an object.</p>
</li>
<li>
<p>If you can, use List.AddRange instead of List.Add.</p>
</li>
<li>
<p>Using a for loop with Lists is the fastest approach.</p>
</li>
<li>
<p>If you need something that looks like a Dictionary, then just use a Dictionary...</p>
</li>
<li>
<p>If you're going to create a list of items, use AddRange instead of feeding them into the constructor.</p>
</li>
<li>
<p>For small items, MemoryStream is better than RecyclableMemoryStream. For larger items, RecyclableMemoryStream is much better though.</p>
</li>
<li>
<p>In terms of what is better (best to worst): Direct Method Call > Func(=>) > Func(Method) > Cached MethodInfo > new Func(=>) > new Func(Method).</p>
</li>
<li>
<p>For null equality, use either is or ReferenceEquals.</p>
</li>
<li>
<p>If you need to create an object, just use new. If you can't use new, compile/cache a lambda expression.</p>
</li>
<li>
<p>Use partitioning when doing Parallel.ForEach if you need to worry about speed but note there will be a slight memory increase.</p>
</li>
<li>
<p>If you're reading in a whole file, create the whole file in one go. This does not apply for instances where you are streaming the file or modifying portions of it.</p>
</li>
<li>
<p>When you can, cache type info as it's not free.</p>
</li>
<li>
<p>When you can, use a simple Contains instead of using Regex.</p>
</li>
<li>
<p>using pointers into an array is slightly faster than a Span.</p>
</li>
<li>
<p>stackalloc seems to be a speed boost at larger number of items.</p>
</li>
<li>
<p>Do not use a static constructor if you don't need to. It gets called every time you call a method on the class.</p>
</li>
<li>
<p>Use a StringBuilder instead of string concat. Memory and speed improvements for anything 100+ concatenations.</p>
</li>
<li>
<p>If you're formatting a string, string concat is usually faster than things like string interpolation.</p>
</li>
<li>
<p>If you can use a StringBuilderPool. Faster and memory improvements to be had.</p>
</li>
<li>
<p>If you are going to replace a value in a string, use string.Replace instead of StringBuilder.Replace.</p>
</li>
<li>
<p>String.Substring works slightly better than Span.Slice.</p>
</li>
<li>
<p>Using string.Substring works better than Trim for small strings. Larger strings, Trim works better.</p>
</li>
<li>
<p>Vector works better than dealing with straight struct, byte array, etc. in terms of speed. Memory increases though.</p>
</li>
</ol>
<p>Note that the above are based on tests that I will not say are perfect. Similarly these aren't like the <a href="https://github.com/dotnet/performance">micro benchmarks</a> that the .Net people do to check speed improvements between versions of .Net. These are just to check differences between approaches to do the same thing. With that in mind, it would be interesting for people to add their own. So feel free to do a pull request with something that you want to test.</p>
Ways to Improve Your Development Process - Fault Injection
2021-08-23T00:00:00Z
http://www.gutgames.com/post/Ways-to-Improve-Your-Development-Process-Fault-Injection/
<p>When I was younger, I assumed that technology was without any issues. If an application failed, it was because of something that I had done to it. It wasn't until I started working and building software that I realized that we are mostly keeping the world running on duct tape and string. The fact that anything works is amazing to say the least. Since that realization, I've gone from assuming that every 3rd party application, resource, and/or API will work to assuming that they will fail. As such I try to build software to accept that failure and as gracefully as I can, tell the user about the failure.</p>
<p>This series has thus far been about introducing various forms of testing that I find useful that I don't see used that often. This is no different as my assumption that the world of code surrounding my various systems is on the verge of crashing and burning has led me to using a form of testing called fault injection. It's a very simple concept: When you're testing against a border of your software such as pulling a file from disk or data from a database, throw an exception and see what your code does. Because generally one of a couple things will happen. Either everything crashes, your system swallows the crash, or you manage to handle the issue gracefully. In an ideal world the third option would be what happens but usually it's one of the other two.</p>
<h2 id="fault-injection">Fault Injection <a class="direct-link" href="http://www.gutgames.com/post/Ways-to-Improve-Your-Development-Process-Fault-Injection/#fault-injection">#</a></h2>
<p>Fault injection is a process to improve dependability of software/hardware. It dates back to around the 1970s where it was generally used to find hardware level faults. The way it was done originally was by shorting connections on a circuit board and observing what would happen. The reason this was done was to test the dependability of the hardware system. This expanded to include everything from hitting it with radiation in the FIST project to electromagnetic fields in the MARS project. These, however, had the issue of being random. Laser Fault Injection, which is where they aimed a freakin' laser at the hardware, on the other hand allowed them to be very precise with injecting faults.</p>
<p>Eventually people made the realization that software issues are probably going to be more common and so they decided to try fault injection at this level. Test beds like <a href="https://ieeexplore.ieee.org/document/364536">Ferrari</a> were created to test systems by introducing memory and bus faults through CPU traps. <a href="https://ntrs.nasa.gov/citations/19950059069">FTAPE</a> introduces CPU, memory, and disk faults through altered drivers and changes to the OS. The list goes on and on for tools at the system level. Organizations such as Netflix, NASA, and Amazon use it to test their distributed systems, with some even doing so in production. And in more recent years this has filtered down to even the unit testing frameworks and suites with surprising results sometimes.</p>
<p><strong>Pros</strong></p>
<ol>
<li>
<p>There are a number of different approaches for fault injection testing as well as a <a href="https://www.clereco.eu/images/publications/DTIS.2014.pdf">ton of different systems</a> aimed at this topic so finding exact figures of how much each one of them helps is difficult to come by. On top of that it completely depends on what you're building. However <a href="https://d1wqtxts1xzle7.cloudfront.net/42307671/natella_sfi_tse_2011_preprint-with-cover-page-v2.pdf?Expires=1629745890&Signature=E5WIfDC~xMZDzLmWqY2KDKmliGixqIhmH5nmoZYtmYRAndAxMjGjK1dqrGgKbiTRCo61g3HTQ9zrgshgzQOKraoYHINskOMH2S7koebLmhTuHWcatl1hpHzaLljsfV9grCK0vTKYT-TCyXdx1m5G0lAdJ338x1yVGZW87fxlBfrnGT~aPjEOV3CeR1lKe3bTcTiqXteK0JjEvtu0XtR03c7pcsX-lRHwvUJk2niyA9brZYlJF6a6e7tE9gC~bv5ko9KHnBOtb7ObqgpQ72nkZIFHvpWimX10MoRHw96kWkjbgzgpNMhK~zfw6S8SMASeRZHPOQC~LpM301LnVfyynA__&Key-Pair-Id=APKAJLOHF5GGSLRBV4ZA">in some studies involving DBMSs</a>, there is evidence that anywhere from 15% to 70%+ of the tests miss these types of issues. Thus bugs are in production systems that people have no idea are even there.</p>
</li>
<li>
<p>With the right set of tools, you don't need to do much of anything in order to start using this technique. Especially at the unit test level.</p>
</li>
</ol>
<p><strong>Cons</strong></p>
<ol>
<li>
<p>Depending on what you're building you may see no benefit from this tool. 15% to 70% is great but those are databases they were testing. If you're building a completely self contained application then you'll probably not see much in the way of improvement.</p>
</li>
<li>
<p>Some of the tools out there go well beyond what the average dev needs. If you're building a basic CRUD app, you probably don't need to be pointing lasers at your test servers to try and introduce faults.</p>
</li>
</ol>
<h2 id="fault-injection-tools">Fault Injection Tools <a class="direct-link" href="http://www.gutgames.com/post/Ways-to-Improve-Your-Development-Process-Fault-Injection/#fault-injection-tools">#</a></h2>
<p>Once again, I'm primarily a C# dev by day so I'm going to mention the tool that I have the most experience with but there are ton of them out there for any language or platform that you can think of. Personally the one that I have found the most use out of is <a href="https://github.com/Polly-Contrib/Simmy">Simmy</a>. If you want to cause ultimate chaos, it's pretty much the best spot to start. I also recommend the <a href="https://github.com/App-vNext/Polly">Polly</a> project for a nice way to handle faults in .Net. It's better known than Simmy but they spawned out of the same projects. Simmy breaks and Polly protects.</p>
<p>In order to use Simmy, you just need to create a policy and then use that to wrap a method call:</p>
<pre class="language-csharp"><code class="language-csharp"> <span class="token punctuation">[</span><span class="token attribute"><span class="token class-name">Fact</span></span><span class="token punctuation">]</span><br /> <span class="token keyword">public</span> <span class="token return-type class-name"><span class="token keyword">void</span></span> <span class="token function">MyUnitTest</span><span class="token punctuation">(</span><span class="token punctuation">)</span><br /> <span class="token punctuation">{</span><br /> <span class="token class-name"><span class="token keyword">var</span></span> Policy <span class="token operator">=</span> MonkeyPolicy<span class="token punctuation">.</span><span class="token function">InjectLatency</span><span class="token punctuation">(</span>with <span class="token operator">=></span><br /> with<span class="token punctuation">.</span><span class="token function">Latency</span><span class="token punctuation">(</span>TimeSpan<span class="token punctuation">.</span><span class="token function">FromSeconds</span><span class="token punctuation">(</span><span class="token number">2</span><span class="token punctuation">)</span><span class="token punctuation">)</span><br /> <span class="token punctuation">.</span><span class="token function">InjectionRate</span><span class="token punctuation">(</span><span class="token number">0.5</span><span class="token punctuation">)</span><br /> <span class="token punctuation">.</span><span class="token function">Enabled</span><span class="token punctuation">(</span><span class="token boolean">true</span><span class="token punctuation">)</span><br /> <span class="token punctuation">)</span><span class="token punctuation">;</span><br /> <br /> <span class="token class-name"><span class="token keyword">var</span></span> result <span class="token operator">=</span> <span class="token keyword">await</span> Policy<span class="token punctuation">.</span><span class="token function">ExecuteAsync</span><span class="token punctuation">(</span>token <span class="token operator">=></span> MyService<span class="token punctuation">.</span><span class="token function">MyMethodCall</span><span class="token punctuation">(</span>Param1<span class="token punctuation">,</span> Param2<span class="token punctuation">)</span><span class="token punctuation">,</span> MyCancellationToken<span class="token punctuation">)</span><span class="token punctuation">;</span><br /> <span class="token punctuation">}</span></code></pre>
<p>The above code adds 2 seconds of latency to that call about 50% of the time. You can also throw exceptions, return a certain result, or call a method at random intervals. And that's it really. With that you have an easy tool for testing how your code reacts to certain conditions. If you really wanted, you could even put this in your code and simply pass false to the enabled method. Doing so allows you to test API calls, database calls, amongst other things in a test environment without causing issues to your production systems. In test, simply flip the switch. In production, make sure the switch is off.</p>
<p>And with that we have very basic fault injection. As always this has been a very quick overview but if you want, you can go <a href="https://www.amazon.com/Software-Fault-Injection-Jeffrey-Voas/dp/0471183814">on a deeper dive</a> of the topic. Or if you'd prefer there is the <a href="https://microsoft.github.io/code-with-engineering-playbook/automated-testing/fault-injection-testing/">Code With Engineering Playbook</a> description of the subject. Anyway, I'm going to come back to this series and present a couple more types of testing that are easy to add to your tool belt. However in the near future, I want to get down some of my ideas on continuous integration, continuous delivery, and the reasons I'm a big fan of them.</p>
<h2 id="items-in-the-series">Items in the Series <a class="direct-link" href="http://www.gutgames.com/post/Ways-to-Improve-Your-Development-Process-Fault-Injection/#items-in-the-series">#</a></h2>
<ol>
<li><a href="http://www.gutgames.com/post/Ways-to-Improve-Your-Development-Process/">Unit Testing and Automation</a></li>
<li><a href="http://www.gutgames.com/post/Ways-to-Improve-Your-Development-Process-Fuzzing/">Fuzzing</a></li>
<li><a href="http://www.gutgames.com/post/Ways-to-Improve-Your-Development-Process-Property-Based-Testing/">Property-Based Testing</a></li>
<li><a href="http://www.gutgames.com/post/Ways-to-Improve-Your-Development-Process-Mutation-Testing/">Mutation Testing</a></li>
<li><a href="http://www.gutgames.com/post/Ways-to-Improve-Your-Development-Process-Fault-Injection/">Fault Injection</a></li>
</ol>
Ways to Improve Your Development Process - Mutation Testing
2021-07-28T00:00:00Z
http://www.gutgames.com/post/Ways-to-Improve-Your-Development-Process-Mutation-Testing/
<p>One of the things that I've noticed over the years is that our industry tends to be very set in our ways. We hear about a new paradigm or whatever buzz word you want to throw at a concept and we ignore it generally speaking. But give someone an untested new JavaScript library and we're all over it. Testing is generally one of those areas that everyone means to do well and then it falls off a cliff never to be seen again. This is especially true when we have to do example based testing, which basic unit testing is more or less. We give a static input, we expect a static output that equals X. The past couple of posts that I've made have gone over a couple of ways to improve test coverage of the code that we want to ship. Fuzzing can be used to find edge cases or unexpected inputs. Property testing can be used to simplify the example based testing. The joy is that we can add both of them to our setup with minimal cost to us on the development side and they'll find a ton of hidden issues in our code. But what about our tests? How do we know that they're good?</p>
<p>This is one of those areas that a lot of research is being done but it hasn't necessarily made its way to the average developer yet. But there is an easy way to test our tests without too much effort on our part: Mutation testing.</p>
<h2 id="mutation-testing">Mutation Testing <a class="direct-link" href="http://www.gutgames.com/post/Ways-to-Improve-Your-Development-Process-Mutation-Testing/#mutation-testing">#</a></h2>
<p>Mutation testing is pretty simple conceptually speaking. It's a process where faults are automatically added to your code. The addition of these faults makes the resulting code into something known as a mutation and is accomplished by doing things like changing an if statement to be greater than instead of less than or addition instead of subtraction. After we make our change, we run the tests. If your tests fail then the mutation is killed and if your tests pass then the mutation lived.</p>
<p>OK, so how does this help us? Well with this we can measure the quality of our tests by figuring out the percentage of mutations that were killed. The more mutations killed, the better our tests are at finding issues in our code base.</p>
<p>As an example, let's assume we have a code base with traditional unit tests. We can even have 100% branch code coverage in this example. We then make a change in our code and everything passes on the tests BUT as soon as we try to run this thing in production, it crashes and burns. This could be due to issues with libraries that we are linking to or a configuration issue. Similarly it could also be due to us making assumptions in our test suite that pass but are bad assumptions.</p>
<pre class="language-csharp"><code class="language-csharp"> Assert<span class="token punctuation">.</span><span class="token function">Equal</span><span class="token punctuation">(</span><span class="token number">1</span><span class="token punctuation">,</span> TestObject<span class="token punctuation">.</span><span class="token function">MakeObj</span><span class="token punctuation">(</span><span class="token number">2</span><span class="token punctuation">)</span><span class="token punctuation">.</span>SomeProperty<span class="token punctuation">)</span><span class="token punctuation">;</span></code></pre>
<p>In the above code we have no real knowledge of how SomeProperty gets set to 1. Maybe it's simply taking the 1 we sent in and assigning it or maybe it's a more complex formula. Perhaps it's not even based on the value that we sent in. In any case our one test may pass but it's probably not that great of a test. Mutation testing would help point this out to us. So what's the pros/cons of mutation testing?</p>
<p><strong>Pros</strong></p>
<ol>
<li>
<p>It has been used with success to find bugs in code and is generally <a href="https://www.researchgate.net/profile/Jeff-Offutt/publication/224468520_An_Experimental_Comparison_of_Four_Unit_Test_Criteria_Mutation_Edge-Pair_All-Uses_and_Prime_Path_Coverage/links/0046353b595dced33b000000/An-Experimental-Comparison-of-Four-Unit-Test-Criteria-Mutation-Edge-Pair-All-Uses-and-Prime-Path-Coverage.pdf">better than alternative methods for finding issues with unit tests</a>.</p>
</li>
<li>
<p>It also <a href="https://d1wqtxts1xzle7.cloudfront.net/30711971/offutt.pdf?1361989134=&response-content-disposition=inline%3B+filename%3DAn_experimental_evaluation_of_data_flow.pdf&Expires=1627495463&Signature=dCsUS19AHUU0-KpMbXTDH2Z~EN3O6638otTuzQILlbpbFokWxu9rv5yt1NVFZ3g6ZtG8gtzgMdDr4zQ7q8U4xDweVbwsdK4UEmW8vr1m1QTwHwpDsZPMbXjjihVbVAW09EnU21S21S4Xxr0eocYmHENpvQ8K99Fej~GRCPdG1pNNLjUUyxlLcLlGiedG3x8nMB~yM1cuhIJncSfaE61VR9pLGQx0q3p3H4BN64ONTcppbomGxEw~EOwA4xdcsHACUSRwTzdnTHay6TBF13Uo0X~CmVutRLnHJJo3w8H7hxhleft6jskAsOJg-7svCSshDl5XvTdMxKk1pAN~aqTfpw__&Key-Pair-Id=APKAJLOHF5GGSLRBV4ZA">leads to improved code coverage quite a bit</a>.</p>
</li>
</ol>
<p><strong>Cons</strong></p>
<ol>
<li>It's slow. Really slow sometimes, with <a href="https://d1wqtxts1xzle7.cloudfront.net/57324061/AnInvestigationOfCompressionTechniquesToSpeedUpMT.pdf?1536377228=&response-content-disposition=inline%3B+filename%3DAn_Investigation_of_Compression_Techniqu.pdf&Expires=1627495622&Signature=WqgMMCCdKM-L~gNP20Ewh-ECKnm2ya3PVNkmgJEeWvC5nnfl6rbV01au6zV1820sE0lPEFYAgQM579aWpo~JvQz~4kkl8-usPi1K2AmxAhsmKNCrXz9GD8QHRR0naRgEIU63pm2ZMRMIfEosSDZ7dZvODMD5NgZ6G~~xTFy4SQQ3DEzvImMwEhuixeUNMrIcCEWrKlclLA5iZ~4srjeRbRiKOHjtCcIjbvdbTIkCo-5P38mGo-IvF9XmIyl2zS2nUmjy1c1gThVBy-gOrtBsCnyMZbvDy-IwG5qk0JMI~r2n4WlUrNebx9YFbgkLgtJY-~iXnIi3kpB0wZ-8xoPEiA__&Key-Pair-Id=APKAJLOHF5GGSLRBV4ZA">much of the research being aimed at speeding up the process</a>.</li>
<li>There is potential for getting fatigue from duplicate issues being reported to the developer. A real issue and area of research is finding <a href="https://orbilu.uni.lu/bitstream/10993/31612/1/survey.pdf">effective ways to detect equivalent and redundant mutants</a>. Not doing this leads to developers being inundated with the same info over and over again.</li>
</ol>
<p>So considering the aim of this type of testing and the speed issues, this isn't something that you would run every build. This is more of a check up on your code base that you run late at night or over a weekend to see if it kicks up anything. That said, it's usually fire and forget until it finishes so the trade off is usually worth it.</p>
<h2 id="mutation-testing-tools">Mutation Testing Tools <a class="direct-link" href="http://www.gutgames.com/post/Ways-to-Improve-Your-Development-Process-Mutation-Testing/#mutation-testing-tools">#</a></h2>
<p>There are a surprising number of tools in this area, especially considering the lack of use that mutation testing gets in the average corporate dev job. The one that I like to use is <a href="https://stryker-mutator.io/">Stryker Mutator</a>. It supports JavaScript, TypeScript, Scala, and C#. It tends to run rather quickly relatively speaking, supports most test runners, and has good reporting capabilities.</p>
<p>In the case of C#, it <a href="https://stryker-mutator.io/docs/stryker-net/Getting-started">installs as a dotnet tool</a> and from there you just run this from your unit test library:</p>
<pre class="language-powershell"><code class="language-powershell">dotnet stryker</code></pre>
<p>And that's it. It will then go and try to find issues with your code. With that you have mutation testing now in your pipeline and another tool to help reduce issues in your code.</p>
<h2 id="items-in-the-series">Items in the Series <a class="direct-link" href="http://www.gutgames.com/post/Ways-to-Improve-Your-Development-Process-Mutation-Testing/#items-in-the-series">#</a></h2>
<ol>
<li><a href="http://www.gutgames.com/post/Ways-to-Improve-Your-Development-Process/">Unit Testing and Automation</a></li>
<li><a href="http://www.gutgames.com/post/Ways-to-Improve-Your-Development-Process-Fuzzing/">Fuzzing</a></li>
<li><a href="http://www.gutgames.com/post/Ways-to-Improve-Your-Development-Process-Property-Based-Testing/">Property-Based Testing</a></li>
<li><a href="http://www.gutgames.com/post/Ways-to-Improve-Your-Development-Process-Mutation-Testing/">Mutation Testing</a></li>
<li><a href="http://www.gutgames.com/post/Ways-to-Improve-Your-Development-Process-Fault-Injection/">Fault Injection</a></li>
</ol>
Ways to Improve Your Development Process - Property-Based Testing
2021-06-29T00:00:00Z
http://www.gutgames.com/post/Ways-to-Improve-Your-Development-Process-Property-Based-Testing/
<p>At this point I've talked about a <a href="http://www.gutgames.com/post/Ways-to-Improve-Your-Development-Process/">base line</a> along with the concept of <a href="http://www.gutgames.com/post/Ways-to-Improve-Your-Development-Process-Fuzzing/">fuzzing</a>. The basic example based unit tests get us to a point where we're somewhat confident that our software does what we expect when we give it known values. Fuzzing, on the other hand, gives us piece of mind that our software isn't going to blow up. That's great but I'm lazy so is there a way to get the advantages of both in one package? I don't know why I asked that as a question as the answer is obviously yes or I wouldn't have brought it up. On top of that you read the title so you should already have an idea that I'm talking about property-based testing.</p>
<h2 id="property-based-testing">Property-Based Testing <a class="direct-link" href="http://www.gutgames.com/post/Ways-to-Improve-Your-Development-Process-Property-Based-Testing/#property-based-testing">#</a></h2>
<p>Property-based testing generally came about in the late 1990s with libraries like <a href="http://www.cse.chalmers.se/~rjmh/QuickCheck/">QuickCheck</a>. QuickCheck was a library in Haskell that tested an application automatically based on the specifications that the developer gave about how the code should act. The library then finds interesting inputs to see if those specifications hold true or not. In instances where a specification fails, it then does an interesting thing where it runs the code over and over again using a slightly modified input value set. It does this in order to find the smallest input possible that fails the test. For instance if an array of three items fails, it may remove one and see if it continues to fail. Each time removing one until it passes. This, for me, is one of the nicest bits about it as instead of looking at a huge string trying to figure out where the issue is, it's usually the minimal value. In the years since there have been a number of improvements in this space with people expanding it out to testing REST/GraphQL endpoints, testing machine learning algorithms, among other things.</p>
<p>As far as how property testing relates to fuzzing, that's one of those debates that gets surprisingly heated. But generally the way that I view it is that property testing takes the concepts of fuzzing and unit testing and merges them together in an attempt to take the best features of both. For instance property testing is similar to fuzzing in that it takes randomly generated values and checking if the application has issues. With fuzzing we're left with a black box approach where it has no real idea of what the app is attempting to do. We are just looking for that exception to be thrown. With property testing, the developer knows basic facts about the application or bit of code in question. As such we tell it what can be considered a correct response and what is a failing test making it similar to unit tests. Another distinction is that fuzzing generally uses "dumb" data. It's usually completely random. With property tests, we tell it what the general shape of the randomized data should look like. This reduces the search space from the crazy levels that fuzzing deals with to one that's usually a lot more manageable. This reduces the amount of time it takes from hours, days, or weeks down to the seconds and minutes time frame.</p>
<p><strong>Pros</strong></p>
<ol>
<li>
<p>The run time for property tests is greatly reduced leaving us with more time to code because we're limiting our search space to relevant data.</p>
</li>
<li>
<p>Because the data is mostly random, we end up with high branch code coverage similar to fuzzing.</p>
</li>
</ol>
<p><strong>Cons</strong></p>
<ol>
<li>
<p>You have to have a high level of knowledge of the code in order to define the properties.</p>
</li>
<li>
<p>Since we constrain the input values, we may never be able to generate truly bizarre and security critical inputs. Thus fuzzing is generally a better fit for security testing.</p>
</li>
</ol>
<p>I will say that I generally like to find peer reviewed papers to figure out a tangible benefit. For instance the testing time boosts or code coverage stats would be nice but amazingly this seems to be an area of research that is lacking quite a bit. Property-Based Testing is generally accepted as very helpful but finding results to show just how much is difficult at this point in time. That said practical experience by many individuals seems to pan out that the above pros and cons are true.</p>
<p>Looking at the pros alone, you may be thinking "Awesome, I'll just start using this instead of unit tests and fuzzing". The issue is that you have to have domain knowledge of the code that you are testing. And usually that knowledge has to be rather deep. You'll see why in a second. This will be a very simple example to show how deceptive it can be. Let's assume that we have code that adds 1 to an input value to get an index:</p>
<pre class="language-csharp"><code class="language-csharp"> <span class="token keyword">public</span> <span class="token return-type class-name"><span class="token keyword">int</span></span> <span class="token function">NextIndex</span><span class="token punctuation">(</span><span class="token class-name"><span class="token keyword">int</span></span> <span class="token keyword">value</span><span class="token punctuation">)</span> <span class="token operator">=></span> <span class="token keyword">value</span><span class="token operator">++</span><span class="token punctuation">;</span></code></pre>
<p>With property testing, we wouldn't be testing specifically the resulting value because we'd be feeding the function random-ish values. Instead we'd be testing things that we know to be true. For instance we may expect the result from the method above had a value greater than the value that we sent in. That seems correct but is that always the case? Since that's C# above, what happens if we enter in int.MaxValue? Let's scratch C# and let's say we're using a language that doesn't do overflow checking. In that instance we may wrap around to the min value. Do we want that to happen? I mean maybe. Let's say instead of an int, we're using a byte to hold the index of a circular buffer. When we hit 255, loop back to 0. The fact is that without a lot more information about what the above code is being used for, you have no way of determining what the properties for that code should be. Similarly you may make assumptions of the code to only find that those properties don't always hold true. Or what about an instance where you only have access to the library's API and not the internal code? In that instance you would have no idea how it picked the next index. That limits our ability to think up properties even more. So in instances where you are lacking information, a simple example based unit test and fuzzing may be as good as you can do.</p>
<h2 id="property-based-testing-tools">Property-Based Testing Tools <a class="direct-link" href="http://www.gutgames.com/post/Ways-to-Improve-Your-Development-Process-Property-Based-Testing/#property-based-testing-tools">#</a></h2>
<p>I'm going to be honest and say that I'm a bit biased on this one. You may be thinking that I'm saying that because of <a href="https://github.com/JaCraig/Mecha">my own</a> library which uses the concepts but no. I'm talking about <a href="https://fscheck.github.io/FsCheck/">FsCheck</a>, a property based testing library based on QuickCheck. Don't get me wrong, I'd love people to try out my library and give feedback, build upon it, etc. But FsCheck is a joy to work with. FsCheck is a library written in F# that works with C#, <a href="http://vb.net/">VB.Net</a>, F#, etc. to bring property testing to the .Net world. If you're from the F# world then you probably know about it already. If you're from the C# world then this may be your first time hearing about it. The best part is it even has a plugin for <a href="https://www.nuget.org/packages/FsCheck.Xunit/">xUnit</a> to make the experience pretty simple. And if you're using another language, you're in luck as there is probably a library based on QuickCheck for you also. In all seriousness, they're everywhere.</p>
<p>That's the basic concept in a nutshell. So with all of that we have our first easy upgrade to our testing environment. Once you add it to your inventory you should be able to find a number of new bugs that you had never found before. Next time I'll talk about fault tolerance.</p>
<h2 id="items-in-the-series">Items in the Series <a class="direct-link" href="http://www.gutgames.com/post/Ways-to-Improve-Your-Development-Process-Property-Based-Testing/#items-in-the-series">#</a></h2>
<ol>
<li><a href="http://www.gutgames.com/post/Ways-to-Improve-Your-Development-Process/">Unit Testing and Automation</a></li>
<li><a href="http://www.gutgames.com/post/Ways-to-Improve-Your-Development-Process-Fuzzing/">Fuzzing</a></li>
<li><a href="http://www.gutgames.com/post/Ways-to-Improve-Your-Development-Process-Property-Based-Testing/">Property-Based Testing</a></li>
<li><a href="http://www.gutgames.com/post/Ways-to-Improve-Your-Development-Process-Mutation-Testing/">Mutation Testing</a></li>
<li><a href="http://www.gutgames.com/post/Ways-to-Improve-Your-Development-Process-Fault-Injection/">Fault Injection</a></li>
</ol>
Ways to Improve Your Development Process - Fuzzing
2021-06-02T00:00:00Z
http://www.gutgames.com/post/Ways-to-Improve-Your-Development-Process-Fuzzing/
<p>My <a href="http://www.gutgames.com/post/Ways-to-Improve-Your-Development-Process/">last post</a> was me jotting down a few ideas that I've had involving ways to improve development processes. The easiest way to do that is to get a baseline of continuous testing and measuring your code to improve the quality of your code. So all of that gets us to what I consider the baseline that you should consider the minimum for most projects and work environments. The main question at this point is how do we improve upon that?</p>
<p>For now let's stick to testing improvements. Any time we can reduce the number of bugs in our code, that means less time spent after launch at 2AM dealing with a dead service. In later posts I'll talk about automation, tools, etc. that can help with delivery speed a lot more but for now we're going to stick to testing. In this instance we're going to look at:</p>
<h2 id="fuzz-testing">Fuzz Testing <a class="direct-link" href="http://www.gutgames.com/post/Ways-to-Improve-Your-Development-Process-Fuzzing/#fuzz-testing">#</a></h2>
<p>Fuzz testing was originally thought up in a graduate Advanced Operating Systems class in 1988 that was being taught by Barton Miller at University of Wisconsin as a class project. The results were eventually published in 1990. The concept was to test a Unix utility meant to automatically generate random files and parameters as inputs. By doing this with a large number of random inputs and in quick succession they were able to find ways to crash the software. At the time they were able to crash about 30% of the utilities they tested. These were previously undiscovered issues in the software that they were able to debug to determine the cause and categorize each failure.</p>
<p>Since then there have been a number of advances, tons of study, software built, as well as interesting use cases for them. The obvious one is simply to make software more reliable, however fuzz testing has traditionally found a home in security circles as reliability and security tend to go hand in hand. Also note that fuzz testing can happen at multiple levels: the application, a library, a class, or a method. We just need something with an entry point.</p>
<p><strong>Pros</strong></p>
<ol>
<li>
<p>Generally speaking, it's <a href="http://scholar.googleusercontent.com/scholar?q=cache:9oJNytRmYfUJ:scholar.google.com/+%22fuzz+testing%22++benefits&hl=en&as_sdt=0,47&as_ylo=1980&as_yhi=2000">very good at finding bugs in your software</a>. For instance the paper linked was able to find issues in the IRIX kernel within a couple of minutes of testing and this was back in 1996. You may be thinking that the old tests aren't very valid but more recently it was used to find a <a href="https://arxiv.org/pdf/2008.06537.pdf">number of bugs in Linux, MacOS, and FreeBSD</a>. Specifically 12% of the apps in Linux were found to fail, 16% for MacOS, and 19% for FreeBSD. And those numbers were an increase from the same test they ran years ago.</p>
</li>
<li>
<p>We can set this up like any other test to run automatically for us. Nothing needs to be done except look for the exceptions to be thrown.</p>
</li>
</ol>
<p><strong>Cons</strong></p>
<ol>
<li>
<p>It's a slow process. Depending on what you're testing you can run the thing for weeks without hitting just the right set of inputs to trigger a failure. This is especially true the higher up the method => class => library => application tree you go.</p>
</li>
<li>
<p>It does not test correctness of your software. It isn't going to check that your app creates a correctly formatted xml file for instance. Instead it tests reliability. You're looking for the bugs when a user's kid hits the keyboard 14 times and it causes the app to crash sort of bugs.</p>
</li>
</ol>
<p>There are a number of directions that people have gone to improve the slow issue as well as increasing the number of issues that the fuzzer finds. For instance <a href="https://llvm.org/docs/LibFuzzer.html">some take the approach of trying to maximize code coverage</a> to improve the number of issues found. Some use <a href="https://ieeexplore.ieee.org/abstract/document/8115618">machine learning to direct the search process</a>. All of them are interesting but if you want a very detailed run down on the various approaches and concepts, I recommend the <a href="https://www.fuzzingbook.org/">Fuzzing Book</a>. Instead we'll go over a very basic example.</p>
<p>Let's assume you have a method that takes in a string and an integer that indicates the number of characters in the string. The method is supposed to return the string. Now let's assume that you want to write some tests for your code.</p>
<pre class="language-csharp"><code class="language-csharp"> Assert<span class="token punctuation">.</span><span class="token function">Equals</span><span class="token punctuation">(</span><span class="token string">"car"</span><span class="token punctuation">,</span> <span class="token function">MyMethod</span><span class="token punctuation">(</span><span class="token string">"car"</span><span class="token punctuation">,</span> <span class="token number">3</span><span class="token punctuation">)</span><span class="token punctuation">)</span><span class="token punctuation">;</span><br /> Assert<span class="token punctuation">.</span><span class="token function">Equals</span><span class="token punctuation">(</span><span class="token string">"test"</span><span class="token punctuation">,</span> <span class="token function">MyMethod</span><span class="token punctuation">(</span><span class="token string">"test"</span><span class="token punctuation">,</span> <span class="token number">4</span><span class="token punctuation">)</span><span class="token punctuation">)</span><span class="token punctuation">;</span><br /> Assert<span class="token punctuation">.</span><span class="token function">Equals</span><span class="token punctuation">(</span><span class="token string">"testy mctestface"</span><span class="token punctuation">,</span> <span class="token function">MyMethod</span><span class="token punctuation">(</span><span class="token string">"testy mctestface"</span><span class="token punctuation">,</span> <span class="token number">16</span><span class="token punctuation">)</span><span class="token punctuation">)</span><span class="token punctuation">;</span></code></pre>
<p>In the above the code works and the test doesn't fail. Yay, we passed our test. We're done right? Well, if you've ever dealt with C/C++ you already know the answer is hell no. What happens if the string is null? What happens if we enter a number less than the number of characters in the string? What happens if we enter a number greater than the number of characters in the string? What happens if the number is negative? What about the \0 character in the string?</p>
<p>You'll notice that our search space is growing a lot and I'm lazy and don't want to add all those test cases by hand. In this instance we could actually use the concepts found in fuzzing to generate all of those values and more that we didn't think of to test our code for correctness as well as stability. But even in instances where we can't guarantee the outcome of the method as easily based on the input, we could still ensure that our code doesn't fail. Bulletproof code that we can reuse is always a good thing. So how do we go about doing this automatically with little to no setup on our part? Thankfully there are tools for that.</p>
<h2 id="fuzzing-tools">Fuzzing Tools <a class="direct-link" href="http://www.gutgames.com/post/Ways-to-Improve-Your-Development-Process-Fuzzing/#fuzzing-tools">#</a></h2>
<p>This is more of a quick run down than a deep dive and aimed at showing you some options out there. For this I'll be talking about the .Net space as that's the world that I come from. Anyway, the main option for fuzzing an application or library is <a href="https://github.com/Metalnem/sharpfuzz">SharpFuzz</a>. SharpFuzz is an AFL-based fuzzer. It works well, very easy to get going, and <a href="http://lcamtuf.coredump.cx/afl/">AFL</a> is one of the most popular fuzzers out there and SharpFuzz is a wrapper around AFL.</p>
<p>For API endpoint testing, there are a number of options like <a href="https://github.com/microsoft/rest-api-fuzz-testing">RAFT</a>, <a href="https://pypi.org/project/APIFuzzer/">APIFuzzer</a>, among others. The number of options here goes up as not only are there a ton of open source projects but a number of paid services. And since your API is just a web end point, language or platform isn't an issue. Just find a tool that you like. Personally I like <a href="https://www.zaproxy.org/">OWASP ZAP</a> just because it's free and easy to get going with if you want to do fuzzing.</p>
<p>In the example above, we're down at the unit testing/individual method levels of fuzzing and sadly I couldn't find that many options out there when I was originally searching for them. <a href="https://docs.microsoft.com/en-us/visualstudio/test/intellitest-manual/?view=vs-2019">IntelliTest</a> could be considered a fuzzer. It does take an iterative approach to try to increase code coverage by generating different inputs for a method. The caveat is that the values it generates aren't truly random but I'd still say that it falls under the general umbrella. That said if you don't have Enterprise edition of Visual Studio then you don't have access. Great tool if you have it. Other than that searching around only popped up a number of old/unsupported libraries more or less. However since I had a need a couple years ago, I created a plugin for xUnit called <a href="https://github.com/JaCraig/TestFountain">TestFountain</a>. Just add the <a href="https://www.nuget.org/packages/TestFountain/">Nuget package</a> and then add the attribute to your unit test:</p>
<pre class="language-csharp"><code class="language-csharp"> <span class="token punctuation">[</span><span class="token attribute"><span class="token class-name">Theory</span></span><span class="token punctuation">]</span><br /> <span class="token punctuation">[</span><span class="token attribute"><span class="token class-name">FountainData</span><span class="token attribute-arguments"><span class="token punctuation">(</span><span class="token number">100</span><span class="token punctuation">,</span> <span class="token number">1000</span><span class="token punctuation">)</span></span></span><span class="token punctuation">]</span><br /> <span class="token keyword">public</span> <span class="token return-type class-name"><span class="token keyword">void</span></span> <span class="token function">MyUnitTest</span><span class="token punctuation">(</span><span class="token class-name"><span class="token keyword">string</span></span> value1<span class="token punctuation">,</span> <span class="token punctuation">[</span><span class="token attribute"><span class="token class-name">Range</span><span class="token attribute-arguments"><span class="token punctuation">(</span><span class="token number">1</span><span class="token punctuation">,</span> <span class="token number">100</span><span class="token punctuation">)</span></span></span><span class="token punctuation">]</span><span class="token class-name"><span class="token keyword">int</span></span> value1Length<span class="token punctuation">)</span><br /> <span class="token punctuation">{</span><br /> Assert<span class="token punctuation">.</span><span class="token function">Equals</span><span class="token punctuation">(</span>value1<span class="token punctuation">,</span> <span class="token function">MyMethod</span><span class="token punctuation">(</span>value1<span class="token punctuation">,</span> value1Length<span class="token punctuation">)</span><span class="token punctuation">)</span><span class="token punctuation">;</span><br /> <span class="token punctuation">}</span></code></pre>
<p>This would be the equivalent of the tests above using the plugin that I created. That will generate 100 random input values based on the range that you set for the input and will attempt to take a max of 1 second. Anything over that and it will stop after the next run. Also there may be other options out there but I couldn't find them when I needed them.</p>
<p>More recently I've taken this small plugin and added a lot more features that I've been looking for and created the <a href="https://github.com/JaCraig/Mecha">Mecha library</a>. Going forward that will be where I will add features and improvements as I find a need for them. I've been testing it with a couple of my other libraries and already found bugs (null reference, index out of bounds, etc.) so I'm happy with the results thus far. Best part for me is that I can test an entire class with one line of code, because once again I'm lazy:</p>
<pre class="language-csharp"><code class="language-csharp"> Mech<span class="token punctuation">.</span><span class="token generic-method"><span class="token function">BreakAsync</span><span class="token generic class-name"><span class="token punctuation"><</span>MyClass<span class="token punctuation">></span></span></span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">;</span></code></pre>
<p>While I created something for my own needs, in reality all you need to do is create random data for a method that you want to test to get the basic benefits of fuzzing. You could use <a href="https://github.com/bchavez/Bogus">Bogus</a>, <a href="https://github.com/MisterJames/GenFu">GenFu</a>, or any number of libraries for generating values. Heck want to try a machine learning setup for input generation, I've done it with <a href="http://ml.net/">ML.Net</a> and it works fairly well. But generally any random value generator will get you started. In my case, once again, <a href="https://github.com/JaCraig/Mirage">I use my own</a> but there are about 20 different ones out there to choose from. Just generate values and see if it throws an error. Because with fuzzing, you're not generally looking for code correctness, you're looking for what breaks your code so you can defend against it appropriately.</p>
<p>That's the basic concept in a nutshell. So with all of that we have our first easy upgrade to our testing environment. Once you add it to your inventory you should be able to find a number of new bugs that you had never found before. Next time I'll talk about fault tolerance.</p>
<h2 id="items-in-the-series">Items in the Series <a class="direct-link" href="http://www.gutgames.com/post/Ways-to-Improve-Your-Development-Process-Fuzzing/#items-in-the-series">#</a></h2>
<ol>
<li><a href="http://www.gutgames.com/post/Ways-to-Improve-Your-Development-Process/">Unit Testing and Automation</a></li>
<li><a href="http://www.gutgames.com/post/Ways-to-Improve-Your-Development-Process-Fuzzing/">Fuzzing</a></li>
<li><a href="http://www.gutgames.com/post/Ways-to-Improve-Your-Development-Process-Property-Based-Testing/">Property-Based Testing</a></li>
<li><a href="http://www.gutgames.com/post/Ways-to-Improve-Your-Development-Process-Mutation-Testing/">Mutation Testing</a></li>
<li><a href="http://www.gutgames.com/post/Ways-to-Improve-Your-Development-Process-Fault-Injection/">Fault Injection</a></li>
</ol>
Ways to Improve Your Development Process
2021-05-14T00:00:00Z
http://www.gutgames.com/post/Ways-to-Improve-Your-Development-Process/
<p>When it comes to software development there are different levels when it comes to software reliability. The highest echelons would include things like formal proofs while the lowest levels being fire and pray. Note that while I say that the formal proofs would be the high end, I'm not saying everyone should shoot for that. It's time consuming and usually not worth the effort depending on what you're building. However, that doesn't mean that you can't improve your standing on that axis. Let's look at easy ways to do that.</p>
<h2 id="unit-tests">Unit Tests <a class="direct-link" href="http://www.gutgames.com/post/Ways-to-Improve-Your-Development-Process/#unit-tests">#</a></h2>
<p>For the sake of argument lets assume that you have no testing infrastructure in place at all. Perhaps that's because you don't see the point OR because you simply are new to the concept. As such we'll start with the basic tool: Unit testing. Unit testing is a level of testing where we're trying to make sure individual bits of our code works the way we expect it to. The purpose is just to validate those small bits and not the application as a whole.</p>
<p>What is the point of this? I ran my code and it worked on my machine. Well, the issue is generally as you build software, you tend to go back and modify previously written code. The point of the unit tests is to make sure that both your original pass of the code works and secondly that those changes later didn't break something unexpectedly.</p>
<p>Cool, sounds good so is this a universal good thing to do? Well, there are several benefits that come with unit testing but also some downsides:</p>
<p><strong>Pros</strong></p>
<ol>
<li>
<p>There is some evidence that it actually <a href="https://www.researchgate.net/profile/Maurizio-Morisio/publication/3188484_On_the_effectiveness_of_the_test-first_approach_to_programming/links/0046351aef3d1d6b0d000000/On-the-effectiveness-of-the-test-first-approach-to-programming.pdf">helps with productivity</a>.</p>
</li>
<li>
<p>It has almost uniformly been shown to <a href="https://ieeexplore.ieee.org/abstract/document/5362086">reduce defects in software</a> by a similar amount, 20% to 30%.</p>
</li>
<li>
<p>Code tends to be more reusable because in order to make unit testing possible, code needs to be modular.</p>
</li>
</ol>
<p><strong>Cons</strong></p>
<ol>
<li>
<p>There are <a href="https://www.researchgate.net/profile/Michael-Ellims/publication/42790485_The_Economics_of_Unit_Testing/links/546e02270cf2b5fc17602cad/The-Economics-of-Unit-Testing.pdf">issues maintaining the unit tests over the lifetime of a project</a>.</p>
</li>
<li>
<p>So while some research has shown the benefits to productivity, many show an increase of 20% to 30% development time. More development time means that the cost to develop the project goes up initially but long-term maintenance of the software takes less resources due to the reduction in defects. So, spend money now or a lot more later.</p>
</li>
</ol>
<p>If the reduction of issues at 3 AM isn't an issue for you and you don't want to spend the time or resources, awesome. The rest of this post and the next couple will be of no use to you. Feel free to jump now. For those that want to find out HOW to do unit tests, a decent starter is a book like <a href="https://www.amazon.com/dp/0321146530">Test-Driven Development by Example</a> or if you want a quick overview there are a number of blog posts out there like <a href="https://peter.bloomfield.online/how-to-write-a-good-unit-test/">this one</a>. Note that you don't have to do test driven development. You can always write tests after writing the functionality. Like the above there are pros and cons to the practice. On top of that most research shows <a href="https://www.researchgate.net/publication/299469939_105923jse2012020301">very little difference</a> between writing the tests up front vs after the fact. I find it depends on how you build software as to which is better for any individual situation. With that in mind we'll just assume that you have tests and not worry about how you got there when looking at the next step.</p>
<h2 id="continuous-testing">Continuous Testing <a class="direct-link" href="http://www.gutgames.com/post/Ways-to-Improve-Your-Development-Process/#continuous-testing">#</a></h2>
<p>So let's assume that you have tests. Awesome but when was the last time you ran them? If you're running them manually then probably not nearly as often as you need to be. The longer you go between writing them and running them, the less useful they are. You write a bunch of code and when you run them you have to potentially go through days worth of code to find the bug that you introduced. Doing this leads people to drop unit testing. What's the way to fix this? Continuous testing.</p>
<p>What is continuous testing? It's testing that occurs automatically after some trigger happens. For many tools, it happens on a build server during the continuous integration build process. However, there's nothing stopping you from using some of them on your own system. Much of the time IDEs will allow you to automatically run tests when you build. Check a box and you're done. Sometimes there are plugins like <a href="https://github.com/continuoustests/ContinuousTests/">Continuous Tests</a> to fill the gap. In either instance they allow you to run the tests on your own system at specific times in your development process. And assuming you wrote your tests well enough it shouldn't impact anything. Run in the background and just go about your business.</p>
<p>Should you use the build process integrations or the ones in your IDE? Both. Make it part of your development process so you get feedback while you're still working on the item AND make it part of your final build process. Never push anything to production without that final build testing. But for starting out, let's look at setting it up on your own system. What are the pros and cons?</p>
<p><strong>Pros</strong></p>
<ol>
<li>
<p>Reduces overall <a href="https://citeseerx.ist.psu.edu/viewdoc/download?doi=10.1.1.116.7497&rep=rep1&type=pdf">wasted time when developing by about 10%</a>.</p>
</li>
<li>
<p>Developers tend to be more likely to <a href="http://citeseerx.ist.psu.edu/viewdoc/download?doi=10.1.1.68.2143&rep=rep1&type=pdf">finish the thing that they're working on in less time</a> when using continuous testing tools. Note that the linked study was about students finishing a project in a given amount of time. It's assumed that if given more time the people not using the tool would have also finished the project.</p>
</li>
</ol>
<p><strong>Cons</strong></p>
<ol>
<li>
<p>While continuous testing is only a small portion of it, continuous integration's <a href="https://arxiv.org/pdf/2103.05451.pdf">impact is mixed</a> but generally considered positive.</p>
</li>
<li>
<p>Waiting for tests to complete takes up about <a href="https://dspace.mit.edu/handle/1721.1/30096">10% of development time</a> when they're used. But that's if you wait for them to complete and not just continue with developing code. It can also be mitigated by having the system build the software and test in the background, only notifying you when there are issues.</p>
</li>
</ol>
<p>Setting this up is different for each language but usually it's a cheap way to improve your testing. Much of the time being a single check box and you're done. And the bonus is that about 90% of the developers that try it recommend using it. At least based on the literature. Adding it to your continuous integration system as well, which you should also be doing, adds another layer to help you and is usually equally simple to set up.</p>
<p>Anyway, we now have tests and continuously are running those tests. So based on the literature, that means we are getting the improvements in defect reduction with the tests and mitigating some, but not all, of the speed issues with continuous testing. So, what's the next step?</p>
<h2 id="metric-gathering">Metric Gathering <a class="direct-link" href="http://www.gutgames.com/post/Ways-to-Improve-Your-Development-Process/#metric-gathering">#</a></h2>
<p>I can hear the collective groan from here. Metrics have a tendency to be used as a weapon against developers, testers, and the like because generally people don't understand them. Metrics are nothing more than indicators that can be used to help you. The key is to use metrics that are shown to have a correlation with helping you identify areas of your code base that you want to spend some extra effort testing.</p>
<p>So what are those metrics? Well to be honest you can get by with a short list of items:</p>
<ol>
<li>
<p><a href="https://www.tutorialspoint.com/cohesion-in-chash">Code cohesion</a>. Note that this hasn't been tested as much as I would like but cohesion seems to have a <a href="https://www.researchgate.net/publication/221317518_Exploring_Empirically_the_Relationship_between_Lack_of_Cohesion_and_Testability_in_Object-Oriented_Systems">high correlation with testability of software</a>. Higher cohesion means higher testability. Higher testability means unit testing that code will be a whole lot easier.</p>
</li>
<li>
<p><a href="https://en.wikipedia.org/wiki/Cyclomatic_complexity">Cyclomatic Complexity</a> and Lines of Code. While these have a bad rap for being used as cudgels by management, you can actually use them as <a href="https://www.scirp.org/html/10-9301422_19738.htm">decent metrics of where you should focus your time</a>. The higher those numbers, the more you need to test and probably refactor the code.</p>
</li>
<li>
<p><a href="https://en.wikipedia.org/wiki/Coupling_(computer_programming)">Coupling</a>. Although this one is not that great of a metric in comparison to the ones above, like the above metrics it can be used to determine areas of your code that can be simplified.</p>
</li>
</ol>
<p>You may be surprised that I didn't mention this one but <a href="http://se.inf.ethz.ch/~meyer/publications/testing/coverage.pdf">Code coverage</a> may not be that great of a metric. Why? It turns out that while branch coverage is nice and all, true coverage would need to include every data point that's possible. So, unless you're going to wait 20 years to test every integer value possible for your method, you're probably not going to have true 100% coverage of your code. But generally aiming for 80% code coverage for branches is what you should be aiming for. Less than that and you're probably not testing enough. Over that and you probably won't be finding too many new bugs. So it is still a good metric to have in your arsenal but it's not nearly as important as code cohesion and cyclomatic complexity for determining code quality and your ability to test your code.</p>
<p>Anyway, with the addition of these metrics we know where to focus our time thus reducing development time further. With that we're at 30% reduction in defects and about the same development speed as before. We know where issues are most likely to occur in our code. And it can all be automated costing us nothing.</p>
<p>So can we go beyond that? Heck yeah and I'll talk about that in upcoming posts. But going forward I'll assume that the above is our base line. In future posts I'll talk about how we can super charge this to allow us to build better software.</p>
<h2 id="items-in-the-series">Items in the Series <a class="direct-link" href="http://www.gutgames.com/post/Ways-to-Improve-Your-Development-Process/#items-in-the-series">#</a></h2>
<ol>
<li><a href="http://www.gutgames.com/post/Ways-to-Improve-Your-Development-Process/">Unit Testing and Automation</a></li>
<li><a href="http://www.gutgames.com/post/Ways-to-Improve-Your-Development-Process-Fuzzing/">Fuzzing</a></li>
<li><a href="http://www.gutgames.com/post/Ways-to-Improve-Your-Development-Process-Property-Based-Testing/">Property-Based Testing</a></li>
<li><a href="http://www.gutgames.com/post/Ways-to-Improve-Your-Development-Process-Mutation-Testing/">Mutation Testing</a></li>
<li><a href="http://www.gutgames.com/post/Ways-to-Improve-Your-Development-Process-Fault-Injection/">Fault Injection</a></li>
</ol>
Creating an ORM in C# Revisited – Part 2
2011-06-03T00:00:00Z
http://www.gutgames.com/post/Creating-an-ORM-in-C-Revisited-Part-2/
<p>Apparently this didn't actually get uploaded, so here's the second part of this a bit late along with the third. Anyway, last time I talked about coming up with a simple object to object mapper to help speed up and simplify the ORM. In this post we're going to worry about actually connecting to the database. In Dapper and Massive, they simply uses extension methods to DBConnections. I could easily do that but for a while now I've been using a class called SQLHelper to simplify connecting to a database (not Microsoft's SQLHelper, it's my own class). For me, it simplifies things quite a bit (I can set up the connection in one line instead of ten), so I'll be using that instead:</p>
<pre class="language-csharp"><code class="language-csharp"> <span class="token operator">/</span>\<span class="token operator">*</span><br /> Copyright <span class="token punctuation">(</span>c<span class="token punctuation">)</span> <span class="token number">2011</span> <span class="token operator"><</span><span class="token class-name">a</span> href<span class="token operator">=</span><span class="token string">"http://www.gutgames.com"</span><span class="token operator">></span>James Craig<span class="token operator"><</span><span class="token operator">/</span>a<span class="token operator">></span><br /> <br /> Permission <span class="token keyword">is</span> <span class="token class-name">hereby</span> granted<span class="token punctuation">,</span> free <span class="token class-name">of</span> charge<span class="token punctuation">,</span> to any person obtaining a copy<br /> of <span class="token keyword">this</span> software <span class="token keyword">and</span> associated <span class="token return-type class-name">documentation</span> files <span class="token punctuation">(</span>the <span class="token string">"Software"</span><span class="token punctuation">)</span><span class="token punctuation">,</span> <span class="token class-name">to</span> deal<br /> <span class="token keyword">in</span> the Software <span class="token class-name">without</span> restriction<span class="token punctuation">,</span> including without limitation the rights<br /> <span class="token class-name">to</span> use<span class="token punctuation">,</span> copy<span class="token punctuation">,</span> modify<span class="token punctuation">,</span> merge<span class="token punctuation">,</span> publish<span class="token punctuation">,</span> distribute<span class="token punctuation">,</span> sublicense<span class="token punctuation">,</span> <span class="token keyword">and</span><span class="token operator">/</span><span class="token keyword">or</span> sell<br /> copies of <span class="token class-name">the</span> Software<span class="token punctuation">,</span> <span class="token keyword">and</span> to permit persons to whom the Software <span class="token keyword">is</span><br /> <span class="token class-name">furnished</span> to <span class="token keyword">do</span> so<span class="token punctuation">,</span> subject to the <span class="token class-name">following</span> conditions<span class="token punctuation">:</span><br /> <br /> The above copyright notice <span class="token keyword">and</span> <span class="token keyword">this</span> permission notice shall <span class="token class-name">be</span> included <span class="token keyword">in</span><br /> all copies <span class="token keyword">or</span> substantial portions of the Software<span class="token punctuation">.</span><br /> <br /> THE SOFTWARE IS PROVIDED <span class="token string">"AS IS"</span><span class="token punctuation">,</span> WITHOUT WARRANTY OF <span class="token class-name">ANY</span> KIND<span class="token punctuation">,</span> EXPRESS <span class="token class-name">OR</span><br /> IMPLIED<span class="token punctuation">,</span> INCLUDING BUT NOT LIMITED TO THE WARRANTIES <span class="token class-name">OF</span> MERCHANTABILITY<span class="token punctuation">,</span><br /> FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT<span class="token punctuation">.</span> IN NO EVENT SHALL THE<br /> AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR <span class="token class-name">ANY</span> CLAIM<span class="token punctuation">,</span> DAMAGES OR <span class="token class-name">OTHER</span><br /> LIABILITY<span class="token punctuation">,</span> WHETHER IN AN ACTION <span class="token class-name">OF</span> CONTRACT<span class="token punctuation">,</span> TORT <span class="token class-name">OR</span> OTHERWISE<span class="token punctuation">,</span> <span class="token class-name">ARISING</span> FROM<span class="token punctuation">,</span><br /> OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN<br /> THE SOFTWARE<span class="token punctuation">.</span>\<span class="token operator">*</span><span class="token operator">/</span><br /> <br /> <span class="token preprocessor property">#<span class="token directive keyword">region</span> Usings</span><br /> <span class="token keyword">using</span> <span class="token namespace">System</span><span class="token punctuation">;</span><br /> <span class="token keyword">using</span> <span class="token namespace">System<span class="token punctuation">.</span>Data</span><span class="token punctuation">;</span><br /> <span class="token keyword">using</span> <span class="token namespace">System<span class="token punctuation">.</span>Data<span class="token punctuation">.</span>SqlClient</span><span class="token punctuation">;</span><br /> <span class="token keyword">using</span> <span class="token namespace">System<span class="token punctuation">.</span>Xml</span><span class="token punctuation">;</span><br /> <span class="token keyword">using</span> <span class="token namespace">System<span class="token punctuation">.</span>Data<span class="token punctuation">.</span>Common</span><span class="token punctuation">;</span><br /> <span class="token preprocessor property">#<span class="token directive keyword">endregion</span></span><br /> <br /> <span class="token keyword">namespace</span> <span class="token namespace">Utilities<span class="token punctuation">.</span>SQL</span><br /> <span class="token punctuation">{</span><br /> <span class="token comment">/// <summary></span><br /> <span class="token comment">/// SQL Helper class</span><br /> <span class="token comment">/// </summary></span><br /> <span class="token keyword">public</span> <span class="token keyword">class</span> <span class="token class-name">SQLHelper</span> <span class="token punctuation">:</span> <span class="token type-list"><span class="token class-name">IDisposable</span></span><br /> <span class="token punctuation">{</span><br /> <span class="token preprocessor property">#<span class="token directive keyword">region</span> Constructors</span><br /> <br /> <span class="token comment">/// <summary></span><br /> <span class="token comment">/// Constructor</span><br /> <span class="token comment">/// </summary></span><br /> <span class="token comment">/// <param name="Command">Stored procedure/SQL Text to use</param></span><br /> <span class="token comment">/// <param name="ConnectionUsing">The connection string to user</param></span><br /> <span class="token comment">/// <param name="CommandType">The command type of the command sent in</param></span><br /> <span class="token keyword">public</span> <span class="token function">SQLHelper</span><span class="token punctuation">(</span><span class="token class-name"><span class="token keyword">string</span></span> Command<span class="token punctuation">,</span> <span class="token class-name"><span class="token keyword">string</span></span> ConnectionUsing<span class="token punctuation">,</span> <span class="token class-name">CommandType</span> CommandType<span class="token punctuation">,</span> <span class="token class-name"><span class="token keyword">string</span></span> DbType <span class="token operator">=</span> <span class="token string">"System.Data.SqlClient"</span><span class="token punctuation">)</span><br /> <span class="token punctuation">{</span><br /> Factory <span class="token operator">=</span> DbProviderFactories<span class="token punctuation">.</span><span class="token function">GetFactory</span><span class="token punctuation">(</span>DbType<span class="token punctuation">)</span><span class="token punctuation">;</span><br /> Connection <span class="token operator">=</span> Factory<span class="token punctuation">.</span><span class="token function">CreateConnection</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">;</span><br /> Connection<span class="token punctuation">.</span>ConnectionString <span class="token operator">=</span> ConnectionUsing<span class="token punctuation">;</span><br /> \_Command <span class="token operator">=</span> Command<span class="token punctuation">;</span><br /> \_CommandType <span class="token operator">=</span> CommandType<span class="token punctuation">;</span><br /> ExecutableCommand <span class="token operator">=</span> Factory<span class="token punctuation">.</span><span class="token function">CreateCommand</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">;</span><br /> ExecutableCommand<span class="token punctuation">.</span>CommandText <span class="token operator">=</span> \_Command<span class="token punctuation">;</span><br /> ExecutableCommand<span class="token punctuation">.</span>Connection <span class="token operator">=</span> Connection<span class="token punctuation">;</span><br /> ExecutableCommand<span class="token punctuation">.</span>CommandType <span class="token operator">=</span> CommandType<span class="token punctuation">;</span><br /> <span class="token punctuation">}</span><br /> <br /> <span class="token preprocessor property">#<span class="token directive keyword">endregion</span></span><br /> <br /> <span class="token preprocessor property">#<span class="token directive keyword">region</span> Properties</span><br /> <br /> <span class="token comment">/// <summary></span><br /> <span class="token comment">/// Db provider factory (creates connections, etc.)</span><br /> <span class="token comment">/// </summary></span><br /> <span class="token keyword">protected</span> <span class="token keyword">virtual</span> <span class="token return-type class-name">DbProviderFactory</span> Factory <span class="token punctuation">{</span> <span class="token keyword">get</span><span class="token punctuation">;</span> <span class="token keyword">set</span><span class="token punctuation">;</span> <span class="token punctuation">}</span><br /> <br /> <span class="token comment">/// <summary></span><br /> <span class="token comment">/// Connection to the database</span><br /> <span class="token comment">/// </summary></span><br /> <span class="token keyword">protected</span> <span class="token keyword">virtual</span> <span class="token return-type class-name">DbConnection</span> Connection <span class="token punctuation">{</span> <span class="token keyword">get</span><span class="token punctuation">;</span> <span class="token keyword">set</span><span class="token punctuation">;</span> <span class="token punctuation">}</span><br /> <br /> <span class="token comment">/// <summary></span><br /> <span class="token comment">/// The executable command</span><br /> <span class="token comment">/// </summary></span><br /> <span class="token keyword">protected</span> <span class="token return-type class-name">DbCommand</span> ExecutableCommand <span class="token punctuation">{</span> <span class="token keyword">get</span><span class="token punctuation">;</span> <span class="token keyword">set</span><span class="token punctuation">;</span> <span class="token punctuation">}</span><br /> <br /> <span class="token comment">/// <summary></span><br /> <span class="token comment">/// The data reader for the query</span><br /> <span class="token comment">/// </summary></span><br /> <span class="token keyword">protected</span> <span class="token return-type class-name">DbDataReader</span> Reader <span class="token punctuation">{</span> <span class="token keyword">get</span><span class="token punctuation">;</span> <span class="token keyword">set</span><span class="token punctuation">;</span> <span class="token punctuation">}</span><br /> <br /> <span class="token comment">/// <summary></span><br /> <span class="token comment">/// The transaction associated with the query</span><br /> <span class="token comment">/// </summary></span><br /> <span class="token keyword">protected</span> <span class="token return-type class-name">DbTransaction</span> Transaction <span class="token punctuation">{</span> <span class="token keyword">get</span><span class="token punctuation">;</span> <span class="token keyword">set</span><span class="token punctuation">;</span> <span class="token punctuation">}</span><br /> <br /> <span class="token comment">/// <summary></span><br /> <span class="token comment">/// Stored procedure's name or SQL Text</span><br /> <span class="token comment">/// </summary></span><br /> <span class="token keyword">public</span> <span class="token keyword">virtual</span> <span class="token return-type class-name"><span class="token keyword">string</span></span> Command<br /> <span class="token punctuation">{</span><br /> <span class="token keyword">get</span> <span class="token punctuation">{</span> <span class="token keyword">return</span> \_Command<span class="token punctuation">;</span> <span class="token punctuation">}</span><br /> <span class="token keyword">set</span><br /> <span class="token punctuation">{</span><br /> \_Command <span class="token operator">=</span> <span class="token keyword">value</span><span class="token punctuation">;</span><br /> <span class="token function">RecreateConnection</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">;</span><br /> <span class="token punctuation">}</span><br /> <span class="token punctuation">}</span><br /> <br /> <span class="token keyword">private</span> <span class="token keyword">string</span> \_Command <span class="token operator">=</span> <span class="token keyword">null</span><span class="token punctuation">;</span><br /> <br /> <br /> <span class="token comment">/// <summary></span><br /> <span class="token comment">/// Command Type</span><br /> <span class="token comment">/// </summary></span><br /> <span class="token keyword">public</span> <span class="token keyword">virtual</span> <span class="token return-type class-name">CommandType</span> CommandType<br /> <span class="token punctuation">{</span><br /> <span class="token keyword">get</span> <span class="token punctuation">{</span> <span class="token keyword">return</span> \_CommandType<span class="token punctuation">;</span> <span class="token punctuation">}</span><br /> <span class="token keyword">set</span><br /> <span class="token punctuation">{</span><br /> \_CommandType <span class="token operator">=</span> <span class="token keyword">value</span><span class="token punctuation">;</span><br /> <span class="token function">RecreateConnection</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">;</span><br /> <span class="token punctuation">}</span><br /> <span class="token punctuation">}</span><br /> <span class="token keyword">private</span> CommandType \_CommandType<span class="token punctuation">;</span><br /> <br /> <span class="token preprocessor property">#<span class="token directive keyword">endregion</span></span><br /> <br /> <span class="token preprocessor property">#<span class="token directive keyword">region</span> Functions</span><br /> <br /> <span class="token preprocessor property">#<span class="token directive keyword">region</span> AddOutputParameter</span><br /> <br /> <span class="token comment">/// <summary></span><br /> <span class="token comment">/// Adds an output parameter</span><br /> <span class="token comment">/// </summary></span><br /> <span class="token comment">/// <param name="ID">Name of the parameter</param></span><br /> <span class="token comment">/// <param name="Type">SQL type of the parameter</param></span><br /> <span class="token keyword">public</span> <span class="token keyword">virtual</span> <span class="token return-type class-name"><span class="token keyword">void</span></span> <span class="token function">AddOutputParameter</span><span class="token punctuation">(</span><span class="token class-name"><span class="token keyword">string</span></span> ID<span class="token punctuation">,</span> <span class="token class-name">SqlDbType</span> Type<span class="token punctuation">)</span><br /> <span class="token punctuation">{</span><br /> <span class="token function">AddOutputParameter</span><span class="token punctuation">(</span>ID<span class="token punctuation">,</span> Utilities<span class="token punctuation">.</span>DataTypes<span class="token punctuation">.</span>DataTypeConversion<span class="token punctuation">.</span><span class="token function">SqlDbTypeToDbType</span><span class="token punctuation">(</span>Type<span class="token punctuation">)</span><span class="token punctuation">)</span><span class="token punctuation">;</span><br /> <span class="token punctuation">}</span><br /> <br /> <span class="token comment">/// <summary></span><br /> <span class="token comment">/// Adds an output parameter</span><br /> <span class="token comment">/// </summary></span><br /> <span class="token comment">/// <param name="ID">Name of the parameter</param></span><br /> <span class="token comment">/// <param name="Type">SQL type of the parameter</param></span><br /> <span class="token keyword">public</span> <span class="token keyword">virtual</span> <span class="token return-type class-name"><span class="token keyword">void</span></span> <span class="token function">AddOutputParameter</span><span class="token punctuation">(</span><span class="token class-name"><span class="token keyword">string</span></span> ID<span class="token punctuation">,</span> <span class="token class-name">DbType</span> Type<span class="token punctuation">)</span><br /> <span class="token punctuation">{</span><br /> <span class="token keyword">if</span> <span class="token punctuation">(</span>ExecutableCommand <span class="token operator">!=</span> <span class="token keyword">null</span><span class="token punctuation">)</span><br /> <span class="token punctuation">{</span><br /> <span class="token class-name">DbParameter</span> Parameter <span class="token operator">=</span> <span class="token keyword">null</span><span class="token punctuation">;</span><br /> <span class="token keyword">if</span> <span class="token punctuation">(</span>ExecutableCommand<span class="token punctuation">.</span>Parameters<span class="token punctuation">.</span><span class="token function">Contains</span><span class="token punctuation">(</span>ID<span class="token punctuation">)</span><span class="token punctuation">)</span><br /> Parameter <span class="token operator">=</span> ExecutableCommand<span class="token punctuation">.</span>Parameters\<span class="token punctuation">[</span>ID\<span class="token punctuation">]</span><span class="token punctuation">;</span><br /> <span class="token keyword">else</span><br /> <span class="token punctuation">{</span><br /> Parameter <span class="token operator">=</span> ExecutableCommand<span class="token punctuation">.</span><span class="token function">CreateParameter</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">;</span><br /> ExecutableCommand<span class="token punctuation">.</span>Parameters<span class="token punctuation">.</span><span class="token function">Add</span><span class="token punctuation">(</span>Parameter<span class="token punctuation">)</span><span class="token punctuation">;</span><br /> <span class="token punctuation">}</span><br /> Parameter<span class="token punctuation">.</span>ParameterName <span class="token operator">=</span> ID<span class="token punctuation">;</span><br /> Parameter<span class="token punctuation">.</span>Value <span class="token operator">=</span> <span class="token keyword">null</span><span class="token punctuation">;</span><br /> Parameter<span class="token punctuation">.</span>DbType <span class="token operator">=</span> Type<span class="token punctuation">;</span><br /> Parameter<span class="token punctuation">.</span>Direction <span class="token operator">=</span> ParameterDirection<span class="token punctuation">.</span>Output<span class="token punctuation">;</span><br /> <span class="token punctuation">}</span><br /> <span class="token punctuation">}</span><br /> <br /> <span class="token comment">/// <summary></span><br /> <span class="token comment">/// Adds an output parameter</span><br /> <span class="token comment">/// </summary></span><br /> <span class="token comment">/// <typeparam name="DataType">Data type of the parameter</typeparam></span><br /> <span class="token comment">/// <param name="ID">ID associated with the output parameter</param></span><br /> <span class="token keyword">public</span> <span class="token keyword">virtual</span> <span class="token return-type class-name"><span class="token keyword">void</span></span> <span class="token generic-method"><span class="token function">AddOutputParameter</span><span class="token generic class-name"><span class="token punctuation"><</span>DataType<span class="token punctuation">></span></span></span><span class="token punctuation">(</span><span class="token class-name"><span class="token keyword">string</span></span> ID<span class="token punctuation">)</span><br /> <span class="token punctuation">{</span><br /> <span class="token function">AddOutputParameter</span><span class="token punctuation">(</span>ID<span class="token punctuation">,</span> Utilities<span class="token punctuation">.</span>DataTypes<span class="token punctuation">.</span>DataTypeConversion<span class="token punctuation">.</span><span class="token function">NetTypeToDbType</span><span class="token punctuation">(</span><span class="token keyword">typeof</span><span class="token punctuation">(</span><span class="token type-expression class-name">DataType</span><span class="token punctuation">)</span><span class="token punctuation">)</span><span class="token punctuation">)</span><span class="token punctuation">;</span><br /> <span class="token punctuation">}</span><br /> <br /> <span class="token comment">/// <summary></span><br /> <span class="token comment">/// Adds an output parameter</span><br /> <span class="token comment">/// </summary></span><br /> <span class="token comment">/// <param name="ID">Name of the parameter</param></span><br /> <span class="token comment">/// <param name="Length">Length of the string (either -1 or 5000 should be used to indicate nvarchar(max))</param></span><br /> <span class="token keyword">public</span> <span class="token keyword">virtual</span> <span class="token return-type class-name"><span class="token keyword">void</span></span> <span class="token function">AddOutputParameter</span><span class="token punctuation">(</span><span class="token class-name"><span class="token keyword">string</span></span> ID<span class="token punctuation">,</span> <span class="token class-name"><span class="token keyword">int</span></span> Length<span class="token punctuation">)</span><br /> <span class="token punctuation">{</span><br /> <span class="token keyword">if</span> <span class="token punctuation">(</span>Length <span class="token operator">==</span> <span class="token number">5000</span><span class="token punctuation">)</span><br /> Length <span class="token operator">=</span> <span class="token operator">-</span><span class="token number">1</span><span class="token punctuation">;</span><br /> <span class="token keyword">if</span> <span class="token punctuation">(</span>ExecutableCommand <span class="token operator">!=</span> <span class="token keyword">null</span><span class="token punctuation">)</span><br /> <span class="token punctuation">{</span><br /> <span class="token class-name">DbParameter</span> Parameter <span class="token operator">=</span> <span class="token keyword">null</span><span class="token punctuation">;</span><br /> <span class="token keyword">if</span> <span class="token punctuation">(</span>ExecutableCommand<span class="token punctuation">.</span>Parameters<span class="token punctuation">.</span><span class="token function">Contains</span><span class="token punctuation">(</span>ID<span class="token punctuation">)</span><span class="token punctuation">)</span><br /> Parameter <span class="token operator">=</span> ExecutableCommand<span class="token punctuation">.</span>Parameters\<span class="token punctuation">[</span>ID\<span class="token punctuation">]</span><span class="token punctuation">;</span><br /> <span class="token keyword">else</span><br /> <span class="token punctuation">{</span><br /> Parameter <span class="token operator">=</span> ExecutableCommand<span class="token punctuation">.</span><span class="token function">CreateParameter</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">;</span><br /> ExecutableCommand<span class="token punctuation">.</span>Parameters<span class="token punctuation">.</span><span class="token function">Add</span><span class="token punctuation">(</span>Parameter<span class="token punctuation">)</span><span class="token punctuation">;</span><br /> <span class="token punctuation">}</span><br /> Parameter<span class="token punctuation">.</span>ParameterName <span class="token operator">=</span> ID<span class="token punctuation">;</span><br /> Parameter<span class="token punctuation">.</span>Value <span class="token operator">=</span> <span class="token keyword">null</span><span class="token punctuation">;</span><br /> Parameter<span class="token punctuation">.</span>DbType <span class="token operator">=</span> Utilities<span class="token punctuation">.</span>DataTypes<span class="token punctuation">.</span>DataTypeConversion<span class="token punctuation">.</span><span class="token function">NetTypeToDbType</span><span class="token punctuation">(</span><span class="token keyword">typeof</span><span class="token punctuation">(</span><span class="token type-expression class-name"><span class="token keyword">string</span></span><span class="token punctuation">)</span><span class="token punctuation">)</span><span class="token punctuation">;</span><br /> Parameter<span class="token punctuation">.</span>Direction <span class="token operator">=</span> ParameterDirection<span class="token punctuation">.</span>Output<span class="token punctuation">;</span><br /> Parameter<span class="token punctuation">.</span>Size <span class="token operator">=</span> Length<span class="token punctuation">;</span><br /> <span class="token punctuation">}</span><br /> <span class="token punctuation">}</span><br /> <br /> <span class="token preprocessor property">#<span class="token directive keyword">endregion</span></span><br /> <br /> <span class="token preprocessor property">#<span class="token directive keyword">region</span> AddParameter</span><br /> <br /> <span class="token comment">/// <summary></span><br /> <span class="token comment">/// Adds a parameter to the call (for strings only)</span><br /> <span class="token comment">/// </summary></span><br /> <span class="token comment">/// <param name="ID">Name of the parameter</param></span><br /> <span class="token comment">/// <param name="Value">Value to add</param></span><br /> <span class="token comment">/// <param name="Length">Size of the string(either -1 or 5000 should be used to indicate nvarchar(max))</param></span><br /> <span class="token keyword">public</span> <span class="token keyword">virtual</span> <span class="token return-type class-name"><span class="token keyword">void</span></span> <span class="token function">AddParameter</span><span class="token punctuation">(</span><span class="token class-name"><span class="token keyword">string</span></span> ID<span class="token punctuation">,</span> <span class="token class-name"><span class="token keyword">string</span></span> Value<span class="token punctuation">,</span> <span class="token class-name"><span class="token keyword">int</span></span> Length<span class="token punctuation">)</span><br /> <span class="token punctuation">{</span><br /> <span class="token keyword">if</span> <span class="token punctuation">(</span>Length <span class="token operator">==</span> <span class="token number">5000</span><span class="token punctuation">)</span><br /> Length <span class="token operator">=</span> <span class="token operator">-</span><span class="token number">1</span><span class="token punctuation">;</span><br /> <span class="token keyword">if</span> <span class="token punctuation">(</span>ExecutableCommand <span class="token operator">!=</span> <span class="token keyword">null</span><span class="token punctuation">)</span><br /> <span class="token punctuation">{</span><br /> <span class="token class-name">DbParameter</span> Parameter <span class="token operator">=</span> <span class="token keyword">null</span><span class="token punctuation">;</span><br /> <span class="token keyword">if</span> <span class="token punctuation">(</span>ExecutableCommand<span class="token punctuation">.</span>Parameters<span class="token punctuation">.</span><span class="token function">Contains</span><span class="token punctuation">(</span>ID<span class="token punctuation">)</span><span class="token punctuation">)</span><br /> Parameter <span class="token operator">=</span> ExecutableCommand<span class="token punctuation">.</span>Parameters\<span class="token punctuation">[</span>ID\<span class="token punctuation">]</span><span class="token punctuation">;</span><br /> <span class="token keyword">else</span><br /> <span class="token punctuation">{</span><br /> Parameter <span class="token operator">=</span> ExecutableCommand<span class="token punctuation">.</span><span class="token function">CreateParameter</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">;</span><br /> ExecutableCommand<span class="token punctuation">.</span>Parameters<span class="token punctuation">.</span><span class="token function">Add</span><span class="token punctuation">(</span>Parameter<span class="token punctuation">)</span><span class="token punctuation">;</span><br /> <span class="token punctuation">}</span><br /> Parameter<span class="token punctuation">.</span>ParameterName <span class="token operator">=</span> ID<span class="token punctuation">;</span><br /> Parameter<span class="token punctuation">.</span>Value <span class="token operator">=</span> <span class="token punctuation">(</span><span class="token keyword">string</span><span class="token punctuation">.</span><span class="token function">IsNullOrEmpty</span><span class="token punctuation">(</span>Value<span class="token punctuation">)</span><span class="token punctuation">)</span> <span class="token punctuation">?</span> System<span class="token punctuation">.</span>DBNull<span class="token punctuation">.</span>Value <span class="token punctuation">:</span> <span class="token punctuation">(</span><span class="token keyword">object</span><span class="token punctuation">)</span>Value<span class="token punctuation">;</span><br /> Parameter<span class="token punctuation">.</span>IsNullable <span class="token operator">=</span> <span class="token punctuation">(</span><span class="token keyword">string</span><span class="token punctuation">.</span><span class="token function">IsNullOrEmpty</span><span class="token punctuation">(</span>Value<span class="token punctuation">)</span><span class="token punctuation">)</span><span class="token punctuation">;</span><br /> Parameter<span class="token punctuation">.</span>DbType <span class="token operator">=</span> Utilities<span class="token punctuation">.</span>DataTypes<span class="token punctuation">.</span>DataTypeConversion<span class="token punctuation">.</span><span class="token function">NetTypeToDbType</span><span class="token punctuation">(</span><span class="token keyword">typeof</span><span class="token punctuation">(</span><span class="token type-expression class-name"><span class="token keyword">string</span></span><span class="token punctuation">)</span><span class="token punctuation">)</span><span class="token punctuation">;</span><br /> Parameter<span class="token punctuation">.</span>Direction <span class="token operator">=</span> ParameterDirection<span class="token punctuation">.</span>Input<span class="token punctuation">;</span><br /> Parameter<span class="token punctuation">.</span>Size <span class="token operator">=</span> Length<span class="token punctuation">;</span><br /> <span class="token punctuation">}</span><br /> <span class="token punctuation">}</span><br /> <br /> <span class="token comment">/// <summary></span><br /> <span class="token comment">/// Adds a parameter to the call (for all types other than strings)</span><br /> <span class="token comment">/// </summary></span><br /> <span class="token comment">/// <param name="ID">Name of the parameter</param></span><br /> <span class="token comment">/// <param name="Value">Value to add</param></span><br /> <span class="token comment">/// <param name="Type">SQL type of the parameter</param></span><br /> <span class="token keyword">public</span> <span class="token keyword">virtual</span> <span class="token return-type class-name"><span class="token keyword">void</span></span> <span class="token function">AddParameter</span><span class="token punctuation">(</span><span class="token class-name"><span class="token keyword">string</span></span> ID<span class="token punctuation">,</span> <span class="token class-name"><span class="token keyword">object</span></span> Value<span class="token punctuation">,</span> <span class="token class-name">SqlDbType</span> Type<span class="token punctuation">)</span><br /> <span class="token punctuation">{</span><br /> <span class="token function">AddParameter</span><span class="token punctuation">(</span>ID<span class="token punctuation">,</span> Value<span class="token punctuation">,</span> Utilities<span class="token punctuation">.</span>DataTypes<span class="token punctuation">.</span>DataTypeConversion<span class="token punctuation">.</span><span class="token function">SqlDbTypeToDbType</span><span class="token punctuation">(</span>Type<span class="token punctuation">)</span><span class="token punctuation">)</span><span class="token punctuation">;</span><br /> <span class="token punctuation">}</span><br /> <br /> <span class="token comment">/// <summary></span><br /> <span class="token comment">/// Adds a parameter to the call (for all types other than strings)</span><br /> <span class="token comment">/// </summary></span><br /> <span class="token comment">/// <typeparam name="DataType">Data type of the parameter</typeparam></span><br /> <span class="token comment">/// <param name="ID">Name of the parameter</param></span><br /> <span class="token comment">/// <param name="Value">Value to add</param></span><br /> <span class="token keyword">public</span> <span class="token keyword">virtual</span> <span class="token return-type class-name"><span class="token keyword">void</span></span> <span class="token generic-method"><span class="token function">AddParameter</span><span class="token generic class-name"><span class="token punctuation"><</span>DataType<span class="token punctuation">></span></span></span><span class="token punctuation">(</span><span class="token class-name"><span class="token keyword">string</span></span> ID<span class="token punctuation">,</span> <span class="token class-name">DataType</span> Value<span class="token punctuation">)</span><br /> <span class="token punctuation">{</span><br /> <span class="token function">AddParameter</span><span class="token punctuation">(</span>ID<span class="token punctuation">,</span> Value<span class="token punctuation">,</span> Utilities<span class="token punctuation">.</span>DataTypes<span class="token punctuation">.</span>DataTypeConversion<span class="token punctuation">.</span><span class="token function">NetTypeToDbType</span><span class="token punctuation">(</span>Value<span class="token punctuation">.</span><span class="token function">GetType</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">)</span><span class="token punctuation">)</span><span class="token punctuation">;</span><br /> <span class="token punctuation">}</span><br /> <br /> <span class="token comment">/// <summary></span><br /> <span class="token comment">/// Adds a parameter to the call (for all types other than strings)</span><br /> <span class="token comment">/// </summary></span><br /> <span class="token comment">/// <param name="ID">Name of the parameter</param></span><br /> <span class="token comment">/// <param name="Value">Value to add</param></span><br /> <span class="token comment">/// <param name="Type">SQL type of the parameter</param></span><br /> <span class="token keyword">public</span> <span class="token keyword">virtual</span> <span class="token return-type class-name"><span class="token keyword">void</span></span> <span class="token function">AddParameter</span><span class="token punctuation">(</span><span class="token class-name"><span class="token keyword">string</span></span> ID<span class="token punctuation">,</span> <span class="token class-name"><span class="token keyword">object</span></span> Value<span class="token punctuation">,</span> <span class="token class-name">DbType</span> Type<span class="token punctuation">)</span><br /> <span class="token punctuation">{</span><br /> <span class="token keyword">if</span> <span class="token punctuation">(</span>ExecutableCommand <span class="token operator">!=</span> <span class="token keyword">null</span><span class="token punctuation">)</span><br /> <span class="token punctuation">{</span><br /> <span class="token class-name">DbParameter</span> Parameter <span class="token operator">=</span> <span class="token keyword">null</span><span class="token punctuation">;</span><br /> <span class="token keyword">if</span> <span class="token punctuation">(</span>ExecutableCommand<span class="token punctuation">.</span>Parameters<span class="token punctuation">.</span><span class="token function">Contains</span><span class="token punctuation">(</span>ID<span class="token punctuation">)</span><span class="token punctuation">)</span><br /> Parameter <span class="token operator">=</span> ExecutableCommand<span class="token punctuation">.</span>Parameters\<span class="token punctuation">[</span>ID\<span class="token punctuation">]</span><span class="token punctuation">;</span><br /> <span class="token keyword">else</span><br /> <span class="token punctuation">{</span><br /> Parameter <span class="token operator">=</span> ExecutableCommand<span class="token punctuation">.</span><span class="token function">CreateParameter</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">;</span><br /> ExecutableCommand<span class="token punctuation">.</span>Parameters<span class="token punctuation">.</span><span class="token function">Add</span><span class="token punctuation">(</span>Parameter<span class="token punctuation">)</span><span class="token punctuation">;</span><br /> <span class="token punctuation">}</span><br /> Parameter<span class="token punctuation">.</span>ParameterName <span class="token operator">=</span> ID<span class="token punctuation">;</span><br /> Parameter<span class="token punctuation">.</span>Value <span class="token operator">=</span> <span class="token punctuation">(</span>Value <span class="token operator">==</span> <span class="token keyword">null</span><span class="token punctuation">)</span> <span class="token punctuation">?</span> System<span class="token punctuation">.</span>DBNull<span class="token punctuation">.</span>Value <span class="token punctuation">:</span> Value<span class="token punctuation">;</span><br /> Parameter<span class="token punctuation">.</span>IsNullable <span class="token operator">=</span> <span class="token punctuation">(</span>Value <span class="token operator">==</span> <span class="token keyword">null</span><span class="token punctuation">)</span><span class="token punctuation">;</span><br /> Parameter<span class="token punctuation">.</span>DbType <span class="token operator">=</span> Type<span class="token punctuation">;</span><br /> Parameter<span class="token punctuation">.</span>Direction <span class="token operator">=</span> ParameterDirection<span class="token punctuation">.</span>Input<span class="token punctuation">;</span><br /> <span class="token punctuation">}</span><br /> <span class="token punctuation">}</span><br /> <br /> <span class="token preprocessor property">#<span class="token directive keyword">endregion</span></span><br /> <br /> <span class="token preprocessor property">#<span class="token directive keyword">region</span> BeginTransaction</span><br /> <br /> <span class="token comment">/// <summary></span><br /> <span class="token comment">/// Begins a transaction</span><br /> <span class="token comment">/// </summary></span><br /> <span class="token keyword">public</span> <span class="token keyword">virtual</span> <span class="token return-type class-name"><span class="token keyword">void</span></span> <span class="token function">BeginTransaction</span><span class="token punctuation">(</span><span class="token punctuation">)</span><br /> <span class="token punctuation">{</span><br /> <span class="token function">Open</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">;</span><br /> Transaction <span class="token operator">=</span> Connection<span class="token punctuation">.</span><span class="token function">BeginTransaction</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">;</span><br /> Command <span class="token operator">=</span> \_Command<span class="token punctuation">;</span><br /> <span class="token punctuation">}</span><br /> <br /> <span class="token preprocessor property">#<span class="token directive keyword">endregion</span></span><br /> <br /> <span class="token preprocessor property">#<span class="token directive keyword">region</span> ClearParameters</span><br /> <br /> <span class="token comment">/// <summary></span><br /> <span class="token comment">/// Clears the parameters</span><br /> <span class="token comment">/// </summary></span><br /> <span class="token keyword">public</span> <span class="token keyword">virtual</span> <span class="token return-type class-name"><span class="token keyword">void</span></span> <span class="token function">ClearParameters</span><span class="token punctuation">(</span><span class="token punctuation">)</span><br /> <span class="token punctuation">{</span><br /> <span class="token keyword">if</span> <span class="token punctuation">(</span>ExecutableCommand <span class="token operator">!=</span> <span class="token keyword">null</span><span class="token punctuation">)</span><br /> ExecutableCommand<span class="token punctuation">.</span>Parameters<span class="token punctuation">.</span><span class="token function">Clear</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">;</span><br /> <span class="token punctuation">}</span><br /> <br /> <span class="token preprocessor property">#<span class="token directive keyword">endregion</span></span><br /> <br /> <span class="token preprocessor property">#<span class="token directive keyword">region</span> Close</span><br /> <br /> <span class="token comment">/// <summary></span><br /> <span class="token comment">/// Closes the connection</span><br /> <span class="token comment">/// </summary></span><br /> <span class="token keyword">public</span> <span class="token keyword">virtual</span> <span class="token return-type class-name"><span class="token keyword">void</span></span> <span class="token function">Close</span><span class="token punctuation">(</span><span class="token punctuation">)</span><br /> <span class="token punctuation">{</span><br /> <span class="token keyword">if</span> <span class="token punctuation">(</span>ExecutableCommand <span class="token operator">!=</span> <span class="token keyword">null</span><br /> <span class="token operator">&&</span> ExecutableCommand<span class="token punctuation">.</span>Connection <span class="token operator">!=</span> <span class="token keyword">null</span><br /> <span class="token operator">&&</span> ExecutableCommand<span class="token punctuation">.</span>Connection<span class="token punctuation">.</span>State <span class="token operator">!=</span> ConnectionState<span class="token punctuation">.</span>Closed<span class="token punctuation">)</span><br /> ExecutableCommand<span class="token punctuation">.</span>Connection<span class="token punctuation">.</span><span class="token function">Close</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">;</span><br /> <span class="token punctuation">}</span><br /> <br /> <span class="token preprocessor property">#<span class="token directive keyword">endregion</span></span><br /> <br /> <span class="token preprocessor property">#<span class="token directive keyword">region</span> Commit</span><br /> <br /> <span class="token comment">/// <summary></span><br /> <span class="token comment">/// Commits a transaction</span><br /> <span class="token comment">/// </summary></span><br /> <span class="token keyword">public</span> <span class="token keyword">virtual</span> <span class="token return-type class-name"><span class="token keyword">void</span></span> <span class="token function">Commit</span><span class="token punctuation">(</span><span class="token punctuation">)</span><br /> <span class="token punctuation">{</span><br /> <span class="token keyword">if</span> <span class="token punctuation">(</span>Transaction <span class="token operator">!=</span> <span class="token keyword">null</span><span class="token punctuation">)</span><br /> Transaction<span class="token punctuation">.</span><span class="token function">Commit</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">;</span><br /> <span class="token punctuation">}</span><br /> <br /> <span class="token preprocessor property">#<span class="token directive keyword">endregion</span></span><br /> <br /> <span class="token preprocessor property">#<span class="token directive keyword">region</span> ExecuteDataSet</span><br /> <br /> <span class="token comment">/// <summary></span><br /> <span class="token comment">/// Executes the query and returns a data set</span><br /> <span class="token comment">/// </summary></span><br /> <span class="token comment">/// <returns>A dataset filled with the results of the query</returns></span><br /> <span class="token keyword">public</span> <span class="token keyword">virtual</span> <span class="token return-type class-name">DataSet</span> <span class="token function">ExecuteDataSet</span><span class="token punctuation">(</span><span class="token punctuation">)</span><br /> <span class="token punctuation">{</span><br /> <span class="token function">Open</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">;</span><br /> <span class="token keyword">if</span> <span class="token punctuation">(</span>ExecutableCommand <span class="token operator">!=</span> <span class="token keyword">null</span><span class="token punctuation">)</span><br /> <span class="token punctuation">{</span><br /> <span class="token class-name">DbDataAdapter</span> Adapter <span class="token operator">=</span> Factory<span class="token punctuation">.</span><span class="token function">CreateDataAdapter</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">;</span><br /> Adapter<span class="token punctuation">.</span>SelectCommand <span class="token operator">=</span> ExecutableCommand<span class="token punctuation">;</span><br /> <span class="token class-name">DataSet</span> ReturnSet <span class="token operator">=</span> <span class="token keyword">new</span> <span class="token constructor-invocation class-name">DataSet</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">;</span><br /> Adapter<span class="token punctuation">.</span><span class="token function">Fill</span><span class="token punctuation">(</span>ReturnSet<span class="token punctuation">)</span><span class="token punctuation">;</span><br /> <span class="token keyword">return</span> ReturnSet<span class="token punctuation">;</span><br /> <span class="token punctuation">}</span><br /> <span class="token keyword">return</span> <span class="token keyword">null</span><span class="token punctuation">;</span><br /> <span class="token punctuation">}</span><br /> <br /> <span class="token preprocessor property">#<span class="token directive keyword">endregion</span></span><br /> <br /> <span class="token preprocessor property">#<span class="token directive keyword">region</span> ExecuteNonQuery</span><br /> <br /> <span class="token comment">/// <summary></span><br /> <span class="token comment">/// Executes the stored procedure as a non query</span><br /> <span class="token comment">/// </summary></span><br /> <span class="token comment">/// <returns>Number of rows effected</returns></span><br /> <span class="token keyword">public</span> <span class="token keyword">virtual</span> <span class="token return-type class-name"><span class="token keyword">int</span></span> <span class="token function">ExecuteNonQuery</span><span class="token punctuation">(</span><span class="token punctuation">)</span><br /> <span class="token punctuation">{</span><br /> <span class="token function">Open</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">;</span><br /> <span class="token keyword">if</span> <span class="token punctuation">(</span>ExecutableCommand <span class="token operator">!=</span> <span class="token keyword">null</span><span class="token punctuation">)</span><br /> <span class="token keyword">return</span> ExecutableCommand<span class="token punctuation">.</span><span class="token function">ExecuteNonQuery</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">;</span><br /> <span class="token keyword">return</span> <span class="token number">0</span><span class="token punctuation">;</span><br /> <span class="token punctuation">}</span><br /> <br /> <span class="token preprocessor property">#<span class="token directive keyword">endregion</span></span><br /> <br /> <span class="token preprocessor property">#<span class="token directive keyword">region</span> ExecuteReader</span><br /> <br /> <span class="token comment">/// <summary></span><br /> <span class="token comment">/// Executes the stored procedure and returns a reader object</span><br /> <span class="token comment">/// </summary></span><br /> <span class="token keyword">public</span> <span class="token keyword">virtual</span> <span class="token return-type class-name"><span class="token keyword">void</span></span> <span class="token function">ExecuteReader</span><span class="token punctuation">(</span><span class="token punctuation">)</span><br /> <span class="token punctuation">{</span><br /> <span class="token function">Open</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">;</span><br /> <span class="token keyword">if</span> <span class="token punctuation">(</span>ExecutableCommand <span class="token operator">!=</span> <span class="token keyword">null</span><span class="token punctuation">)</span><br /> Reader <span class="token operator">=</span> ExecutableCommand<span class="token punctuation">.</span><span class="token function">ExecuteReader</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">;</span><br /> <span class="token punctuation">}</span><br /> <br /> <span class="token preprocessor property">#<span class="token directive keyword">endregion</span></span><br /> <br /> <span class="token preprocessor property">#<span class="token directive keyword">region</span> ExecuteScalar</span><br /> <br /> <span class="token comment">/// <summary></span><br /> <span class="token comment">/// Executes the stored procedure as a scalar query</span><br /> <span class="token comment">/// </summary></span><br /> <span class="token comment">/// <returns>The object of the first row and first column</returns></span><br /> <span class="token keyword">public</span> <span class="token keyword">virtual</span> <span class="token return-type class-name"><span class="token keyword">object</span></span> <span class="token function">ExecuteScalar</span><span class="token punctuation">(</span><span class="token punctuation">)</span><br /> <span class="token punctuation">{</span><br /> <span class="token function">Open</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">;</span><br /> <span class="token keyword">if</span> <span class="token punctuation">(</span>ExecutableCommand <span class="token operator">!=</span> <span class="token keyword">null</span><span class="token punctuation">)</span><br /> <span class="token keyword">return</span> ExecutableCommand<span class="token punctuation">.</span><span class="token function">ExecuteScalar</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">;</span><br /> <span class="token keyword">return</span> <span class="token keyword">null</span><span class="token punctuation">;</span><br /> <span class="token punctuation">}</span><br /> <br /> <span class="token preprocessor property">#<span class="token directive keyword">endregion</span></span><br /> <br /> <span class="token preprocessor property">#<span class="token directive keyword">region</span> ExecuteXmlReader</span><br /> <br /> <span class="token comment">/// <summary></span><br /> <span class="token comment">/// Executes the query and returns an XmlReader</span><br /> <span class="token comment">/// </summary></span><br /> <span class="token comment">/// <returns>The XmlReader filled with the data from the query</returns></span><br /> <span class="token keyword">public</span> <span class="token keyword">virtual</span> <span class="token return-type class-name">XmlReader</span> <span class="token function">ExecuteXmlReader</span><span class="token punctuation">(</span><span class="token punctuation">)</span><br /> <span class="token punctuation">{</span><br /> <span class="token function">Open</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">;</span><br /> <span class="token keyword">if</span> <span class="token punctuation">(</span>ExecutableCommand <span class="token operator">!=</span> <span class="token keyword">null</span> <span class="token operator">&&</span> ExecutableCommand <span class="token keyword">is</span> <span class="token class-name">SqlCommand</span><span class="token punctuation">)</span><br /> <span class="token keyword">return</span> <span class="token punctuation">(</span><span class="token punctuation">(</span>SqlCommand<span class="token punctuation">)</span>ExecutableCommand<span class="token punctuation">)</span><span class="token punctuation">.</span><span class="token function">ExecuteXmlReader</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">;</span><br /> <span class="token keyword">return</span> <span class="token keyword">null</span><span class="token punctuation">;</span><br /> <span class="token punctuation">}</span><br /> <br /> <span class="token preprocessor property">#<span class="token directive keyword">endregion</span></span><br /> <br /> <span class="token preprocessor property">#<span class="token directive keyword">region</span> GetParameter</span><br /> <br /> <span class="token comment">/// <summary></span><br /> <span class="token comment">/// Returns a parameter's value</span><br /> <span class="token comment">/// </summary></span><br /> <span class="token comment">/// <param name="ID">Parameter name</param></span><br /> <span class="token comment">/// <param name="Default">Default value for the parameter</param></span><br /> <span class="token comment">/// <returns>if the parameter exists (and isn't null or empty), it returns the parameter's value. Otherwise the default value is returned.</returns></span><br /> <span class="token keyword">public</span> <span class="token keyword">virtual</span> <span class="token return-type class-name"><span class="token keyword">object</span></span> <span class="token function">GetParameter</span><span class="token punctuation">(</span><span class="token class-name"><span class="token keyword">string</span></span> ID<span class="token punctuation">,</span> <span class="token class-name"><span class="token keyword">object</span></span> Default<span class="token punctuation">)</span><br /> <span class="token punctuation">{</span><br /> <span class="token keyword">if</span> <span class="token punctuation">(</span>Reader <span class="token operator">!=</span> <span class="token keyword">null</span> <span class="token operator">&&</span> <span class="token operator">!</span>Convert<span class="token punctuation">.</span><span class="token function">IsDBNull</span><span class="token punctuation">(</span>Reader\<span class="token punctuation">[</span>ID\<span class="token punctuation">]</span><span class="token punctuation">)</span><span class="token punctuation">)</span><br /> <span class="token keyword">return</span> Reader\<span class="token punctuation">[</span>ID\<span class="token punctuation">]</span><span class="token punctuation">;</span><br /> <span class="token keyword">return</span> Default<span class="token punctuation">;</span><br /> <span class="token punctuation">}</span><br /> <br /> <span class="token comment">/// <summary></span><br /> <span class="token comment">/// Returns a parameter's value</span><br /> <span class="token comment">/// </summary></span><br /> <span class="token comment">/// <typeparam name="DataType">Data type of the object</typeparam></span><br /> <span class="token comment">/// <param name="ID">Parameter name</param></span><br /> <span class="token comment">/// <param name="Default">Default value for the parameter</param></span><br /> <span class="token comment">/// <returns>if the parameter exists (and isn't null or empty), it returns the parameter's value. Otherwise the default value is returned.</returns></span><br /> <span class="token keyword">public</span> <span class="token keyword">virtual</span> <span class="token return-type class-name">DataType</span> <span class="token generic-method"><span class="token function">GetParameter</span><span class="token generic class-name"><span class="token punctuation"><</span>DataType<span class="token punctuation">></span></span></span><span class="token punctuation">(</span><span class="token class-name"><span class="token keyword">string</span></span> ID<span class="token punctuation">,</span> <span class="token class-name">DataType</span> Default<span class="token punctuation">)</span><br /> <span class="token punctuation">{</span><br /> <span class="token keyword">if</span> <span class="token punctuation">(</span>Reader <span class="token operator">!=</span> <span class="token keyword">null</span> <span class="token operator">&&</span> <span class="token operator">!</span>Convert<span class="token punctuation">.</span><span class="token function">IsDBNull</span><span class="token punctuation">(</span>Reader\<span class="token punctuation">[</span>ID\<span class="token punctuation">]</span><span class="token punctuation">)</span><span class="token punctuation">)</span><br /> <span class="token keyword">return</span> <span class="token punctuation">(</span>DataType<span class="token punctuation">)</span>Convert<span class="token punctuation">.</span><span class="token function">ChangeType</span><span class="token punctuation">(</span>Reader\<span class="token punctuation">[</span>ID\<span class="token punctuation">]</span><span class="token punctuation">,</span> <span class="token keyword">typeof</span><span class="token punctuation">(</span><span class="token type-expression class-name">DataType</span><span class="token punctuation">)</span><span class="token punctuation">)</span><span class="token punctuation">;</span><br /> <span class="token keyword">return</span> Default<span class="token punctuation">;</span><br /> <span class="token punctuation">}</span><br /> <br /> <span class="token comment">/// <summary></span><br /> <span class="token comment">/// Returns a parameter's value</span><br /> <span class="token comment">/// </summary></span><br /> <span class="token comment">/// <param name="Position">Position in the row</param></span><br /> <span class="token comment">/// <param name="Default">Default value for the parameter</param></span><br /> <span class="token comment">/// <returns>if the parameter exists (and isn't null or empty), it returns the parameter's value. Otherwise the default value is returned.</returns></span><br /> <span class="token keyword">public</span> <span class="token keyword">virtual</span> <span class="token return-type class-name"><span class="token keyword">object</span></span> <span class="token function">GetParameter</span><span class="token punctuation">(</span><span class="token class-name"><span class="token keyword">int</span></span> Position<span class="token punctuation">,</span> <span class="token class-name"><span class="token keyword">object</span></span> Default<span class="token punctuation">)</span><br /> <span class="token punctuation">{</span><br /> <span class="token keyword">if</span> <span class="token punctuation">(</span>Reader <span class="token operator">!=</span> <span class="token keyword">null</span> <span class="token operator">&&</span> <span class="token operator">!</span>Convert<span class="token punctuation">.</span><span class="token function">IsDBNull</span><span class="token punctuation">(</span>Reader\<span class="token punctuation">[</span>Position\<span class="token punctuation">]</span><span class="token punctuation">)</span><span class="token punctuation">)</span><br /> <span class="token keyword">return</span> Reader\<span class="token punctuation">[</span>Position\<span class="token punctuation">]</span><span class="token punctuation">;</span><br /> <span class="token keyword">return</span> Default<span class="token punctuation">;</span><br /> <span class="token punctuation">}</span><br /> <br /> <span class="token comment">/// <summary></span><br /> <span class="token comment">/// Returns a parameter's value</span><br /> <span class="token comment">/// </summary></span><br /> <span class="token comment">/// <typeparam name="DataType">Data type of the object</typeparam></span><br /> <span class="token comment">/// <param name="Position">Position in the row</param></span><br /> <span class="token comment">/// <param name="Default">Default value for the parameter</param></span><br /> <span class="token comment">/// <returns>if the parameter exists (and isn't null or empty), it returns the parameter's value. Otherwise the default value is returned.</returns></span><br /> <span class="token keyword">public</span> <span class="token keyword">virtual</span> <span class="token return-type class-name">DataType</span> <span class="token generic-method"><span class="token function">GetParameter</span><span class="token generic class-name"><span class="token punctuation"><</span>DataType<span class="token punctuation">></span></span></span><span class="token punctuation">(</span><span class="token class-name"><span class="token keyword">int</span></span> Position<span class="token punctuation">,</span> <span class="token class-name">DataType</span> Default<span class="token punctuation">)</span><br /> <span class="token punctuation">{</span><br /> <span class="token keyword">if</span> <span class="token punctuation">(</span>Reader <span class="token operator">!=</span> <span class="token keyword">null</span> <span class="token operator">&&</span> <span class="token operator">!</span>Convert<span class="token punctuation">.</span><span class="token function">IsDBNull</span><span class="token punctuation">(</span>Reader\<span class="token punctuation">[</span>Position\<span class="token punctuation">]</span><span class="token punctuation">)</span><span class="token punctuation">)</span><br /> <span class="token keyword">return</span> <span class="token punctuation">(</span>DataType<span class="token punctuation">)</span>Convert<span class="token punctuation">.</span><span class="token function">ChangeType</span><span class="token punctuation">(</span>Reader\<span class="token punctuation">[</span>Position\<span class="token punctuation">]</span><span class="token punctuation">,</span> <span class="token keyword">typeof</span><span class="token punctuation">(</span><span class="token type-expression class-name">DataType</span><span class="token punctuation">)</span><span class="token punctuation">)</span><span class="token punctuation">;</span><br /> <span class="token keyword">return</span> Default<span class="token punctuation">;</span><br /> <span class="token punctuation">}</span><br /> <br /> <span class="token preprocessor property">#<span class="token directive keyword">endregion</span></span><br /> <br /> <span class="token preprocessor property">#<span class="token directive keyword">region</span> GetOutputParameter</span><br /> <br /> <span class="token comment">/// <summary></span><br /> <span class="token comment">/// Returns an output parameter's value</span><br /> <span class="token comment">/// </summary></span><br /> <span class="token comment">/// <param name="ID">Parameter name</param></span><br /> <span class="token comment">/// <param name="Default">Default value for the parameter</param></span><br /> <span class="token comment">/// <returns>if the parameter exists (and isn't null or empty), it returns the parameter's value. Otherwise the default value is returned.</returns></span><br /> <span class="token keyword">public</span> <span class="token keyword">virtual</span> <span class="token return-type class-name"><span class="token keyword">object</span></span> <span class="token function">GetOutputParameter</span><span class="token punctuation">(</span><span class="token class-name"><span class="token keyword">string</span></span> ID<span class="token punctuation">,</span> <span class="token class-name"><span class="token keyword">object</span></span> Default<span class="token punctuation">)</span><br /> <span class="token punctuation">{</span><br /> <span class="token keyword">if</span> <span class="token punctuation">(</span>ExecutableCommand <span class="token operator">!=</span> <span class="token keyword">null</span> <span class="token operator">&&</span> <span class="token operator">!</span>Convert<span class="token punctuation">.</span><span class="token function">IsDBNull</span><span class="token punctuation">(</span>ExecutableCommand<span class="token punctuation">.</span>Parameters\<span class="token punctuation">[</span>ID\<span class="token punctuation">]</span><span class="token punctuation">)</span><span class="token punctuation">)</span><br /> <span class="token keyword">return</span> ExecutableCommand<span class="token punctuation">.</span>Parameters\<span class="token punctuation">[</span>ID\<span class="token punctuation">]</span><span class="token punctuation">.</span>Value<span class="token punctuation">;</span><br /> <span class="token keyword">return</span> Default<span class="token punctuation">;</span><br /> <span class="token punctuation">}</span><br /> <br /> <span class="token comment">/// <summary></span><br /> <span class="token comment">/// Returns an output parameter's value</span><br /> <span class="token comment">/// </summary></span><br /> <span class="token comment">/// <typeparam name="DataType">Data type of the object</typeparam></span><br /> <span class="token comment">/// <param name="ID">Parameter name</param></span><br /> <span class="token comment">/// <param name="Default">Default value for the parameter</param></span><br /> <span class="token comment">/// <returns>if the parameter exists (and isn't null or empty), it returns the parameter's value. Otherwise the default value is returned.</returns></span><br /> <span class="token keyword">public</span> <span class="token keyword">virtual</span> <span class="token return-type class-name">DataType</span> <span class="token generic-method"><span class="token function">GetOutputParameter</span><span class="token generic class-name"><span class="token punctuation"><</span>DataType<span class="token punctuation">></span></span></span><span class="token punctuation">(</span><span class="token class-name"><span class="token keyword">string</span></span> ID<span class="token punctuation">,</span> <span class="token class-name">DataType</span> Default<span class="token punctuation">)</span><br /> <span class="token punctuation">{</span><br /> <span class="token keyword">if</span> <span class="token punctuation">(</span>ExecutableCommand <span class="token operator">!=</span> <span class="token keyword">null</span> <span class="token operator">&&</span> <span class="token operator">!</span>Convert<span class="token punctuation">.</span><span class="token function">IsDBNull</span><span class="token punctuation">(</span>ExecutableCommand<span class="token punctuation">.</span>Parameters\<span class="token punctuation">[</span>ID\<span class="token punctuation">]</span><span class="token punctuation">)</span><span class="token punctuation">)</span><br /> <span class="token keyword">return</span> <span class="token punctuation">(</span>DataType<span class="token punctuation">)</span>Convert<span class="token punctuation">.</span><span class="token function">ChangeType</span><span class="token punctuation">(</span>ExecutableCommand<span class="token punctuation">.</span>Parameters\<span class="token punctuation">[</span>ID\<span class="token punctuation">]</span><span class="token punctuation">.</span>Value<span class="token punctuation">,</span> <span class="token keyword">typeof</span><span class="token punctuation">(</span><span class="token type-expression class-name">DataType</span><span class="token punctuation">)</span><span class="token punctuation">)</span><span class="token punctuation">;</span><br /> <span class="token keyword">return</span> Default<span class="token punctuation">;</span><br /> <span class="token punctuation">}</span><br /> <br /> <span class="token preprocessor property">#<span class="token directive keyword">endregion</span></span><br /> <br /> <span class="token preprocessor property">#<span class="token directive keyword">region</span> NextResult</span><br /> <br /> <span class="token comment">/// <summary></span><br /> <span class="token comment">/// Goes to the next result set (used if multiple queries are sent in)</span><br /> <span class="token comment">/// </summary></span><br /> <span class="token keyword">public</span> <span class="token keyword">virtual</span> <span class="token return-type class-name"><span class="token keyword">void</span></span> <span class="token function">NextResult</span><span class="token punctuation">(</span><span class="token punctuation">)</span><br /> <span class="token punctuation">{</span><br /> <span class="token keyword">if</span> <span class="token punctuation">(</span>Reader <span class="token operator">!=</span> <span class="token keyword">null</span><span class="token punctuation">)</span><br /> Reader<span class="token punctuation">.</span><span class="token function">NextResult</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">;</span><br /> <span class="token punctuation">}</span><br /> <br /> <span class="token preprocessor property">#<span class="token directive keyword">endregion</span></span><br /> <br /> <span class="token preprocessor property">#<span class="token directive keyword">region</span> Open</span><br /> <br /> <span class="token comment">/// <summary></span><br /> <span class="token comment">/// Opens the connection</span><br /> <span class="token comment">/// </summary></span><br /> <span class="token keyword">public</span> <span class="token keyword">virtual</span> <span class="token return-type class-name"><span class="token keyword">void</span></span> <span class="token function">Open</span><span class="token punctuation">(</span><span class="token punctuation">)</span><br /> <span class="token punctuation">{</span><br /> <span class="token keyword">if</span> <span class="token punctuation">(</span>ExecutableCommand <span class="token operator">!=</span> <span class="token keyword">null</span> <br /> <span class="token operator">&&</span> ExecutableCommand<span class="token punctuation">.</span>Connection <span class="token operator">!=</span> <span class="token keyword">null</span> <br /> <span class="token operator">&&</span> ExecutableCommand<span class="token punctuation">.</span>Connection<span class="token punctuation">.</span>State <span class="token operator">!=</span> ConnectionState<span class="token punctuation">.</span>Open<span class="token punctuation">)</span><br /> ExecutableCommand<span class="token punctuation">.</span>Connection<span class="token punctuation">.</span><span class="token function">Open</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">;</span><br /> <span class="token punctuation">}</span><br /> <br /> <span class="token preprocessor property">#<span class="token directive keyword">endregion</span></span><br /> <br /> <span class="token preprocessor property">#<span class="token directive keyword">region</span> Read</span><br /> <br /> <span class="token comment">/// <summary></span><br /> <span class="token comment">/// Is there more information?</span><br /> <span class="token comment">/// </summary></span><br /> <span class="token comment">/// <returns>True if there is more rows, false otherwise</returns></span><br /> <span class="token keyword">public</span> <span class="token keyword">virtual</span> <span class="token return-type class-name"><span class="token keyword">bool</span></span> <span class="token function">Read</span><span class="token punctuation">(</span><span class="token punctuation">)</span><br /> <span class="token punctuation">{</span><br /> <span class="token keyword">return</span> <span class="token punctuation">(</span>Reader <span class="token operator">!=</span> <span class="token keyword">null</span><span class="token punctuation">)</span> <span class="token punctuation">?</span> Reader<span class="token punctuation">.</span><span class="token function">Read</span><span class="token punctuation">(</span><span class="token punctuation">)</span> <span class="token punctuation">:</span> <span class="token boolean">false</span><span class="token punctuation">;</span><br /> <span class="token punctuation">}</span><br /> <br /> <span class="token preprocessor property">#<span class="token directive keyword">endregion</span></span><br /> <br /> <span class="token preprocessor property">#<span class="token directive keyword">region</span> RecreateConnection</span><br /> <br /> <span class="token keyword">private</span> <span class="token return-type class-name"><span class="token keyword">void</span></span> <span class="token function">RecreateConnection</span><span class="token punctuation">(</span><span class="token punctuation">)</span><br /> <span class="token punctuation">{</span><br /> <span class="token keyword">if</span> <span class="token punctuation">(</span>Reader <span class="token operator">!=</span> <span class="token keyword">null</span><span class="token punctuation">)</span><br /> <span class="token punctuation">{</span><br /> Reader<span class="token punctuation">.</span><span class="token function">Close</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">;</span><br /> Reader<span class="token punctuation">.</span><span class="token function">Dispose</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">;</span><br /> Reader <span class="token operator">=</span> <span class="token keyword">null</span><span class="token punctuation">;</span><br /> <span class="token punctuation">}</span><br /> <span class="token keyword">if</span> <span class="token punctuation">(</span>ExecutableCommand <span class="token operator">!=</span> <span class="token keyword">null</span><span class="token punctuation">)</span><br /> <span class="token punctuation">{</span><br /> ExecutableCommand<span class="token punctuation">.</span><span class="token function">Dispose</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">;</span><br /> ExecutableCommand <span class="token operator">=</span> <span class="token keyword">null</span><span class="token punctuation">;</span><br /> <span class="token punctuation">}</span><br /> ExecutableCommand <span class="token operator">=</span> Factory<span class="token punctuation">.</span><span class="token function">CreateCommand</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">;</span><br /> ExecutableCommand<span class="token punctuation">.</span>CommandText <span class="token operator">=</span> \_Command<span class="token punctuation">;</span><br /> ExecutableCommand<span class="token punctuation">.</span>Connection <span class="token operator">=</span> Connection<span class="token punctuation">;</span><br /> ExecutableCommand<span class="token punctuation">.</span>CommandType <span class="token operator">=</span> CommandType<span class="token punctuation">;</span><br /> <span class="token keyword">if</span> <span class="token punctuation">(</span>Transaction <span class="token operator">!=</span> <span class="token keyword">null</span><span class="token punctuation">)</span><br /> ExecutableCommand<span class="token punctuation">.</span>Transaction <span class="token operator">=</span> Transaction<span class="token punctuation">;</span><br /> <span class="token punctuation">}</span><br /> <br /> <span class="token preprocessor property">#<span class="token directive keyword">endregion</span></span><br /> <br /> <span class="token preprocessor property">#<span class="token directive keyword">region</span> Rollback</span><br /> <br /> <span class="token comment">/// <summary></span><br /> <span class="token comment">/// Rolls back a transaction</span><br /> <span class="token comment">/// </summary></span><br /> <span class="token keyword">public</span> <span class="token keyword">virtual</span> <span class="token return-type class-name"><span class="token keyword">void</span></span> <span class="token function">Rollback</span><span class="token punctuation">(</span><span class="token punctuation">)</span><br /> <span class="token punctuation">{</span><br /> <span class="token keyword">if</span> <span class="token punctuation">(</span>Transaction <span class="token operator">!=</span> <span class="token keyword">null</span><span class="token punctuation">)</span><br /> Transaction<span class="token punctuation">.</span><span class="token function">Rollback</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">;</span><br /> <span class="token punctuation">}</span><br /> <br /> <span class="token preprocessor property">#<span class="token directive keyword">endregion</span></span><br /> <br /> <span class="token preprocessor property">#<span class="token directive keyword">endregion</span></span><br /> <br /> <span class="token preprocessor property">#<span class="token directive keyword">region</span> IDisposable Members</span><br /> <br /> <span class="token keyword">public</span> <span class="token keyword">virtual</span> <span class="token return-type class-name"><span class="token keyword">void</span></span> <span class="token function">Dispose</span><span class="token punctuation">(</span><span class="token punctuation">)</span><br /> <span class="token punctuation">{</span><br /> <span class="token function">Close</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">;</span><br /> <span class="token keyword">if</span> <span class="token punctuation">(</span>Connection <span class="token operator">!=</span> <span class="token keyword">null</span><span class="token punctuation">)</span><br /> <span class="token punctuation">{</span><br /> Connection<span class="token punctuation">.</span><span class="token function">Dispose</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">;</span><br /> Connection <span class="token operator">=</span> <span class="token keyword">null</span><span class="token punctuation">;</span><br /> <span class="token punctuation">}</span><br /> <span class="token keyword">if</span> <span class="token punctuation">(</span>Transaction <span class="token operator">!=</span> <span class="token keyword">null</span><span class="token punctuation">)</span><br /> <span class="token punctuation">{</span><br /> Transaction<span class="token punctuation">.</span><span class="token function">Dispose</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">;</span><br /> Transaction <span class="token operator">=</span> <span class="token keyword">null</span><span class="token punctuation">;</span><br /> <span class="token punctuation">}</span><br /> <span class="token keyword">if</span> <span class="token punctuation">(</span>ExecutableCommand <span class="token operator">!=</span> <span class="token keyword">null</span><span class="token punctuation">)</span><br /> <span class="token punctuation">{</span><br /> ExecutableCommand<span class="token punctuation">.</span><span class="token function">Dispose</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">;</span><br /> ExecutableCommand <span class="token operator">=</span> <span class="token keyword">null</span><span class="token punctuation">;</span><br /> <span class="token punctuation">}</span><br /> <span class="token keyword">if</span> <span class="token punctuation">(</span>Reader <span class="token operator">!=</span> <span class="token keyword">null</span><span class="token punctuation">)</span><br /> <span class="token punctuation">{</span><br /> Reader<span class="token punctuation">.</span><span class="token function">Dispose</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">;</span><br /> Reader <span class="token operator">=</span> <span class="token keyword">null</span><span class="token punctuation">;</span><br /> <span class="token punctuation">}</span><br /> <span class="token punctuation">}</span><br /> <br /> <span class="token preprocessor property">#<span class="token directive keyword">endregion</span></span><br /> <span class="token punctuation">}</span><br /> <span class="token punctuation">}</span></code></pre>
<p>Note that you don't have to use something like this, you can simply add extension methods to DBConnection (like Massive/Dapper). This is just a bit of code to help make things easier for me. The next bit of code that is needed is a way to map the various properties of the business object to the database:</p>
<pre class="language-csharp"><code class="language-csharp"> <span class="token preprocessor property">#<span class="token directive keyword">region</span> Map</span><br /> <br /> <span class="token comment">/// <summary></span><br /> <span class="token comment">/// Maps a property to a database property name (required to actually get data from the database)</span><br /> <span class="token comment">/// </summary></span><br /> <span class="token comment">/// <typeparam name="DataType">Data type of the property</typeparam></span><br /> <span class="token comment">/// <param name="Property">Property to add a mapping for</param></span><br /> <span class="token comment">/// <param name="DatabasePropertyName">Property name</param></span><br /> <span class="token keyword">public</span> <span class="token keyword">virtual</span> <span class="token return-type class-name">Mapping<span class="token punctuation"><</span>ClassType<span class="token punctuation">></span></span> <span class="token generic-method"><span class="token function">Map</span><span class="token generic class-name"><span class="token punctuation"><</span>DataType<span class="token punctuation">></span></span></span><span class="token punctuation">(</span><span class="token class-name">Expression<span class="token punctuation"><</span>Func<span class="token punctuation"><</span>ClassType<span class="token punctuation">,</span> DataType<span class="token punctuation">></span><span class="token punctuation">></span></span> Property<span class="token punctuation">,</span> <span class="token class-name"><span class="token keyword">string</span></span> DatabasePropertyName<span class="token punctuation">)</span><br /> <span class="token punctuation">{</span><br /> <span class="token function">Check</span><span class="token punctuation">(</span>Property<span class="token punctuation">,</span> <span class="token string">"Property"</span><span class="token punctuation">)</span><span class="token punctuation">;</span><br /> <span class="token function">Check</span><span class="token punctuation">(</span>DatabasePropertyName<span class="token punctuation">,</span> <span class="token string">"DatabasePropertyName"</span><span class="token punctuation">)</span><span class="token punctuation">;</span><br /> <span class="token function">Check</span><span class="token punctuation">(</span>Mappings<span class="token punctuation">,</span> <span class="token string">"Mappings"</span><span class="token punctuation">)</span><span class="token punctuation">;</span><br /> <span class="token class-name">Expression</span> Convert <span class="token operator">=</span> Expression<span class="token punctuation">.</span><span class="token function">Convert</span><span class="token punctuation">(</span>Property<span class="token punctuation">.</span>Body<span class="token punctuation">,</span> <span class="token keyword">typeof</span><span class="token punctuation">(</span><span class="token type-expression class-name"><span class="token keyword">object</span></span><span class="token punctuation">)</span><span class="token punctuation">)</span><span class="token punctuation">;</span><br /> <span class="token class-name">Expression<span class="token punctuation"><</span>Func<span class="token punctuation"><</span>ClassType<span class="token punctuation">,</span> <span class="token keyword">object</span>\<span class="token punctuation">></span><span class="token punctuation">></span></span> PropertyExpression <span class="token operator">=</span> Expression<span class="token punctuation">.</span><span class="token generic-method"><span class="token function">Lambda</span><span class="token generic class-name"><span class="token punctuation"><</span>Func<span class="token punctuation"><</span>ClassType<span class="token punctuation">,</span> <span class="token keyword">object</span>\<span class="token punctuation">></span><span class="token punctuation">></span></span></span><span class="token punctuation">(</span>Convert<span class="token punctuation">,</span> Property<span class="token punctuation">.</span>Parameters<span class="token punctuation">)</span><span class="token punctuation">;</span><br /> Mappings<span class="token punctuation">.</span><span class="token function">AddMapping</span><span class="token punctuation">(</span>PropertyExpression<span class="token punctuation">,</span><br /> <span class="token keyword">new</span> <span class="token constructor-invocation class-name">Func<span class="token punctuation"><</span>SQLHelper<span class="token punctuation">,</span> <span class="token keyword">object</span>\<span class="token punctuation">></span></span><span class="token punctuation">(</span><span class="token punctuation">(</span>x<span class="token punctuation">)</span> <span class="token operator">=></span> x<span class="token punctuation">.</span><span class="token function">GetParameter</span><span class="token punctuation">(</span>DatabasePropertyName<span class="token punctuation">,</span> <span class="token keyword">default</span><span class="token punctuation">(</span><span class="token type-expression class-name">DataType</span><span class="token punctuation">)</span><span class="token punctuation">)</span><span class="token punctuation">)</span><span class="token punctuation">,</span><br /> <span class="token keyword">new</span> <span class="token constructor-invocation class-name">Action<span class="token punctuation"><</span>SQLHelper<span class="token punctuation">,</span> <span class="token keyword">object</span>\<span class="token punctuation">></span></span><span class="token punctuation">(</span><span class="token punctuation">(</span>x<span class="token punctuation">,</span> y<span class="token punctuation">)</span> <span class="token operator">=></span> x<span class="token punctuation">.</span><span class="token function">AddParameter</span><span class="token punctuation">(</span>DatabasePropertyName<span class="token punctuation">,</span> y<span class="token punctuation">)</span><span class="token punctuation">)</span><span class="token punctuation">)</span><span class="token punctuation">;</span><br /> ParameterNames<span class="token punctuation">.</span><span class="token function">Add</span><span class="token punctuation">(</span>DatabasePropertyName<span class="token punctuation">)</span><span class="token punctuation">;</span><br /> <span class="token keyword">return</span> <span class="token keyword">this</span><span class="token punctuation">;</span><br /> <span class="token punctuation">}</span><br /> <br /> <span class="token comment">/// <summary></span><br /> <span class="token comment">/// Maps a property to a database property name (required to actually get data from the database)</span><br /> <span class="token comment">/// </summary></span><br /> <span class="token comment">/// <param name="Property">Property to add a mapping for</param></span><br /> <span class="token comment">/// <param name="DatabasePropertyName">Property name</param></span><br /> <span class="token comment">/// <param name="Length">Max length of the string</param></span><br /> <span class="token keyword">public</span> <span class="token keyword">virtual</span> <span class="token return-type class-name">Mapping<span class="token punctuation"><</span>ClassType<span class="token punctuation">></span></span> <span class="token function">Map</span><span class="token punctuation">(</span><span class="token class-name">Expression<span class="token punctuation"><</span>Func<span class="token punctuation"><</span>ClassType<span class="token punctuation">,</span> <span class="token keyword">string</span>\<span class="token punctuation">></span><span class="token punctuation">></span></span> Property<span class="token punctuation">,</span> <span class="token class-name"><span class="token keyword">string</span></span> DatabasePropertyName<span class="token punctuation">,</span> <span class="token class-name"><span class="token keyword">int</span></span> Length<span class="token punctuation">)</span><br /> <span class="token punctuation">{</span><br /> <span class="token function">Check</span><span class="token punctuation">(</span>Property<span class="token punctuation">,</span> <span class="token string">"Property"</span><span class="token punctuation">)</span><span class="token punctuation">;</span><br /> <span class="token function">Check</span><span class="token punctuation">(</span>DatabasePropertyName<span class="token punctuation">,</span> <span class="token string">"DatabasePropertyName"</span><span class="token punctuation">)</span><span class="token punctuation">;</span><br /> <span class="token function">Check</span><span class="token punctuation">(</span>Mappings<span class="token punctuation">,</span> <span class="token string">"Mappings"</span><span class="token punctuation">)</span><span class="token punctuation">;</span><br /> <span class="token class-name">Expression</span> Convert <span class="token operator">=</span> Expression<span class="token punctuation">.</span><span class="token function">Convert</span><span class="token punctuation">(</span>Property<span class="token punctuation">.</span>Body<span class="token punctuation">,</span> <span class="token keyword">typeof</span><span class="token punctuation">(</span><span class="token type-expression class-name"><span class="token keyword">object</span></span><span class="token punctuation">)</span><span class="token punctuation">)</span><span class="token punctuation">;</span><br /> <span class="token class-name">Expression<span class="token punctuation"><</span>Func<span class="token punctuation"><</span>ClassType<span class="token punctuation">,</span> <span class="token keyword">object</span>\<span class="token punctuation">></span><span class="token punctuation">></span></span> PropertyExpression <span class="token operator">=</span> Expression<span class="token punctuation">.</span><span class="token generic-method"><span class="token function">Lambda</span><span class="token generic class-name"><span class="token punctuation"><</span>Func<span class="token punctuation"><</span>ClassType<span class="token punctuation">,</span> <span class="token keyword">object</span>\<span class="token punctuation">></span><span class="token punctuation">></span></span></span><span class="token punctuation">(</span>Convert<span class="token punctuation">,</span> Property<span class="token punctuation">.</span>Parameters<span class="token punctuation">)</span><span class="token punctuation">;</span><br /> Mappings<span class="token punctuation">.</span><span class="token function">AddMapping</span><span class="token punctuation">(</span>PropertyExpression<span class="token punctuation">,</span><br /> <span class="token keyword">new</span> <span class="token constructor-invocation class-name">Func<span class="token punctuation"><</span>SQLHelper<span class="token punctuation">,</span> <span class="token keyword">object</span>\<span class="token punctuation">></span></span><span class="token punctuation">(</span><span class="token punctuation">(</span>x<span class="token punctuation">)</span> <span class="token operator">=></span> x<span class="token punctuation">.</span><span class="token function">GetParameter</span><span class="token punctuation">(</span>DatabasePropertyName<span class="token punctuation">,</span> <span class="token string">""</span><span class="token punctuation">)</span><span class="token punctuation">)</span><span class="token punctuation">,</span><br /> <span class="token keyword">new</span> <span class="token constructor-invocation class-name">Action<span class="token punctuation"><</span>SQLHelper<span class="token punctuation">,</span> <span class="token keyword">object</span>\<span class="token punctuation">></span></span><span class="token punctuation">(</span><span class="token punctuation">(</span>x<span class="token punctuation">,</span> y<span class="token punctuation">)</span> <span class="token operator">=></span> x<span class="token punctuation">.</span><span class="token function">AddParameter</span><span class="token punctuation">(</span>DatabasePropertyName<span class="token punctuation">,</span> <span class="token punctuation">(</span><span class="token keyword">string</span><span class="token punctuation">)</span>y<span class="token punctuation">,</span> Length<span class="token punctuation">)</span><span class="token punctuation">)</span><span class="token punctuation">)</span><span class="token punctuation">;</span><br /> ParameterNames<span class="token punctuation">.</span><span class="token function">Add</span><span class="token punctuation">(</span>DatabasePropertyName<span class="token punctuation">)</span><span class="token punctuation">;</span><br /> <span class="token keyword">return</span> <span class="token keyword">this</span><span class="token punctuation">;</span><br /> <span class="token punctuation">}</span><br /> <br /> <span class="token preprocessor property">#<span class="token directive keyword">endregion</span></span></code></pre>
<p>This code comes from a class called Mapping, which will hold our data and make our calls to the database. These functions simply map our properties to database properties. As you can see, it takes in an expression and the name of the parameter (database side). It in turn uses that expression and our object to object mapper from the previous post to create a mapping between the SQLHelper (the GetParameter/AddParameter calls). This isn't perfect as it doesn't deal with IEnumerables that well but we're only going to deal with simple items for now (int, string, etc.). Also it returns this so we can do a nice, simple fluent interface. So now that we've seen the small bit of code that handles the mapping of the data, lets look at everything else:</p>
<pre class="language-csharp"><code class="language-csharp"> <span class="token operator">/</span>\<span class="token operator">*</span><br /> Copyright <span class="token punctuation">(</span>c<span class="token punctuation">)</span> <span class="token number">2011</span> <span class="token operator"><</span><span class="token class-name">a</span> href<span class="token operator">=</span><span class="token string">"http://www.gutgames.com"</span><span class="token operator">></span>James Craig<span class="token operator"><</span><span class="token operator">/</span>a<span class="token operator">></span><br /> <br /> Permission <span class="token keyword">is</span> <span class="token class-name">hereby</span> granted<span class="token punctuation">,</span> free <span class="token class-name">of</span> charge<span class="token punctuation">,</span> to any person obtaining a copy<br /> of <span class="token keyword">this</span> software <span class="token keyword">and</span> associated <span class="token return-type class-name">documentation</span> files <span class="token punctuation">(</span>the <span class="token string">"Software"</span><span class="token punctuation">)</span><span class="token punctuation">,</span> <span class="token class-name">to</span> deal<br /> <span class="token keyword">in</span> the Software <span class="token class-name">without</span> restriction<span class="token punctuation">,</span> including without limitation the rights<br /> <span class="token class-name">to</span> use<span class="token punctuation">,</span> copy<span class="token punctuation">,</span> modify<span class="token punctuation">,</span> merge<span class="token punctuation">,</span> publish<span class="token punctuation">,</span> distribute<span class="token punctuation">,</span> sublicense<span class="token punctuation">,</span> <span class="token keyword">and</span><span class="token operator">/</span><span class="token keyword">or</span> sell<br /> copies of <span class="token class-name">the</span> Software<span class="token punctuation">,</span> <span class="token keyword">and</span> to permit persons to whom the Software <span class="token keyword">is</span><br /> <span class="token class-name">furnished</span> to <span class="token keyword">do</span> so<span class="token punctuation">,</span> subject to the <span class="token class-name">following</span> conditions<span class="token punctuation">:</span><br /> <br /> The above copyright notice <span class="token keyword">and</span> <span class="token keyword">this</span> permission notice shall <span class="token class-name">be</span> included <span class="token keyword">in</span><br /> all copies <span class="token keyword">or</span> substantial portions of the Software<span class="token punctuation">.</span><br /> <br /> THE SOFTWARE IS PROVIDED <span class="token string">"AS IS"</span><span class="token punctuation">,</span> WITHOUT WARRANTY OF <span class="token class-name">ANY</span> KIND<span class="token punctuation">,</span> EXPRESS <span class="token class-name">OR</span><br /> IMPLIED<span class="token punctuation">,</span> INCLUDING BUT NOT LIMITED TO THE WARRANTIES <span class="token class-name">OF</span> MERCHANTABILITY<span class="token punctuation">,</span><br /> FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT<span class="token punctuation">.</span> IN NO EVENT SHALL THE<br /> AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR <span class="token class-name">ANY</span> CLAIM<span class="token punctuation">,</span> DAMAGES OR <span class="token class-name">OTHER</span><br /> LIABILITY<span class="token punctuation">,</span> WHETHER IN AN ACTION <span class="token class-name">OF</span> CONTRACT<span class="token punctuation">,</span> TORT <span class="token class-name">OR</span> OTHERWISE<span class="token punctuation">,</span> <span class="token class-name">ARISING</span> FROM<span class="token punctuation">,</span><br /> OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN<br /> THE SOFTWARE<span class="token punctuation">.</span>\<span class="token operator">*</span><span class="token operator">/</span><br /> <br /> <span class="token preprocessor property">#<span class="token directive keyword">region</span> Usings</span><br /> <span class="token keyword">using</span> <span class="token namespace">System</span><span class="token punctuation">;</span><br /> <span class="token keyword">using</span> <span class="token namespace">System<span class="token punctuation">.</span>Collections<span class="token punctuation">.</span>Generic</span><span class="token punctuation">;</span><br /> <span class="token keyword">using</span> <span class="token namespace">System<span class="token punctuation">.</span>Linq</span><span class="token punctuation">;</span><br /> <span class="token keyword">using</span> <span class="token namespace">System<span class="token punctuation">.</span>Text</span><span class="token punctuation">;</span><br /> <span class="token keyword">using</span> <span class="token namespace">Utilities<span class="token punctuation">.</span>DataMapper</span><span class="token punctuation">;</span><br /> <span class="token keyword">using</span> <span class="token namespace">System<span class="token punctuation">.</span>Linq<span class="token punctuation">.</span>Expressions</span><span class="token punctuation">;</span><br /> <span class="token keyword">using</span> <span class="token namespace">Utilities<span class="token punctuation">.</span>SQL<span class="token punctuation">.</span>MicroORM<span class="token punctuation">.</span>Interfaces</span><span class="token punctuation">;</span><br /> <span class="token keyword">using</span> <span class="token namespace">System<span class="token punctuation">.</span>Data</span><span class="token punctuation">;</span><br /> <span class="token preprocessor property">#<span class="token directive keyword">endregion</span></span><br /> <br /> <span class="token keyword">namespace</span> <span class="token namespace">Utilities<span class="token punctuation">.</span>SQL<span class="token punctuation">.</span>MicroORM</span><br /> <span class="token punctuation">{</span><br /> <span class="token comment">/// <summary></span><br /> <span class="token comment">/// Class that acts as a mapping within the micro ORM</span><br /> <span class="token comment">/// </summary></span><br /> <span class="token comment">/// <typeparam name="ClassType">Class type that this will accept</typeparam></span><br /> <span class="token keyword">public</span> <span class="token keyword">class</span> <span class="token class-name">Mapping<span class="token punctuation"><</span>ClassType<span class="token punctuation">></span></span> <span class="token punctuation">:</span> <span class="token type-list"><span class="token class-name">IMapping</span></span> <span class="token keyword">where</span> <span class="token class-name">ClassType</span> <span class="token punctuation">:</span> <span class="token keyword">class</span><span class="token punctuation">,</span><span class="token keyword">new</span><span class="token punctuation">(</span><span class="token punctuation">)</span><br /> <span class="token punctuation">{</span><br /> <span class="token preprocessor property">#<span class="token directive keyword">region</span> Constructors</span><br /> <br /> <span class="token comment">/// <summary></span><br /> <span class="token comment">/// Constructor</span><br /> <span class="token comment">/// </summary></span><br /> <span class="token comment">/// <param name="Connection">Connection string</param></span><br /> <span class="token comment">/// <param name="TableName">Table name</param></span><br /> <span class="token comment">/// <param name="PrimaryKey">Primary key in the table</param></span><br /> <span class="token comment">/// <param name="AutoIncrement">Is the primary key set to auto increment?</param></span><br /> <span class="token comment">/// <param name="ParameterStarter">What the database expects as the</span><br /> <span class="token comment">/// parameter starting string ("@" for SQL Server, ":" for Oracle, etc.)</param></span><br /> <span class="token comment">/// <param name="DbType">DbType for this connection</param></span><br /> <span class="token keyword">public</span> <span class="token function">Mapping</span><span class="token punctuation">(</span><span class="token class-name"><span class="token keyword">string</span></span> Connection<span class="token punctuation">,</span> <span class="token class-name"><span class="token keyword">string</span></span> TableName<span class="token punctuation">,</span> <span class="token class-name"><span class="token keyword">string</span></span> PrimaryKey<span class="token punctuation">,</span> <span class="token class-name"><span class="token keyword">bool</span></span> AutoIncrement <span class="token operator">=</span> <span class="token boolean">true</span><span class="token punctuation">,</span> <span class="token class-name"><span class="token keyword">string</span></span> ParameterStarter <span class="token operator">=</span> <span class="token string">"@"</span><span class="token punctuation">,</span> <span class="token class-name"><span class="token keyword">string</span></span> DbType <span class="token operator">=</span> <span class="token string">"System.Data.SqlClient"</span><span class="token punctuation">)</span><br /> <span class="token punctuation">{</span><br /> Helper <span class="token operator">=</span> <span class="token keyword">new</span> <span class="token constructor-invocation class-name">SQLHelper</span><span class="token punctuation">(</span><span class="token string">""</span><span class="token punctuation">,</span> Connection<span class="token punctuation">,</span> System<span class="token punctuation">.</span>Data<span class="token punctuation">.</span>CommandType<span class="token punctuation">.</span>Text<span class="token punctuation">,</span> DbType<span class="token punctuation">)</span><span class="token punctuation">;</span><br /> Mappings <span class="token operator">=</span> <span class="token keyword">new</span> <span class="token constructor-invocation class-name">TypeMapping<span class="token punctuation"><</span>ClassType<span class="token punctuation">,</span> SQLHelper<span class="token punctuation">></span></span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">;</span><br /> ParameterNames <span class="token operator">=</span> <span class="token keyword">new</span> <span class="token constructor-invocation class-name">List<span class="token punctuation"><</span><span class="token keyword">string</span>\<span class="token punctuation">></span></span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">;</span><br /> <span class="token keyword">this</span><span class="token punctuation">.</span>TableName <span class="token operator">=</span> TableName<span class="token punctuation">;</span><br /> <span class="token keyword">this</span><span class="token punctuation">.</span>PrimaryKey <span class="token operator">=</span> PrimaryKey<span class="token punctuation">;</span><br /> <span class="token keyword">this</span><span class="token punctuation">.</span>AutoIncrement <span class="token operator">=</span> AutoIncrement<span class="token punctuation">;</span><br /> <span class="token keyword">this</span><span class="token punctuation">.</span>ParameterStarter <span class="token operator">=</span> ParameterStarter<span class="token punctuation">;</span><br /> <span class="token punctuation">}</span><br /> <br /> <span class="token comment">/// <summary></span><br /> <span class="token comment">/// Constructor (can be used if supplying own SQLHelper)</span><br /> <span class="token comment">/// </summary></span><br /> <span class="token comment">/// <param name="TableName">Table name</param></span><br /> <span class="token comment">/// <param name="PrimaryKey">Primary key</param></span><br /> <span class="token comment">/// <param name="AutoIncrement">Is the primary key set to auto increment?</param></span><br /> <span class="token comment">/// <param name="ParameterStarter">What the database expects as the</span><br /> <span class="token comment">/// parameter starting string ("@" for SQL Server, ":" for Oracle, etc.)</param></span><br /> <span class="token keyword">public</span> <span class="token function">Mapping</span><span class="token punctuation">(</span><span class="token class-name"><span class="token keyword">string</span></span> TableName<span class="token punctuation">,</span> <span class="token class-name"><span class="token keyword">string</span></span> PrimaryKey<span class="token punctuation">,</span> <span class="token class-name"><span class="token keyword">bool</span></span> AutoIncrement <span class="token operator">=</span> <span class="token boolean">true</span><span class="token punctuation">,</span> <span class="token class-name"><span class="token keyword">string</span></span> ParameterStarter <span class="token operator">=</span> <span class="token string">"@"</span><span class="token punctuation">)</span><br /> <span class="token punctuation">{</span><br /> Mappings <span class="token operator">=</span> <span class="token keyword">new</span> <span class="token constructor-invocation class-name">TypeMapping<span class="token punctuation"><</span>ClassType<span class="token punctuation">,</span> SQLHelper<span class="token punctuation">></span></span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">;</span><br /> ParameterNames <span class="token operator">=</span> <span class="token keyword">new</span> <span class="token constructor-invocation class-name">List<span class="token punctuation"><</span><span class="token keyword">string</span>\<span class="token punctuation">></span></span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">;</span><br /> <span class="token keyword">this</span><span class="token punctuation">.</span>TableName <span class="token operator">=</span> TableName<span class="token punctuation">;</span><br /> <span class="token keyword">this</span><span class="token punctuation">.</span>PrimaryKey <span class="token operator">=</span> PrimaryKey<span class="token punctuation">;</span><br /> <span class="token keyword">this</span><span class="token punctuation">.</span>AutoIncrement <span class="token operator">=</span> AutoIncrement<span class="token punctuation">;</span><br /> <span class="token keyword">this</span><span class="token punctuation">.</span>ParameterStarter <span class="token operator">=</span> ParameterStarter<span class="token punctuation">;</span><br /> <span class="token punctuation">}</span><br /> <br /> <span class="token preprocessor property">#<span class="token directive keyword">endregion</span></span><br /> <br /> <span class="token preprocessor property">#<span class="token directive keyword">region</span> Properties</span><br /> <br /> <span class="token comment">/// <summary></span><br /> <span class="token comment">/// SQL Helper</span><br /> <span class="token comment">/// </summary></span><br /> <span class="token keyword">public</span> <span class="token keyword">virtual</span> <span class="token return-type class-name">SQLHelper</span> Helper <span class="token punctuation">{</span> <span class="token keyword">get</span><span class="token punctuation">;</span> <span class="token keyword">set</span><span class="token punctuation">;</span> <span class="token punctuation">}</span><br /> <br /> <span class="token comment">/// <summary></span><br /> <span class="token comment">/// Mapper used to map properties to SQLHelper</span><br /> <span class="token comment">/// </summary></span><br /> <span class="token keyword">public</span> <span class="token keyword">virtual</span> <span class="token return-type class-name">TypeMapping<span class="token punctuation"><</span>ClassType<span class="token punctuation">,</span> SQLHelper<span class="token punctuation">></span></span> Mappings <span class="token punctuation">{</span> <span class="token keyword">get</span><span class="token punctuation">;</span> <span class="token keyword">set</span><span class="token punctuation">;</span> <span class="token punctuation">}</span><br /> <br /> <span class="token comment">/// <summary></span><br /> <span class="token comment">/// Table name</span><br /> <span class="token comment">/// </summary></span><br /> <span class="token keyword">protected</span> <span class="token keyword">virtual</span> <span class="token return-type class-name"><span class="token keyword">string</span></span> TableName <span class="token punctuation">{</span> <span class="token keyword">get</span><span class="token punctuation">;</span> <span class="token keyword">set</span><span class="token punctuation">;</span> <span class="token punctuation">}</span><br /> <br /> <span class="token comment">/// <summary></span><br /> <span class="token comment">/// Primar key</span><br /> <span class="token comment">/// </summary></span><br /> <span class="token keyword">protected</span> <span class="token keyword">virtual</span> <span class="token return-type class-name"><span class="token keyword">string</span></span> PrimaryKey <span class="token punctuation">{</span> <span class="token keyword">get</span><span class="token punctuation">;</span> <span class="token keyword">set</span><span class="token punctuation">;</span> <span class="token punctuation">}</span><br /> <br /> <span class="token comment">/// <summary></span><br /> <span class="token comment">/// Auto increment?</span><br /> <span class="token comment">/// </summary></span><br /> <span class="token keyword">protected</span> <span class="token keyword">virtual</span> <span class="token return-type class-name"><span class="token keyword">bool</span></span> AutoIncrement <span class="token punctuation">{</span> <span class="token keyword">get</span><span class="token punctuation">;</span> <span class="token keyword">set</span><span class="token punctuation">;</span> <span class="token punctuation">}</span><br /> <br /> <span class="token comment">/// <summary></span><br /> <span class="token comment">/// Parameter starter</span><br /> <span class="token comment">/// </summary></span><br /> <span class="token keyword">protected</span> <span class="token keyword">virtual</span> <span class="token return-type class-name"><span class="token keyword">string</span></span> ParameterStarter <span class="token punctuation">{</span> <span class="token keyword">get</span><span class="token punctuation">;</span> <span class="token keyword">set</span><span class="token punctuation">;</span> <span class="token punctuation">}</span><br /> <br /> <span class="token comment">/// <summary></span><br /> <span class="token comment">/// Parameter names</span><br /> <span class="token comment">/// </summary></span><br /> <span class="token keyword">public</span> <span class="token keyword">virtual</span> <span class="token return-type class-name">List<span class="token punctuation"><</span><span class="token keyword">string</span>\<span class="token punctuation">></span></span> ParameterNames <span class="token punctuation">{</span> <span class="token keyword">get</span><span class="token punctuation">;</span> <span class="token keyword">set</span><span class="token punctuation">;</span> <span class="token punctuation">}</span><br /> <br /> <span class="token preprocessor property">#<span class="token directive keyword">endregion</span></span><br /> <br /> <span class="token preprocessor property">#<span class="token directive keyword">region</span> Public Functions</span><br /> <br /> <span class="token preprocessor property">#<span class="token directive keyword">region</span> All</span><br /> <br /> <span class="token comment">/// <summary></span><br /> <span class="token comment">/// Gets a list of all objects that meet the specified criteria</span><br /> <span class="token comment">/// </summary></span><br /> <span class="token comment">/// <param name="Command">Command to use (can be an SQL string or stored procedure)</param></span><br /> <span class="token comment">/// <param name="CommandType">Command type</param></span><br /> <span class="token comment">/// <param name="Parameters">Parameters to search by</param></span><br /> <span class="token comment">/// <returns>A list of all objects that meet the specified criteria</returns></span><br /> <span class="token keyword">public</span> <span class="token keyword">virtual</span> <span class="token return-type class-name">IEnumerable<span class="token punctuation"><</span>ClassType<span class="token punctuation">></span></span> <span class="token function">All</span><span class="token punctuation">(</span><span class="token class-name"><span class="token keyword">string</span></span> Command<span class="token punctuation">,</span> <span class="token class-name">CommandType</span> CommandType<span class="token punctuation">,</span> <span class="token keyword">params</span> IParameter\<span class="token punctuation">[</span>\<span class="token punctuation">]</span> Parameters<span class="token punctuation">)</span><br /> <span class="token punctuation">{</span><br /> <span class="token function">Check</span><span class="token punctuation">(</span>Command<span class="token punctuation">,</span> <span class="token string">"Command"</span><span class="token punctuation">)</span><span class="token punctuation">;</span><br /> <span class="token function">Check</span><span class="token punctuation">(</span>Helper<span class="token punctuation">,</span> <span class="token string">"Helper"</span><span class="token punctuation">)</span><span class="token punctuation">;</span><br /> <span class="token function">Check</span><span class="token punctuation">(</span>Mappings<span class="token punctuation">,</span> <span class="token string">"Mappings"</span><span class="token punctuation">)</span><span class="token punctuation">;</span><br /> <span class="token class-name">List<span class="token punctuation"><</span>ClassType<span class="token punctuation">></span></span> Return <span class="token operator">=</span> <span class="token keyword">new</span> <span class="token constructor-invocation class-name">List<span class="token punctuation"><</span>ClassType<span class="token punctuation">></span></span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">;</span><br /> <span class="token function">SetupCommand</span><span class="token punctuation">(</span>Command<span class="token punctuation">,</span> CommandType<span class="token punctuation">,</span> Parameters<span class="token punctuation">)</span><span class="token punctuation">;</span><br /> Helper<span class="token punctuation">.</span><span class="token function">ExecuteReader</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">;</span><br /> <span class="token keyword">while</span> <span class="token punctuation">(</span>Helper<span class="token punctuation">.</span><span class="token function">Read</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">)</span><br /> <span class="token punctuation">{</span><br /> <span class="token class-name">ClassType</span> Temp <span class="token operator">=</span> <span class="token keyword">new</span> <span class="token constructor-invocation class-name">ClassType</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">;</span><br /> Mappings<span class="token punctuation">.</span><span class="token function">Copy</span><span class="token punctuation">(</span>Helper<span class="token punctuation">,</span> Temp<span class="token punctuation">)</span><span class="token punctuation">;</span><br /> Return<span class="token punctuation">.</span><span class="token function">Add</span><span class="token punctuation">(</span>Temp<span class="token punctuation">)</span><span class="token punctuation">;</span><br /> <span class="token punctuation">}</span><br /> <span class="token keyword">return</span> Return<span class="token punctuation">;</span><br /> <span class="token punctuation">}</span><br /> <br /> <span class="token comment">/// <summary></span><br /> <span class="token comment">/// Gets a list of all objects that meet the specified criteria</span><br /> <span class="token comment">/// </summary></span><br /> <span class="token comment">/// <param name="Columns">Columns to return</param></span><br /> <span class="token comment">/// <param name="Limit">Limit on the number of items to return</param></span><br /> <span class="token comment">/// <param name="OrderBy">Order by clause</param></span><br /> <span class="token comment">/// <param name="Parameters">Parameters to search by</param></span><br /> <span class="token comment">/// <returns>A list of all objects that meet the specified criteria</returns></span><br /> <span class="token keyword">public</span> <span class="token keyword">virtual</span> <span class="token return-type class-name">IEnumerable<span class="token punctuation"><</span>ClassType<span class="token punctuation">></span></span> <span class="token function">All</span><span class="token punctuation">(</span><span class="token class-name"><span class="token keyword">string</span></span> Columns <span class="token operator">=</span> <span class="token string">"\*"</span><span class="token punctuation">,</span> <span class="token class-name"><span class="token keyword">int</span></span> Limit <span class="token operator">=</span> <span class="token number">0</span><span class="token punctuation">,</span> <span class="token class-name"><span class="token keyword">string</span></span> OrderBy <span class="token operator">=</span> <span class="token string">""</span><span class="token punctuation">,</span> <span class="token keyword">params</span> IParameter\<span class="token punctuation">[</span>\<span class="token punctuation">]</span> Parameters<span class="token punctuation">)</span><br /> <span class="token punctuation">{</span><br /> <span class="token function">Check</span><span class="token punctuation">(</span>Columns<span class="token punctuation">,</span> <span class="token string">"Columns"</span><span class="token punctuation">)</span><span class="token punctuation">;</span><br /> <span class="token keyword">return</span> <span class="token function">All</span><span class="token punctuation">(</span><span class="token function">SetupSelectCommand</span><span class="token punctuation">(</span>Columns<span class="token punctuation">,</span> Limit<span class="token punctuation">,</span> OrderBy<span class="token punctuation">,</span> Parameters<span class="token punctuation">)</span><span class="token punctuation">,</span> CommandType<span class="token punctuation">.</span>Text<span class="token punctuation">,</span> Parameters<span class="token punctuation">)</span><span class="token punctuation">;</span><br /> <span class="token punctuation">}</span><br /> <br /> <span class="token preprocessor property">#<span class="token directive keyword">endregion</span></span><br /> <br /> <span class="token preprocessor property">#<span class="token directive keyword">region</span> Any</span><br /> <br /> <span class="token comment">/// <summary></span><br /> <span class="token comment">/// Gets a single object that fits the criteria</span><br /> <span class="token comment">/// </summary></span><br /> <span class="token comment">/// <param name="Columns">Columns to select</param></span><br /> <span class="token comment">/// <param name="Parameters">Parameters to search by</param></span><br /> <span class="token comment">/// <returns>An object fitting the criteria specified or null if none are found</returns></span><br /> <span class="token keyword">public</span> <span class="token keyword">virtual</span> <span class="token return-type class-name">ClassType</span> <span class="token function">Any</span><span class="token punctuation">(</span><span class="token class-name"><span class="token keyword">string</span></span> Columns <span class="token operator">=</span> <span class="token string">"\*"</span><span class="token punctuation">,</span> <span class="token class-name">ClassType</span> ObjectToReturn <span class="token operator">=</span> <span class="token keyword">null</span><span class="token punctuation">,</span> <span class="token keyword">params</span> IParameter\<span class="token punctuation">[</span>\<span class="token punctuation">]</span> Parameters<span class="token punctuation">)</span><br /> <span class="token punctuation">{</span><br /> <span class="token function">Check</span><span class="token punctuation">(</span>Columns<span class="token punctuation">,</span> <span class="token string">"Columns"</span><span class="token punctuation">)</span><span class="token punctuation">;</span><br /> <span class="token keyword">return</span> <span class="token function">Any</span><span class="token punctuation">(</span><span class="token function">SetupSelectCommand</span><span class="token punctuation">(</span>Columns<span class="token punctuation">,</span> <span class="token number">1</span><span class="token punctuation">,</span> <span class="token string">""</span><span class="token punctuation">,</span> Parameters<span class="token punctuation">)</span><span class="token punctuation">,</span> CommandType<span class="token punctuation">.</span>Text<span class="token punctuation">,</span> ObjectToReturn<span class="token punctuation">,</span> Parameters<span class="token punctuation">)</span><span class="token punctuation">;</span><br /> <span class="token punctuation">}</span><br /> <br /> <span class="token comment">/// <summary></span><br /> <span class="token comment">/// Gets a single object that fits the criteria</span><br /> <span class="token comment">/// </summary></span><br /> <span class="token comment">/// <param name="Command">Command to use (can be an SQL string or stored procedure name)</param></span><br /> <span class="token comment">/// <param name="CommandType">Command type</param></span><br /> <span class="token comment">/// <param name="ObjectToReturn">Object to return (in case the object needs to be created outside this)</param></span><br /> <span class="token comment">/// <param name="Parameters">Parameters used to search by</param></span><br /> <span class="token comment">/// <returns>An object fitting the criteria specified or null if none are found</returns></span><br /> <span class="token keyword">public</span> <span class="token keyword">virtual</span> <span class="token return-type class-name">ClassType</span> <span class="token function">Any</span><span class="token punctuation">(</span><span class="token class-name"><span class="token keyword">string</span></span> Command<span class="token punctuation">,</span> <span class="token class-name">CommandType</span> CommandType<span class="token punctuation">,</span> <span class="token class-name">ClassType</span> ObjectToReturn <span class="token operator">=</span> <span class="token keyword">null</span><span class="token punctuation">,</span> <span class="token keyword">params</span> IParameter\<span class="token punctuation">[</span>\<span class="token punctuation">]</span> Parameters<span class="token punctuation">)</span><br /> <span class="token punctuation">{</span><br /> <span class="token function">Check</span><span class="token punctuation">(</span>Mappings<span class="token punctuation">,</span> <span class="token string">"Mappings"</span><span class="token punctuation">)</span><span class="token punctuation">;</span><br /> <span class="token function">Check</span><span class="token punctuation">(</span>Command<span class="token punctuation">,</span> <span class="token string">"Command"</span><span class="token punctuation">)</span><span class="token punctuation">;</span><br /> <span class="token function">Check</span><span class="token punctuation">(</span>Helper<span class="token punctuation">,</span> <span class="token string">"Helper"</span><span class="token punctuation">)</span><span class="token punctuation">;</span><br /> <span class="token class-name">ClassType</span> Return <span class="token operator">=</span> <span class="token punctuation">(</span>ObjectToReturn <span class="token operator">==</span> <span class="token keyword">null</span><span class="token punctuation">)</span> <span class="token punctuation">?</span> <span class="token keyword">new</span> <span class="token constructor-invocation class-name">ClassType</span><span class="token punctuation">(</span><span class="token punctuation">)</span> <span class="token punctuation">:</span> ObjectToReturn<span class="token punctuation">;</span><br /> <span class="token function">SetupCommand</span><span class="token punctuation">(</span>Command<span class="token punctuation">,</span> CommandType<span class="token punctuation">,</span> Parameters<span class="token punctuation">)</span><span class="token punctuation">;</span><br /> Helper<span class="token punctuation">.</span><span class="token function">ExecuteReader</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">;</span><br /> <span class="token keyword">if</span> <span class="token punctuation">(</span>Helper<span class="token punctuation">.</span><span class="token function">Read</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">)</span><br /> Mappings<span class="token punctuation">.</span><span class="token function">Copy</span><span class="token punctuation">(</span>Helper<span class="token punctuation">,</span> Return<span class="token punctuation">)</span><span class="token punctuation">;</span><br /> <span class="token keyword">return</span> Return<span class="token punctuation">;</span><br /> <span class="token punctuation">}</span><br /> <br /> <span class="token preprocessor property">#<span class="token directive keyword">endregion</span></span><br /> <br /> <span class="token preprocessor property">#<span class="token directive keyword">region</span> Close</span><br /> <br /> <span class="token comment">/// <summary></span><br /> <span class="token comment">/// Closes the connection to the database</span><br /> <span class="token comment">/// </summary></span><br /> <span class="token keyword">public</span> <span class="token keyword">virtual</span> <span class="token return-type class-name"><span class="token keyword">void</span></span> <span class="token function">Close</span><span class="token punctuation">(</span><span class="token punctuation">)</span><br /> <span class="token punctuation">{</span><br /> <span class="token function">Check</span><span class="token punctuation">(</span>Helper<span class="token punctuation">,</span> <span class="token string">"Helper"</span><span class="token punctuation">)</span><span class="token punctuation">;</span><br /> Helper<span class="token punctuation">.</span><span class="token function">Close</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">;</span><br /> <span class="token punctuation">}</span><br /> <br /> <span class="token preprocessor property">#<span class="token directive keyword">endregion</span></span><br /> <br /> <span class="token preprocessor property">#<span class="token directive keyword">region</span> Delete</span><br /> <br /> <span class="token comment">/// <summary></span><br /> <span class="token comment">/// Deletes an object from the database</span><br /> <span class="token comment">/// </summary></span><br /> <span class="token comment">/// <param name="Command">Command to use</param></span><br /> <span class="token comment">/// <param name="CommandType">Command type</param></span><br /> <span class="token comment">/// <param name="Object">Object to delete</param></span><br /> <span class="token keyword">public</span> <span class="token keyword">virtual</span> <span class="token return-type class-name"><span class="token keyword">void</span></span> <span class="token function">Delete</span><span class="token punctuation">(</span><span class="token class-name"><span class="token keyword">string</span></span> Command<span class="token punctuation">,</span> <span class="token class-name">CommandType</span> CommandType<span class="token punctuation">,</span> <span class="token class-name">ClassType</span> Object<span class="token punctuation">)</span><br /> <span class="token punctuation">{</span><br /> <span class="token function">Check</span><span class="token punctuation">(</span>Object<span class="token punctuation">,</span> <span class="token string">"Object"</span><span class="token punctuation">)</span><span class="token punctuation">;</span><br /> <span class="token function">Check</span><span class="token punctuation">(</span>Command<span class="token punctuation">,</span> <span class="token string">"Command"</span><span class="token punctuation">)</span><span class="token punctuation">;</span><br /> <span class="token function">Check</span><span class="token punctuation">(</span>Helper<span class="token punctuation">,</span> <span class="token string">"Helper"</span><span class="token punctuation">)</span><span class="token punctuation">;</span><br /> <span class="token function">Check</span><span class="token punctuation">(</span>Mappings<span class="token punctuation">,</span> <span class="token string">"Mappings"</span><span class="token punctuation">)</span><span class="token punctuation">;</span><br /> <span class="token function">SetupCommand</span><span class="token punctuation">(</span>Command<span class="token punctuation">,</span> CommandType<span class="token punctuation">,</span> <span class="token keyword">null</span><span class="token punctuation">)</span><span class="token punctuation">;</span><br /> Mappings<span class="token punctuation">.</span><span class="token function">Copy</span><span class="token punctuation">(</span>Object<span class="token punctuation">,</span> Helper<span class="token punctuation">)</span><span class="token punctuation">;</span><br /> Helper<span class="token punctuation">.</span><span class="token function">ExecuteNonQuery</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">;</span><br /> <span class="token punctuation">}</span><br /> <br /> <span class="token comment">/// <summary></span><br /> <span class="token comment">/// Deletes an object from the database</span><br /> <span class="token comment">/// </summary></span><br /> <span class="token comment">/// <param name="Object">Object to delete</param></span><br /> <span class="token keyword">public</span> <span class="token keyword">virtual</span> <span class="token return-type class-name"><span class="token keyword">void</span></span> <span class="token function">Delete</span><span class="token punctuation">(</span><span class="token class-name">ClassType</span> Object<span class="token punctuation">)</span><br /> <span class="token punctuation">{</span><br /> <span class="token function">Delete</span><span class="token punctuation">(</span><span class="token function">SetupDeleteCommand</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">,</span> CommandType<span class="token punctuation">.</span>Text<span class="token punctuation">,</span> Object<span class="token punctuation">)</span><span class="token punctuation">;</span><br /> <span class="token punctuation">}</span><br /> <br /> <span class="token preprocessor property">#<span class="token directive keyword">endregion</span></span><br /> <br /> <span class="token preprocessor property">#<span class="token directive keyword">region</span> Insert</span><br /> <br /> <span class="token comment">/// <summary></span><br /> <span class="token comment">/// Inserts an object based on the command specified</span><br /> <span class="token comment">/// </summary></span><br /> <span class="token comment">/// <typeparam name="DataType">Data type expected to be returned from the query (to get the ID, etc.)</typeparam></span><br /> <span class="token comment">/// <param name="Command">Command to run</param></span><br /> <span class="token comment">/// <param name="CommandType">Command type</param></span><br /> <span class="token comment">/// <param name="Object">Object to insert</param></span><br /> <span class="token comment">/// <returns>The returned object from the query (usually the newly created row's ID)</returns></span><br /> <span class="token keyword">public</span> <span class="token keyword">virtual</span> <span class="token return-type class-name">DataType</span> <span class="token generic-method"><span class="token function">Insert</span><span class="token generic class-name"><span class="token punctuation"><</span>DataType<span class="token punctuation">></span></span></span><span class="token punctuation">(</span><span class="token class-name"><span class="token keyword">string</span></span> Command<span class="token punctuation">,</span> <span class="token class-name">CommandType</span> CommandType<span class="token punctuation">,</span> <span class="token class-name">ClassType</span> Object<span class="token punctuation">)</span><br /> <span class="token punctuation">{</span><br /> <span class="token function">Check</span><span class="token punctuation">(</span>Object<span class="token punctuation">,</span> <span class="token string">"Object"</span><span class="token punctuation">)</span><span class="token punctuation">;</span><br /> <span class="token function">Check</span><span class="token punctuation">(</span>Command<span class="token punctuation">,</span> <span class="token string">"Command"</span><span class="token punctuation">)</span><span class="token punctuation">;</span><br /> <span class="token function">Check</span><span class="token punctuation">(</span>Helper<span class="token punctuation">,</span> <span class="token string">"Helper"</span><span class="token punctuation">)</span><span class="token punctuation">;</span><br /> <span class="token function">Check</span><span class="token punctuation">(</span>Mappings<span class="token punctuation">,</span> <span class="token string">"Mappings"</span><span class="token punctuation">)</span><span class="token punctuation">;</span><br /> <span class="token function">SetupCommand</span><span class="token punctuation">(</span>Command<span class="token punctuation">,</span> CommandType<span class="token punctuation">,</span> <span class="token keyword">null</span><span class="token punctuation">)</span><span class="token punctuation">;</span><br /> Mappings<span class="token punctuation">.</span><span class="token function">Copy</span><span class="token punctuation">(</span>Object<span class="token punctuation">,</span> Helper<span class="token punctuation">)</span><span class="token punctuation">;</span><br /> <span class="token keyword">return</span> <span class="token punctuation">(</span>DataType<span class="token punctuation">)</span>Convert<span class="token punctuation">.</span><span class="token function">ChangeType</span><span class="token punctuation">(</span>Helper<span class="token punctuation">.</span><span class="token function">ExecuteScalar</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">,</span> <span class="token keyword">typeof</span><span class="token punctuation">(</span><span class="token type-expression class-name">DataType</span><span class="token punctuation">)</span><span class="token punctuation">)</span><span class="token punctuation">;</span><br /> <span class="token punctuation">}</span><br /> <br /> <span class="token comment">/// <summary></span><br /> <span class="token comment">/// Inserts an object into the database</span><br /> <span class="token comment">/// </summary></span><br /> <span class="token comment">/// <typeparam name="DataType">Data type expected (should be the same type as the primary key)</typeparam></span><br /> <span class="token comment">/// <param name="Object">Object to insert</param></span><br /> <span class="token comment">/// <returns>The returned object from the query (the newly created row's ID)</returns></span><br /> <span class="token keyword">public</span> <span class="token keyword">virtual</span> <span class="token return-type class-name">DataType</span> <span class="token generic-method"><span class="token function">Insert</span><span class="token generic class-name"><span class="token punctuation"><</span>DataType<span class="token punctuation">></span></span></span><span class="token punctuation">(</span><span class="token class-name">ClassType</span> Object<span class="token punctuation">)</span><br /> <span class="token punctuation">{</span><br /> <span class="token keyword">return</span> <span class="token generic-method"><span class="token function">Insert</span><span class="token generic class-name"><span class="token punctuation"><</span>DataType<span class="token punctuation">></span></span></span><span class="token punctuation">(</span><span class="token function">SetupInsertCommand</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">,</span> CommandType<span class="token punctuation">.</span>Text<span class="token punctuation">,</span> Object<span class="token punctuation">)</span><span class="token punctuation">;</span><br /> <span class="token punctuation">}</span><br /> <br /> <span class="token preprocessor property">#<span class="token directive keyword">endregion</span></span><br /> <br /> <span class="token preprocessor property">#<span class="token directive keyword">region</span> Map</span><br /> <br /> <span class="token comment">/// <summary></span><br /> <span class="token comment">/// Maps a property to a database property name (required to actually get data from the database)</span><br /> <span class="token comment">/// </summary></span><br /> <span class="token comment">/// <typeparam name="DataType">Data type of the property</typeparam></span><br /> <span class="token comment">/// <param name="Property">Property to add a mapping for</param></span><br /> <span class="token comment">/// <param name="DatabasePropertyName">Property name</param></span><br /> <span class="token keyword">public</span> <span class="token keyword">virtual</span> <span class="token return-type class-name">Mapping<span class="token punctuation"><</span>ClassType<span class="token punctuation">></span></span> <span class="token generic-method"><span class="token function">Map</span><span class="token generic class-name"><span class="token punctuation"><</span>DataType<span class="token punctuation">></span></span></span><span class="token punctuation">(</span><span class="token class-name">Expression<span class="token punctuation"><</span>Func<span class="token punctuation"><</span>ClassType<span class="token punctuation">,</span> DataType<span class="token punctuation">></span><span class="token punctuation">></span></span> Property<span class="token punctuation">,</span> <span class="token class-name"><span class="token keyword">string</span></span> DatabasePropertyName<span class="token punctuation">)</span><br /> <span class="token punctuation">{</span><br /> <span class="token function">Check</span><span class="token punctuation">(</span>Property<span class="token punctuation">,</span> <span class="token string">"Property"</span><span class="token punctuation">)</span><span class="token punctuation">;</span><br /> <span class="token function">Check</span><span class="token punctuation">(</span>DatabasePropertyName<span class="token punctuation">,</span> <span class="token string">"DatabasePropertyName"</span><span class="token punctuation">)</span><span class="token punctuation">;</span><br /> <span class="token function">Check</span><span class="token punctuation">(</span>Mappings<span class="token punctuation">,</span> <span class="token string">"Mappings"</span><span class="token punctuation">)</span><span class="token punctuation">;</span><br /> <span class="token class-name">Expression</span> Convert <span class="token operator">=</span> Expression<span class="token punctuation">.</span><span class="token function">Convert</span><span class="token punctuation">(</span>Property<span class="token punctuation">.</span>Body<span class="token punctuation">,</span> <span class="token keyword">typeof</span><span class="token punctuation">(</span><span class="token type-expression class-name"><span class="token keyword">object</span></span><span class="token punctuation">)</span><span class="token punctuation">)</span><span class="token punctuation">;</span><br /> <span class="token class-name">Expression<span class="token punctuation"><</span>Func<span class="token punctuation"><</span>ClassType<span class="token punctuation">,</span> <span class="token keyword">object</span>\<span class="token punctuation">></span><span class="token punctuation">></span></span> PropertyExpression <span class="token operator">=</span> Expression<span class="token punctuation">.</span><span class="token generic-method"><span class="token function">Lambda</span><span class="token generic class-name"><span class="token punctuation"><</span>Func<span class="token punctuation"><</span>ClassType<span class="token punctuation">,</span> <span class="token keyword">object</span>\<span class="token punctuation">></span><span class="token punctuation">></span></span></span><span class="token punctuation">(</span>Convert<span class="token punctuation">,</span> Property<span class="token punctuation">.</span>Parameters<span class="token punctuation">)</span><span class="token punctuation">;</span><br /> Mappings<span class="token punctuation">.</span><span class="token function">AddMapping</span><span class="token punctuation">(</span>PropertyExpression<span class="token punctuation">,</span><br /> <span class="token keyword">new</span> <span class="token constructor-invocation class-name">Func<span class="token punctuation"><</span>SQLHelper<span class="token punctuation">,</span> <span class="token keyword">object</span>\<span class="token punctuation">></span></span><span class="token punctuation">(</span><span class="token punctuation">(</span>x<span class="token punctuation">)</span> <span class="token operator">=></span> x<span class="token punctuation">.</span><span class="token function">GetParameter</span><span class="token punctuation">(</span>DatabasePropertyName<span class="token punctuation">,</span> <span class="token keyword">default</span><span class="token punctuation">(</span><span class="token type-expression class-name">DataType</span><span class="token punctuation">)</span><span class="token punctuation">)</span><span class="token punctuation">)</span><span class="token punctuation">,</span><br /> <span class="token keyword">new</span> <span class="token constructor-invocation class-name">Action<span class="token punctuation"><</span>SQLHelper<span class="token punctuation">,</span> <span class="token keyword">object</span>\<span class="token punctuation">></span></span><span class="token punctuation">(</span><span class="token punctuation">(</span>x<span class="token punctuation">,</span> y<span class="token punctuation">)</span> <span class="token operator">=></span> x<span class="token punctuation">.</span><span class="token function">AddParameter</span><span class="token punctuation">(</span>DatabasePropertyName<span class="token punctuation">,</span> y<span class="token punctuation">)</span><span class="token punctuation">)</span><span class="token punctuation">)</span><span class="token punctuation">;</span><br /> ParameterNames<span class="token punctuation">.</span><span class="token function">Add</span><span class="token punctuation">(</span>DatabasePropertyName<span class="token punctuation">)</span><span class="token punctuation">;</span><br /> <span class="token keyword">return</span> <span class="token keyword">this</span><span class="token punctuation">;</span><br /> <span class="token punctuation">}</span><br /> <br /> <span class="token comment">/// <summary></span><br /> <span class="token comment">/// Maps a property to a database property name (required to actually get data from the database)</span><br /> <span class="token comment">/// </summary></span><br /> <span class="token comment">/// <param name="Property">Property to add a mapping for</param></span><br /> <span class="token comment">/// <param name="DatabasePropertyName">Property name</param></span><br /> <span class="token comment">/// <param name="Length">Max length of the string</param></span><br /> <span class="token keyword">public</span> <span class="token keyword">virtual</span> <span class="token return-type class-name">Mapping<span class="token punctuation"><</span>ClassType<span class="token punctuation">></span></span> <span class="token function">Map</span><span class="token punctuation">(</span><span class="token class-name">Expression<span class="token punctuation"><</span>Func<span class="token punctuation"><</span>ClassType<span class="token punctuation">,</span> <span class="token keyword">string</span>\<span class="token punctuation">></span><span class="token punctuation">></span></span> Property<span class="token punctuation">,</span> <span class="token class-name"><span class="token keyword">string</span></span> DatabasePropertyName<span class="token punctuation">,</span> <span class="token class-name"><span class="token keyword">int</span></span> Length<span class="token punctuation">)</span><br /> <span class="token punctuation">{</span><br /> <span class="token function">Check</span><span class="token punctuation">(</span>Property<span class="token punctuation">,</span> <span class="token string">"Property"</span><span class="token punctuation">)</span><span class="token punctuation">;</span><br /> <span class="token function">Check</span><span class="token punctuation">(</span>DatabasePropertyName<span class="token punctuation">,</span> <span class="token string">"DatabasePropertyName"</span><span class="token punctuation">)</span><span class="token punctuation">;</span><br /> <span class="token function">Check</span><span class="token punctuation">(</span>Mappings<span class="token punctuation">,</span> <span class="token string">"Mappings"</span><span class="token punctuation">)</span><span class="token punctuation">;</span><br /> <span class="token class-name">Expression</span> Convert <span class="token operator">=</span> Expression<span class="token punctuation">.</span><span class="token function">Convert</span><span class="token punctuation">(</span>Property<span class="token punctuation">.</span>Body<span class="token punctuation">,</span> <span class="token keyword">typeof</span><span class="token punctuation">(</span><span class="token type-expression class-name"><span class="token keyword">object</span></span><span class="token punctuation">)</span><span class="token punctuation">)</span><span class="token punctuation">;</span><br /> <span class="token class-name">Expression<span class="token punctuation"><</span>Func<span class="token punctuation"><</span>ClassType<span class="token punctuation">,</span> <span class="token keyword">object</span>\<span class="token punctuation">></span><span class="token punctuation">></span></span> PropertyExpression <span class="token operator">=</span> Expression<span class="token punctuation">.</span><span class="token generic-method"><span class="token function">Lambda</span><span class="token generic class-name"><span class="token punctuation"><</span>Func<span class="token punctuation"><</span>ClassType<span class="token punctuation">,</span> <span class="token keyword">object</span>\<span class="token punctuation">></span><span class="token punctuation">></span></span></span><span class="token punctuation">(</span>Convert<span class="token punctuation">,</span> Property<span class="token punctuation">.</span>Parameters<span class="token punctuation">)</span><span class="token punctuation">;</span><br /> Mappings<span class="token punctuation">.</span><span class="token function">AddMapping</span><span class="token punctuation">(</span>PropertyExpression<span class="token punctuation">,</span><br /> <span class="token keyword">new</span> <span class="token constructor-invocation class-name">Func<span class="token punctuation"><</span>SQLHelper<span class="token punctuation">,</span> <span class="token keyword">object</span>\<span class="token punctuation">></span></span><span class="token punctuation">(</span><span class="token punctuation">(</span>x<span class="token punctuation">)</span> <span class="token operator">=></span> x<span class="token punctuation">.</span><span class="token function">GetParameter</span><span class="token punctuation">(</span>DatabasePropertyName<span class="token punctuation">,</span> <span class="token string">""</span><span class="token punctuation">)</span><span class="token punctuation">)</span><span class="token punctuation">,</span><br /> <span class="token keyword">new</span> <span class="token constructor-invocation class-name">Action<span class="token punctuation"><</span>SQLHelper<span class="token punctuation">,</span> <span class="token keyword">object</span>\<span class="token punctuation">></span></span><span class="token punctuation">(</span><span class="token punctuation">(</span>x<span class="token punctuation">,</span> y<span class="token punctuation">)</span> <span class="token operator">=></span> x<span class="token punctuation">.</span><span class="token function">AddParameter</span><span class="token punctuation">(</span>DatabasePropertyName<span class="token punctuation">,</span> <span class="token punctuation">(</span><span class="token keyword">string</span><span class="token punctuation">)</span>y<span class="token punctuation">,</span> Length<span class="token punctuation">)</span><span class="token punctuation">)</span><span class="token punctuation">)</span><span class="token punctuation">;</span><br /> ParameterNames<span class="token punctuation">.</span><span class="token function">Add</span><span class="token punctuation">(</span>DatabasePropertyName<span class="token punctuation">)</span><span class="token punctuation">;</span><br /> <span class="token keyword">return</span> <span class="token keyword">this</span><span class="token punctuation">;</span><br /> <span class="token punctuation">}</span><br /> <br /> <span class="token preprocessor property">#<span class="token directive keyword">endregion</span></span><br /> <br /> <span class="token preprocessor property">#<span class="token directive keyword">region</span> Open</span><br /> <br /> <span class="token comment">/// <summary></span><br /> <span class="token comment">/// Opens the connection to the database</span><br /> <span class="token comment">/// </summary></span><br /> <span class="token keyword">public</span> <span class="token keyword">virtual</span> <span class="token return-type class-name"><span class="token keyword">void</span></span> <span class="token function">Open</span><span class="token punctuation">(</span><span class="token punctuation">)</span><br /> <span class="token punctuation">{</span><br /> <span class="token function">Check</span><span class="token punctuation">(</span>Helper<span class="token punctuation">,</span> <span class="token string">"Helper"</span><span class="token punctuation">)</span><span class="token punctuation">;</span><br /> Helper<span class="token punctuation">.</span><span class="token function">Open</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">;</span><br /> <span class="token punctuation">}</span><br /> <br /> <span class="token preprocessor property">#<span class="token directive keyword">endregion</span></span><br /> <br /> <span class="token preprocessor property">#<span class="token directive keyword">region</span> PageCount</span><br /> <br /> <span class="token comment">/// <summary></span><br /> <span class="token comment">/// Gets the number of pages based on the specified </span><br /> <span class="token comment">/// </summary></span><br /> <span class="token comment">/// <param name="PageSize">Page size</param></span><br /> <span class="token comment">/// <param name="Parameters">Parameters to search by</param></span><br /> <span class="token comment">/// <returns>The number of pages that the table contains for the specified page size</returns></span><br /> <span class="token keyword">public</span> <span class="token keyword">virtual</span> <span class="token return-type class-name"><span class="token keyword">int</span></span> <span class="token function">PageCount</span><span class="token punctuation">(</span><span class="token class-name"><span class="token keyword">int</span></span> PageSize <span class="token operator">=</span> <span class="token number">25</span><span class="token punctuation">,</span> <span class="token keyword">params</span> IParameter\<span class="token punctuation">[</span>\<span class="token punctuation">]</span> Parameters<span class="token punctuation">)</span><br /> <span class="token punctuation">{</span><br /> <span class="token function">Check</span><span class="token punctuation">(</span>Helper<span class="token punctuation">,</span> <span class="token string">"Helper"</span><span class="token punctuation">)</span><span class="token punctuation">;</span><br /> <span class="token function">SetupCommand</span><span class="token punctuation">(</span><span class="token function">SetupPageCountCommand</span><span class="token punctuation">(</span>PageSize<span class="token punctuation">,</span> Parameters<span class="token punctuation">)</span><span class="token punctuation">,</span> CommandType<span class="token punctuation">.</span>Text<span class="token punctuation">,</span> Parameters<span class="token punctuation">)</span><span class="token punctuation">;</span><br /> Helper<span class="token punctuation">.</span><span class="token function">ExecuteReader</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">;</span><br /> <span class="token keyword">if</span> <span class="token punctuation">(</span>Helper<span class="token punctuation">.</span><span class="token function">Read</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">)</span><br /> <span class="token punctuation">{</span><br /> <span class="token class-name"><span class="token keyword">int</span></span> Total <span class="token operator">=</span> Helper<span class="token punctuation">.</span><span class="token function">GetParameter</span><span class="token punctuation">(</span><span class="token string">"Total"</span><span class="token punctuation">,</span> <span class="token number">0</span><span class="token punctuation">)</span><span class="token punctuation">;</span><br /> <span class="token keyword">return</span> Total <span class="token operator">%</span> PageSize <span class="token operator">==</span> <span class="token number">0</span> <span class="token punctuation">?</span> Total <span class="token operator">/</span> PageSize <span class="token punctuation">:</span> <span class="token punctuation">(</span>Total <span class="token operator">/</span> PageSize<span class="token punctuation">)</span> <span class="token operator">+</span> <span class="token number">1</span><span class="token punctuation">;</span><br /> <span class="token punctuation">}</span><br /> <span class="token keyword">return</span> <span class="token number">0</span><span class="token punctuation">;</span><br /> <span class="token punctuation">}</span><br /> <br /> <span class="token preprocessor property">#<span class="token directive keyword">endregion</span></span><br /> <br /> <span class="token preprocessor property">#<span class="token directive keyword">region</span> Paged</span><br /> <br /> <span class="token comment">/// <summary></span><br /> <span class="token comment">/// Gets a paged list of objects fitting the specified criteria</span><br /> <span class="token comment">/// </summary></span><br /> <span class="token comment">/// <param name="Columns">Columns to return</param></span><br /> <span class="token comment">/// <param name="OrderBy">Order by clause</param></span><br /> <span class="token comment">/// <param name="PageSize">Page size</param></span><br /> <span class="token comment">/// <param name="CurrentPage">The current page (starting at 0)</param></span><br /> <span class="token comment">/// <param name="Parameters">Parameters to search by</param></span><br /> <span class="token comment">/// <returns>A list of objects that fit the specified criteria</returns></span><br /> <span class="token keyword">public</span> <span class="token keyword">virtual</span> <span class="token return-type class-name">IEnumerable<span class="token punctuation"><</span>ClassType<span class="token punctuation">></span></span> <span class="token function">Paged</span><span class="token punctuation">(</span><span class="token class-name"><span class="token keyword">string</span></span> Columns <span class="token operator">=</span> <span class="token string">"\*"</span><span class="token punctuation">,</span> <span class="token class-name"><span class="token keyword">string</span></span> OrderBy <span class="token operator">=</span> <span class="token string">""</span><span class="token punctuation">,</span> <span class="token class-name"><span class="token keyword">int</span></span> PageSize <span class="token operator">=</span> <span class="token number">25</span><span class="token punctuation">,</span> <span class="token class-name"><span class="token keyword">int</span></span> CurrentPage <span class="token operator">=</span> <span class="token number">0</span><span class="token punctuation">,</span> <span class="token keyword">params</span> IParameter\<span class="token punctuation">[</span>\<span class="token punctuation">]</span> Parameters<span class="token punctuation">)</span><br /> <span class="token punctuation">{</span><br /> <span class="token function">Check</span><span class="token punctuation">(</span>Columns<span class="token punctuation">,</span> <span class="token string">"Columns"</span><span class="token punctuation">)</span><span class="token punctuation">;</span><br /> <span class="token keyword">return</span> <span class="token function">All</span><span class="token punctuation">(</span><span class="token function">SetupPagedCommand</span><span class="token punctuation">(</span>Columns<span class="token punctuation">,</span> OrderBy<span class="token punctuation">,</span> PageSize<span class="token punctuation">,</span> CurrentPage<span class="token punctuation">,</span> Parameters<span class="token punctuation">)</span><span class="token punctuation">,</span> CommandType<span class="token punctuation">.</span>Text<span class="token punctuation">,</span> Parameters<span class="token punctuation">)</span><span class="token punctuation">;</span><br /> <span class="token punctuation">}</span><br /> <br /> <span class="token preprocessor property">#<span class="token directive keyword">endregion</span></span><br /> <br /> <span class="token preprocessor property">#<span class="token directive keyword">region</span> Update</span><br /> <br /> <span class="token comment">/// <summary></span><br /> <span class="token comment">/// Updates an object in the database</span><br /> <span class="token comment">/// </summary></span><br /> <span class="token comment">/// <param name="Command">Command to use</param></span><br /> <span class="token comment">/// <param name="CommandType">Command type</param></span><br /> <span class="token comment">/// <param name="Object">Object to update</param></span><br /> <span class="token keyword">public</span> <span class="token keyword">virtual</span> <span class="token return-type class-name"><span class="token keyword">void</span></span> <span class="token function">Update</span><span class="token punctuation">(</span><span class="token class-name"><span class="token keyword">string</span></span> Command<span class="token punctuation">,</span> <span class="token class-name">CommandType</span> CommandType<span class="token punctuation">,</span> <span class="token class-name">ClassType</span> Object<span class="token punctuation">)</span><br /> <span class="token punctuation">{</span><br /> <span class="token function">Check</span><span class="token punctuation">(</span>Helper<span class="token punctuation">,</span> <span class="token string">"Helper"</span><span class="token punctuation">)</span><span class="token punctuation">;</span><br /> <span class="token function">Check</span><span class="token punctuation">(</span>Mappings<span class="token punctuation">,</span> <span class="token string">"Mappings"</span><span class="token punctuation">)</span><span class="token punctuation">;</span><br /> <span class="token function">Check</span><span class="token punctuation">(</span>Command<span class="token punctuation">,</span> <span class="token string">"Command"</span><span class="token punctuation">)</span><span class="token punctuation">;</span><br /> <span class="token function">SetupCommand</span><span class="token punctuation">(</span>Command<span class="token punctuation">,</span> CommandType<span class="token punctuation">,</span> <span class="token keyword">null</span><span class="token punctuation">)</span><span class="token punctuation">;</span><br /> Mappings<span class="token punctuation">.</span><span class="token function">Copy</span><span class="token punctuation">(</span>Object<span class="token punctuation">,</span> Helper<span class="token punctuation">)</span><span class="token punctuation">;</span><br /> Helper<span class="token punctuation">.</span><span class="token function">ExecuteNonQuery</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">;</span><br /> <span class="token punctuation">}</span><br /> <br /> <span class="token comment">/// <summary></span><br /> <span class="token comment">/// Updates an object in the database</span><br /> <span class="token comment">/// </summary></span><br /> <span class="token comment">/// <param name="Object">Object to update</param></span><br /> <span class="token keyword">public</span> <span class="token keyword">virtual</span> <span class="token return-type class-name"><span class="token keyword">void</span></span> <span class="token function">Update</span><span class="token punctuation">(</span><span class="token class-name">ClassType</span> Object<span class="token punctuation">)</span><br /> <span class="token punctuation">{</span><br /> <span class="token function">Update</span><span class="token punctuation">(</span><span class="token function">SetupUpdateCommand</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">,</span> CommandType<span class="token punctuation">.</span>Text<span class="token punctuation">,</span> Object<span class="token punctuation">)</span><span class="token punctuation">;</span><br /> <span class="token punctuation">}</span><br /> <br /> <span class="token preprocessor property">#<span class="token directive keyword">endregion</span></span><br /> <br /> <span class="token preprocessor property">#<span class="token directive keyword">endregion</span></span><br /> <br /> <span class="token preprocessor property">#<span class="token directive keyword">region</span> Protected Functions</span><br /> <br /> <span class="token preprocessor property">#<span class="token directive keyword">region</span> Check</span><br /> <br /> <span class="token comment">/// <summary></span><br /> <span class="token comment">/// Checks if an object is null, throwing an exception if it is</span><br /> <span class="token comment">/// </summary></span><br /> <span class="token comment">/// <param name="Object">Object to check</param></span><br /> <span class="token comment">/// <param name="Name">Parameter name</param></span><br /> <span class="token keyword">protected</span> <span class="token keyword">virtual</span> <span class="token return-type class-name"><span class="token keyword">void</span></span> <span class="token function">Check</span><span class="token punctuation">(</span><span class="token class-name"><span class="token keyword">object</span></span> Object<span class="token punctuation">,</span> <span class="token class-name"><span class="token keyword">string</span></span> Name<span class="token punctuation">)</span><br /> <span class="token punctuation">{</span><br /> <span class="token keyword">if</span> <span class="token punctuation">(</span>Object <span class="token operator">==</span> <span class="token keyword">null</span><span class="token punctuation">)</span><br /> <span class="token keyword">throw</span> <span class="token keyword">new</span> <span class="token constructor-invocation class-name">ArgumentNullException</span><span class="token punctuation">(</span>Name<span class="token punctuation">)</span><span class="token punctuation">;</span><br /> <span class="token punctuation">}</span><br /> <br /> <span class="token comment">/// <summary></span><br /> <span class="token comment">/// Checks if a string is null/empty, throwing an exception if it is</span><br /> <span class="token comment">/// </summary></span><br /> <span class="token comment">/// <param name="String">String to check</param></span><br /> <span class="token comment">/// <param name="Name">Parameter name</param></span><br /> <span class="token keyword">protected</span> <span class="token keyword">virtual</span> <span class="token return-type class-name"><span class="token keyword">void</span></span> <span class="token function">Check</span><span class="token punctuation">(</span><span class="token class-name"><span class="token keyword">string</span></span> String<span class="token punctuation">,</span> <span class="token class-name"><span class="token keyword">string</span></span> Name<span class="token punctuation">)</span><br /> <span class="token punctuation">{</span><br /> <span class="token keyword">if</span> <span class="token punctuation">(</span><span class="token keyword">string</span><span class="token punctuation">.</span><span class="token function">IsNullOrEmpty</span><span class="token punctuation">(</span>String<span class="token punctuation">)</span><span class="token punctuation">)</span><br /> <span class="token keyword">throw</span> <span class="token keyword">new</span> <span class="token constructor-invocation class-name">ArgumentNullException</span><span class="token punctuation">(</span>Name<span class="token punctuation">)</span><span class="token punctuation">;</span><br /> <span class="token punctuation">}</span><br /> <br /> <span class="token preprocessor property">#<span class="token directive keyword">endregion</span></span><br /> <br /> <span class="token preprocessor property">#<span class="token directive keyword">region</span> SetupCommand</span><br /> <br /> <span class="token comment">/// <summary></span><br /> <span class="token comment">/// Sets up a command</span><br /> <span class="token comment">/// </summary></span><br /> <span class="token comment">/// <param name="Command">Command to add to the SQL Helper</param></span><br /> <span class="token comment">/// <param name="CommandType">Command type</param></span><br /> <span class="token comment">/// <param name="Parameters">Parameter list</param></span><br /> <span class="token keyword">protected</span> <span class="token keyword">virtual</span> <span class="token return-type class-name"><span class="token keyword">void</span></span> <span class="token function">SetupCommand</span><span class="token punctuation">(</span><span class="token class-name"><span class="token keyword">string</span></span> Command<span class="token punctuation">,</span> <span class="token class-name">CommandType</span> CommandType<span class="token punctuation">,</span> IParameter\<span class="token punctuation">[</span>\<span class="token punctuation">]</span> Parameters<span class="token punctuation">)</span><br /> <span class="token punctuation">{</span><br /> <span class="token function">Check</span><span class="token punctuation">(</span>Helper<span class="token punctuation">,</span> <span class="token string">"Helper"</span><span class="token punctuation">)</span><span class="token punctuation">;</span><br /> <span class="token function">Check</span><span class="token punctuation">(</span>Command<span class="token punctuation">,</span> <span class="token string">"Command"</span><span class="token punctuation">)</span><span class="token punctuation">;</span><br /> Helper<span class="token punctuation">.</span>Command <span class="token operator">=</span> Command<span class="token punctuation">;</span><br /> Helper<span class="token punctuation">.</span>CommandType <span class="token operator">=</span> CommandType<span class="token punctuation">;</span><br /> <span class="token keyword">if</span> <span class="token punctuation">(</span>Parameters <span class="token operator">!=</span> <span class="token keyword">null</span><span class="token punctuation">)</span><br /> <span class="token punctuation">{</span><br /> <span class="token keyword">foreach</span> <span class="token punctuation">(</span><span class="token class-name">IParameter</span> Parameter <span class="token keyword">in</span> Parameters<span class="token punctuation">)</span><br /> <span class="token punctuation">{</span><br /> Parameter<span class="token punctuation">.</span><span class="token function">AddParameter</span><span class="token punctuation">(</span>Helper<span class="token punctuation">)</span><span class="token punctuation">;</span><br /> <span class="token punctuation">}</span><br /> <span class="token punctuation">}</span><br /> <span class="token punctuation">}</span><br /> <br /> <span class="token preprocessor property">#<span class="token directive keyword">endregion</span></span><br /> <br /> <span class="token preprocessor property">#<span class="token directive keyword">region</span> SetupDeleteCommand</span><br /> <br /> <span class="token comment">/// <summary></span><br /> <span class="token comment">/// Sets up the delete command</span><br /> <span class="token comment">/// </summary></span><br /> <span class="token comment">/// <returns>The command string</returns></span><br /> <span class="token keyword">protected</span> <span class="token keyword">virtual</span> <span class="token return-type class-name"><span class="token keyword">string</span></span> <span class="token function">SetupDeleteCommand</span><span class="token punctuation">(</span><span class="token punctuation">)</span><br /> <span class="token punctuation">{</span><br /> <span class="token keyword">return</span> <span class="token keyword">string</span><span class="token punctuation">.</span><span class="token function">Format</span><span class="token punctuation">(</span><span class="token string">"DELETE FROM {0} WHERE {1}"</span><span class="token punctuation">,</span> TableName<span class="token punctuation">,</span> PrimaryKey <span class="token operator">+</span> <span class="token string">"="</span> <span class="token operator">+</span> ParameterStarter <span class="token operator">+</span> PrimaryKey<span class="token punctuation">)</span><span class="token punctuation">;</span><br /> <span class="token punctuation">}</span><br /> <br /> <span class="token preprocessor property">#<span class="token directive keyword">endregion</span></span><br /> <br /> <span class="token preprocessor property">#<span class="token directive keyword">region</span> SetupInsertCommand</span><br /> <br /> <span class="token comment">/// <summary></span><br /> <span class="token comment">/// Sets up the insert command</span><br /> <span class="token comment">/// </summary></span><br /> <span class="token comment">/// <returns>The command string</returns></span><br /> <span class="token keyword">protected</span> <span class="token keyword">virtual</span> <span class="token return-type class-name"><span class="token keyword">string</span></span> <span class="token function">SetupInsertCommand</span><span class="token punctuation">(</span><span class="token punctuation">)</span><br /> <span class="token punctuation">{</span><br /> <span class="token class-name"><span class="token keyword">string</span></span> ParameterList <span class="token operator">=</span> <span class="token string">""</span><span class="token punctuation">;</span><br /> <span class="token class-name"><span class="token keyword">string</span></span> ValueList <span class="token operator">=</span> <span class="token string">""</span><span class="token punctuation">;</span><br /> <span class="token class-name"><span class="token keyword">string</span></span> Splitter <span class="token operator">=</span> <span class="token string">""</span><span class="token punctuation">;</span><br /> <span class="token keyword">foreach</span> <span class="token punctuation">(</span><span class="token class-name"><span class="token keyword">string</span></span> Name <span class="token keyword">in</span> ParameterNames<span class="token punctuation">)</span><br /> <span class="token punctuation">{</span><br /> <span class="token keyword">if</span> <span class="token punctuation">(</span><span class="token operator">!</span>AutoIncrement <span class="token operator">||</span> Name <span class="token operator">!=</span> PrimaryKey<span class="token punctuation">)</span><br /> <span class="token punctuation">{</span><br /> ParameterList <span class="token operator">+=</span> Splitter <span class="token operator">+</span> Name<span class="token punctuation">;</span><br /> ValueList <span class="token operator">+=</span> Splitter <span class="token operator">+</span> ParameterStarter <span class="token operator">+</span> Name<span class="token punctuation">;</span><br /> Splitter <span class="token operator">=</span> <span class="token string">","</span><span class="token punctuation">;</span><br /> <span class="token punctuation">}</span><br /> <span class="token punctuation">}</span><br /> <span class="token keyword">return</span> <span class="token keyword">string</span><span class="token punctuation">.</span><span class="token function">Format</span><span class="token punctuation">(</span><span class="token string">"INSERT INTO {0}({1}) VALUES({2}) SELECT scope\_identity() as \[ID\]"</span><span class="token punctuation">,</span> TableName<span class="token punctuation">,</span> ParameterList<span class="token punctuation">,</span> ValueList<span class="token punctuation">)</span><span class="token punctuation">;</span><br /> <span class="token punctuation">}</span><br /> <br /> <span class="token preprocessor property">#<span class="token directive keyword">endregion</span></span><br /> <br /> <span class="token preprocessor property">#<span class="token directive keyword">region</span> SetupPageCountCommand</span><br /> <br /> <span class="token comment">/// <summary></span><br /> <span class="token comment">/// Sets up the page count command</span><br /> <span class="token comment">/// </summary></span><br /> <span class="token comment">/// <param name="PageSize">Page size</param></span><br /> <span class="token comment">/// <param name="Parameters">Parameter list</param></span><br /> <span class="token comment">/// <returns>The string command</returns></span><br /> <span class="token keyword">protected</span> <span class="token keyword">virtual</span> <span class="token return-type class-name"><span class="token keyword">string</span></span> <span class="token function">SetupPageCountCommand</span><span class="token punctuation">(</span><span class="token class-name"><span class="token keyword">int</span></span> PageSize<span class="token punctuation">,</span> IParameter\<span class="token punctuation">[</span>\<span class="token punctuation">]</span> Parameters<span class="token punctuation">)</span><br /> <span class="token punctuation">{</span><br /> <span class="token class-name"><span class="token keyword">string</span></span> WhereCommand <span class="token operator">=</span> <span class="token string">""</span><span class="token punctuation">;</span><br /> <span class="token keyword">if</span> <span class="token punctuation">(</span>Parameters <span class="token operator">!=</span> <span class="token keyword">null</span> <span class="token operator">&&</span> Parameters<span class="token punctuation">.</span>Length <span class="token operator">></span> <span class="token number">0</span><span class="token punctuation">)</span><br /> <span class="token punctuation">{</span><br /> WhereCommand <span class="token operator">+=</span> <span class="token string">" WHERE "</span><span class="token punctuation">;</span><br /> <span class="token class-name"><span class="token keyword">string</span></span> Splitter <span class="token operator">=</span> <span class="token string">""</span><span class="token punctuation">;</span><br /> <span class="token keyword">foreach</span> <span class="token punctuation">(</span><span class="token class-name">IParameter</span> Parameter <span class="token keyword">in</span> Parameters<span class="token punctuation">)</span><br /> <span class="token punctuation">{</span><br /> WhereCommand <span class="token operator">+=</span> Splitter <span class="token operator">+</span> Parameter<span class="token punctuation">;</span><br /> Splitter <span class="token operator">=</span> <span class="token string">" AND "</span><span class="token punctuation">;</span><br /> <span class="token punctuation">}</span><br /> <span class="token punctuation">}</span><br /> <span class="token keyword">return</span> <span class="token keyword">string</span><span class="token punctuation">.</span><span class="token function">Format</span><span class="token punctuation">(</span><span class="token string">"SELECT COUNT({0}) as Total FROM {1} {2}"</span><span class="token punctuation">,</span> PrimaryKey<span class="token punctuation">,</span> TableName<span class="token punctuation">,</span> WhereCommand<span class="token punctuation">)</span><span class="token punctuation">;</span><br /> <span class="token punctuation">}</span><br /> <br /> <span class="token preprocessor property">#<span class="token directive keyword">endregion</span></span><br /> <br /> <span class="token preprocessor property">#<span class="token directive keyword">region</span> SetupPagedCommand</span><br /> <br /> <span class="token comment">/// <summary></span><br /> <span class="token comment">/// Sets up the paged select command</span><br /> <span class="token comment">/// </summary></span><br /> <span class="token comment">/// <param name="Columns">Columns to return</param></span><br /> <span class="token comment">/// <param name="OrderBy">Order by clause</param></span><br /> <span class="token comment">/// <param name="PageSize">Page size</param></span><br /> <span class="token comment">/// <param name="CurrentPage">Current page</param></span><br /> <span class="token comment">/// <param name="Parameters">Parameter list</param></span><br /> <span class="token comment">/// <returns>The command string</returns></span><br /> <span class="token keyword">protected</span> <span class="token keyword">virtual</span> <span class="token return-type class-name"><span class="token keyword">string</span></span> <span class="token function">SetupPagedCommand</span><span class="token punctuation">(</span><span class="token class-name"><span class="token keyword">string</span></span> Columns<span class="token punctuation">,</span> <span class="token class-name"><span class="token keyword">string</span></span> OrderBy<span class="token punctuation">,</span> <span class="token class-name"><span class="token keyword">int</span></span> PageSize<span class="token punctuation">,</span> <span class="token class-name"><span class="token keyword">int</span></span> CurrentPage<span class="token punctuation">,</span> IParameter\<span class="token punctuation">[</span>\<span class="token punctuation">]</span> Parameters<span class="token punctuation">)</span><br /> <span class="token punctuation">{</span><br /> <span class="token keyword">if</span> <span class="token punctuation">(</span><span class="token keyword">string</span><span class="token punctuation">.</span><span class="token function">IsNullOrEmpty</span><span class="token punctuation">(</span>OrderBy<span class="token punctuation">)</span><span class="token punctuation">)</span><br /> OrderBy <span class="token operator">=</span> PrimaryKey<span class="token punctuation">;</span><br /> <br /> <span class="token class-name"><span class="token keyword">string</span></span> WhereCommand <span class="token operator">=</span> <span class="token string">""</span><span class="token punctuation">;</span><br /> <span class="token keyword">if</span> <span class="token punctuation">(</span>Parameters <span class="token operator">!=</span> <span class="token keyword">null</span> <span class="token operator">&&</span> Parameters<span class="token punctuation">.</span>Length <span class="token operator">></span> <span class="token number">0</span><span class="token punctuation">)</span><br /> <span class="token punctuation">{</span><br /> WhereCommand <span class="token operator">+=</span> <span class="token string">" WHERE "</span><span class="token punctuation">;</span><br /> <span class="token class-name"><span class="token keyword">string</span></span> Splitter <span class="token operator">=</span> <span class="token string">""</span><span class="token punctuation">;</span><br /> <span class="token keyword">foreach</span> <span class="token punctuation">(</span><span class="token class-name">IParameter</span> Parameter <span class="token keyword">in</span> Parameters<span class="token punctuation">)</span><br /> <span class="token punctuation">{</span><br /> WhereCommand <span class="token operator">+=</span> Splitter <span class="token operator">+</span> Parameter<span class="token punctuation">;</span><br /> Splitter <span class="token operator">=</span> <span class="token string">" AND "</span><span class="token punctuation">;</span><br /> <span class="token punctuation">}</span><br /> <span class="token punctuation">}</span><br /> <span class="token class-name"><span class="token keyword">string</span></span> Command <span class="token operator">=</span> <span class="token keyword">string</span><span class="token punctuation">.</span><span class="token function">Format</span><span class="token punctuation">(</span><span class="token string">"SELECT {0} FROM (SELECT ROW\_NUMBER() OVER (ORDER BY {1}) AS Row, {0} FROM {2} {3}) AS Paged "</span><span class="token punctuation">,</span> Columns<span class="token punctuation">,</span> OrderBy<span class="token punctuation">,</span> TableName<span class="token punctuation">,</span> WhereCommand<span class="token punctuation">)</span><span class="token punctuation">;</span><br /> <span class="token class-name"><span class="token keyword">int</span></span> PageStart <span class="token operator">=</span> CurrentPage \<span class="token operator">*</span> PageSize<span class="token punctuation">;</span><br /> Command <span class="token operator">+=</span> <span class="token keyword">string</span><span class="token punctuation">.</span><span class="token function">Format</span><span class="token punctuation">(</span><span class="token string">" WHERE Row>{0} AND Row<={1}"</span><span class="token punctuation">,</span> PageStart<span class="token punctuation">,</span> PageStart <span class="token operator">+</span> PageSize<span class="token punctuation">)</span><span class="token punctuation">;</span><br /> <span class="token keyword">return</span> Command<span class="token punctuation">;</span><br /> <span class="token punctuation">}</span><br /> <br /> <span class="token preprocessor property">#<span class="token directive keyword">endregion</span></span><br /> <br /> <span class="token preprocessor property">#<span class="token directive keyword">region</span> SetupSelectCommand</span><br /> <br /> <span class="token comment">/// <summary></span><br /> <span class="token comment">/// Sets up the select command</span><br /> <span class="token comment">/// </summary></span><br /> <span class="token comment">/// <param name="Columns">Columns to return</param></span><br /> <span class="token comment">/// <param name="Limit">limit on the number of items to return</param></span><br /> <span class="token comment">/// <param name="OrderBy">Order by clause</param></span><br /> <span class="token comment">/// <param name="Parameters">Parameter list</param></span><br /> <span class="token comment">/// <returns>The string command</returns></span><br /> <span class="token keyword">protected</span> <span class="token keyword">virtual</span> <span class="token return-type class-name"><span class="token keyword">string</span></span> <span class="token function">SetupSelectCommand</span><span class="token punctuation">(</span><span class="token class-name"><span class="token keyword">string</span></span> Columns<span class="token punctuation">,</span> <span class="token class-name"><span class="token keyword">int</span></span> Limit<span class="token punctuation">,</span> <span class="token class-name"><span class="token keyword">string</span></span> OrderBy<span class="token punctuation">,</span> IParameter\<span class="token punctuation">[</span>\<span class="token punctuation">]</span> Parameters<span class="token punctuation">)</span><br /> <span class="token punctuation">{</span><br /> <span class="token class-name"><span class="token keyword">string</span></span> Command <span class="token operator">=</span> <span class="token punctuation">(</span>Limit <span class="token operator">></span> <span class="token number">0</span> <span class="token punctuation">?</span> <span class="token string">"SELECT TOP "</span> <span class="token operator">+</span> Limit <span class="token punctuation">:</span> <span class="token string">"SELECT"</span><span class="token punctuation">)</span> <span class="token operator">+</span> <span class="token string">" {0} FROM {1}"</span><span class="token punctuation">;</span><br /> <span class="token keyword">if</span> <span class="token punctuation">(</span>Parameters <span class="token operator">!=</span> <span class="token keyword">null</span> <span class="token operator">&&</span> Parameters<span class="token punctuation">.</span>Length <span class="token operator">></span> <span class="token number">0</span><span class="token punctuation">)</span><br /> <span class="token punctuation">{</span><br /> Command <span class="token operator">+=</span> <span class="token string">" WHERE "</span><span class="token punctuation">;</span><br /> <span class="token class-name"><span class="token keyword">string</span></span> Splitter <span class="token operator">=</span> <span class="token string">""</span><span class="token punctuation">;</span><br /> <span class="token keyword">foreach</span> <span class="token punctuation">(</span><span class="token class-name">IParameter</span> Parameter <span class="token keyword">in</span> Parameters<span class="token punctuation">)</span><br /> <span class="token punctuation">{</span><br /> Command <span class="token operator">+=</span> Splitter <span class="token operator">+</span> Parameter<span class="token punctuation">;</span><br /> Splitter <span class="token operator">=</span> <span class="token string">" AND "</span><span class="token punctuation">;</span><br /> <span class="token punctuation">}</span><br /> <span class="token punctuation">}</span><br /> <span class="token keyword">if</span> <span class="token punctuation">(</span><span class="token operator">!</span><span class="token keyword">string</span><span class="token punctuation">.</span><span class="token function">IsNullOrEmpty</span><span class="token punctuation">(</span>OrderBy<span class="token punctuation">)</span><span class="token punctuation">)</span><br /> Command <span class="token operator">+=</span> OrderBy<span class="token punctuation">.</span><span class="token function">Trim</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">.</span><span class="token function">ToLower</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">.</span><span class="token function">StartsWith</span><span class="token punctuation">(</span><span class="token string">"order by"</span><span class="token punctuation">,</span> StringComparison<span class="token punctuation">.</span>CurrentCultureIgnoreCase<span class="token punctuation">)</span> <span class="token punctuation">?</span> <span class="token string">" "</span> <span class="token operator">+</span> OrderBy <span class="token punctuation">:</span> <span class="token string">" ORDER BY "</span> <span class="token operator">+</span> OrderBy<span class="token punctuation">;</span><br /> <span class="token keyword">return</span> <span class="token keyword">string</span><span class="token punctuation">.</span><span class="token function">Format</span><span class="token punctuation">(</span>Command<span class="token punctuation">,</span> Columns<span class="token punctuation">,</span> TableName<span class="token punctuation">)</span><span class="token punctuation">;</span><br /> <span class="token punctuation">}</span><br /> <br /> <span class="token preprocessor property">#<span class="token directive keyword">endregion</span></span><br /> <br /> <span class="token preprocessor property">#<span class="token directive keyword">region</span> SetupUpdateCommand</span><br /> <br /> <span class="token comment">/// <summary></span><br /> <span class="token comment">/// Sets up the update command</span><br /> <span class="token comment">/// </summary></span><br /> <span class="token comment">/// <returns>The command string</returns></span><br /> <span class="token keyword">protected</span> <span class="token keyword">virtual</span> <span class="token return-type class-name"><span class="token keyword">string</span></span> <span class="token function">SetupUpdateCommand</span><span class="token punctuation">(</span><span class="token punctuation">)</span><br /> <span class="token punctuation">{</span><br /> <span class="token class-name"><span class="token keyword">string</span></span> ParameterList <span class="token operator">=</span> <span class="token string">""</span><span class="token punctuation">;</span><br /> <span class="token class-name"><span class="token keyword">string</span></span> WhereCommand <span class="token operator">=</span> <span class="token string">""</span><span class="token punctuation">;</span><br /> <span class="token class-name"><span class="token keyword">string</span></span> Splitter <span class="token operator">=</span> <span class="token string">""</span><span class="token punctuation">;</span><br /> <span class="token keyword">foreach</span> <span class="token punctuation">(</span><span class="token class-name"><span class="token keyword">string</span></span> Name <span class="token keyword">in</span> ParameterNames<span class="token punctuation">)</span><br /> <span class="token punctuation">{</span><br /> <span class="token keyword">if</span> <span class="token punctuation">(</span>Name <span class="token operator">!=</span> PrimaryKey<span class="token punctuation">)</span><br /> <span class="token punctuation">{</span><br /> ParameterList <span class="token operator">+=</span> Splitter <span class="token operator">+</span> Name <span class="token operator">+</span> <span class="token string">"="</span> <span class="token operator">+</span> ParameterStarter <span class="token operator">+</span> Name<span class="token punctuation">;</span><br /> Splitter <span class="token operator">=</span> <span class="token string">","</span><span class="token punctuation">;</span><br /> <span class="token punctuation">}</span><br /> <span class="token keyword">else</span><br /> WhereCommand <span class="token operator">=</span> Name <span class="token operator">+</span> <span class="token string">"="</span> <span class="token operator">+</span> ParameterStarter <span class="token operator">+</span> Name<span class="token punctuation">;</span><br /> <span class="token punctuation">}</span><br /> <span class="token keyword">return</span> <span class="token keyword">string</span><span class="token punctuation">.</span><span class="token function">Format</span><span class="token punctuation">(</span><span class="token string">"UPDATE {0} SET {1} WHERE {2}"</span><span class="token punctuation">,</span> TableName<span class="token punctuation">,</span> ParameterList<span class="token punctuation">,</span> WhereCommand<span class="token punctuation">)</span><span class="token punctuation">;</span><br /> <span class="token punctuation">}</span><br /> <br /> <span class="token preprocessor property">#<span class="token directive keyword">endregion</span></span><br /> <br /> <span class="token preprocessor property">#<span class="token directive keyword">endregion</span></span><br /> <br /> <span class="token preprocessor property">#<span class="token directive keyword">region</span> IDisposable</span><br /> <br /> <span class="token comment">/// <summary></span><br /> <span class="token comment">/// Dispose</span><br /> <span class="token comment">/// </summary></span><br /> <span class="token keyword">public</span> <span class="token return-type class-name"><span class="token keyword">void</span></span> <span class="token function">Dispose</span><span class="token punctuation">(</span><span class="token punctuation">)</span><br /> <span class="token punctuation">{</span><br /> <span class="token keyword">if</span> <span class="token punctuation">(</span>Helper <span class="token operator">!=</span> <span class="token keyword">null</span><span class="token punctuation">)</span><br /> <span class="token punctuation">{</span><br /> Helper <span class="token operator">=</span> <span class="token keyword">null</span><span class="token punctuation">;</span><br /> <span class="token punctuation">}</span><br /> <span class="token punctuation">}</span><br /> <br /> <span class="token preprocessor property">#<span class="token directive keyword">endregion</span></span><br /> <span class="token punctuation">}</span><br /> <span class="token punctuation">}</span></code></pre>
<p>Lets start with the top, the constructors take in (at minimum) the table name and primary key for the class. Doing this makes things a lot simpler later on (specifically inserts, updates, etc.). But basically we're doing basic data setup. The next bit is the properties that are needed, we'll skip that... The next, actually interesting bit of code is All. The All function makes a query against the database and gives us all entries that it finds. For the most part it's pretty straightforward, it takes in the Command (could be sql text or a stored procedure), the command type, and allows you to add a number of parameters if they are needed. The parameter class looks like the following:</p>
<pre class="language-csharp"><code class="language-csharp"> <span class="token operator">/</span>\<span class="token operator">*</span><br /> Copyright <span class="token punctuation">(</span>c<span class="token punctuation">)</span> <span class="token number">2011</span> <span class="token operator"><</span><span class="token class-name">a</span> href<span class="token operator">=</span><span class="token string">"http://www.gutgames.com"</span><span class="token operator">></span>James Craig<span class="token operator"><</span><span class="token operator">/</span>a<span class="token operator">></span><br /> <br /> Permission <span class="token keyword">is</span> <span class="token class-name">hereby</span> granted<span class="token punctuation">,</span> free <span class="token class-name">of</span> charge<span class="token punctuation">,</span> to any person obtaining a copy<br /> of <span class="token keyword">this</span> software <span class="token keyword">and</span> associated <span class="token return-type class-name">documentation</span> files <span class="token punctuation">(</span>the <span class="token string">"Software"</span><span class="token punctuation">)</span><span class="token punctuation">,</span> <span class="token class-name">to</span> deal<br /> <span class="token keyword">in</span> the Software <span class="token class-name">without</span> restriction<span class="token punctuation">,</span> including without limitation the rights<br /> <span class="token class-name">to</span> use<span class="token punctuation">,</span> copy<span class="token punctuation">,</span> modify<span class="token punctuation">,</span> merge<span class="token punctuation">,</span> publish<span class="token punctuation">,</span> distribute<span class="token punctuation">,</span> sublicense<span class="token punctuation">,</span> <span class="token keyword">and</span><span class="token operator">/</span><span class="token keyword">or</span> sell<br /> copies of <span class="token class-name">the</span> Software<span class="token punctuation">,</span> <span class="token keyword">and</span> to permit persons to whom the Software <span class="token keyword">is</span><br /> <span class="token class-name">furnished</span> to <span class="token keyword">do</span> so<span class="token punctuation">,</span> subject to the <span class="token class-name">following</span> conditions<span class="token punctuation">:</span><br /> <br /> The above copyright notice <span class="token keyword">and</span> <span class="token keyword">this</span> permission notice shall <span class="token class-name">be</span> included <span class="token keyword">in</span><br /> all copies <span class="token keyword">or</span> substantial portions of the Software<span class="token punctuation">.</span><br /> <br /> THE SOFTWARE IS PROVIDED <span class="token string">"AS IS"</span><span class="token punctuation">,</span> WITHOUT WARRANTY OF <span class="token class-name">ANY</span> KIND<span class="token punctuation">,</span> EXPRESS <span class="token class-name">OR</span><br /> IMPLIED<span class="token punctuation">,</span> INCLUDING BUT NOT LIMITED TO THE WARRANTIES <span class="token class-name">OF</span> MERCHANTABILITY<span class="token punctuation">,</span><br /> FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT<span class="token punctuation">.</span> IN NO EVENT SHALL THE<br /> AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR <span class="token class-name">ANY</span> CLAIM<span class="token punctuation">,</span> DAMAGES OR <span class="token class-name">OTHER</span><br /> LIABILITY<span class="token punctuation">,</span> WHETHER IN AN ACTION <span class="token class-name">OF</span> CONTRACT<span class="token punctuation">,</span> TORT <span class="token class-name">OR</span> OTHERWISE<span class="token punctuation">,</span> <span class="token class-name">ARISING</span> FROM<span class="token punctuation">,</span><br /> OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN<br /> THE SOFTWARE<span class="token punctuation">.</span>\<span class="token operator">*</span><span class="token operator">/</span><br /> <br /> <span class="token preprocessor property">#<span class="token directive keyword">region</span> Usings</span><br /> <span class="token keyword">using</span> <span class="token namespace">System</span><span class="token punctuation">;</span><br /> <span class="token keyword">using</span> <span class="token namespace">System<span class="token punctuation">.</span>Collections<span class="token punctuation">.</span>Generic</span><span class="token punctuation">;</span><br /> <span class="token keyword">using</span> <span class="token namespace">System<span class="token punctuation">.</span>Linq</span><span class="token punctuation">;</span><br /> <span class="token keyword">using</span> <span class="token namespace">System<span class="token punctuation">.</span>Text</span><span class="token punctuation">;</span><br /> <span class="token keyword">using</span> <span class="token namespace">Utilities<span class="token punctuation">.</span>SQL<span class="token punctuation">.</span>MicroORM<span class="token punctuation">.</span>Interfaces</span><span class="token punctuation">;</span><br /> <span class="token preprocessor property">#<span class="token directive keyword">endregion</span></span><br /> <br /> <span class="token keyword">namespace</span> <span class="token namespace">Utilities<span class="token punctuation">.</span>SQL<span class="token punctuation">.</span>MicroORM</span><br /> <span class="token punctuation">{</span><br /> <span class="token comment">/// <summary></span><br /> <span class="token comment">/// Parameter class</span><br /> <span class="token comment">/// </summary></span><br /> <span class="token comment">/// <typeparam name="DataType">Type of the parameter</typeparam></span><br /> <span class="token keyword">public</span> <span class="token keyword">class</span> <span class="token class-name">Parameter<span class="token punctuation"><</span>DataType<span class="token punctuation">></span></span><span class="token punctuation">:</span><span class="token type-list"><span class="token class-name">IParameter</span></span><br /> <span class="token punctuation">{</span><br /> <span class="token preprocessor property">#<span class="token directive keyword">region</span> Constructor</span><br /> <br /> <span class="token comment">/// <summary></span><br /> <span class="token comment">/// Constructor</span><br /> <span class="token comment">/// </summary></span><br /> <span class="token comment">/// <param name="Value">Value of the parameter</param></span><br /> <span class="token comment">/// <param name="ID">Name of the parameter</param></span><br /> <span class="token comment">/// <param name="ParameterStarter">What the database expects as the</span><br /> <span class="token comment">/// parameter starting string ("@" for SQL Server, ":" for Oracle, etc.)</param></span><br /> <span class="token keyword">public</span> <span class="token function">Parameter</span><span class="token punctuation">(</span><span class="token class-name">DataType</span> Value<span class="token punctuation">,</span> <span class="token class-name"><span class="token keyword">string</span></span> ID<span class="token punctuation">,</span> <span class="token class-name"><span class="token keyword">string</span></span> ParameterStarter <span class="token operator">=</span> <span class="token string">"@"</span><span class="token punctuation">)</span><br /> <span class="token punctuation">{</span><br /> <span class="token keyword">this</span><span class="token punctuation">.</span>Value <span class="token operator">=</span> Value<span class="token punctuation">;</span><br /> <span class="token keyword">this</span><span class="token punctuation">.</span>ID <span class="token operator">=</span> ID<span class="token punctuation">;</span><br /> <span class="token keyword">this</span><span class="token punctuation">.</span>ParameterStarter <span class="token operator">=</span> ParameterStarter<span class="token punctuation">;</span><br /> <span class="token punctuation">}</span><br /> <br /> <span class="token preprocessor property">#<span class="token directive keyword">endregion</span></span><br /> <br /> <span class="token preprocessor property">#<span class="token directive keyword">region</span> Properties</span><br /> <br /> <span class="token comment">/// <summary></span><br /> <span class="token comment">/// Value of the parameter</span><br /> <span class="token comment">/// </summary></span><br /> <span class="token keyword">public</span> <span class="token return-type class-name">DataType</span> Value <span class="token punctuation">{</span> <span class="token keyword">get</span><span class="token punctuation">;</span> <span class="token keyword">set</span><span class="token punctuation">;</span> <span class="token punctuation">}</span><br /> <br /> <span class="token comment">/// <summary></span><br /> <span class="token comment">/// Name of the parameter</span><br /> <span class="token comment">/// </summary></span><br /> <span class="token keyword">public</span> <span class="token return-type class-name"><span class="token keyword">string</span></span> ID <span class="token punctuation">{</span> <span class="token keyword">get</span><span class="token punctuation">;</span> <span class="token keyword">set</span><span class="token punctuation">;</span> <span class="token punctuation">}</span><br /> <br /> <span class="token comment">/// <summary></span><br /> <span class="token comment">/// Starting string of the parameter</span><br /> <span class="token comment">/// </summary></span><br /> <span class="token keyword">public</span> <span class="token return-type class-name"><span class="token keyword">string</span></span> ParameterStarter <span class="token punctuation">{</span> <span class="token keyword">get</span><span class="token punctuation">;</span> <span class="token keyword">set</span><span class="token punctuation">;</span> <span class="token punctuation">}</span><br /> <br /> <span class="token preprocessor property">#<span class="token directive keyword">endregion</span></span><br /> <br /> <span class="token preprocessor property">#<span class="token directive keyword">region</span> Functions</span><br /> <br /> <span class="token keyword">public</span> <span class="token return-type class-name"><span class="token keyword">void</span></span> <span class="token function">AddParameter</span><span class="token punctuation">(</span><span class="token class-name">SQLHelper</span> Helper<span class="token punctuation">)</span> <span class="token punctuation">{</span> Helper<span class="token punctuation">.</span><span class="token function">AddParameter</span><span class="token punctuation">(</span>ID<span class="token punctuation">,</span> Value<span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token punctuation">}</span><br /> <br /> <span class="token keyword">public</span> <span class="token keyword">override</span> <span class="token return-type class-name"><span class="token keyword">string</span></span> <span class="token function">ToString</span><span class="token punctuation">(</span><span class="token punctuation">)</span> <span class="token punctuation">{</span> <span class="token keyword">return</span> ID <span class="token operator">+</span> <span class="token string">"="</span> <span class="token operator">+</span> ParameterStarter <span class="token operator">+</span> ID<span class="token punctuation">;</span> <span class="token punctuation">}</span><br /> <br /> <span class="token preprocessor property">#<span class="token directive keyword">endregion</span></span><br /> <span class="token punctuation">}</span><br /> <span class="token punctuation">}</span></code></pre>
<p>The parameter class is really just a glorified key/value pair. Anyway, the All function just creates a list, calls our command, and lets the object to object mapper fill our object for us. We have another option (the function that asks for Columns, etc.), that will allow us to simply call All() if we only want to worry about such things like an order by clause. In this call though the class is generating the select statement for us (Pretty standard: SELECT Columns FROM TableName WHERE [List of parameters are true] ORDER BY OrderByClause).</p>
<p>You'll find that most of the functions are similar to All. For instance, the Any function is pretty much a copy but it only returns the first item found by the query. Delete, Update, and Insert are only slightly different. Instead of copying data from the SQLHelper to the object, it simply goes the other way around. They all have the option to generate the code for you. Since we've set up our mappings beforehand, we know the names of the properties and we know the primary key from the constructor so it's not too difficult to generate the needed queries.</p>
<p>The only function that might give you pause are the Pages and PageCount functions. Paged is simply a paged query (automatically generated). It works similarly to All but takes in page size and the current page that you want (0 based as I'm not a big fan of starting at 1 for such things). The code that it generates is also rather straightforward (but probably not the best), if you've ever done a paged query before. That being said, it's currently pretty specific to SQL Server but I'll probably change that to make it a bit more open in the future. Anyway, I also have a separate query called PageCount to allow you to figure out the total number of pages based on the page size that you specify. I could have that as an out parameter of the Paged function, but I figure you might want that information separately. But that's it really. There are also Open/Close functions to actually open the connection to the database, but those are pretty simple.</p>
<p>So at this point we have our simple mapping of a single class. What we need now is a class to hold all of our mappings that we can use to make this simpler:</p>
<pre class="language-csharp"><code class="language-csharp"> <span class="token operator">/</span>\<span class="token operator">*</span><br /> Copyright <span class="token punctuation">(</span>c<span class="token punctuation">)</span> <span class="token number">2011</span> <span class="token operator"><</span><span class="token class-name">a</span> href<span class="token operator">=</span><span class="token string">"http://www.gutgames.com"</span><span class="token operator">></span>James Craig<span class="token operator"><</span><span class="token operator">/</span>a<span class="token operator">></span><br /> <br /> Permission <span class="token keyword">is</span> <span class="token class-name">hereby</span> granted<span class="token punctuation">,</span> free <span class="token class-name">of</span> charge<span class="token punctuation">,</span> to any person obtaining a copy<br /> of <span class="token keyword">this</span> software <span class="token keyword">and</span> associated <span class="token return-type class-name">documentation</span> files <span class="token punctuation">(</span>the <span class="token string">"Software"</span><span class="token punctuation">)</span><span class="token punctuation">,</span> <span class="token class-name">to</span> deal<br /> <span class="token keyword">in</span> the Software <span class="token class-name">without</span> restriction<span class="token punctuation">,</span> including without limitation the rights<br /> <span class="token class-name">to</span> use<span class="token punctuation">,</span> copy<span class="token punctuation">,</span> modify<span class="token punctuation">,</span> merge<span class="token punctuation">,</span> publish<span class="token punctuation">,</span> distribute<span class="token punctuation">,</span> sublicense<span class="token punctuation">,</span> <span class="token keyword">and</span><span class="token operator">/</span><span class="token keyword">or</span> sell<br /> copies of <span class="token class-name">the</span> Software<span class="token punctuation">,</span> <span class="token keyword">and</span> to permit persons to whom the Software <span class="token keyword">is</span><br /> <span class="token class-name">furnished</span> to <span class="token keyword">do</span> so<span class="token punctuation">,</span> subject to the <span class="token class-name">following</span> conditions<span class="token punctuation">:</span><br /> <br /> The above copyright notice <span class="token keyword">and</span> <span class="token keyword">this</span> permission notice shall <span class="token class-name">be</span> included <span class="token keyword">in</span><br /> all copies <span class="token keyword">or</span> substantial portions of the Software<span class="token punctuation">.</span><br /> <br /> THE SOFTWARE IS PROVIDED <span class="token string">"AS IS"</span><span class="token punctuation">,</span> WITHOUT WARRANTY OF <span class="token class-name">ANY</span> KIND<span class="token punctuation">,</span> EXPRESS <span class="token class-name">OR</span><br /> IMPLIED<span class="token punctuation">,</span> INCLUDING BUT NOT LIMITED TO THE WARRANTIES <span class="token class-name">OF</span> MERCHANTABILITY<span class="token punctuation">,</span><br /> FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT<span class="token punctuation">.</span> IN NO EVENT SHALL THE<br /> AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR <span class="token class-name">ANY</span> CLAIM<span class="token punctuation">,</span> DAMAGES OR <span class="token class-name">OTHER</span><br /> LIABILITY<span class="token punctuation">,</span> WHETHER IN AN ACTION <span class="token class-name">OF</span> CONTRACT<span class="token punctuation">,</span> TORT <span class="token class-name">OR</span> OTHERWISE<span class="token punctuation">,</span> <span class="token class-name">ARISING</span> FROM<span class="token punctuation">,</span><br /> OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN<br /> THE SOFTWARE<span class="token punctuation">.</span>\<span class="token operator">*</span><span class="token operator">/</span><br /> <br /> <span class="token preprocessor property">#<span class="token directive keyword">region</span> Usings</span><br /> <span class="token keyword">using</span> <span class="token namespace">System</span><span class="token punctuation">;</span><br /> <span class="token keyword">using</span> <span class="token namespace">System<span class="token punctuation">.</span>Collections<span class="token punctuation">.</span>Generic</span><span class="token punctuation">;</span><br /> <span class="token keyword">using</span> <span class="token namespace">System<span class="token punctuation">.</span>Linq</span><span class="token punctuation">;</span><br /> <span class="token keyword">using</span> <span class="token namespace">System<span class="token punctuation">.</span>Text</span><span class="token punctuation">;</span><br /> <span class="token keyword">using</span> <span class="token namespace">Utilities<span class="token punctuation">.</span>DataMapper</span><span class="token punctuation">;</span><br /> <span class="token keyword">using</span> <span class="token namespace">System<span class="token punctuation">.</span>Linq<span class="token punctuation">.</span>Expressions</span><span class="token punctuation">;</span><br /> <span class="token keyword">using</span> <span class="token namespace">Utilities<span class="token punctuation">.</span>SQL<span class="token punctuation">.</span>MicroORM<span class="token punctuation">.</span>Interfaces</span><span class="token punctuation">;</span><br /> <span class="token keyword">using</span> <span class="token namespace">System<span class="token punctuation">.</span>Data</span><span class="token punctuation">;</span><br /> <span class="token preprocessor property">#<span class="token directive keyword">endregion</span></span><br /> <br /> <span class="token keyword">namespace</span> <span class="token namespace">Utilities<span class="token punctuation">.</span>SQL<span class="token punctuation">.</span>MicroORM</span><br /> <span class="token punctuation">{</span><br /> <span class="token comment">/// <summary></span><br /> <span class="token comment">/// Manager class that can be used to manage</span><br /> <span class="token comment">/// </summary></span><br /> <span class="token keyword">public</span> <span class="token keyword">class</span> <span class="token class-name">MicroORM</span> <span class="token punctuation">:</span> <span class="token type-list"><span class="token class-name">SQLHelper</span></span><br /> <span class="token punctuation">{</span><br /> <span class="token preprocessor property">#<span class="token directive keyword">region</span> Constructor</span><br /> <br /> <span class="token comment">/// <summary></span><br /> <span class="token comment">/// Constructor</span><br /> <span class="token comment">/// </summary></span><br /> <span class="token keyword">public</span> <span class="token function">MicroORM</span><span class="token punctuation">(</span><span class="token class-name"><span class="token keyword">string</span></span> Connection<span class="token punctuation">)</span><br /> <span class="token punctuation">:</span> <span class="token keyword">base</span><span class="token punctuation">(</span><span class="token string">""</span><span class="token punctuation">,</span> Connection<span class="token punctuation">,</span> CommandType<span class="token punctuation">.</span>Text<span class="token punctuation">)</span><br /> <span class="token punctuation">{</span><br /> <span class="token punctuation">}</span><br /> <br /> <span class="token preprocessor property">#<span class="token directive keyword">endregion</span></span><br /> <br /> <span class="token preprocessor property">#<span class="token directive keyword">region</span> Properties</span><br /> <br /> <span class="token comment">/// <summary></span><br /> <span class="token comment">/// Mappings</span><br /> <span class="token comment">/// </summary></span><br /> <span class="token keyword">protected</span> <span class="token keyword">static</span> <span class="token class-name">Dictionary<span class="token punctuation"><</span>Type<span class="token punctuation">,</span> IMapping<span class="token punctuation">></span></span> Mappings <span class="token operator">=</span> <span class="token keyword">new</span> <span class="token constructor-invocation class-name">Dictionary<span class="token punctuation"><</span>Type<span class="token punctuation">,</span> IMapping<span class="token punctuation">></span></span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">;</span><br /> <br /> <span class="token preprocessor property">#<span class="token directive keyword">endregion</span></span><br /> <br /> <span class="token preprocessor property">#<span class="token directive keyword">region</span> Functions</span><br /> <br /> <span class="token comment">/// <summary></span><br /> <span class="token comment">/// Creates a mapping</span><br /> <span class="token comment">/// </summary></span><br /> <span class="token comment">/// <typeparam name="ClassType">Class type to map</typeparam></span><br /> <span class="token comment">/// <param name="TableName">Table name</param></span><br /> <span class="token comment">/// <param name="PrimaryKey">Primary key</param></span><br /> <span class="token comment">/// <param name="AutoIncrement">Auto incrementing primar key</param></span><br /> <span class="token comment">/// <param name="ParameterStarter">Parameter starter</param></span><br /> <span class="token comment">/// <returns>The created mapping (or an already created one if it exists</returns></span><br /> <span class="token keyword">public</span> <span class="token keyword">static</span> <span class="token return-type class-name">Mapping<span class="token punctuation"><</span>ClassType<span class="token punctuation">></span></span> <span class="token generic-method"><span class="token function">Map</span><span class="token generic class-name"><span class="token punctuation"><</span>ClassType<span class="token punctuation">></span></span></span><span class="token punctuation">(</span><span class="token class-name"><span class="token keyword">string</span></span> TableName<span class="token punctuation">,</span> <span class="token class-name"><span class="token keyword">string</span></span> PrimaryKey<span class="token punctuation">,</span> <span class="token class-name"><span class="token keyword">bool</span></span> AutoIncrement <span class="token operator">=</span> <span class="token boolean">true</span><span class="token punctuation">,</span> <span class="token class-name"><span class="token keyword">string</span></span> ParameterStarter <span class="token operator">=</span> <span class="token string">"@"</span><span class="token punctuation">)</span> <span class="token keyword">where</span> <span class="token class-name">ClassType</span> <span class="token punctuation">:</span> <span class="token keyword">class</span><span class="token punctuation">,</span><span class="token keyword">new</span><span class="token punctuation">(</span><span class="token punctuation">)</span><br /> <span class="token punctuation">{</span><br /> <span class="token keyword">if</span> <span class="token punctuation">(</span>Mappings<span class="token punctuation">.</span><span class="token function">ContainsKey</span><span class="token punctuation">(</span><span class="token keyword">typeof</span><span class="token punctuation">(</span><span class="token type-expression class-name">ClassType</span><span class="token punctuation">)</span><span class="token punctuation">)</span><span class="token punctuation">)</span><br /> <span class="token keyword">return</span> <span class="token punctuation">(</span>Mapping<span class="token operator"><</span>ClassType<span class="token operator">></span><span class="token punctuation">)</span>Mappings\<span class="token punctuation">[</span><span class="token keyword">typeof</span><span class="token punctuation">(</span><span class="token type-expression class-name">ClassType</span><span class="token punctuation">)</span>\<span class="token punctuation">]</span><span class="token punctuation">;</span><br /> <span class="token class-name">Mapping<span class="token punctuation"><</span>ClassType<span class="token punctuation">></span></span> Mapping <span class="token operator">=</span> <span class="token keyword">new</span> <span class="token constructor-invocation class-name">Mapping<span class="token punctuation"><</span>ClassType<span class="token punctuation">></span></span><span class="token punctuation">(</span>TableName<span class="token punctuation">,</span> PrimaryKey<span class="token punctuation">,</span> AutoIncrement<span class="token punctuation">,</span> ParameterStarter<span class="token punctuation">)</span><span class="token punctuation">;</span><br /> Mappings<span class="token punctuation">.</span><span class="token function">Add</span><span class="token punctuation">(</span><span class="token keyword">typeof</span><span class="token punctuation">(</span><span class="token type-expression class-name">ClassType</span><span class="token punctuation">)</span><span class="token punctuation">,</span> Mapping<span class="token punctuation">)</span><span class="token punctuation">;</span><br /> <span class="token keyword">return</span> Mapping<span class="token punctuation">;</span><br /> <span class="token punctuation">}</span><br /> <br /> <span class="token comment">/// <summary></span><br /> <span class="token comment">/// Returns a specific mapping</span><br /> <span class="token comment">/// </summary></span><br /> <span class="token comment">/// <typeparam name="ClassType">Class type to get</typeparam></span><br /> <span class="token comment">/// <returns>The mapping specified</returns></span><br /> <span class="token keyword">public</span> <span class="token return-type class-name">Mapping<span class="token punctuation"><</span>ClassType<span class="token punctuation">></span></span> <span class="token generic-method"><span class="token function">Map</span><span class="token generic class-name"><span class="token punctuation"><</span>ClassType<span class="token punctuation">></span></span></span><span class="token punctuation">(</span><span class="token punctuation">)</span> <span class="token keyword">where</span> <span class="token class-name">ClassType</span> <span class="token punctuation">:</span> <span class="token keyword">class</span><span class="token punctuation">,</span><span class="token keyword">new</span><span class="token punctuation">(</span><span class="token punctuation">)</span><br /> <span class="token punctuation">{</span><br /> <span class="token keyword">if</span> <span class="token punctuation">(</span><span class="token operator">!</span>Mappings<span class="token punctuation">.</span><span class="token function">ContainsKey</span><span class="token punctuation">(</span><span class="token keyword">typeof</span><span class="token punctuation">(</span><span class="token type-expression class-name">ClassType</span><span class="token punctuation">)</span><span class="token punctuation">)</span><span class="token punctuation">)</span><br /> <span class="token keyword">throw</span> <span class="token keyword">new</span> <span class="token constructor-invocation class-name">ArgumentOutOfRangeException</span><span class="token punctuation">(</span><span class="token keyword">typeof</span><span class="token punctuation">(</span><span class="token type-expression class-name">ClassType</span><span class="token punctuation">)</span><span class="token punctuation">.</span>Name <span class="token operator">+</span> <span class="token string">" not found"</span><span class="token punctuation">)</span><span class="token punctuation">;</span><br /> <span class="token class-name">Mapping<span class="token punctuation"><</span>ClassType<span class="token punctuation">></span></span> ReturnValue <span class="token operator">=</span> <span class="token punctuation">(</span>Mapping<span class="token operator"><</span>ClassType<span class="token operator">></span><span class="token punctuation">)</span>Mappings\<span class="token punctuation">[</span><span class="token keyword">typeof</span><span class="token punctuation">(</span><span class="token type-expression class-name">ClassType</span><span class="token punctuation">)</span>\<span class="token punctuation">]</span><span class="token punctuation">;</span><br /> ReturnValue<span class="token punctuation">.</span>Helper <span class="token operator">=</span> <span class="token keyword">this</span><span class="token punctuation">;</span><br /> <span class="token keyword">return</span> ReturnValue<span class="token punctuation">;</span><br /> <span class="token punctuation">}</span><br /> <br /> <span class="token preprocessor property">#<span class="token directive keyword">endregion</span></span><br /> <br /> <span class="token preprocessor property">#<span class="token directive keyword">region</span> IDisposable Members</span><br /> <br /> <span class="token keyword">public</span> <span class="token keyword">override</span> <span class="token return-type class-name"><span class="token keyword">void</span></span> <span class="token function">Dispose</span><span class="token punctuation">(</span><span class="token punctuation">)</span><br /> <span class="token punctuation">{</span><br /> <span class="token keyword">base</span><span class="token punctuation">.</span><span class="token function">Dispose</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">;</span><br /> <span class="token keyword">foreach</span> <span class="token punctuation">(</span><span class="token class-name">Type</span> Key <span class="token keyword">in</span> Mappings<span class="token punctuation">.</span>Keys<span class="token punctuation">)</span><br /> <span class="token punctuation">{</span><br /> Mappings\<span class="token punctuation">[</span>Key\<span class="token punctuation">]</span><span class="token punctuation">.</span><span class="token function">Dispose</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">;</span><br /> <span class="token punctuation">}</span><br /> Mappings<span class="token punctuation">.</span><span class="token function">Clear</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">;</span><br /> <span class="token punctuation">}</span><br /> <br /> <span class="token preprocessor property">#<span class="token directive keyword">endregion</span></span><br /> <span class="token punctuation">}</span><br /> <span class="token punctuation">}</span></code></pre>
<p>This class really only has a couple of functions, but inherits from the SQLHelper class from earlier. It basically just adds a static Map function (allowing us to store our mapping data in the MicroORM object). It also adds a nonstatic Map function on the object that we can use to actually call our mapping. For instance we can do the following:</p>
<pre class="language-csharp"><code class="language-csharp"> <span class="token keyword">class</span> <span class="token class-name">Program</span><br /> <span class="token punctuation">{</span><br /> <span class="token keyword">static</span> <span class="token return-type class-name"><span class="token keyword">void</span></span> <span class="token function">Main</span><span class="token punctuation">(</span><span class="token keyword">string</span>\<span class="token punctuation">[</span>\<span class="token punctuation">]</span> args<span class="token punctuation">)</span><br /> <span class="token punctuation">{</span><br /> MicroORM<span class="token punctuation">.</span><span class="token generic-method"><span class="token function">Map</span><span class="token generic class-name"><span class="token punctuation"><</span>User<span class="token punctuation">></span></span></span><span class="token punctuation">(</span><span class="token string">"User\_"</span><span class="token punctuation">,</span> <span class="token string">"ID\_"</span><span class="token punctuation">)</span><br /> <span class="token punctuation">.</span><span class="token function">Map</span><span class="token punctuation">(</span>x <span class="token operator">=></span> x<span class="token punctuation">.</span>ID<span class="token punctuation">,</span> <span class="token string">"ID\_"</span><span class="token punctuation">)</span><br /> <span class="token punctuation">.</span><span class="token function">Map</span><span class="token punctuation">(</span>x <span class="token operator">=></span> x<span class="token punctuation">.</span>DateCreated<span class="token punctuation">,</span> <span class="token string">"DateCreated\_"</span><span class="token punctuation">)</span><br /> <span class="token punctuation">.</span><span class="token function">Map</span><span class="token punctuation">(</span>x <span class="token operator">=></span> x<span class="token punctuation">.</span>DateModified<span class="token punctuation">,</span> <span class="token string">"DateModified\_"</span><span class="token punctuation">)</span><br /> <span class="token punctuation">.</span><span class="token function">Map</span><span class="token punctuation">(</span>x <span class="token operator">=></span> x<span class="token punctuation">.</span>Active<span class="token punctuation">,</span> <span class="token string">"Active\_"</span><span class="token punctuation">)</span><br /> <span class="token punctuation">.</span><span class="token function">Map</span><span class="token punctuation">(</span>x <span class="token operator">=></span> x<span class="token punctuation">.</span>UserName<span class="token punctuation">,</span> <span class="token string">"UserName\_"</span><span class="token punctuation">,</span> <span class="token number">128</span><span class="token punctuation">)</span><span class="token punctuation">;</span><br /> <br /> <span class="token keyword">using</span> <span class="token punctuation">(</span><span class="token class-name">MicroORM</span> ORM <span class="token operator">=</span> <span class="token keyword">new</span> <span class="token constructor-invocation class-name">MicroORM</span><span class="token punctuation">(</span><span class="token string">"Data Source=localhost;Initial Catalog=MyDatabase;Integrated Security=SSPI;"</span><span class="token punctuation">)</span><span class="token punctuation">)</span><br /> <span class="token punctuation">{</span><br /> <span class="token class-name">IEnumerable<span class="token punctuation"><</span>User<span class="token punctuation">></span></span> Users <span class="token operator">=</span> ORM<span class="token punctuation">.</span><span class="token generic-method"><span class="token function">Map</span><span class="token generic class-name"><span class="token punctuation"><</span>User<span class="token punctuation">></span></span></span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">.</span><span class="token function">All</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">;</span><br /> <span class="token keyword">foreach</span> <span class="token punctuation">(</span><span class="token class-name">User</span> User <span class="token keyword">in</span> Users<span class="token punctuation">)</span><br /> <span class="token punctuation">{</span><br /> Console<span class="token punctuation">.</span><span class="token function">WriteLine</span><span class="token punctuation">(</span>User<span class="token punctuation">.</span>UserName<span class="token punctuation">)</span><span class="token punctuation">;</span><br /> <span class="token punctuation">}</span><br /> <span class="token punctuation">}</span><br /> <br /> Console<span class="token punctuation">.</span><span class="token function">ReadKey</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">;</span><br /> <span class="token punctuation">}</span><br /> <span class="token punctuation">}</span><br /> <br /> <span class="token keyword">public</span> <span class="token keyword">class</span> <span class="token class-name">User</span><br /> <span class="token punctuation">{</span><br /> <span class="token keyword">public</span> <span class="token keyword">virtual</span> <span class="token return-type class-name"><span class="token keyword">int</span></span> ID <span class="token punctuation">{</span> <span class="token keyword">get</span><span class="token punctuation">;</span> <span class="token keyword">set</span><span class="token punctuation">;</span> <span class="token punctuation">}</span><br /> <span class="token keyword">public</span> <span class="token keyword">virtual</span> <span class="token return-type class-name">DateTime</span> DateModified <span class="token punctuation">{</span> <span class="token keyword">get</span><span class="token punctuation">;</span> <span class="token keyword">set</span><span class="token punctuation">;</span> <span class="token punctuation">}</span><br /> <span class="token keyword">public</span> <span class="token keyword">virtual</span> <span class="token return-type class-name">DateTime</span> DateCreated <span class="token punctuation">{</span> <span class="token keyword">get</span><span class="token punctuation">;</span> <span class="token keyword">set</span><span class="token punctuation">;</span> <span class="token punctuation">}</span><br /> <span class="token keyword">public</span> <span class="token keyword">virtual</span> <span class="token return-type class-name"><span class="token keyword">bool</span></span> Active <span class="token punctuation">{</span> <span class="token keyword">get</span><span class="token punctuation">;</span> <span class="token keyword">set</span><span class="token punctuation">;</span> <span class="token punctuation">}</span><br /> <span class="token keyword">public</span> <span class="token keyword">virtual</span> <span class="token return-type class-name"><span class="token keyword">string</span></span> UserName <span class="token punctuation">{</span> <span class="token keyword">get</span><span class="token punctuation">;</span> <span class="token keyword">set</span><span class="token punctuation">;</span> <span class="token punctuation">}</span><br /> <span class="token punctuation">}</span></code></pre>
<p>That code sets up the user object in a couple of lines of code, then it creates a MicroORM object an feeds it the connection string. From there it gets the User mapping and calls All (giving us all of the users). It then just spits the user names onto the screen. It's basic, simple, rather quick and all that you need for a micro ORM. In the future I will integrate this into my ORM project. Basically I'll show how to take a micro ORM and add on the features that you might want (database generation, lazy loading, etc.) while still keeping things simple.</p>
Creating an ORM in C# Revisited – Part 1
2011-05-18T00:00:00Z
http://www.gutgames.com/post/Creating-an-ORM-in-C-Revisited-Part-1/
<p>This is a bit long but I feel that a bit of backstory is warranted here. For those unaware, a while ago I <a href="http://www.gutgames.com/post/Creating-an-ORM-in-C-Part-1">wrote my own ORM</a>. It wasn't meant to really compete with the likes of <a href="http://nhforge.org/">nhibernate</a>, etc. It was simply a learning project (what goes into an ORM, etc.). A while ago I started redoing parts and pieces to get better stability and speed (fixed a number of bugs, etc.). Once it got rather stable, I started to use it in some of my projects. At first it worked well, cut down on turn around time, etc. However I kept running into issues (mainly speed related). Eventually, on some of my larger projects, I had to strip out parts and write things by hand... I tried some of the other ORMs (nhibernate, <a href="http://www.subsonicproject.com/">subsonic</a>, etc.) out there and ran into the same issues (although to a lesser extent as they were actually written by individuals that knew what they were doing). One thing was a constant though, no matter what I tried or which library I plugged in the speed issue would raise its ugly head. Eventually though, I ran into Massive.</p>
<p><a href="https://github.com/robconery/massive">Massive</a>, written by <a href="http://blog.wekeroad.com/">Rob Conery</a>, is what is called a micro ORM. It's very small (about 364 lines as of this writing) and rather fast (in my experience much faster than the other ORMs when I was testing it out). So back in February/March I start testing it out and instantly ran into a brick wall. It uses expando objects (which is a .Net 4 feature) and I'm stuck on .Net 3.5 for a number of my projects. So I start looking around for an alternative and couldn't find one. Instantly I thought, I know, I'll create my own! I have enough experience writing my first ORM, and since Massive is open source I can just look at that if I get into a corner in the design process. It will be simple! And then Zeus looked down from Olympus and said "Listen here you wanker, I'll show you what happens to people with too much hubris". By the way, I don't know why Zeus is British (maybe he's American but just likes watching a lot of BBC America, I don't know). It doesn't really matter, because the important part of the story is it was at this point that he sent down a lightening bolt and destroyed my laptop... Last laugh was on him as I needed a new one anyway so this just gave me an excuse.</p>
<p>So time passed, I got a new laptop, I loaded it up, etc. However I just, sort of, took a break from programming and just played some games on my 360 (replayed Dragon Age: Origins, played Dragon Age 2 [which was a bit of a disappointment in some ways], some expansions for Mass Effect 2 [which I actually liked more than the original], etc.). It was a rather peaceful break. Eventually though I decided to get going on this project. So I start and instantly find that someone already came out with a micro ORM that can do what I need... <a href="https://github.com/SamSaffron/dapper-dot-net">Dapper</a>. Dapper, another micro ORM, was written by <a href="http://samsaffron.com/">Sam Saffron</a> and came in at about 1038 lines of code (as of this writing). Supposedly he created it for the same reasons that I had (speed issues), although part of me thinks it was to piss me off (even though I'm certain that he has no idea who I am or about my previous plan to write my own micro ORM since I didn't tell anyone else about it). All I could think at the time was how dare Mr. Saffron write a fantastic library that you should totally try out. So I decided even with his library being out there, I was going to still create my own because 1) I didn't learn anything from my encounter with Zeus and 2) Screw you Sam, screw you.</p>
<p>Unlike my previous series, this is probably going to be shorter for a couple of reasons. But basically it comes down to the fact that there are a number of things that we no longer need with this system (caching, etc.). Instead we just need a simple mapping mechanism (database to object and vice versa) and some way to communicate with the database. That's it, just two things (however I've broken it down into a couple classes, helper functions, etc. to keep things on the smaller side and hopefully simpler to follow). In fact it's so simple that I'm adding this directly to my utility library. Anyway, today I'm just going to talk about the mapping mechanism.</p>
<p>A while back I saw a project called <a href="http://automapper.codeplex.com/">AutoMapper</a>. It seemed a bit of overkill to me at the time, but in this situation it was exactly the type of thing that I needed (basically something that would allow me to automatically copy from one location to another). However since I'm adding this directly to my utility library, I can't add AutoMapper (my number one rule with my utility library is I can't have outside dependencies other than .Net/windows libs. I'm even iffy about adding in any XNA/DirectX stuff). So I set out to recreate my own version of the code (and actually found a very easy way to do it).</p>
<p>Basically an object to object mapper is nothing more than a bunch of gets and sets saved away and then run when called. That's it. So the easiest way that I could think of to do this was to use Funcs and Actions (Func for the getting of the value, Action for the setting of the value). And since I didn't want to force the coder to supply a Func and Action for every property, I needed a way using Expression trees to create the appropriate items on the fly:</p>
<pre class="language-csharp"><code class="language-csharp"> <span class="token comment">/// <summary></span><br /> <span class="token comment">/// Gets a lambda expression that calls a specific property's getter function</span><br /> <span class="token comment">/// </summary></span><br /> <span class="token comment">/// <typeparam name="ClassType">Class type</typeparam></span><br /> <span class="token comment">/// <typeparam name="DataType">Data type expecting</typeparam></span><br /> <span class="token comment">/// <param name="PropertyName">Property name</param></span><br /> <span class="token comment">/// <returns>A lambda expression that calls a specific property's getter function</returns></span><br /> <span class="token keyword">public</span> <span class="token keyword">static</span> <span class="token return-type class-name">Expression<span class="token punctuation"><</span>Func<span class="token punctuation"><</span>ClassType<span class="token punctuation">,</span>DataType<span class="token punctuation">></span><span class="token punctuation">></span></span> <span class="token generic-method"><span class="token function">GetPropertyGetter</span><span class="token generic class-name"><span class="token punctuation"><</span>ClassType<span class="token punctuation">,</span>DataType<span class="token punctuation">></span></span></span><span class="token punctuation">(</span><span class="token class-name"><span class="token keyword">string</span></span> PropertyName<span class="token punctuation">)</span><br /> <span class="token punctuation">{</span><br /> <span class="token keyword">if</span> <span class="token punctuation">(</span><span class="token keyword">string</span><span class="token punctuation">.</span><span class="token function">IsNullOrEmpty</span><span class="token punctuation">(</span>PropertyName<span class="token punctuation">)</span><span class="token punctuation">)</span><br /> <span class="token keyword">throw</span> <span class="token keyword">new</span> <span class="token constructor-invocation class-name">ArgumentNullException</span><span class="token punctuation">(</span><span class="token string">"PropertyName"</span><span class="token punctuation">)</span><span class="token punctuation">;</span><br /> <span class="token keyword">string</span>\<span class="token punctuation">[</span>\<span class="token punctuation">]</span> SplitName <span class="token operator">=</span> PropertyName<span class="token punctuation">.</span><span class="token function">Split</span><span class="token punctuation">(</span><span class="token keyword">new</span> <span class="token keyword">string</span>\<span class="token punctuation">[</span>\<span class="token punctuation">]</span> <span class="token punctuation">{</span> <span class="token string">"."</span> <span class="token punctuation">}</span><span class="token punctuation">,</span> StringSplitOptions<span class="token punctuation">.</span>RemoveEmptyEntries<span class="token punctuation">)</span><span class="token punctuation">;</span><br /> <span class="token class-name">PropertyInfo</span> Property <span class="token operator">=</span> Utilities<span class="token punctuation">.</span>Reflection<span class="token punctuation">.</span>Reflection<span class="token punctuation">.</span><span class="token generic-method"><span class="token function">GetProperty</span><span class="token generic class-name"><span class="token punctuation"><</span>ClassType<span class="token punctuation">></span></span></span><span class="token punctuation">(</span>SplitName\<span class="token punctuation">[</span><span class="token number">0</span>\<span class="token punctuation">]</span><span class="token punctuation">)</span><span class="token punctuation">;</span><br /> <span class="token class-name">ParameterExpression</span> ObjectInstance <span class="token operator">=</span> Expression<span class="token punctuation">.</span><span class="token function">Parameter</span><span class="token punctuation">(</span>Property<span class="token punctuation">.</span>DeclaringType<span class="token punctuation">,</span> <span class="token string">"x"</span><span class="token punctuation">)</span><span class="token punctuation">;</span><br /> <span class="token class-name">MemberExpression</span> PropertyGet <span class="token operator">=</span> Expression<span class="token punctuation">.</span><span class="token function">Property</span><span class="token punctuation">(</span>ObjectInstance<span class="token punctuation">,</span> Property<span class="token punctuation">)</span><span class="token punctuation">;</span><br /> <span class="token keyword">for</span> <span class="token punctuation">(</span><span class="token class-name"><span class="token keyword">int</span></span> x <span class="token operator">=</span> <span class="token number">1</span><span class="token punctuation">;</span> x <span class="token operator"><</span> SplitName<span class="token punctuation">.</span>Length<span class="token punctuation">;</span> <span class="token operator">++</span>x<span class="token punctuation">)</span><br /> <span class="token punctuation">{</span><br /> Property <span class="token operator">=</span> Utilities<span class="token punctuation">.</span>Reflection<span class="token punctuation">.</span>Reflection<span class="token punctuation">.</span><span class="token function">GetProperty</span><span class="token punctuation">(</span>Property<span class="token punctuation">.</span>PropertyType<span class="token punctuation">,</span> SplitName\<span class="token punctuation">[</span>x\<span class="token punctuation">]</span><span class="token punctuation">)</span><span class="token punctuation">;</span><br /> PropertyGet <span class="token operator">=</span> Expression<span class="token punctuation">.</span><span class="token function">Property</span><span class="token punctuation">(</span>PropertyGet<span class="token punctuation">,</span> Property<span class="token punctuation">)</span><span class="token punctuation">;</span><br /> <span class="token punctuation">}</span><br /> <span class="token keyword">if</span> <span class="token punctuation">(</span>Property<span class="token punctuation">.</span>PropertyType <span class="token operator">!=</span> <span class="token keyword">typeof</span><span class="token punctuation">(</span><span class="token type-expression class-name">DataType</span><span class="token punctuation">)</span><span class="token punctuation">)</span><br /> <span class="token punctuation">{</span><br /> <span class="token class-name">UnaryExpression</span> Convert <span class="token operator">=</span> Expression<span class="token punctuation">.</span><span class="token function">Convert</span><span class="token punctuation">(</span>PropertyGet<span class="token punctuation">,</span> <span class="token keyword">typeof</span><span class="token punctuation">(</span><span class="token type-expression class-name">DataType</span><span class="token punctuation">)</span><span class="token punctuation">)</span><span class="token punctuation">;</span><br /> <span class="token keyword">return</span> Expression<span class="token punctuation">.</span><span class="token generic-method"><span class="token function">Lambda</span><span class="token generic class-name"><span class="token punctuation"><</span>Func<span class="token punctuation"><</span>ClassType<span class="token punctuation">,</span> DataType<span class="token punctuation">></span><span class="token punctuation">></span></span></span><span class="token punctuation">(</span>Convert<span class="token punctuation">,</span> ObjectInstance<span class="token punctuation">)</span><span class="token punctuation">;</span><br /> <span class="token punctuation">}</span><br /> <span class="token keyword">return</span> Expression<span class="token punctuation">.</span><span class="token generic-method"><span class="token function">Lambda</span><span class="token generic class-name"><span class="token punctuation"><</span>Func<span class="token punctuation"><</span>ClassType<span class="token punctuation">,</span> DataType<span class="token punctuation">></span><span class="token punctuation">></span></span></span><span class="token punctuation">(</span>PropertyGet<span class="token punctuation">,</span> ObjectInstance<span class="token punctuation">)</span><span class="token punctuation">;</span><br /> <span class="token punctuation">}</span><br /> <br /> <span class="token comment">/// <summary></span><br /> <span class="token comment">/// Gets a lambda expression that calls a specific property's getter function</span><br /> <span class="token comment">/// </summary></span><br /> <span class="token comment">/// <typeparam name="ClassType">Class type</typeparam></span><br /> <span class="token comment">/// <typeparam name="DataType">Data type expecting</typeparam></span><br /> <span class="token comment">/// <param name="Property">Property</param></span><br /> <span class="token comment">/// <returns>A lambda expression that calls a specific property's getter function</returns></span><br /> <span class="token keyword">public</span> <span class="token keyword">static</span> <span class="token return-type class-name">Expression<span class="token punctuation"><</span>Func<span class="token punctuation"><</span>ClassType<span class="token punctuation">,</span> DataType<span class="token punctuation">></span><span class="token punctuation">></span></span> <span class="token generic-method"><span class="token function">GetPropertyGetter</span><span class="token generic class-name"><span class="token punctuation"><</span>ClassType<span class="token punctuation">,</span> DataType<span class="token punctuation">></span></span></span><span class="token punctuation">(</span><span class="token class-name">PropertyInfo</span> Property<span class="token punctuation">)</span><br /> <span class="token punctuation">{</span><br /> <span class="token keyword">if</span> <span class="token punctuation">(</span><span class="token operator">!</span><span class="token function">IsOfType</span><span class="token punctuation">(</span>Property<span class="token punctuation">.</span>PropertyType<span class="token punctuation">,</span> <span class="token keyword">typeof</span><span class="token punctuation">(</span><span class="token type-expression class-name">DataType</span><span class="token punctuation">)</span><span class="token punctuation">)</span><span class="token punctuation">)</span><br /> <span class="token keyword">throw</span> <span class="token keyword">new</span> <span class="token constructor-invocation class-name">ArgumentException</span><span class="token punctuation">(</span><span class="token string">"Property is not of the type specified"</span><span class="token punctuation">)</span><span class="token punctuation">;</span><br /> <span class="token keyword">if</span> <span class="token punctuation">(</span><span class="token operator">!</span><span class="token function">IsOfType</span><span class="token punctuation">(</span>Property<span class="token punctuation">.</span>DeclaringType<span class="token punctuation">,</span> <span class="token keyword">typeof</span><span class="token punctuation">(</span><span class="token type-expression class-name">ClassType</span><span class="token punctuation">)</span><span class="token punctuation">)</span><span class="token punctuation">)</span><br /> <span class="token keyword">throw</span> <span class="token keyword">new</span> <span class="token constructor-invocation class-name">ArgumentException</span><span class="token punctuation">(</span><span class="token string">"Property is not from the declaring class type specified"</span><span class="token punctuation">)</span><span class="token punctuation">;</span><br /> <span class="token class-name">ParameterExpression</span> ObjectInstance <span class="token operator">=</span> Expression<span class="token punctuation">.</span><span class="token function">Parameter</span><span class="token punctuation">(</span>Property<span class="token punctuation">.</span>DeclaringType<span class="token punctuation">,</span> <span class="token string">"x"</span><span class="token punctuation">)</span><span class="token punctuation">;</span><br /> <span class="token class-name">MemberExpression</span> PropertyGet <span class="token operator">=</span> Expression<span class="token punctuation">.</span><span class="token function">Property</span><span class="token punctuation">(</span>ObjectInstance<span class="token punctuation">,</span> Property<span class="token punctuation">)</span><span class="token punctuation">;</span><br /> <span class="token keyword">if</span><span class="token punctuation">(</span>Property<span class="token punctuation">.</span>PropertyType<span class="token operator">!=</span><span class="token keyword">typeof</span><span class="token punctuation">(</span><span class="token type-expression class-name">DataType</span><span class="token punctuation">)</span><span class="token punctuation">)</span><br /> <span class="token punctuation">{</span><br /> <span class="token class-name">UnaryExpression</span> Convert<span class="token operator">=</span>Expression<span class="token punctuation">.</span><span class="token function">Convert</span><span class="token punctuation">(</span>PropertyGet<span class="token punctuation">,</span><span class="token keyword">typeof</span><span class="token punctuation">(</span><span class="token type-expression class-name">DataType</span><span class="token punctuation">)</span><span class="token punctuation">)</span><span class="token punctuation">;</span><br /> <span class="token keyword">return</span> Expression<span class="token punctuation">.</span><span class="token generic-method"><span class="token function">Lambda</span><span class="token generic class-name"><span class="token punctuation"><</span>Func<span class="token punctuation"><</span>ClassType<span class="token punctuation">,</span> DataType<span class="token punctuation">></span><span class="token punctuation">></span></span></span><span class="token punctuation">(</span>Convert<span class="token punctuation">,</span> ObjectInstance<span class="token punctuation">)</span><span class="token punctuation">;</span><br /> <span class="token punctuation">}</span><br /> <span class="token keyword">return</span> Expression<span class="token punctuation">.</span><span class="token generic-method"><span class="token function">Lambda</span><span class="token generic class-name"><span class="token punctuation"><</span>Func<span class="token punctuation"><</span>ClassType<span class="token punctuation">,</span> DataType<span class="token punctuation">></span><span class="token punctuation">></span></span></span><span class="token punctuation">(</span>PropertyGet<span class="token punctuation">,</span> ObjectInstance<span class="token punctuation">)</span><span class="token punctuation">;</span><br /> <span class="token punctuation">}</span><br /> <br /> <span class="token comment">/// <summary></span><br /> <span class="token comment">/// Gets a lambda expression that calls a specific property's getter function</span><br /> <span class="token comment">/// </summary></span><br /> <span class="token comment">/// <typeparam name="ClassType">Class type</typeparam></span><br /> <span class="token comment">/// <param name="PropertyName">Property name</param></span><br /> <span class="token comment">/// <returns>A lambda expression that calls a specific property's getter function</returns></span><br /> <span class="token keyword">public</span> <span class="token keyword">static</span> <span class="token return-type class-name">Expression<span class="token punctuation"><</span>Func<span class="token punctuation"><</span>ClassType<span class="token punctuation">,</span> <span class="token keyword">object</span>\<span class="token punctuation">></span><span class="token punctuation">></span></span> <span class="token generic-method"><span class="token function">GetPropertyGetter</span><span class="token generic class-name"><span class="token punctuation"><</span>ClassType<span class="token punctuation">></span></span></span><span class="token punctuation">(</span><span class="token class-name"><span class="token keyword">string</span></span> PropertyName<span class="token punctuation">)</span><br /> <span class="token punctuation">{</span><br /> <span class="token keyword">return</span> <span class="token generic-method"><span class="token function">GetPropertyGetter</span><span class="token generic class-name"><span class="token punctuation"><</span>ClassType<span class="token punctuation">,</span> <span class="token keyword">object</span>\<span class="token punctuation">></span></span></span><span class="token punctuation">(</span>PropertyName<span class="token punctuation">)</span><span class="token punctuation">;</span><br /> <span class="token punctuation">}</span><br /> <br /> <span class="token comment">/// <summary></span><br /> <span class="token comment">/// Gets a lambda expression that calls a specific property's getter function</span><br /> <span class="token comment">/// </summary></span><br /> <span class="token comment">/// <typeparam name="ClassType">Class type</typeparam></span><br /> <span class="token comment">/// <param name="Property">Property</param></span><br /> <span class="token comment">/// <returns>A lambda expression that calls a specific property's getter function</returns></span><br /> <span class="token keyword">public</span> <span class="token keyword">static</span> <span class="token return-type class-name">Expression<span class="token punctuation"><</span>Func<span class="token punctuation"><</span>ClassType<span class="token punctuation">,</span> <span class="token keyword">object</span>\<span class="token punctuation">></span><span class="token punctuation">></span></span> <span class="token generic-method"><span class="token function">GetPropertyGetter</span><span class="token generic class-name"><span class="token punctuation"><</span>ClassType<span class="token punctuation">></span></span></span><span class="token punctuation">(</span><span class="token class-name">PropertyInfo</span> Property<span class="token punctuation">)</span><br /> <span class="token punctuation">{</span><br /> <span class="token keyword">return</span> <span class="token generic-method"><span class="token function">GetPropertyGetter</span><span class="token generic class-name"><span class="token punctuation"><</span>ClassType<span class="token punctuation">,</span> <span class="token keyword">object</span>\<span class="token punctuation">></span></span></span><span class="token punctuation">(</span>Property<span class="token punctuation">)</span><span class="token punctuation">;</span><br /> <span class="token punctuation">}</span><br /> <br /> <span class="token comment">/// <summary></span><br /> <span class="token comment">/// Gets a lambda expression that calls a specific property's setter function</span><br /> <span class="token comment">/// </summary></span><br /> <span class="token comment">/// <typeparam name="ClassType">Class type</typeparam></span><br /> <span class="token comment">/// <typeparam name="DataType">Data type expecting</typeparam></span><br /> <span class="token comment">/// <param name="PropertyName">Property name</param></span><br /> <span class="token comment">/// <returns>A lambda expression that calls a specific property's setter function</returns></span><br /> <span class="token keyword">public</span> <span class="token keyword">static</span> <span class="token return-type class-name">Expression<span class="token punctuation"><</span>Action<span class="token punctuation"><</span>ClassType<span class="token punctuation">,</span> DataType<span class="token punctuation">></span><span class="token punctuation">></span></span> <span class="token generic-method"><span class="token function">GetPropertySetter</span><span class="token generic class-name"><span class="token punctuation"><</span>ClassType<span class="token punctuation">,</span>DataType<span class="token punctuation">></span></span></span><span class="token punctuation">(</span><span class="token class-name"><span class="token keyword">string</span></span> PropertyName<span class="token punctuation">)</span><br /> <span class="token punctuation">{</span><br /> <span class="token keyword">if</span> <span class="token punctuation">(</span><span class="token keyword">string</span><span class="token punctuation">.</span><span class="token function">IsNullOrEmpty</span><span class="token punctuation">(</span>PropertyName<span class="token punctuation">)</span><span class="token punctuation">)</span><br /> <span class="token keyword">throw</span> <span class="token keyword">new</span> <span class="token constructor-invocation class-name">ArgumentNullException</span><span class="token punctuation">(</span><span class="token string">"PropertyName"</span><span class="token punctuation">)</span><span class="token punctuation">;</span><br /> <span class="token keyword">string</span>\<span class="token punctuation">[</span>\<span class="token punctuation">]</span> SplitName <span class="token operator">=</span> PropertyName<span class="token punctuation">.</span><span class="token function">Split</span><span class="token punctuation">(</span><span class="token keyword">new</span> <span class="token keyword">string</span>\<span class="token punctuation">[</span>\<span class="token punctuation">]</span> <span class="token punctuation">{</span> <span class="token string">"."</span> <span class="token punctuation">}</span><span class="token punctuation">,</span> StringSplitOptions<span class="token punctuation">.</span>RemoveEmptyEntries<span class="token punctuation">)</span><span class="token punctuation">;</span><br /> <span class="token class-name">PropertyInfo</span> Property <span class="token operator">=</span> Utilities<span class="token punctuation">.</span>Reflection<span class="token punctuation">.</span>Reflection<span class="token punctuation">.</span><span class="token generic-method"><span class="token function">GetProperty</span><span class="token generic class-name"><span class="token punctuation"><</span>ClassType<span class="token punctuation">></span></span></span><span class="token punctuation">(</span>SplitName\<span class="token punctuation">[</span><span class="token number">0</span>\<span class="token punctuation">]</span><span class="token punctuation">)</span><span class="token punctuation">;</span><br /> <span class="token class-name">ParameterExpression</span> ObjectInstance <span class="token operator">=</span> Expression<span class="token punctuation">.</span><span class="token function">Parameter</span><span class="token punctuation">(</span>Property<span class="token punctuation">.</span>DeclaringType<span class="token punctuation">,</span> <span class="token string">"x"</span><span class="token punctuation">)</span><span class="token punctuation">;</span><br /> <span class="token class-name">ParameterExpression</span> PropertySet <span class="token operator">=</span> Expression<span class="token punctuation">.</span><span class="token function">Parameter</span><span class="token punctuation">(</span><span class="token keyword">typeof</span><span class="token punctuation">(</span><span class="token type-expression class-name">DataType</span><span class="token punctuation">)</span><span class="token punctuation">,</span> <span class="token string">"y"</span><span class="token punctuation">)</span><span class="token punctuation">;</span><br /> <span class="token class-name">MethodCallExpression</span> SetterCall <span class="token operator">=</span> <span class="token keyword">null</span><span class="token punctuation">;</span><br /> <span class="token class-name">MemberExpression</span> PropertyGet <span class="token operator">=</span> <span class="token keyword">null</span><span class="token punctuation">;</span><br /> <span class="token keyword">if</span> <span class="token punctuation">(</span>SplitName<span class="token punctuation">.</span>Length <span class="token operator">></span> <span class="token number">1</span><span class="token punctuation">)</span><br /> <span class="token punctuation">{</span><br /> PropertyGet <span class="token operator">=</span> Expression<span class="token punctuation">.</span><span class="token function">Property</span><span class="token punctuation">(</span>ObjectInstance<span class="token punctuation">,</span> Property<span class="token punctuation">)</span><span class="token punctuation">;</span><br /> <span class="token keyword">for</span> <span class="token punctuation">(</span><span class="token class-name"><span class="token keyword">int</span></span> x <span class="token operator">=</span> <span class="token number">1</span><span class="token punctuation">;</span> x <span class="token operator"><</span> SplitName<span class="token punctuation">.</span>Length <span class="token operator">-</span> <span class="token number">1</span><span class="token punctuation">;</span> <span class="token operator">++</span>x<span class="token punctuation">)</span><br /> <span class="token punctuation">{</span><br /> Property <span class="token operator">=</span> Utilities<span class="token punctuation">.</span>Reflection<span class="token punctuation">.</span>Reflection<span class="token punctuation">.</span><span class="token function">GetProperty</span><span class="token punctuation">(</span>Property<span class="token punctuation">.</span>PropertyType<span class="token punctuation">,</span> SplitName\<span class="token punctuation">[</span>x\<span class="token punctuation">]</span><span class="token punctuation">)</span><span class="token punctuation">;</span><br /> PropertyGet <span class="token operator">=</span> Expression<span class="token punctuation">.</span><span class="token function">Property</span><span class="token punctuation">(</span>PropertyGet<span class="token punctuation">,</span> Property<span class="token punctuation">)</span><span class="token punctuation">;</span><br /> <span class="token punctuation">}</span><br /> Property <span class="token operator">=</span> Utilities<span class="token punctuation">.</span>Reflection<span class="token punctuation">.</span>Reflection<span class="token punctuation">.</span><span class="token function">GetProperty</span><span class="token punctuation">(</span>Property<span class="token punctuation">.</span>PropertyType<span class="token punctuation">,</span> SplitName\<span class="token punctuation">[</span>SplitName<span class="token punctuation">.</span>Length <span class="token operator">-</span> <span class="token number">1</span>\<span class="token punctuation">]</span><span class="token punctuation">)</span><span class="token punctuation">;</span><br /> <span class="token punctuation">}</span><br /> <span class="token keyword">if</span> <span class="token punctuation">(</span>Property<span class="token punctuation">.</span>PropertyType <span class="token operator">!=</span> <span class="token keyword">typeof</span><span class="token punctuation">(</span><span class="token type-expression class-name">DataType</span><span class="token punctuation">)</span><span class="token punctuation">)</span><br /> <span class="token punctuation">{</span><br /> <span class="token class-name">UnaryExpression</span> Convert <span class="token operator">=</span> Expression<span class="token punctuation">.</span><span class="token function">Convert</span><span class="token punctuation">(</span>PropertySet<span class="token punctuation">,</span> Property<span class="token punctuation">.</span>PropertyType<span class="token punctuation">)</span><span class="token punctuation">;</span><br /> <span class="token keyword">if</span> <span class="token punctuation">(</span>PropertyGet <span class="token operator">==</span> <span class="token keyword">null</span><span class="token punctuation">)</span><br /> SetterCall <span class="token operator">=</span> Expression<span class="token punctuation">.</span><span class="token function">Call</span><span class="token punctuation">(</span>ObjectInstance<span class="token punctuation">,</span> Property<span class="token punctuation">.</span><span class="token function">GetSetMethod</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">,</span> Convert<span class="token punctuation">)</span><span class="token punctuation">;</span><br /> <span class="token keyword">else</span><br /> SetterCall <span class="token operator">=</span> Expression<span class="token punctuation">.</span><span class="token function">Call</span><span class="token punctuation">(</span>PropertyGet<span class="token punctuation">,</span> Property<span class="token punctuation">.</span><span class="token function">GetSetMethod</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">,</span> Convert<span class="token punctuation">)</span><span class="token punctuation">;</span><br /> <span class="token keyword">return</span> Expression<span class="token punctuation">.</span><span class="token generic-method"><span class="token function">Lambda</span><span class="token generic class-name"><span class="token punctuation"><</span>Action<span class="token punctuation"><</span>ClassType<span class="token punctuation">,</span> DataType<span class="token punctuation">></span><span class="token punctuation">></span></span></span><span class="token punctuation">(</span>SetterCall<span class="token punctuation">,</span> ObjectInstance<span class="token punctuation">,</span> PropertySet<span class="token punctuation">)</span><span class="token punctuation">;</span><br /> <span class="token punctuation">}</span><br /> <span class="token keyword">if</span> <span class="token punctuation">(</span>PropertyGet <span class="token operator">==</span> <span class="token keyword">null</span><span class="token punctuation">)</span><br /> SetterCall <span class="token operator">=</span> Expression<span class="token punctuation">.</span><span class="token function">Call</span><span class="token punctuation">(</span>ObjectInstance<span class="token punctuation">,</span> Property<span class="token punctuation">.</span><span class="token function">GetSetMethod</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">,</span> PropertySet<span class="token punctuation">)</span><span class="token punctuation">;</span><br /> <span class="token keyword">else</span><br /> SetterCall <span class="token operator">=</span> Expression<span class="token punctuation">.</span><span class="token function">Call</span><span class="token punctuation">(</span>PropertyGet<span class="token punctuation">,</span> Property<span class="token punctuation">.</span><span class="token function">GetSetMethod</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">,</span> PropertySet<span class="token punctuation">)</span><span class="token punctuation">;</span><br /> <span class="token keyword">return</span> Expression<span class="token punctuation">.</span><span class="token generic-method"><span class="token function">Lambda</span><span class="token generic class-name"><span class="token punctuation"><</span>Action<span class="token punctuation"><</span>ClassType<span class="token punctuation">,</span> DataType<span class="token punctuation">></span><span class="token punctuation">></span></span></span><span class="token punctuation">(</span>SetterCall<span class="token punctuation">,</span> ObjectInstance<span class="token punctuation">,</span> PropertySet<span class="token punctuation">)</span><span class="token punctuation">;</span><br /> <span class="token punctuation">}</span><br /> <br /> <span class="token comment">/// <summary></span><br /> <span class="token comment">/// Gets a lambda expression that calls a specific property's setter function</span><br /> <span class="token comment">/// </summary></span><br /> <span class="token comment">/// <typeparam name="ClassType">Class type</typeparam></span><br /> <span class="token comment">/// <typeparam name="DataType">Data type expecting</typeparam></span><br /> <span class="token comment">/// <param name="PropertyName">Property name</param></span><br /> <span class="token comment">/// <returns>A lambda expression that calls a specific property's setter function</returns></span><br /> <span class="token keyword">public</span> <span class="token keyword">static</span> <span class="token return-type class-name">Expression<span class="token punctuation"><</span>Action<span class="token punctuation"><</span>ClassType<span class="token punctuation">,</span> DataType<span class="token punctuation">></span><span class="token punctuation">></span></span> <span class="token generic-method"><span class="token function">GetPropertySetter</span><span class="token generic class-name"><span class="token punctuation"><</span>ClassType<span class="token punctuation">,</span> DataType<span class="token punctuation">></span></span></span><span class="token punctuation">(</span><span class="token class-name">PropertyInfo</span> Property<span class="token punctuation">)</span><br /> <span class="token punctuation">{</span><br /> <span class="token keyword">if</span> <span class="token punctuation">(</span><span class="token operator">!</span><span class="token function">IsOfType</span><span class="token punctuation">(</span>Property<span class="token punctuation">.</span>PropertyType<span class="token punctuation">,</span> <span class="token keyword">typeof</span><span class="token punctuation">(</span><span class="token type-expression class-name">DataType</span><span class="token punctuation">)</span><span class="token punctuation">)</span><span class="token punctuation">)</span><br /> <span class="token keyword">throw</span> <span class="token keyword">new</span> <span class="token constructor-invocation class-name">ArgumentException</span><span class="token punctuation">(</span><span class="token string">"Property is not of the type specified"</span><span class="token punctuation">)</span><span class="token punctuation">;</span><br /> <span class="token keyword">if</span> <span class="token punctuation">(</span><span class="token operator">!</span><span class="token function">IsOfType</span><span class="token punctuation">(</span>Property<span class="token punctuation">.</span>DeclaringType<span class="token punctuation">,</span> <span class="token keyword">typeof</span><span class="token punctuation">(</span><span class="token type-expression class-name">ClassType</span><span class="token punctuation">)</span><span class="token punctuation">)</span><span class="token punctuation">)</span><br /> <span class="token keyword">throw</span> <span class="token keyword">new</span> <span class="token constructor-invocation class-name">ArgumentException</span><span class="token punctuation">(</span><span class="token string">"Property is not from the declaring class type specified"</span><span class="token punctuation">)</span><span class="token punctuation">;</span><br /> <br /> <span class="token class-name">ParameterExpression</span> ObjectInstance <span class="token operator">=</span> Expression<span class="token punctuation">.</span><span class="token function">Parameter</span><span class="token punctuation">(</span>Property<span class="token punctuation">.</span>DeclaringType<span class="token punctuation">,</span> <span class="token string">"x"</span><span class="token punctuation">)</span><span class="token punctuation">;</span><br /> <span class="token class-name">ParameterExpression</span> PropertySet <span class="token operator">=</span> Expression<span class="token punctuation">.</span><span class="token function">Parameter</span><span class="token punctuation">(</span><span class="token keyword">typeof</span><span class="token punctuation">(</span><span class="token type-expression class-name">DataType</span><span class="token punctuation">)</span><span class="token punctuation">,</span> <span class="token string">"y"</span><span class="token punctuation">)</span><span class="token punctuation">;</span><br /> <span class="token class-name">MethodCallExpression</span> SetterCall <span class="token operator">=</span> <span class="token keyword">null</span><span class="token punctuation">;</span><br /> <span class="token keyword">if</span><span class="token punctuation">(</span>Property<span class="token punctuation">.</span>PropertyType<span class="token operator">!=</span><span class="token keyword">typeof</span><span class="token punctuation">(</span><span class="token type-expression class-name">DataType</span><span class="token punctuation">)</span><span class="token punctuation">)</span><br /> <span class="token punctuation">{</span><br /> <br /> <span class="token class-name">UnaryExpression</span> Convert<span class="token operator">=</span>Expression<span class="token punctuation">.</span><span class="token function">Convert</span><span class="token punctuation">(</span>PropertySet<span class="token punctuation">,</span>Property<span class="token punctuation">.</span>PropertyType<span class="token punctuation">)</span><span class="token punctuation">;</span><br /> SetterCall <span class="token operator">=</span> Expression<span class="token punctuation">.</span><span class="token function">Call</span><span class="token punctuation">(</span>ObjectInstance<span class="token punctuation">,</span> Property<span class="token punctuation">.</span><span class="token function">GetSetMethod</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">,</span> Convert<span class="token punctuation">)</span><span class="token punctuation">;</span><br /> <span class="token keyword">return</span> Expression<span class="token punctuation">.</span><span class="token generic-method"><span class="token function">Lambda</span><span class="token generic class-name"><span class="token punctuation"><</span>Action<span class="token punctuation"><</span>ClassType<span class="token punctuation">,</span> DataType<span class="token punctuation">></span><span class="token punctuation">></span></span></span><span class="token punctuation">(</span>SetterCall<span class="token punctuation">,</span> ObjectInstance<span class="token punctuation">,</span> PropertySet<span class="token punctuation">)</span><span class="token punctuation">;</span><br /> <span class="token punctuation">}</span><br /> SetterCall <span class="token operator">=</span> Expression<span class="token punctuation">.</span><span class="token function">Call</span><span class="token punctuation">(</span>ObjectInstance<span class="token punctuation">,</span> Property<span class="token punctuation">.</span><span class="token function">GetSetMethod</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">,</span> PropertySet<span class="token punctuation">)</span><span class="token punctuation">;</span><br /> <span class="token keyword">return</span> Expression<span class="token punctuation">.</span><span class="token generic-method"><span class="token function">Lambda</span><span class="token generic class-name"><span class="token punctuation"><</span>Action<span class="token punctuation"><</span>ClassType<span class="token punctuation">,</span> DataType<span class="token punctuation">></span><span class="token punctuation">></span></span></span><span class="token punctuation">(</span>SetterCall<span class="token punctuation">,</span> ObjectInstance<span class="token punctuation">,</span> PropertySet<span class="token punctuation">)</span><span class="token punctuation">;</span><br /> <span class="token punctuation">}</span><br /> <br /> <span class="token comment">/// <summary></span><br /> <span class="token comment">/// Gets a lambda expression that calls a specific property's setter function</span><br /> <span class="token comment">/// </summary></span><br /> <span class="token comment">/// <typeparam name="ClassType">Class type</typeparam></span><br /> <span class="token comment">/// <param name="PropertyName">Property name</param></span><br /> <span class="token comment">/// <returns>A lambda expression that calls a specific property's setter function</returns></span><br /> <span class="token keyword">public</span> <span class="token keyword">static</span> <span class="token return-type class-name">Expression<span class="token punctuation"><</span>Action<span class="token punctuation"><</span>ClassType<span class="token punctuation">,</span><span class="token keyword">object</span>\<span class="token punctuation">></span><span class="token punctuation">></span></span> <span class="token generic-method"><span class="token function">GetPropertySetter</span><span class="token generic class-name"><span class="token punctuation"><</span>ClassType<span class="token punctuation">></span></span></span><span class="token punctuation">(</span><span class="token class-name"><span class="token keyword">string</span></span> PropertyName<span class="token punctuation">)</span><br /> <span class="token punctuation">{</span><br /> <span class="token keyword">return</span> <span class="token generic-method"><span class="token function">GetPropertySetter</span><span class="token generic class-name"><span class="token punctuation"><</span>ClassType<span class="token punctuation">,</span> <span class="token keyword">object</span>\<span class="token punctuation">></span></span></span><span class="token punctuation">(</span>PropertyName<span class="token punctuation">)</span><span class="token punctuation">;</span><br /> <span class="token punctuation">}</span><br /> <br /> <span class="token comment">/// <summary></span><br /> <span class="token comment">/// Gets a lambda expression that calls a specific property's setter function</span><br /> <span class="token comment">/// </summary></span><br /> <span class="token comment">/// <typeparam name="ClassType">Class type</typeparam></span><br /> <span class="token comment">/// <param name="PropertyName">Property name</param></span><br /> <span class="token comment">/// <returns>A lambda expression that calls a specific property's setter function</returns></span><br /> <span class="token keyword">public</span> <span class="token keyword">static</span> <span class="token return-type class-name">Expression<span class="token punctuation"><</span>Action<span class="token punctuation"><</span>ClassType<span class="token punctuation">,</span> <span class="token keyword">object</span>\<span class="token punctuation">></span><span class="token punctuation">></span></span> <span class="token generic-method"><span class="token function">GetPropertySetter</span><span class="token generic class-name"><span class="token punctuation"><</span>ClassType<span class="token punctuation">></span></span></span><span class="token punctuation">(</span><span class="token class-name">PropertyInfo</span> Property<span class="token punctuation">)</span><br /> <span class="token punctuation">{</span><br /> <span class="token keyword">return</span> <span class="token generic-method"><span class="token function">GetPropertySetter</span><span class="token generic class-name"><span class="token punctuation"><</span>ClassType<span class="token punctuation">,</span> <span class="token keyword">object</span>\<span class="token punctuation">></span></span></span><span class="token punctuation">(</span>Property<span class="token punctuation">)</span><span class="token punctuation">;</span><br /> <span class="token punctuation">}</span></code></pre>
<p>I don't have object creation or null checking in there, but it does do type conversion, etc. So not perfect, but it will do for our purposes. But basically I can use one of my other functions in my utility library:</p>
<pre class="language-csharp"><code class="language-csharp"> <span class="token comment">/// <summary></span><br /> <span class="token comment">/// Gets the name of the property held within the expression</span><br /> <span class="token comment">/// </summary></span><br /> <span class="token comment">/// <typeparam name="T">The type of object used in the expression</typeparam></span><br /> <span class="token comment">/// <param name="Expression">The expression</param></span><br /> <span class="token comment">/// <returns>A string containing the name of the property</returns></span><br /> <span class="token keyword">public</span> <span class="token keyword">static</span> <span class="token return-type class-name"><span class="token keyword">string</span></span> <span class="token generic-method"><span class="token function">GetPropertyName</span><span class="token generic class-name"><span class="token punctuation"><</span>T<span class="token punctuation">></span></span></span><span class="token punctuation">(</span><span class="token class-name">Expression<span class="token punctuation"><</span>Func<span class="token punctuation"><</span>T<span class="token punctuation">,</span> <span class="token keyword">object</span>\<span class="token punctuation">></span><span class="token punctuation">></span></span> Expression<span class="token punctuation">)</span><br /> <span class="token punctuation">{</span><br /> <span class="token keyword">if</span> <span class="token punctuation">(</span>Expression <span class="token operator">==</span> <span class="token keyword">null</span><span class="token punctuation">)</span><br /> <span class="token keyword">return</span> <span class="token string">""</span><span class="token punctuation">;</span><br /> <span class="token class-name"><span class="token keyword">string</span></span> Name <span class="token operator">=</span> <span class="token string">""</span><span class="token punctuation">;</span><br /> <span class="token keyword">if</span> <span class="token punctuation">(</span>Expression<span class="token punctuation">.</span>Body<span class="token punctuation">.</span>NodeType <span class="token operator">==</span> ExpressionType<span class="token punctuation">.</span>Convert<span class="token punctuation">)</span><br /> <span class="token punctuation">{</span><br /> Name <span class="token operator">=</span> Expression<span class="token punctuation">.</span>Body<span class="token punctuation">.</span><span class="token function">ToString</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">.</span><span class="token function">Replace</span><span class="token punctuation">(</span><span class="token string">"Convert("</span><span class="token punctuation">,</span> <span class="token string">""</span><span class="token punctuation">)</span><span class="token punctuation">.</span><span class="token function">Replace</span><span class="token punctuation">(</span><span class="token string">")"</span><span class="token punctuation">,</span> <span class="token string">""</span><span class="token punctuation">)</span><span class="token punctuation">;</span><br /> Name <span class="token operator">=</span> Name<span class="token punctuation">.</span><span class="token function">Remove</span><span class="token punctuation">(</span><span class="token number">0</span><span class="token punctuation">,</span> Name<span class="token punctuation">.</span><span class="token function">IndexOf</span><span class="token punctuation">(</span><span class="token string">"."</span><span class="token punctuation">)</span> <span class="token operator">+</span> <span class="token number">1</span><span class="token punctuation">)</span><span class="token punctuation">;</span><br /> <span class="token punctuation">}</span><br /> <span class="token keyword">else</span><br /> <span class="token punctuation">{</span><br /> Name <span class="token operator">=</span> Expression<span class="token punctuation">.</span>Body<span class="token punctuation">.</span><span class="token function">ToString</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">;</span><br /> Name <span class="token operator">=</span> Name<span class="token punctuation">.</span><span class="token function">Remove</span><span class="token punctuation">(</span><span class="token number">0</span><span class="token punctuation">,</span> Name<span class="token punctuation">.</span><span class="token function">IndexOf</span><span class="token punctuation">(</span><span class="token string">"."</span><span class="token punctuation">)</span> <span class="token operator">+</span> <span class="token number">1</span><span class="token punctuation">)</span><span class="token punctuation">;</span><br /> <span class="token punctuation">}</span><br /> <span class="token keyword">return</span> Name<span class="token punctuation">;</span><br /> <span class="token punctuation">}</span><br /> <br /> <span class="token comment">/// <summary></span><br /> <span class="token comment">/// Gets a property name</span><br /> <span class="token comment">/// </summary></span><br /> <span class="token comment">/// <typeparam name="ClassType">Class type</typeparam></span><br /> <span class="token comment">/// <typeparam name="DataType">Data type of the property</typeparam></span><br /> <span class="token comment">/// <param name="Expression">LINQ expression</param></span><br /> <span class="token comment">/// <returns>The name of the property</returns></span><br /> <span class="token keyword">public</span> <span class="token keyword">static</span> <span class="token return-type class-name"><span class="token keyword">string</span></span> <span class="token generic-method"><span class="token function">GetPropertyName</span><span class="token generic class-name"><span class="token punctuation"><</span>ClassType<span class="token punctuation">,</span> DataType<span class="token punctuation">></span></span></span><span class="token punctuation">(</span><span class="token class-name">Expression<span class="token punctuation"><</span>Func<span class="token punctuation"><</span>ClassType<span class="token punctuation">,</span> DataType<span class="token punctuation">></span><span class="token punctuation">></span></span> Expression<span class="token punctuation">)</span><br /> <span class="token punctuation">{</span><br /> <span class="token keyword">if</span> <span class="token punctuation">(</span><span class="token operator">!</span><span class="token punctuation">(</span>Expression<span class="token punctuation">.</span>Body <span class="token keyword">is</span> <span class="token class-name">MemberExpression</span><span class="token punctuation">)</span><span class="token punctuation">)</span><br /> <span class="token keyword">throw</span> <span class="token keyword">new</span> <span class="token constructor-invocation class-name">ArgumentException</span><span class="token punctuation">(</span><span class="token string">"Expression.Body is not a MemberExpression"</span><span class="token punctuation">)</span><span class="token punctuation">;</span><br /> <span class="token keyword">return</span> <span class="token function">GetPropertyName</span><span class="token punctuation">(</span><span class="token punctuation">(</span><span class="token punctuation">(</span>MemberExpression<span class="token punctuation">)</span>Expression<span class="token punctuation">.</span>Body<span class="token punctuation">)</span><span class="token punctuation">.</span>Expression<span class="token punctuation">)</span> <span class="token operator">+</span> <span class="token punctuation">(</span><span class="token punctuation">(</span>MemberExpression<span class="token punctuation">)</span>Expression<span class="token punctuation">.</span>Body<span class="token punctuation">)</span><span class="token punctuation">.</span>Member<span class="token punctuation">.</span>Name<span class="token punctuation">;</span><br /> <span class="token punctuation">}</span><br /> <br /> <span class="token keyword">private</span> <span class="token keyword">static</span> <span class="token return-type class-name"><span class="token keyword">string</span></span> <span class="token function">GetPropertyName</span><span class="token punctuation">(</span><span class="token class-name">Expression</span> expression<span class="token punctuation">)</span><br /> <span class="token punctuation">{</span><br /> <span class="token keyword">if</span> <span class="token punctuation">(</span><span class="token operator">!</span><span class="token punctuation">(</span>expression <span class="token keyword">is</span> <span class="token class-name">MemberExpression</span><span class="token punctuation">)</span><span class="token punctuation">)</span><br /> <span class="token keyword">return</span> <span class="token string">""</span><span class="token punctuation">;</span><br /> <span class="token keyword">return</span> <span class="token function">GetPropertyName</span><span class="token punctuation">(</span><span class="token punctuation">(</span><span class="token punctuation">(</span>MemberExpression<span class="token punctuation">)</span>expression<span class="token punctuation">)</span><span class="token punctuation">.</span>Expression<span class="token punctuation">)</span> <span class="token operator">+</span> <span class="token punctuation">(</span><span class="token punctuation">(</span>MemberExpression<span class="token punctuation">)</span>expression<span class="token punctuation">)</span><span class="token punctuation">.</span>Member<span class="token punctuation">.</span>Name <span class="token operator">+</span> <span class="token string">"."</span><span class="token punctuation">;</span><br /> <span class="token punctuation">}</span></code></pre>
<p>And send that to GetPropertyGetter/Setter and you have the Expression trees that you need for getting/setting your properties. So let's look at how we can use this:</p>
<pre class="language-csharp"><code class="language-csharp"> <span class="token comment">/// <summary></span><br /> <span class="token comment">/// Mapping class</span><br /> <span class="token comment">/// </summary></span><br /> <span class="token comment">/// <typeparam name="Left">Left type</typeparam></span><br /> <span class="token comment">/// <typeparam name="Right">Right type</typeparam></span><br /> <span class="token keyword">public</span> <span class="token keyword">class</span> <span class="token class-name">Mapping<span class="token punctuation"><</span>Left<span class="token punctuation">,</span> Right<span class="token punctuation">></span></span><br /> <span class="token punctuation">{</span><br /> <span class="token preprocessor property">#<span class="token directive keyword">region</span> Constructors</span><br /> <br /> <span class="token comment">/// <summary></span><br /> <span class="token comment">/// Constructor</span><br /> <span class="token comment">/// </summary></span><br /> <span class="token comment">/// <param name="LeftExpression">Left expression</param></span><br /> <span class="token comment">/// <param name="RightExpression">Right expression</param></span><br /> <span class="token keyword">public</span> <span class="token function">Mapping</span><span class="token punctuation">(</span><span class="token class-name">Expression<span class="token punctuation"><</span>Func<span class="token punctuation"><</span>Left<span class="token punctuation">,</span> <span class="token keyword">object</span>\<span class="token punctuation">></span><span class="token punctuation">></span></span> LeftExpression<span class="token punctuation">,</span> <span class="token class-name">Expression<span class="token punctuation"><</span>Func<span class="token punctuation"><</span>Right<span class="token punctuation">,</span> <span class="token keyword">object</span>\<span class="token punctuation">></span><span class="token punctuation">></span></span> RightExpression<span class="token punctuation">)</span><br /> <span class="token punctuation">{</span><br /> <span class="token class-name"><span class="token keyword">string</span></span> Name <span class="token operator">=</span> Utilities<span class="token punctuation">.</span>Reflection<span class="token punctuation">.</span>Reflection<span class="token punctuation">.</span><span class="token function">GetPropertyName</span><span class="token punctuation">(</span>LeftExpression<span class="token punctuation">)</span><span class="token punctuation">;</span><br /> LeftGet <span class="token operator">=</span> Utilities<span class="token punctuation">.</span>Reflection<span class="token punctuation">.</span>Reflection<span class="token punctuation">.</span><span class="token generic-method"><span class="token function">GetPropertyGetter</span><span class="token generic class-name"><span class="token punctuation"><</span>Left<span class="token punctuation">></span></span></span><span class="token punctuation">(</span>Name<span class="token punctuation">)</span><span class="token punctuation">.</span><span class="token function">Compile</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">;</span><br /> LeftSet <span class="token operator">=</span> Utilities<span class="token punctuation">.</span>Reflection<span class="token punctuation">.</span>Reflection<span class="token punctuation">.</span><span class="token generic-method"><span class="token function">GetPropertySetter</span><span class="token generic class-name"><span class="token punctuation"><</span>Left<span class="token punctuation">></span></span></span><span class="token punctuation">(</span>Name<span class="token punctuation">)</span><span class="token punctuation">.</span><span class="token function">Compile</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">;</span><br /> Name <span class="token operator">=</span> Utilities<span class="token punctuation">.</span>Reflection<span class="token punctuation">.</span>Reflection<span class="token punctuation">.</span><span class="token function">GetPropertyName</span><span class="token punctuation">(</span>RightExpression<span class="token punctuation">)</span><span class="token punctuation">;</span><br /> RightGet <span class="token operator">=</span> Utilities<span class="token punctuation">.</span>Reflection<span class="token punctuation">.</span>Reflection<span class="token punctuation">.</span><span class="token generic-method"><span class="token function">GetPropertyGetter</span><span class="token generic class-name"><span class="token punctuation"><</span>Right<span class="token punctuation">></span></span></span><span class="token punctuation">(</span>Name<span class="token punctuation">)</span><span class="token punctuation">.</span><span class="token function">Compile</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">;</span><br /> RightSet <span class="token operator">=</span> Utilities<span class="token punctuation">.</span>Reflection<span class="token punctuation">.</span>Reflection<span class="token punctuation">.</span><span class="token generic-method"><span class="token function">GetPropertySetter</span><span class="token generic class-name"><span class="token punctuation"><</span>Right<span class="token punctuation">></span></span></span><span class="token punctuation">(</span>Name<span class="token punctuation">)</span><span class="token punctuation">.</span><span class="token function">Compile</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">;</span><br /> <span class="token punctuation">}</span><br /> <br /> <span class="token comment">/// <summary></span><br /> <span class="token comment">/// Constructor</span><br /> <span class="token comment">/// </summary></span><br /> <span class="token comment">/// <param name="LeftGet">Left get function</param></span><br /> <span class="token comment">/// <param name="LeftSet">Left set action</param></span><br /> <span class="token comment">/// <param name="RightExpression">Right expression</param></span><br /> <span class="token keyword">public</span> <span class="token function">Mapping</span><span class="token punctuation">(</span><span class="token class-name">Func<span class="token punctuation"><</span>Left<span class="token punctuation">,</span> <span class="token keyword">object</span>\<span class="token punctuation">></span></span> LeftGet<span class="token punctuation">,</span> <span class="token class-name">Action<span class="token punctuation"><</span>Left<span class="token punctuation">,</span> <span class="token keyword">object</span>\<span class="token punctuation">></span></span> LeftSet<span class="token punctuation">,</span> <span class="token class-name">Expression<span class="token punctuation"><</span>Func<span class="token punctuation"><</span>Right<span class="token punctuation">,</span> <span class="token keyword">object</span>\<span class="token punctuation">></span><span class="token punctuation">></span></span> RightExpression<span class="token punctuation">)</span><br /> <span class="token punctuation">{</span><br /> <span class="token keyword">this</span><span class="token punctuation">.</span>LeftGet <span class="token operator">=</span> LeftGet<span class="token punctuation">;</span><br /> <span class="token keyword">this</span><span class="token punctuation">.</span>LeftSet <span class="token operator">=</span> LeftSet<span class="token punctuation">;</span><br /> <span class="token class-name"><span class="token keyword">string</span></span> Name <span class="token operator">=</span> Utilities<span class="token punctuation">.</span>Reflection<span class="token punctuation">.</span>Reflection<span class="token punctuation">.</span><span class="token function">GetPropertyName</span><span class="token punctuation">(</span>RightExpression<span class="token punctuation">)</span><span class="token punctuation">;</span><br /> RightGet <span class="token operator">=</span> Utilities<span class="token punctuation">.</span>Reflection<span class="token punctuation">.</span>Reflection<span class="token punctuation">.</span><span class="token generic-method"><span class="token function">GetPropertyGetter</span><span class="token generic class-name"><span class="token punctuation"><</span>Right<span class="token punctuation">></span></span></span><span class="token punctuation">(</span>Name<span class="token punctuation">)</span><span class="token punctuation">.</span><span class="token function">Compile</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">;</span><br /> RightSet <span class="token operator">=</span> Utilities<span class="token punctuation">.</span>Reflection<span class="token punctuation">.</span>Reflection<span class="token punctuation">.</span><span class="token generic-method"><span class="token function">GetPropertySetter</span><span class="token generic class-name"><span class="token punctuation"><</span>Right<span class="token punctuation">></span></span></span><span class="token punctuation">(</span>Name<span class="token punctuation">)</span><span class="token punctuation">.</span><span class="token function">Compile</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">;</span><br /> <span class="token punctuation">}</span><br /> <br /> <span class="token comment">/// <summary></span><br /> <span class="token comment">/// Constructor</span><br /> <span class="token comment">/// </summary></span><br /> <span class="token comment">/// <param name="LeftExpression">Left expression</param></span><br /> <span class="token comment">/// <param name="RightGet">Right get function</param></span><br /> <span class="token comment">/// <param name="RightSet">Right set function</param></span><br /> <span class="token keyword">public</span> <span class="token function">Mapping</span><span class="token punctuation">(</span><span class="token class-name">Expression<span class="token punctuation"><</span>Func<span class="token punctuation"><</span>Left<span class="token punctuation">,</span> <span class="token keyword">object</span>\<span class="token punctuation">></span><span class="token punctuation">></span></span> LeftExpression<span class="token punctuation">,</span> <span class="token class-name">Func<span class="token punctuation"><</span>Right<span class="token punctuation">,</span> <span class="token keyword">object</span>\<span class="token punctuation">></span></span> RightGet<span class="token punctuation">,</span> <span class="token class-name">Action<span class="token punctuation"><</span>Right<span class="token punctuation">,</span> <span class="token keyword">object</span>\<span class="token punctuation">></span></span> RightSet<span class="token punctuation">)</span><br /> <span class="token punctuation">{</span><br /> <span class="token class-name"><span class="token keyword">string</span></span> Name <span class="token operator">=</span> Utilities<span class="token punctuation">.</span>Reflection<span class="token punctuation">.</span>Reflection<span class="token punctuation">.</span><span class="token function">GetPropertyName</span><span class="token punctuation">(</span>LeftExpression<span class="token punctuation">)</span><span class="token punctuation">;</span><br /> LeftGet <span class="token operator">=</span> Utilities<span class="token punctuation">.</span>Reflection<span class="token punctuation">.</span>Reflection<span class="token punctuation">.</span><span class="token generic-method"><span class="token function">GetPropertyGetter</span><span class="token generic class-name"><span class="token punctuation"><</span>Left<span class="token punctuation">></span></span></span><span class="token punctuation">(</span>Name<span class="token punctuation">)</span><span class="token punctuation">.</span><span class="token function">Compile</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">;</span><br /> LeftSet <span class="token operator">=</span> Utilities<span class="token punctuation">.</span>Reflection<span class="token punctuation">.</span>Reflection<span class="token punctuation">.</span><span class="token generic-method"><span class="token function">GetPropertySetter</span><span class="token generic class-name"><span class="token punctuation"><</span>Left<span class="token punctuation">></span></span></span><span class="token punctuation">(</span>Name<span class="token punctuation">)</span><span class="token punctuation">.</span><span class="token function">Compile</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">;</span><br /> <span class="token keyword">this</span><span class="token punctuation">.</span>RightGet <span class="token operator">=</span> RightGet<span class="token punctuation">;</span><br /> <span class="token keyword">this</span><span class="token punctuation">.</span>RightSet <span class="token operator">=</span> RightSet<span class="token punctuation">;</span><br /> <span class="token punctuation">}</span><br /> <br /> <span class="token comment">/// <summary></span><br /> <span class="token comment">/// Constructor</span><br /> <span class="token comment">/// </summary></span><br /> <span class="token comment">/// <param name="LeftGet">Left get function</param></span><br /> <span class="token comment">/// <param name="LeftSet">Left set function</param></span><br /> <span class="token comment">/// <param name="RightGet">Right get function</param></span><br /> <span class="token comment">/// <param name="RightSet">Right set function</param></span><br /> <span class="token keyword">public</span> <span class="token function">Mapping</span><span class="token punctuation">(</span><span class="token class-name">Func<span class="token punctuation"><</span>Left<span class="token punctuation">,</span> <span class="token keyword">object</span>\<span class="token punctuation">></span></span> LeftGet<span class="token punctuation">,</span> <span class="token class-name">Action<span class="token punctuation"><</span>Left<span class="token punctuation">,</span> <span class="token keyword">object</span>\<span class="token punctuation">></span></span> LeftSet<span class="token punctuation">,</span> <span class="token class-name">Func<span class="token punctuation"><</span>Right<span class="token punctuation">,</span> <span class="token keyword">object</span>\<span class="token punctuation">></span></span> RightGet<span class="token punctuation">,</span> <span class="token class-name">Action<span class="token punctuation"><</span>Right<span class="token punctuation">,</span> <span class="token keyword">object</span>\<span class="token punctuation">></span></span> RightSet<span class="token punctuation">)</span><br /> <span class="token punctuation">{</span><br /> <span class="token keyword">this</span><span class="token punctuation">.</span>LeftGet <span class="token operator">=</span> LeftGet<span class="token punctuation">;</span><br /> <span class="token keyword">this</span><span class="token punctuation">.</span>LeftSet <span class="token operator">=</span> LeftSet<span class="token punctuation">;</span><br /> <span class="token keyword">this</span><span class="token punctuation">.</span>RightGet <span class="token operator">=</span> RightGet<span class="token punctuation">;</span><br /> <span class="token keyword">this</span><span class="token punctuation">.</span>RightSet <span class="token operator">=</span> RightSet<span class="token punctuation">;</span><br /> <span class="token punctuation">}</span><br /> <br /> <span class="token preprocessor property">#<span class="token directive keyword">endregion</span></span><br /> <br /> <span class="token preprocessor property">#<span class="token directive keyword">region</span> Properties</span><br /> <br /> <span class="token comment">/// <summary></span><br /> <span class="token comment">/// Left get function</span><br /> <span class="token comment">/// </summary></span><br /> <span class="token keyword">protected</span> <span class="token keyword">virtual</span> <span class="token return-type class-name">Func<span class="token punctuation"><</span>Left<span class="token punctuation">,</span> <span class="token keyword">object</span>\<span class="token punctuation">></span></span> LeftGet <span class="token punctuation">{</span> <span class="token keyword">get</span><span class="token punctuation">;</span> <span class="token keyword">set</span><span class="token punctuation">;</span> <span class="token punctuation">}</span><br /> <br /> <span class="token comment">/// <summary></span><br /> <span class="token comment">/// Right get function</span><br /> <span class="token comment">/// </summary></span><br /> <span class="token keyword">protected</span> <span class="token keyword">virtual</span> <span class="token return-type class-name">Func<span class="token punctuation"><</span>Right<span class="token punctuation">,</span> <span class="token keyword">object</span>\<span class="token punctuation">></span></span> RightGet <span class="token punctuation">{</span> <span class="token keyword">get</span><span class="token punctuation">;</span> <span class="token keyword">set</span><span class="token punctuation">;</span> <span class="token punctuation">}</span><br /> <br /> <span class="token comment">/// <summary></span><br /> <span class="token comment">/// Left set function</span><br /> <span class="token comment">/// </summary></span><br /> <span class="token keyword">protected</span> <span class="token keyword">virtual</span> <span class="token return-type class-name">Action<span class="token punctuation"><</span>Left<span class="token punctuation">,</span> <span class="token keyword">object</span>\<span class="token punctuation">></span></span> LeftSet <span class="token punctuation">{</span> <span class="token keyword">get</span><span class="token punctuation">;</span> <span class="token keyword">set</span><span class="token punctuation">;</span> <span class="token punctuation">}</span><br /> <br /> <span class="token comment">/// <summary></span><br /> <span class="token comment">/// Right set function</span><br /> <span class="token comment">/// </summary></span><br /> <span class="token keyword">protected</span> <span class="token keyword">virtual</span> <span class="token return-type class-name">Action<span class="token punctuation"><</span>Right<span class="token punctuation">,</span> <span class="token keyword">object</span>\<span class="token punctuation">></span></span> RightSet <span class="token punctuation">{</span> <span class="token keyword">get</span><span class="token punctuation">;</span> <span class="token keyword">set</span><span class="token punctuation">;</span> <span class="token punctuation">}</span><br /> <br /> <span class="token preprocessor property">#<span class="token directive keyword">endregion</span></span><br /> <br /> <span class="token preprocessor property">#<span class="token directive keyword">region</span> Functions</span><br /> <br /> <span class="token comment">/// <summary></span><br /> <span class="token comment">/// Copies the source to the destination</span><br /> <span class="token comment">/// </summary></span><br /> <span class="token comment">/// <param name="Source">Source object</param></span><br /> <span class="token comment">/// <param name="Destination">Destination object</param></span><br /> <span class="token keyword">public</span> <span class="token keyword">virtual</span> <span class="token return-type class-name"><span class="token keyword">void</span></span> <span class="token function">Copy</span><span class="token punctuation">(</span><span class="token class-name">Left</span> Source<span class="token punctuation">,</span> <span class="token class-name">Right</span> Destination<span class="token punctuation">)</span><br /> <span class="token punctuation">{</span><br /> <span class="token function">RightSet</span><span class="token punctuation">(</span>Destination<span class="token punctuation">,</span> <span class="token function">LeftGet</span><span class="token punctuation">(</span>Source<span class="token punctuation">)</span><span class="token punctuation">)</span><span class="token punctuation">;</span><br /> <span class="token punctuation">}</span><br /> <br /> <span class="token comment">/// <summary></span><br /> <span class="token comment">/// Copies the source to the destination</span><br /> <span class="token comment">/// </summary></span><br /> <span class="token comment">/// <param name="Source">Source object</param></span><br /> <span class="token comment">/// <param name="Destination">Destination object</param></span><br /> <span class="token keyword">public</span> <span class="token keyword">virtual</span> <span class="token return-type class-name"><span class="token keyword">void</span></span> <span class="token function">Copy</span><span class="token punctuation">(</span><span class="token class-name">Right</span> Source<span class="token punctuation">,</span> <span class="token class-name">Left</span> Destination<span class="token punctuation">)</span><br /> <span class="token punctuation">{</span><br /> <span class="token function">LeftSet</span><span class="token punctuation">(</span>Destination<span class="token punctuation">,</span> <span class="token function">RightGet</span><span class="token punctuation">(</span>Source<span class="token punctuation">)</span><span class="token punctuation">)</span><span class="token punctuation">;</span><br /> <span class="token punctuation">}</span><br /> <br /> <span class="token comment">/// <summary></span><br /> <span class="token comment">/// Copies from the source to the destination (used in </span><br /> <span class="token comment">/// instances when both Left and Right are the same type</span><br /> <span class="token comment">/// and thus Copy is ambiguous)</span><br /> <span class="token comment">/// </summary></span><br /> <span class="token comment">/// <param name="Source">Source object</param></span><br /> <span class="token comment">/// <param name="Destination">Destination object</param></span><br /> <span class="token keyword">public</span> <span class="token keyword">virtual</span> <span class="token return-type class-name"><span class="token keyword">void</span></span> <span class="token function">CopyLeftToRight</span><span class="token punctuation">(</span><span class="token class-name">Left</span> Source<span class="token punctuation">,</span> <span class="token class-name">Right</span> Destination<span class="token punctuation">)</span><br /> <span class="token punctuation">{</span><br /> <span class="token function">RightSet</span><span class="token punctuation">(</span>Destination<span class="token punctuation">,</span> <span class="token function">LeftGet</span><span class="token punctuation">(</span>Source<span class="token punctuation">)</span><span class="token punctuation">)</span><span class="token punctuation">;</span><br /> <span class="token punctuation">}</span><br /> <br /> <span class="token preprocessor property">#<span class="token directive keyword">endregion</span></span><br /> <span class="token punctuation">}</span></code></pre>
<p>This class is a simple class for copying A to B or vice versa (and it's generic enough that you can pass in your own Funcs/Actions (which will be important in the later stages). We have one special case if Left and Right are the same type and thus the special forms of copy but that's it. However this only copies one property to another, we still need something that copies multiple properties to their appropriate destinations:</p>
<pre class="language-csharp"><code class="language-csharp"> <span class="token comment">/// <summary></span><br /> <span class="token comment">/// Maps two types together</span><br /> <span class="token comment">/// </summary></span><br /> <span class="token comment">/// <typeparam name="Left">Left type</typeparam></span><br /> <span class="token comment">/// <typeparam name="Right">Right type</typeparam></span><br /> <span class="token keyword">public</span> <span class="token keyword">class</span> <span class="token class-name">TypeMapping<span class="token punctuation"><</span>Left<span class="token punctuation">,</span> Right<span class="token punctuation">></span></span><br /> <span class="token punctuation">{</span><br /> <span class="token preprocessor property">#<span class="token directive keyword">region</span> Constructor</span><br /> <br /> <span class="token comment">/// <summary></span><br /> <span class="token comment">/// Constructor</span><br /> <span class="token comment">/// </summary></span><br /> <span class="token keyword">public</span> <span class="token function">TypeMapping</span><span class="token punctuation">(</span><span class="token punctuation">)</span> <span class="token punctuation">{</span> Mappings <span class="token operator">=</span> <span class="token keyword">new</span> <span class="token constructor-invocation class-name">List<span class="token punctuation"><</span>Mapping<span class="token punctuation"><</span>Left<span class="token punctuation">,</span> Right<span class="token punctuation">></span><span class="token punctuation">></span></span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token punctuation">}</span><br /> <br /> <span class="token preprocessor property">#<span class="token directive keyword">endregion</span></span><br /> <br /> <span class="token preprocessor property">#<span class="token directive keyword">region</span> Properties</span><br /> <br /> <span class="token comment">/// <summary></span><br /> <span class="token comment">/// List of mappings</span><br /> <span class="token comment">/// </summary></span><br /> <span class="token keyword">protected</span> <span class="token keyword">virtual</span> <span class="token return-type class-name">List<span class="token punctuation"><</span>Mapping<span class="token punctuation"><</span>Left<span class="token punctuation">,</span> Right<span class="token punctuation">></span><span class="token punctuation">></span></span> Mappings <span class="token punctuation">{</span> <span class="token keyword">get</span><span class="token punctuation">;</span> <span class="token keyword">set</span><span class="token punctuation">;</span> <span class="token punctuation">}</span><br /> <br /> <span class="token preprocessor property">#<span class="token directive keyword">endregion</span></span><br /> <br /> <span class="token preprocessor property">#<span class="token directive keyword">region</span> Functions</span><br /> <br /> <span class="token comment">/// <summary></span><br /> <span class="token comment">/// Adds a mapping</span><br /> <span class="token comment">/// </summary></span><br /> <span class="token comment">/// <param name="LeftExpression">Left expression</param></span><br /> <span class="token comment">/// <param name="RightExpression">Right expression</param></span><br /> <span class="token keyword">public</span> <span class="token keyword">virtual</span> <span class="token return-type class-name"><span class="token keyword">void</span></span> <span class="token function">AddMapping</span><span class="token punctuation">(</span><span class="token class-name">Expression<span class="token punctuation"><</span>Func<span class="token punctuation"><</span>Left<span class="token punctuation">,</span> <span class="token keyword">object</span>\<span class="token punctuation">></span><span class="token punctuation">></span></span> LeftExpression<span class="token punctuation">,</span> <span class="token class-name">Expression<span class="token punctuation"><</span>Func<span class="token punctuation"><</span>Right<span class="token punctuation">,</span> <span class="token keyword">object</span>\<span class="token punctuation">></span><span class="token punctuation">></span></span> RightExpression<span class="token punctuation">)</span><br /> <span class="token punctuation">{</span><br /> Mappings<span class="token punctuation">.</span><span class="token function">Add</span><span class="token punctuation">(</span><span class="token keyword">new</span> <span class="token constructor-invocation class-name">Mapping<span class="token punctuation"><</span>Left<span class="token punctuation">,</span> Right<span class="token punctuation">></span></span><span class="token punctuation">(</span>LeftExpression<span class="token punctuation">,</span> RightExpression<span class="token punctuation">)</span><span class="token punctuation">)</span><span class="token punctuation">;</span><br /> <span class="token punctuation">}</span><br /> <br /> <span class="token comment">/// <summary></span><br /> <span class="token comment">/// Adds a mapping</span><br /> <span class="token comment">/// </summary></span><br /> <span class="token comment">/// <param name="LeftGet">Left get function</param></span><br /> <span class="token comment">/// <param name="LeftSet">Left set action</param></span><br /> <span class="token comment">/// <param name="RightExpression">Right expression</param></span><br /> <span class="token keyword">public</span> <span class="token keyword">virtual</span> <span class="token return-type class-name"><span class="token keyword">void</span></span> <span class="token function">AddMapping</span><span class="token punctuation">(</span><span class="token class-name">Func<span class="token punctuation"><</span>Left<span class="token punctuation">,</span> <span class="token keyword">object</span>\<span class="token punctuation">></span></span> LeftGet<span class="token punctuation">,</span> <span class="token class-name">Action<span class="token punctuation"><</span>Left<span class="token punctuation">,</span> <span class="token keyword">object</span>\<span class="token punctuation">></span></span> LeftSet<span class="token punctuation">,</span> <span class="token class-name">Expression<span class="token punctuation"><</span>Func<span class="token punctuation"><</span>Right<span class="token punctuation">,</span> <span class="token keyword">object</span>\<span class="token punctuation">></span><span class="token punctuation">></span></span> RightExpression<span class="token punctuation">)</span><br /> <span class="token punctuation">{</span><br /> Mappings<span class="token punctuation">.</span><span class="token function">Add</span><span class="token punctuation">(</span><span class="token keyword">new</span> <span class="token constructor-invocation class-name">Mapping<span class="token punctuation"><</span>Left<span class="token punctuation">,</span> Right<span class="token punctuation">></span></span><span class="token punctuation">(</span>LeftGet<span class="token punctuation">,</span> LeftSet<span class="token punctuation">,</span> RightExpression<span class="token punctuation">)</span><span class="token punctuation">)</span><span class="token punctuation">;</span><br /> <span class="token punctuation">}</span><br /> <br /> <span class="token comment">/// <summary></span><br /> <span class="token comment">/// Adds a mapping</span><br /> <span class="token comment">/// </summary></span><br /> <span class="token comment">/// <param name="LeftExpression">Left expression</param></span><br /> <span class="token comment">/// <param name="RightGet">Right get function</param></span><br /> <span class="token comment">/// <param name="RightSet">Right set function</param></span><br /> <span class="token keyword">public</span> <span class="token keyword">virtual</span> <span class="token return-type class-name"><span class="token keyword">void</span></span> <span class="token function">AddMapping</span><span class="token punctuation">(</span><span class="token class-name">Expression<span class="token punctuation"><</span>Func<span class="token punctuation"><</span>Left<span class="token punctuation">,</span> <span class="token keyword">object</span>\<span class="token punctuation">></span><span class="token punctuation">></span></span> LeftExpression<span class="token punctuation">,</span> <span class="token class-name">Func<span class="token punctuation"><</span>Right<span class="token punctuation">,</span> <span class="token keyword">object</span>\<span class="token punctuation">></span></span> RightGet<span class="token punctuation">,</span> <span class="token class-name">Action<span class="token punctuation"><</span>Right<span class="token punctuation">,</span> <span class="token keyword">object</span>\<span class="token punctuation">></span></span> RightSet<span class="token punctuation">)</span><br /> <span class="token punctuation">{</span><br /> Mappings<span class="token punctuation">.</span><span class="token function">Add</span><span class="token punctuation">(</span><span class="token keyword">new</span> <span class="token constructor-invocation class-name">Mapping<span class="token punctuation"><</span>Left<span class="token punctuation">,</span> Right<span class="token punctuation">></span></span><span class="token punctuation">(</span>LeftExpression<span class="token punctuation">,</span> RightGet<span class="token punctuation">,</span> RightSet<span class="token punctuation">)</span><span class="token punctuation">)</span><span class="token punctuation">;</span><br /> <span class="token punctuation">}</span><br /> <br /> <span class="token comment">/// <summary></span><br /> <span class="token comment">/// Adds a mapping</span><br /> <span class="token comment">/// </summary></span><br /> <span class="token comment">/// <param name="LeftGet">Left get function</param></span><br /> <span class="token comment">/// <param name="LeftSet">Left set function</param></span><br /> <span class="token comment">/// <param name="RightGet">Right get function</param></span><br /> <span class="token comment">/// <param name="RightSet">Right set function</param></span><br /> <span class="token keyword">public</span> <span class="token keyword">virtual</span> <span class="token return-type class-name"><span class="token keyword">void</span></span> <span class="token function">AddMapping</span><span class="token punctuation">(</span><span class="token class-name">Func<span class="token punctuation"><</span>Left<span class="token punctuation">,</span> <span class="token keyword">object</span>\<span class="token punctuation">></span></span> LeftGet<span class="token punctuation">,</span> <span class="token class-name">Action<span class="token punctuation"><</span>Left<span class="token punctuation">,</span> <span class="token keyword">object</span>\<span class="token punctuation">></span></span> LeftSet<span class="token punctuation">,</span> <span class="token class-name">Func<span class="token punctuation"><</span>Right<span class="token punctuation">,</span> <span class="token keyword">object</span>\<span class="token punctuation">></span></span> RightGet<span class="token punctuation">,</span> <span class="token class-name">Action<span class="token punctuation"><</span>Right<span class="token punctuation">,</span> <span class="token keyword">object</span>\<span class="token punctuation">></span></span> RightSet<span class="token punctuation">)</span><br /> <span class="token punctuation">{</span><br /> Mappings<span class="token punctuation">.</span><span class="token function">Add</span><span class="token punctuation">(</span><span class="token keyword">new</span> <span class="token constructor-invocation class-name">Mapping<span class="token punctuation"><</span>Left<span class="token punctuation">,</span> Right<span class="token punctuation">></span></span><span class="token punctuation">(</span>LeftGet<span class="token punctuation">,</span> LeftSet<span class="token punctuation">,</span> RightGet<span class="token punctuation">,</span> RightSet<span class="token punctuation">)</span><span class="token punctuation">)</span><span class="token punctuation">;</span><br /> <span class="token punctuation">}</span><br /> <br /> <span class="token comment">/// <summary></span><br /> <span class="token comment">/// Copies from the source to the destination</span><br /> <span class="token comment">/// </summary></span><br /> <span class="token comment">/// <param name="Source">Source object</param></span><br /> <span class="token comment">/// <param name="Destination">Destination object</param></span><br /> <span class="token keyword">public</span> <span class="token return-type class-name"><span class="token keyword">void</span></span> <span class="token function">Copy</span><span class="token punctuation">(</span><span class="token class-name">Left</span> Source<span class="token punctuation">,</span> <span class="token class-name">Right</span> Destination<span class="token punctuation">)</span><br /> <span class="token punctuation">{</span><br /> <span class="token keyword">foreach</span> <span class="token punctuation">(</span><span class="token class-name">Mapping<span class="token punctuation"><</span>Left<span class="token punctuation">,</span> Right<span class="token punctuation">></span></span> Mapping <span class="token keyword">in</span> Mappings<span class="token punctuation">)</span><br /> <span class="token punctuation">{</span><br /> Mapping<span class="token punctuation">.</span><span class="token function">Copy</span><span class="token punctuation">(</span>Source<span class="token punctuation">,</span> Destination<span class="token punctuation">)</span><span class="token punctuation">;</span><br /> <span class="token punctuation">}</span><br /> <span class="token punctuation">}</span><br /> <br /> <span class="token comment">/// <summary></span><br /> <span class="token comment">/// Copies from the source to the destination</span><br /> <span class="token comment">/// </summary></span><br /> <span class="token comment">/// <param name="Source">Source object</param></span><br /> <span class="token comment">/// <param name="Destination">Destination object</param></span><br /> <span class="token keyword">public</span> <span class="token return-type class-name"><span class="token keyword">void</span></span> <span class="token function">Copy</span><span class="token punctuation">(</span><span class="token class-name">Right</span> Source<span class="token punctuation">,</span> <span class="token class-name">Left</span> Destination<span class="token punctuation">)</span><br /> <span class="token punctuation">{</span><br /> <span class="token keyword">foreach</span> <span class="token punctuation">(</span><span class="token class-name">Mapping<span class="token punctuation"><</span>Left<span class="token punctuation">,</span> Right<span class="token punctuation">></span></span> Mapping <span class="token keyword">in</span> Mappings<span class="token punctuation">)</span><br /> <span class="token punctuation">{</span><br /> Mapping<span class="token punctuation">.</span><span class="token function">Copy</span><span class="token punctuation">(</span>Source<span class="token punctuation">,</span> Destination<span class="token punctuation">)</span><span class="token punctuation">;</span><br /> <span class="token punctuation">}</span><br /> <span class="token punctuation">}</span><br /> <br /> <span class="token comment">/// <summary></span><br /> <span class="token comment">/// Copies from the source to the destination (used in </span><br /> <span class="token comment">/// instances when both Left and Right are the same type</span><br /> <span class="token comment">/// and thus Copy is ambiguous)</span><br /> <span class="token comment">/// </summary></span><br /> <span class="token comment">/// <param name="Source">Source</param></span><br /> <span class="token comment">/// <param name="Destination">Destination</param></span><br /> <span class="token keyword">public</span> <span class="token return-type class-name"><span class="token keyword">void</span></span> <span class="token function">CopyLeftToRight</span><span class="token punctuation">(</span><span class="token class-name">Left</span> Source<span class="token punctuation">,</span> <span class="token class-name">Right</span> Destination<span class="token punctuation">)</span><br /> <span class="token punctuation">{</span><br /> <span class="token keyword">foreach</span> <span class="token punctuation">(</span><span class="token class-name">Mapping<span class="token punctuation"><</span>Left<span class="token punctuation">,</span> Right<span class="token punctuation">></span></span> Mapping <span class="token keyword">in</span> Mappings<span class="token punctuation">)</span><br /> <span class="token punctuation">{</span><br /> Mapping<span class="token punctuation">.</span><span class="token function">CopyLeftToRight</span><span class="token punctuation">(</span>Source<span class="token punctuation">,</span> Destination<span class="token punctuation">)</span><span class="token punctuation">;</span><br /> <span class="token punctuation">}</span><br /> <span class="token punctuation">}</span><br /> <br /> <span class="token preprocessor property">#<span class="token directive keyword">endregion</span></span><br /> <span class="token punctuation">}</span></code></pre>
<p>This class simple acts as a list type, allowing you to bundle up multiple mappings. But that's all that we need. We could go one more step up and have a manager that saves the various type mappings, but for the ORM it isn't needed. With this we have a simple way to set up some rather fast functions for copying data back and forth in our system. Next post I'll talk about the wrapper for the database connections and then in the last post, I'll show the actual ORM. So for now, take a look (or look ahead at my <a href="http://cul.codeplex.com/">utility library</a> as my code is pretty much finished and in there), and happy coding.</p>
Creating a Zip File in C#
2011-02-27T00:00:00Z
http://www.gutgames.com/post/Creating-a-Zip-File-in-C/
<p>I recently ran into a request in a project where I needed to zip up a number of files on the fly and email them to a specific individual. The email part was easy but I thought that the zip file part of the request would be a bit more difficult. I mean there is <a href="http://www.icsharpcode.net/OpenSource/SharpZipLib/Default">SharpZipLib</a>, but that uses the GPL and that instantly killed that as an option for this product (I didn't make that requirement, it was forced upon me). At that point I thought that I was rather screwed until I found out that .Net has the ability to create zip files built into the system. Specifically if you look at the System.IO.Packaging portion of .Net (which is in the winbase DLL), you will find the ZipPackage class. This class, plus a couple others, allows you to package files together (by default into a zip file). So I spent about an hour and created a basic class to accomplish what I needed:</p>
<pre class="language-csharp"><code class="language-csharp"><span class="token operator">/</span>\<span class="token operator">*</span><br />Copyright <span class="token punctuation">(</span>c<span class="token punctuation">)</span> <span class="token number">2011</span> <span class="token operator"><</span><span class="token class-name">a</span> href<span class="token operator">=</span><span class="token string">"http://www.gutgames.com"</span><span class="token operator">></span>James Craig<span class="token operator"><</span><span class="token operator">/</span>a<span class="token operator">></span><br /><br />Permission <span class="token keyword">is</span> <span class="token class-name">hereby</span> granted<span class="token punctuation">,</span> free <span class="token class-name">of</span> charge<span class="token punctuation">,</span> to any person obtaining a copy<br />of <span class="token keyword">this</span> software <span class="token keyword">and</span> associated <span class="token return-type class-name">documentation</span> files <span class="token punctuation">(</span>the <span class="token string">"Software"</span><span class="token punctuation">)</span><span class="token punctuation">,</span> <span class="token class-name">to</span> deal<br /><span class="token keyword">in</span> the Software <span class="token class-name">without</span> restriction<span class="token punctuation">,</span> including without limitation the rights<br /><span class="token class-name">to</span> use<span class="token punctuation">,</span> copy<span class="token punctuation">,</span> modify<span class="token punctuation">,</span> merge<span class="token punctuation">,</span> publish<span class="token punctuation">,</span> distribute<span class="token punctuation">,</span> sublicense<span class="token punctuation">,</span> <span class="token keyword">and</span><span class="token operator">/</span><span class="token keyword">or</span> sell<br />copies of <span class="token class-name">the</span> Software<span class="token punctuation">,</span> <span class="token keyword">and</span> to permit persons to whom the Software <span class="token keyword">is</span><br /><span class="token class-name">furnished</span> to <span class="token keyword">do</span> so<span class="token punctuation">,</span> subject to the <span class="token class-name">following</span> conditions<span class="token punctuation">:</span><br /><br />The above copyright notice <span class="token keyword">and</span> <span class="token keyword">this</span> permission notice shall <span class="token class-name">be</span> included <span class="token keyword">in</span><br />all copies <span class="token keyword">or</span> substantial portions of the Software<span class="token punctuation">.</span><br /><br />THE SOFTWARE IS PROVIDED <span class="token string">"AS IS"</span><span class="token punctuation">,</span> WITHOUT WARRANTY OF <span class="token class-name">ANY</span> KIND<span class="token punctuation">,</span> EXPRESS <span class="token class-name">OR</span><br />IMPLIED<span class="token punctuation">,</span> INCLUDING BUT NOT LIMITED TO THE WARRANTIES <span class="token class-name">OF</span> MERCHANTABILITY<span class="token punctuation">,</span><br />FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT<span class="token punctuation">.</span> IN NO EVENT SHALL THE<br />AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR <span class="token class-name">ANY</span> CLAIM<span class="token punctuation">,</span> DAMAGES OR <span class="token class-name">OTHER</span><br />LIABILITY<span class="token punctuation">,</span> WHETHER IN AN ACTION <span class="token class-name">OF</span> CONTRACT<span class="token punctuation">,</span> TORT <span class="token class-name">OR</span> OTHERWISE<span class="token punctuation">,</span> <span class="token class-name">ARISING</span> FROM<span class="token punctuation">,</span><br />OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN<br />THE SOFTWARE<span class="token punctuation">.</span>\<span class="token operator">*</span><span class="token operator">/</span><br /> <br /><span class="token preprocessor property">#<span class="token directive keyword">region</span> Usings</span><br /><span class="token keyword">using</span> <span class="token namespace">System</span><span class="token punctuation">;</span><br /><span class="token keyword">using</span> <span class="token namespace">System<span class="token punctuation">.</span>Collections<span class="token punctuation">.</span>Generic</span><span class="token punctuation">;</span><br /><span class="token keyword">using</span> <span class="token namespace">System<span class="token punctuation">.</span>Linq</span><span class="token punctuation">;</span><br /><span class="token keyword">using</span> <span class="token namespace">System<span class="token punctuation">.</span>Text</span><span class="token punctuation">;</span><br /><span class="token keyword">using</span> <span class="token namespace">System<span class="token punctuation">.</span>IO<span class="token punctuation">.</span>Packaging</span><span class="token punctuation">;</span><br /><span class="token keyword">using</span> <span class="token namespace">System<span class="token punctuation">.</span>IO</span><span class="token punctuation">;</span><br /><span class="token preprocessor property">#<span class="token directive keyword">endregion</span></span><br /> <br /><span class="token keyword">namespace</span> <span class="token namespace">Utilities<span class="token punctuation">.</span>FileFormats<span class="token punctuation">.</span>Zip</span><br /><span class="token punctuation">{</span><br /> <span class="token comment">/// <summary></span><br /> <span class="token comment">/// Helper class for dealing with zip files</span><br /> <span class="token comment">/// </summary></span><br /> <span class="token keyword">public</span> <span class="token keyword">class</span> <span class="token class-name">ZipFile</span> <span class="token punctuation">:</span> <span class="token type-list"><span class="token class-name">IDisposable</span></span><br /> <span class="token punctuation">{</span><br /> <span class="token preprocessor property">#<span class="token directive keyword">region</span> Constructor</span><br /> <br /> <span class="token comment">/// <summary></span><br /> <span class="token comment">/// Constructor</span><br /> <span class="token comment">/// </summary></span><br /> <span class="token comment">/// <param name="FilePath">Path to the zip file</param></span><br /> <span class="token comment">/// <param name="Overwrite">Should the zip file be overwritten?</param></span><br /> <span class="token keyword">public</span> <span class="token function">ZipFile</span><span class="token punctuation">(</span><span class="token class-name"><span class="token keyword">string</span></span> FilePath<span class="token punctuation">,</span> <span class="token class-name"><span class="token keyword">bool</span></span> Overwrite<span class="token punctuation">)</span><br /> <span class="token punctuation">{</span><br /> <span class="token keyword">if</span> <span class="token punctuation">(</span><span class="token keyword">string</span><span class="token punctuation">.</span><span class="token function">IsNullOrEmpty</span><span class="token punctuation">(</span>FilePath<span class="token punctuation">)</span><span class="token punctuation">)</span><br /> <span class="token keyword">throw</span> <span class="token keyword">new</span> <span class="token constructor-invocation class-name">ArgumentNullException</span><span class="token punctuation">(</span><span class="token string">"FilePath"</span><span class="token punctuation">)</span><span class="token punctuation">;</span><br /> ZipFileStream <span class="token operator">=</span> <span class="token keyword">new</span> <span class="token constructor-invocation class-name">FileStream</span><span class="token punctuation">(</span>FilePath<span class="token punctuation">,</span> Overwrite <span class="token punctuation">?</span> FileMode<span class="token punctuation">.</span>Create <span class="token punctuation">:</span> FileMode<span class="token punctuation">.</span>OpenOrCreate<span class="token punctuation">)</span><span class="token punctuation">;</span><br /> <span class="token punctuation">}</span><br /> <br /> <span class="token preprocessor property">#<span class="token directive keyword">endregion</span></span><br /> <br /> <span class="token preprocessor property">#<span class="token directive keyword">region</span> Properties</span><br /> <br /> <span class="token comment">/// <summary></span><br /> <span class="token comment">/// Zip file's FileStream</span><br /> <span class="token comment">/// </summary></span><br /> <span class="token keyword">protected</span> <span class="token keyword">virtual</span> <span class="token return-type class-name">FileStream</span> ZipFileStream <span class="token punctuation">{</span> <span class="token keyword">get</span><span class="token punctuation">;</span> <span class="token keyword">set</span><span class="token punctuation">;</span> <span class="token punctuation">}</span><br /> <br /> <span class="token preprocessor property">#<span class="token directive keyword">endregion</span></span><br /> <br /> <span class="token preprocessor property">#<span class="token directive keyword">region</span> Functions</span><br /> <br /> <span class="token comment">/// <summary></span><br /> <span class="token comment">/// Adds a folder to the zip file</span><br /> <span class="token comment">/// </summary></span><br /> <span class="token comment">/// <param name="Folder">Folder to add</param></span><br /> <span class="token keyword">public</span> <span class="token keyword">virtual</span> <span class="token return-type class-name"><span class="token keyword">void</span></span> <span class="token function">AddFolder</span><span class="token punctuation">(</span><span class="token class-name"><span class="token keyword">string</span></span> Folder<span class="token punctuation">)</span><br /> <span class="token punctuation">{</span><br /> <span class="token keyword">if</span> <span class="token punctuation">(</span><span class="token keyword">string</span><span class="token punctuation">.</span><span class="token function">IsNullOrEmpty</span><span class="token punctuation">(</span>Folder<span class="token punctuation">)</span><span class="token punctuation">)</span><br /> <span class="token keyword">throw</span> <span class="token keyword">new</span> <span class="token constructor-invocation class-name">ArgumentNullException</span><span class="token punctuation">(</span><span class="token string">"Folder"</span><span class="token punctuation">)</span><span class="token punctuation">;</span><br /> <span class="token keyword">if</span> <span class="token punctuation">(</span>Folder<span class="token punctuation">.</span><span class="token function">EndsWith</span><span class="token punctuation">(</span><span class="token string">@"\\"</span><span class="token punctuation">)</span><span class="token punctuation">)</span><br /> Folder <span class="token operator">=</span> Folder<span class="token punctuation">.</span><span class="token function">Remove</span><span class="token punctuation">(</span>Folder<span class="token punctuation">.</span>Length <span class="token operator">-</span> <span class="token number">1</span><span class="token punctuation">)</span><span class="token punctuation">;</span><br /> <span class="token keyword">using</span> <span class="token punctuation">(</span><span class="token class-name">Package</span> Package <span class="token operator">=</span> ZipPackage<span class="token punctuation">.</span><span class="token function">Open</span><span class="token punctuation">(</span>ZipFileStream<span class="token punctuation">,</span> FileMode<span class="token punctuation">.</span>OpenOrCreate<span class="token punctuation">)</span><span class="token punctuation">)</span><br /> <span class="token punctuation">{</span><br /> <span class="token class-name">List<span class="token punctuation"><</span>FileInfo<span class="token punctuation">></span></span> Files <span class="token operator">=</span> Utilities<span class="token punctuation">.</span>IO<span class="token punctuation">.</span>FileManager<span class="token punctuation">.</span><span class="token function">FileList</span><span class="token punctuation">(</span>Folder<span class="token punctuation">,</span> <span class="token boolean">true</span><span class="token punctuation">)</span><span class="token punctuation">;</span><br /> <span class="token keyword">foreach</span> <span class="token punctuation">(</span><span class="token class-name">FileInfo</span> File <span class="token keyword">in</span> Files<span class="token punctuation">)</span><br /> <span class="token punctuation">{</span><br /> <span class="token class-name"><span class="token keyword">string</span></span> FilePath <span class="token operator">=</span> File<span class="token punctuation">.</span>FullName<span class="token punctuation">.</span><span class="token function">Replace</span><span class="token punctuation">(</span>Folder<span class="token punctuation">,</span> <span class="token string">""</span><span class="token punctuation">)</span><span class="token punctuation">;</span><br /> <span class="token function">AddFile</span><span class="token punctuation">(</span>FilePath<span class="token punctuation">,</span> File<span class="token punctuation">,</span> Package<span class="token punctuation">)</span><span class="token punctuation">;</span><br /> <span class="token punctuation">}</span><br /> <span class="token punctuation">}</span><br /> <span class="token punctuation">}</span><br /> <br /> <span class="token comment">/// <summary></span><br /> <span class="token comment">/// Adds a file to the zip file</span><br /> <span class="token comment">/// </summary></span><br /> <span class="token comment">/// <param name="File">File to add</param></span><br /> <span class="token keyword">public</span> <span class="token keyword">virtual</span> <span class="token return-type class-name"><span class="token keyword">void</span></span> <span class="token function">AddFile</span><span class="token punctuation">(</span><span class="token class-name"><span class="token keyword">string</span></span> File<span class="token punctuation">)</span><br /> <span class="token punctuation">{</span><br /> <span class="token keyword">if</span> <span class="token punctuation">(</span><span class="token keyword">string</span><span class="token punctuation">.</span><span class="token function">IsNullOrEmpty</span><span class="token punctuation">(</span>File<span class="token punctuation">)</span><span class="token punctuation">)</span><br /> <span class="token keyword">throw</span> <span class="token keyword">new</span> <span class="token constructor-invocation class-name">ArgumentNullException</span><span class="token punctuation">(</span><span class="token string">"File"</span><span class="token punctuation">)</span><span class="token punctuation">;</span><br /> <span class="token keyword">if</span> <span class="token punctuation">(</span><span class="token operator">!</span>Utilities<span class="token punctuation">.</span>IO<span class="token punctuation">.</span>FileManager<span class="token punctuation">.</span><span class="token function">FileExists</span><span class="token punctuation">(</span>File<span class="token punctuation">)</span><span class="token punctuation">)</span><br /> <span class="token keyword">throw</span> <span class="token keyword">new</span> <span class="token constructor-invocation class-name">ArgumentException</span><span class="token punctuation">(</span><span class="token string">"File"</span><span class="token punctuation">)</span><span class="token punctuation">;</span><br /> <span class="token keyword">using</span> <span class="token punctuation">(</span><span class="token class-name">Package</span> Package <span class="token operator">=</span> ZipPackage<span class="token punctuation">.</span><span class="token function">Open</span><span class="token punctuation">(</span>ZipFileStream<span class="token punctuation">)</span><span class="token punctuation">)</span><br /> <span class="token punctuation">{</span><br /> <span class="token function">AddFile</span><span class="token punctuation">(</span>File<span class="token punctuation">,</span> <span class="token keyword">new</span> <span class="token constructor-invocation class-name">FileInfo</span><span class="token punctuation">(</span>File<span class="token punctuation">)</span><span class="token punctuation">,</span> Package<span class="token punctuation">)</span><span class="token punctuation">;</span><br /> <span class="token punctuation">}</span><br /> <span class="token punctuation">}</span><br /> <br /> <span class="token comment">/// <summary></span><br /> <span class="token comment">/// Uncompresses the zip file to the specified folder</span><br /> <span class="token comment">/// </summary></span><br /> <span class="token comment">/// <param name="Folder">Folder to uncompress the file in</param></span><br /> <span class="token keyword">public</span> <span class="token keyword">virtual</span> <span class="token return-type class-name"><span class="token keyword">void</span></span> <span class="token function">UncompressFile</span><span class="token punctuation">(</span><span class="token class-name"><span class="token keyword">string</span></span> Folder<span class="token punctuation">)</span><br /> <span class="token punctuation">{</span><br /> <span class="token keyword">if</span> <span class="token punctuation">(</span><span class="token keyword">string</span><span class="token punctuation">.</span><span class="token function">IsNullOrEmpty</span><span class="token punctuation">(</span>Folder<span class="token punctuation">)</span><span class="token punctuation">)</span><br /> <span class="token keyword">throw</span> <span class="token keyword">new</span> <span class="token constructor-invocation class-name">ArgumentNullException</span><span class="token punctuation">(</span>Folder<span class="token punctuation">)</span><span class="token punctuation">;</span><br /> Utilities<span class="token punctuation">.</span>IO<span class="token punctuation">.</span>FileManager<span class="token punctuation">.</span><span class="token function">CreateDirectory</span><span class="token punctuation">(</span>Folder<span class="token punctuation">)</span><span class="token punctuation">;</span><br /> <span class="token keyword">using</span> <span class="token punctuation">(</span><span class="token class-name">Package</span> Package <span class="token operator">=</span> ZipPackage<span class="token punctuation">.</span><span class="token function">Open</span><span class="token punctuation">(</span>ZipFileStream<span class="token punctuation">,</span> FileMode<span class="token punctuation">.</span>Open<span class="token punctuation">,</span> FileAccess<span class="token punctuation">.</span>Read<span class="token punctuation">)</span><span class="token punctuation">)</span><br /> <span class="token punctuation">{</span><br /> <span class="token keyword">foreach</span> <span class="token punctuation">(</span><span class="token class-name">PackageRelationship</span> Relationship <span class="token keyword">in</span> Package<span class="token punctuation">.</span><span class="token function">GetRelationshipsByType</span><span class="token punctuation">(</span><span class="token string">"http://schemas.microsoft.com/opc/2006/sample/document"</span><span class="token punctuation">)</span><span class="token punctuation">)</span><br /> <span class="token punctuation">{</span><br /> <span class="token class-name">Uri</span> UriTarget <span class="token operator">=</span> PackUriHelper<span class="token punctuation">.</span><span class="token function">ResolvePartUri</span><span class="token punctuation">(</span><span class="token keyword">new</span> <span class="token constructor-invocation class-name">Uri</span><span class="token punctuation">(</span><span class="token string">"/"</span><span class="token punctuation">,</span> UriKind<span class="token punctuation">.</span>Relative<span class="token punctuation">)</span><span class="token punctuation">,</span> Relationship<span class="token punctuation">.</span>TargetUri<span class="token punctuation">)</span><span class="token punctuation">;</span><br /> <span class="token class-name">PackagePart</span> Document <span class="token operator">=</span> Package<span class="token punctuation">.</span><span class="token function">GetPart</span><span class="token punctuation">(</span>UriTarget<span class="token punctuation">)</span><span class="token punctuation">;</span><br /> <span class="token function">Extract</span><span class="token punctuation">(</span>Document<span class="token punctuation">,</span> Folder<span class="token punctuation">)</span><span class="token punctuation">;</span><br /> <span class="token punctuation">}</span><br /> <span class="token keyword">if</span> <span class="token punctuation">(</span>File<span class="token punctuation">.</span><span class="token function">Exists</span><span class="token punctuation">(</span>Folder <span class="token operator">+</span> <span class="token string">@"\\\[Content\_Types\].xml"</span><span class="token punctuation">)</span><span class="token punctuation">)</span><br /> File<span class="token punctuation">.</span><span class="token function">Delete</span><span class="token punctuation">(</span>Folder <span class="token operator">+</span> <span class="token string">@"\\\[Content\_Types\].xml"</span><span class="token punctuation">)</span><span class="token punctuation">;</span><br /> <span class="token punctuation">}</span><br /> <span class="token punctuation">}</span><br /> <br /> <span class="token comment">/// <summary></span><br /> <span class="token comment">/// Extracts an individual file</span><br /> <span class="token comment">/// </summary></span><br /> <span class="token comment">/// <param name="Document">Document to extract</param></span><br /> <span class="token comment">/// <param name="Folder">Folder to extract it into</param></span><br /> <span class="token keyword">protected</span> <span class="token keyword">virtual</span> <span class="token return-type class-name"><span class="token keyword">void</span></span> <span class="token function">Extract</span><span class="token punctuation">(</span><span class="token class-name">PackagePart</span> Document<span class="token punctuation">,</span> <span class="token class-name"><span class="token keyword">string</span></span> Folder<span class="token punctuation">)</span><br /> <span class="token punctuation">{</span><br /> <span class="token keyword">if</span> <span class="token punctuation">(</span><span class="token keyword">string</span><span class="token punctuation">.</span><span class="token function">IsNullOrEmpty</span><span class="token punctuation">(</span>Folder<span class="token punctuation">)</span><span class="token punctuation">)</span><br /> <span class="token keyword">throw</span> <span class="token keyword">new</span> <span class="token constructor-invocation class-name">ArgumentNullException</span><span class="token punctuation">(</span>Folder<span class="token punctuation">)</span><span class="token punctuation">;</span><br /> <span class="token class-name"><span class="token keyword">string</span></span> Location <span class="token operator">=</span> Folder <span class="token operator">+</span> System<span class="token punctuation">.</span>Web<span class="token punctuation">.</span>HttpUtility<span class="token punctuation">.</span><span class="token function">UrlDecode</span><span class="token punctuation">(</span>Document<span class="token punctuation">.</span>Uri<span class="token punctuation">.</span><span class="token function">ToString</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">)</span><span class="token punctuation">.</span><span class="token function">Replace</span><span class="token punctuation">(</span>'\\\\'<span class="token punctuation">,</span> <span class="token string character">'/'</span><span class="token punctuation">)</span><span class="token punctuation">;</span><br /> Utilities<span class="token punctuation">.</span>IO<span class="token punctuation">.</span>FileManager<span class="token punctuation">.</span><span class="token function">CreateDirectory</span><span class="token punctuation">(</span>Path<span class="token punctuation">.</span><span class="token function">GetDirectoryName</span><span class="token punctuation">(</span>Location<span class="token punctuation">)</span><span class="token punctuation">)</span><span class="token punctuation">;</span><br /> <span class="token keyword">byte</span>\<span class="token punctuation">[</span>\<span class="token punctuation">]</span> Data <span class="token operator">=</span> <span class="token keyword">new</span> <span class="token keyword">byte</span>\<span class="token punctuation">[</span><span class="token number">1024</span>\<span class="token punctuation">]</span><span class="token punctuation">;</span><br /> <span class="token keyword">using</span> <span class="token punctuation">(</span><span class="token class-name">FileStream</span> FileStream <span class="token operator">=</span> <span class="token keyword">new</span> <span class="token constructor-invocation class-name">FileStream</span><span class="token punctuation">(</span>Location<span class="token punctuation">,</span> FileMode<span class="token punctuation">.</span>Create<span class="token punctuation">)</span><span class="token punctuation">)</span><br /> <span class="token punctuation">{</span><br /> <span class="token class-name">Stream</span> DocumentStream <span class="token operator">=</span> Document<span class="token punctuation">.</span><span class="token function">GetStream</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">;</span><br /> <span class="token keyword">while</span> <span class="token punctuation">(</span><span class="token boolean">true</span><span class="token punctuation">)</span><br /> <span class="token punctuation">{</span><br /> <span class="token class-name"><span class="token keyword">int</span></span> Size <span class="token operator">=</span> DocumentStream<span class="token punctuation">.</span><span class="token function">Read</span><span class="token punctuation">(</span>Data<span class="token punctuation">,</span> <span class="token number">0</span><span class="token punctuation">,</span> <span class="token number">1024</span><span class="token punctuation">)</span><span class="token punctuation">;</span><br /> FileStream<span class="token punctuation">.</span><span class="token function">Write</span><span class="token punctuation">(</span>Data<span class="token punctuation">,</span> <span class="token number">0</span><span class="token punctuation">,</span> Size<span class="token punctuation">)</span><span class="token punctuation">;</span><br /> <span class="token keyword">if</span> <span class="token punctuation">(</span>Size <span class="token operator">!=</span> <span class="token number">1024</span><span class="token punctuation">)</span><br /> <span class="token keyword">break</span><span class="token punctuation">;</span><br /> <span class="token punctuation">}</span><br /> FileStream<span class="token punctuation">.</span><span class="token function">Close</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">;</span><br /> <span class="token punctuation">}</span><br /> <span class="token punctuation">}</span><br /> <br /> <span class="token comment">/// <summary></span><br /> <span class="token comment">/// Adds a file to the zip file</span><br /> <span class="token comment">/// </summary></span><br /> <span class="token comment">/// <param name="File">File to add</param></span><br /> <span class="token comment">/// <param name="FileInfo">File information</param></span><br /> <span class="token comment">/// <param name="Package">Package to add the file to</param></span><br /> <span class="token keyword">protected</span> <span class="token keyword">virtual</span> <span class="token return-type class-name"><span class="token keyword">void</span></span> <span class="token function">AddFile</span><span class="token punctuation">(</span><span class="token class-name"><span class="token keyword">string</span></span> File<span class="token punctuation">,</span> <span class="token class-name">FileInfo</span> FileInfo<span class="token punctuation">,</span> <span class="token class-name">Package</span> Package<span class="token punctuation">)</span><br /> <span class="token punctuation">{</span><br /> <span class="token keyword">if</span> <span class="token punctuation">(</span><span class="token keyword">string</span><span class="token punctuation">.</span><span class="token function">IsNullOrEmpty</span><span class="token punctuation">(</span>File<span class="token punctuation">)</span><span class="token punctuation">)</span><br /> <span class="token keyword">throw</span> <span class="token keyword">new</span> <span class="token constructor-invocation class-name">ArgumentNullException</span><span class="token punctuation">(</span><span class="token string">"File"</span><span class="token punctuation">)</span><span class="token punctuation">;</span><br /> <span class="token keyword">if</span> <span class="token punctuation">(</span><span class="token operator">!</span>Utilities<span class="token punctuation">.</span>IO<span class="token punctuation">.</span>FileManager<span class="token punctuation">.</span><span class="token function">FileExists</span><span class="token punctuation">(</span>FileInfo<span class="token punctuation">.</span>FullName<span class="token punctuation">)</span><span class="token punctuation">)</span><br /> <span class="token keyword">throw</span> <span class="token keyword">new</span> <span class="token constructor-invocation class-name">ArgumentException</span><span class="token punctuation">(</span><span class="token string">"File"</span><span class="token punctuation">)</span><span class="token punctuation">;</span><br /> <span class="token class-name">Uri</span> UriPath <span class="token operator">=</span> PackUriHelper<span class="token punctuation">.</span><span class="token function">CreatePartUri</span><span class="token punctuation">(</span><span class="token keyword">new</span> <span class="token constructor-invocation class-name">Uri</span><span class="token punctuation">(</span>File<span class="token punctuation">,</span> UriKind<span class="token punctuation">.</span>Relative<span class="token punctuation">)</span><span class="token punctuation">)</span><span class="token punctuation">;</span><br /> <span class="token class-name">PackagePart</span> PackagePart <span class="token operator">=</span> Package<span class="token punctuation">.</span><span class="token function">CreatePart</span><span class="token punctuation">(</span>UriPath<span class="token punctuation">,</span> System<span class="token punctuation">.</span>Net<span class="token punctuation">.</span>Mime<span class="token punctuation">.</span>MediaTypeNames<span class="token punctuation">.</span>Text<span class="token punctuation">.</span>Xml<span class="token punctuation">,</span> CompressionOption<span class="token punctuation">.</span>Maximum<span class="token punctuation">)</span><span class="token punctuation">;</span><br /> <span class="token keyword">byte</span>\<span class="token punctuation">[</span>\<span class="token punctuation">]</span> Data <span class="token operator">=</span> <span class="token keyword">null</span><span class="token punctuation">;</span><br /> Utilities<span class="token punctuation">.</span>IO<span class="token punctuation">.</span>FileManager<span class="token punctuation">.</span><span class="token function">GetFileContents</span><span class="token punctuation">(</span>FileInfo<span class="token punctuation">.</span>FullName<span class="token punctuation">,</span> <span class="token keyword">out</span> Data<span class="token punctuation">)</span><span class="token punctuation">;</span><br /> PackagePart<span class="token punctuation">.</span><span class="token function">GetStream</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">.</span><span class="token function">Write</span><span class="token punctuation">(</span>Data<span class="token punctuation">,</span> <span class="token number">0</span><span class="token punctuation">,</span> Data<span class="token punctuation">.</span><span class="token function">Count</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">)</span><span class="token punctuation">;</span><br /> Package<span class="token punctuation">.</span><span class="token function">CreateRelationship</span><span class="token punctuation">(</span>PackagePart<span class="token punctuation">.</span>Uri<span class="token punctuation">,</span> TargetMode<span class="token punctuation">.</span>Internal<span class="token punctuation">,</span> <span class="token string">"http://schemas.microsoft.com/opc/2006/sample/document"</span><span class="token punctuation">)</span><span class="token punctuation">;</span><br /> <span class="token punctuation">}</span><br /> <br /> <span class="token preprocessor property">#<span class="token directive keyword">endregion</span></span><br /> <br /> <span class="token preprocessor property">#<span class="token directive keyword">region</span> IDisposable Members</span><br /> <br /> <span class="token keyword">public</span> <span class="token return-type class-name"><span class="token keyword">void</span></span> <span class="token function">Dispose</span><span class="token punctuation">(</span><span class="token punctuation">)</span><br /> <span class="token punctuation">{</span><br /> <span class="token keyword">if</span> <span class="token punctuation">(</span>ZipFileStream <span class="token operator">!=</span> <span class="token keyword">null</span><span class="token punctuation">)</span><br /> <span class="token punctuation">{</span><br /> ZipFileStream<span class="token punctuation">.</span><span class="token function">Close</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">;</span><br /> ZipFileStream<span class="token punctuation">.</span><span class="token function">Dispose</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">;</span><br /> ZipFileStream <span class="token operator">=</span> <span class="token keyword">null</span><span class="token punctuation">;</span><br /> <span class="token punctuation">}</span><br /> <span class="token punctuation">}</span><br /> <br /> <span class="token preprocessor property">#<span class="token directive keyword">endregion</span></span><br /> <span class="token punctuation">}</span><br /><span class="token punctuation">}</span></code></pre>
<p>If you'll notice there isn't much actual code there. Just an AddFolder function, AddFile, and Uncompress (plus two protected functions that they use). In order to use it you just create the object like this:</p>
<pre class="language-csharp"><code class="language-csharp"><span class="token keyword">using</span> <span class="token punctuation">(</span><span class="token class-name">Utilities<span class="token punctuation">.</span>FileFormats<span class="token punctuation">.</span>Zip<span class="token punctuation">.</span>ZipFile</span> File <span class="token operator">=</span> <span class="token keyword">new</span> <span class="token constructor-invocation class-name">Utilities<span class="token punctuation">.</span>FileFormats<span class="token punctuation">.</span>Zip<span class="token punctuation">.</span>ZipFile</span><span class="token punctuation">(</span><span class="token string">"ZIPFILENAME.zip"</span><span class="token punctuation">,</span> <span class="token boolean">true</span><span class="token punctuation">)</span><span class="token punctuation">)</span><br /><span class="token punctuation">{</span><br /> File<span class="token punctuation">.</span><span class="token function">AddFolder</span><span class="token punctuation">(</span><span class="token string">"FOLDERTOADD"</span><span class="token punctuation">)</span><span class="token punctuation">;</span><br /><span class="token punctuation">}</span></code></pre>
<p>And that's it, you add the files/folders that you want to the zip file and you're done (the ZipFile class actually handles outputting everything to a file). And we can unzip the file with the following code:</p>
<pre class="language-csharp"><code class="language-csharp"><span class="token keyword">using</span> <span class="token punctuation">(</span><span class="token class-name">Utilities<span class="token punctuation">.</span>FileFormats<span class="token punctuation">.</span>Zip<span class="token punctuation">.</span>ZipFile</span> File <span class="token operator">=</span> <span class="token keyword">new</span> <span class="token constructor-invocation class-name">Utilities<span class="token punctuation">.</span>FileFormats<span class="token punctuation">.</span>Zip<span class="token punctuation">.</span>ZipFile</span><span class="token punctuation">(</span><span class="token string">"ZIPFILENAME.zip"</span><span class="token punctuation">,</span> <span class="token boolean">false</span><span class="token punctuation">)</span><span class="token punctuation">)</span><br /><span class="token punctuation">{</span><br /> File<span class="token punctuation">.</span><span class="token function">UncompressFile</span><span class="token punctuation">(</span><span class="token string">"FOLDERTOUNCOMPRESSWITHIN"</span><span class="token punctuation">)</span><span class="token punctuation">;</span><br /><span class="token punctuation">}</span></code></pre>
<p>And that's it. It accomplished what I needed and was extremely simple. Note that the code above doesn't work on all zip files but the zip files that you create can be opened with other apps. Anyway, try out the code (you may want to go to my <a href="http://cul.codeplex.com/">utility library</a>'s site and check for updates as I've added the code there), leave feedback, and happy coding.</p>
Building Your Own Unit Testing Framework in C#
2011-02-05T00:00:00Z
http://www.gutgames.com/post/Building-Your-Own-Unit-Testing-Framework-in-C/
<p>About two weeks ago I became bored and when I am bored, I write code. In this case I was curious how difficult it would be to write my own unit testing framework. I mean I use <a href="http://xunit.codeplex.com/">xUnit.net</a> for most of my day to day testing, but I never gave much thought into what goes into creating the framework itself. It turns out that it's fairly simple. Truth be told there are only a couple of parts that the framework needs:</p>
<ul>
<li>A test finder/loader/runner</li>
<li>A set of assertions</li>
<li>A set of exceptions</li>
<li>Something to hold the results of a test<br />
For something basic, that's it. And to be honest, none of those take much time to write. The approach that I'm taking is very similar to <a href="http://xunit.net/">xUnit.net</a>, so if you're familiar with it, this will look very similar. Anyway, let's start with the bit of code that finds our tests and loads them:</li>
</ul>
<pre class="language-csharp"><code class="language-csharp"> <span class="token operator">/</span>\<span class="token operator">*</span><br /> Copyright <span class="token punctuation">(</span>c<span class="token punctuation">)</span> <span class="token number">2011</span> <span class="token operator"><</span><span class="token class-name">a</span> href<span class="token operator">=</span><span class="token string">"http://www.gutgames.com"</span><span class="token operator">></span>James Craig<span class="token operator"><</span><span class="token operator">/</span>a<span class="token operator">></span><br /> <br /> Permission <span class="token keyword">is</span> <span class="token class-name">hereby</span> granted<span class="token punctuation">,</span> free <span class="token class-name">of</span> charge<span class="token punctuation">,</span> to any person obtaining a copy<br /> of <span class="token keyword">this</span> software <span class="token keyword">and</span> associated <span class="token return-type class-name">documentation</span> files <span class="token punctuation">(</span>the <span class="token string">"Software"</span><span class="token punctuation">)</span><span class="token punctuation">,</span> <span class="token class-name">to</span> deal<br /> <span class="token keyword">in</span> the Software <span class="token class-name">without</span> restriction<span class="token punctuation">,</span> including without limitation the rights<br /> <span class="token class-name">to</span> use<span class="token punctuation">,</span> copy<span class="token punctuation">,</span> modify<span class="token punctuation">,</span> merge<span class="token punctuation">,</span> publish<span class="token punctuation">,</span> distribute<span class="token punctuation">,</span> sublicense<span class="token punctuation">,</span> <span class="token keyword">and</span><span class="token operator">/</span><span class="token keyword">or</span> sell<br /> copies of <span class="token class-name">the</span> Software<span class="token punctuation">,</span> <span class="token keyword">and</span> to permit persons to whom the Software <span class="token keyword">is</span><br /> <span class="token class-name">furnished</span> to <span class="token keyword">do</span> so<span class="token punctuation">,</span> subject to the <span class="token class-name">following</span> conditions<span class="token punctuation">:</span><br /> <br /> The above copyright notice <span class="token keyword">and</span> <span class="token keyword">this</span> permission notice shall <span class="token class-name">be</span> included <span class="token keyword">in</span><br /> all copies <span class="token keyword">or</span> substantial portions of the Software<span class="token punctuation">.</span><br /> <br /> THE SOFTWARE IS PROVIDED <span class="token string">"AS IS"</span><span class="token punctuation">,</span> WITHOUT WARRANTY OF <span class="token class-name">ANY</span> KIND<span class="token punctuation">,</span> EXPRESS <span class="token class-name">OR</span><br /> IMPLIED<span class="token punctuation">,</span> INCLUDING BUT NOT LIMITED TO THE WARRANTIES <span class="token class-name">OF</span> MERCHANTABILITY<span class="token punctuation">,</span><br /> FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT<span class="token punctuation">.</span> IN NO EVENT SHALL THE<br /> AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR <span class="token class-name">ANY</span> CLAIM<span class="token punctuation">,</span> DAMAGES OR <span class="token class-name">OTHER</span><br /> LIABILITY<span class="token punctuation">,</span> WHETHER IN AN ACTION <span class="token class-name">OF</span> CONTRACT<span class="token punctuation">,</span> TORT <span class="token class-name">OR</span> OTHERWISE<span class="token punctuation">,</span> <span class="token class-name">ARISING</span> FROM<span class="token punctuation">,</span><br /> OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN<br /> THE SOFTWARE<span class="token punctuation">.</span>\<span class="token operator">*</span><span class="token operator">/</span><br /> <br /> <span class="token preprocessor property">#<span class="token directive keyword">region</span> Usings</span><br /> <span class="token keyword">using</span> <span class="token namespace">System</span><span class="token punctuation">;</span><br /> <span class="token keyword">using</span> <span class="token namespace">System<span class="token punctuation">.</span>Collections<span class="token punctuation">.</span>Generic</span><span class="token punctuation">;</span><br /> <span class="token keyword">using</span> <span class="token namespace">System<span class="token punctuation">.</span>Linq</span><span class="token punctuation">;</span><br /> <span class="token keyword">using</span> <span class="token namespace">System<span class="token punctuation">.</span>Text</span><span class="token punctuation">;</span><br /> <span class="token keyword">using</span> <span class="token namespace">Utilities<span class="token punctuation">.</span>DataTypes<span class="token punctuation">.</span>Patterns<span class="token punctuation">.</span>BaseClasses</span><span class="token punctuation">;</span><br /> <span class="token keyword">using</span> <span class="token namespace">System<span class="token punctuation">.</span>Reflection</span><span class="token punctuation">;</span><br /> <span class="token keyword">using</span> <span class="token namespace">MoonUnit<span class="token punctuation">.</span>Attributes</span><span class="token punctuation">;</span><br /> <span class="token keyword">using</span> <span class="token namespace">MoonUnit<span class="token punctuation">.</span>Exceptions</span><span class="token punctuation">;</span><br /> <span class="token keyword">using</span> <span class="token namespace">MoonUnit<span class="token punctuation">.</span>InternalClasses</span><span class="token punctuation">;</span><br /> <span class="token keyword">using</span> <span class="token namespace">Utilities<span class="token punctuation">.</span>Profiler</span><span class="token punctuation">;</span><br /> <span class="token preprocessor property">#<span class="token directive keyword">endregion</span></span><br /> <br /> <span class="token keyword">namespace</span> <span class="token namespace">MoonUnit</span><br /> <span class="token punctuation">{</span><br /> <span class="token comment">/// <summary></span><br /> <span class="token comment">/// Manager class for unit testing framework</span><br /> <span class="token comment">/// </summary></span><br /> <span class="token keyword">public</span> <span class="token keyword">class</span> <span class="token class-name">Manager</span> <span class="token punctuation">:</span> <span class="token type-list"><span class="token class-name">Singleton<span class="token punctuation"><</span>Manager<span class="token punctuation">></span></span></span><br /> <span class="token punctuation">{</span><br /> <span class="token preprocessor property">#<span class="token directive keyword">region</span> Constructor</span><br /> <br /> <span class="token comment">/// <summary></span><br /> <span class="token comment">/// Constructor</span><br /> <span class="token comment">/// </summary></span><br /> <span class="token keyword">protected</span> <span class="token function">Manager</span><span class="token punctuation">(</span><span class="token punctuation">)</span><br /> <span class="token punctuation">:</span> <span class="token keyword">base</span><span class="token punctuation">(</span><span class="token punctuation">)</span><br /> <span class="token punctuation">{</span><br /> <span class="token punctuation">}</span><br /> <br /> <span class="token preprocessor property">#<span class="token directive keyword">endregion</span></span><br /> <br /> <span class="token preprocessor property">#<span class="token directive keyword">region</span> Functions</span><br /> <br /> <span class="token comment">/// <summary></span><br /> <span class="token comment">/// Tests an assembly</span><br /> <span class="token comment">/// </summary></span><br /> <span class="token comment">/// <param name="AssemblyToTest">Assembly to test</param></span><br /> <span class="token comment">/// <returns>The XML string of the results</returns></span><br /> <span class="token keyword">public</span> <span class="token return-type class-name"><span class="token keyword">string</span></span> <span class="token function">Test</span><span class="token punctuation">(</span><span class="token class-name">Assembly</span> AssemblyToTest<span class="token punctuation">)</span><br /> <span class="token punctuation">{</span><br /> Type\<span class="token punctuation">[</span>\<span class="token punctuation">]</span> Types <span class="token operator">=</span> AssemblyToTest<span class="token punctuation">.</span><span class="token function">GetTypes</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">;</span><br /> <span class="token keyword">return</span> <span class="token function">Test</span><span class="token punctuation">(</span>Types<span class="token punctuation">)</span><span class="token punctuation">;</span><br /> <span class="token punctuation">}</span><br /> <br /> <span class="token comment">/// <summary></span><br /> <span class="token comment">/// Test a list of types</span><br /> <span class="token comment">/// </summary></span><br /> <span class="token comment">/// <param name="Types">Types to test</param></span><br /> <span class="token comment">/// <returns>The XML string of the results</returns></span><br /> <span class="token keyword">public</span> <span class="token return-type class-name"><span class="token keyword">string</span></span> <span class="token function">Test</span><span class="token punctuation">(</span>Type\<span class="token punctuation">[</span>\<span class="token punctuation">]</span> Types<span class="token punctuation">)</span><br /> <span class="token punctuation">{</span><br /> <span class="token class-name">Output</span> TempOutput <span class="token operator">=</span> <span class="token keyword">new</span> <span class="token constructor-invocation class-name">Output</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">;</span><br /> <span class="token keyword">foreach</span> <span class="token punctuation">(</span><span class="token class-name">Type</span> Type <span class="token keyword">in</span> Types<span class="token punctuation">)</span><br /> <span class="token function">TestClass</span><span class="token punctuation">(</span>Type<span class="token punctuation">,</span> TempOutput<span class="token punctuation">)</span><span class="token punctuation">;</span><br /> <span class="token keyword">return</span> TempOutput<span class="token punctuation">.</span><span class="token function">ToString</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">;</span><br /> <span class="token punctuation">}</span><br /> <br /> <span class="token comment">/// <summary></span><br /> <span class="token comment">/// Tests a type</span><br /> <span class="token comment">/// </summary></span><br /> <span class="token comment">/// <param name="Type">Type to test</param></span><br /> <span class="token comment">/// <returns>The XML string of the results</returns></span><br /> <span class="token keyword">public</span> <span class="token return-type class-name"><span class="token keyword">string</span></span> <span class="token function">Test</span><span class="token punctuation">(</span><span class="token class-name">Type</span> Type<span class="token punctuation">)</span><br /> <span class="token punctuation">{</span><br /> <span class="token class-name">Output</span> TempOutput <span class="token operator">=</span> <span class="token keyword">new</span> <span class="token constructor-invocation class-name">Output</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">;</span><br /> <span class="token function">TestClass</span><span class="token punctuation">(</span>Type<span class="token punctuation">,</span> TempOutput<span class="token punctuation">)</span><span class="token punctuation">;</span><br /> <span class="token keyword">return</span> TempOutput<span class="token punctuation">.</span><span class="token function">ToString</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">;</span><br /> <span class="token punctuation">}</span><br /> <br /> <span class="token keyword">private</span> <span class="token keyword">static</span> <span class="token return-type class-name"><span class="token keyword">void</span></span> <span class="token function">TestClass</span><span class="token punctuation">(</span><span class="token class-name">Type</span> Type<span class="token punctuation">,</span> <span class="token class-name">Output</span> TempOutput<span class="token punctuation">)</span><br /> <span class="token punctuation">{</span><br /> MethodInfo\<span class="token punctuation">[</span>\<span class="token punctuation">]</span> Methods <span class="token operator">=</span> Type<span class="token punctuation">.</span><span class="token function">GetMethods</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">;</span><br /> <span class="token keyword">foreach</span> <span class="token punctuation">(</span><span class="token class-name">MethodInfo</span> Method <span class="token keyword">in</span> Methods<span class="token punctuation">)</span><br /> <span class="token punctuation">{</span><br /> <span class="token keyword">object</span>\<span class="token punctuation">[</span>\<span class="token punctuation">]</span> Attributes <span class="token operator">=</span> Method<span class="token punctuation">.</span><span class="token function">GetCustomAttributes</span><span class="token punctuation">(</span><span class="token boolean">false</span><span class="token punctuation">)</span><span class="token punctuation">;</span><br /> <span class="token keyword">foreach</span> <span class="token punctuation">(</span><span class="token class-name">Attribute</span> TempAttribute <span class="token keyword">in</span> Attributes<span class="token punctuation">)</span><br /> <span class="token punctuation">{</span><br /> <span class="token keyword">if</span> <span class="token punctuation">(</span>TempAttribute <span class="token keyword">is</span> <span class="token class-name">TestAttribute</span><span class="token punctuation">)</span><br /> <span class="token punctuation">{</span><br /> <span class="token class-name">TestAttribute</span> Attribute <span class="token operator">=</span> <span class="token punctuation">(</span>TestAttribute<span class="token punctuation">)</span>TempAttribute<span class="token punctuation">;</span><br /> <span class="token keyword">if</span> <span class="token punctuation">(</span><span class="token operator">!</span>Attribute<span class="token punctuation">.</span>Skip<span class="token punctuation">)</span><br /> <span class="token punctuation">{</span><br /> <span class="token class-name">StopWatch</span> Watch <span class="token operator">=</span> <span class="token keyword">new</span> <span class="token constructor-invocation class-name">StopWatch</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">;</span><br /> <span class="token class-name"><span class="token keyword">object</span></span> TestClass <span class="token operator">=</span> Type<span class="token punctuation">.</span>Assembly<span class="token punctuation">.</span><span class="token function">CreateInstance</span><span class="token punctuation">(</span>Type<span class="token punctuation">.</span>FullName<span class="token punctuation">)</span><span class="token punctuation">;</span><br /> <span class="token keyword">try</span><br /> <span class="token punctuation">{</span><br /> Watch<span class="token punctuation">.</span><span class="token function">Start</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">;</span><br /> Method<span class="token punctuation">.</span><span class="token function">Invoke</span><span class="token punctuation">(</span>TestClass<span class="token punctuation">,</span> Type<span class="token punctuation">.</span>EmptyTypes<span class="token punctuation">)</span><span class="token punctuation">;</span><br /> Watch<span class="token punctuation">.</span><span class="token function">Stop</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">;</span><br /> <span class="token keyword">if</span> <span class="token punctuation">(</span>Attribute<span class="token punctuation">.</span>TimeOut <span class="token operator">></span> <span class="token number">0</span> <span class="token operator">&&</span> Watch<span class="token punctuation">.</span>ElapsedTime <span class="token operator">></span> Attribute<span class="token punctuation">.</span>TimeOut<span class="token punctuation">)</span><br /> <span class="token keyword">throw</span> <span class="token keyword">new</span> <span class="token constructor-invocation class-name">TimeOut</span><span class="token punctuation">(</span><span class="token string">"Method took longer than expected"</span><span class="token punctuation">)</span><span class="token punctuation">;</span><br /> TempOutput<span class="token punctuation">.</span><span class="token function">MethodCalled</span><span class="token punctuation">(</span>Method<span class="token punctuation">)</span><span class="token punctuation">;</span><br /> <span class="token punctuation">}</span><br /> <span class="token keyword">catch</span> <span class="token punctuation">(</span><span class="token class-name">Exception</span> e<span class="token punctuation">)</span><br /> <span class="token punctuation">{</span><br /> <span class="token keyword">if</span><span class="token punctuation">(</span>e<span class="token punctuation">.</span>InnerException<span class="token operator">!=</span><span class="token keyword">null</span><span class="token punctuation">)</span><br /> TempOutput<span class="token punctuation">.</span><span class="token function">MethodCalled</span><span class="token punctuation">(</span>Method<span class="token punctuation">,</span> e<span class="token punctuation">.</span>InnerException<span class="token punctuation">)</span><span class="token punctuation">;</span><br /> <span class="token keyword">else</span><br /> TempOutput<span class="token punctuation">.</span><span class="token function">MethodCalled</span><span class="token punctuation">(</span>Method<span class="token punctuation">,</span> e<span class="token punctuation">)</span><span class="token punctuation">;</span><br /> <span class="token punctuation">}</span><br /> <span class="token punctuation">}</span><br /> <span class="token keyword">else</span><br /> <span class="token punctuation">{</span><br /> TempOutput<span class="token punctuation">.</span><span class="token function">MethodCalled</span><span class="token punctuation">(</span>Method<span class="token punctuation">,</span> <span class="token keyword">new</span> <span class="token constructor-invocation class-name">Skipped</span><span class="token punctuation">(</span>Attribute<span class="token punctuation">.</span>ReasonForSkipping<span class="token punctuation">)</span><span class="token punctuation">)</span><span class="token punctuation">;</span><br /> <span class="token punctuation">}</span><br /> <span class="token punctuation">}</span><br /> <span class="token punctuation">}</span><br /> <span class="token punctuation">}</span><br /> <span class="token punctuation">}</span><br /> <br /> <span class="token preprocessor property">#<span class="token directive keyword">endregion</span></span><br /> <span class="token punctuation">}</span><br /> <span class="token punctuation">}</span></code></pre>
<p>I'm using code from my <a href="http://cul.codeplex.com/">utility library</a> and will skip over those parts but you should be able to figure out what they're doing. Anyway this class only has a couple of functions of note. The first couple are simply Test. These functions are called to actually run tests (either sending in a Type, array of Types, or an assembly). These then call TestClass which goes through and sees if any methods on the class are marked as a test. We do this by using the following attribute:</p>
<pre class="language-csharp"><code class="language-csharp"> <span class="token preprocessor property">#<span class="token directive keyword">region</span> Usings</span><br /> <span class="token keyword">using</span> <span class="token namespace">System</span><span class="token punctuation">;</span><br /> <span class="token keyword">using</span> <span class="token namespace">System<span class="token punctuation">.</span>Collections<span class="token punctuation">.</span>Generic</span><span class="token punctuation">;</span><br /> <span class="token keyword">using</span> <span class="token namespace">System<span class="token punctuation">.</span>Linq</span><span class="token punctuation">;</span><br /> <span class="token keyword">using</span> <span class="token namespace">System<span class="token punctuation">.</span>Text</span><span class="token punctuation">;</span><br /> <span class="token preprocessor property">#<span class="token directive keyword">endregion</span></span><br /> <br /> <span class="token keyword">namespace</span> <span class="token namespace">MoonUnit<span class="token punctuation">.</span>Attributes</span><br /> <span class="token punctuation">{</span><br /> <span class="token comment">/// <summary></span><br /> <span class="token comment">/// Attribute used to denote a test function</span><br /> <span class="token comment">/// </summary></span><br /> \<span class="token punctuation">[</span><span class="token function">AttributeUsage</span><span class="token punctuation">(</span>AttributeTargets<span class="token punctuation">.</span>Method<span class="token punctuation">,</span> AllowMultiple <span class="token operator">=</span> <span class="token boolean">false</span><span class="token punctuation">)</span>\<span class="token punctuation">]</span><br /> <span class="token keyword">public</span> <span class="token keyword">class</span> <span class="token class-name">TestAttribute</span> <span class="token punctuation">:</span> <span class="token type-list"><span class="token class-name">Attribute</span></span><br /> <span class="token punctuation">{</span><br /> <span class="token preprocessor property">#<span class="token directive keyword">region</span> Constructor</span><br /> <br /> <span class="token comment">/// <summary></span><br /> <span class="token comment">/// Constructor</span><br /> <span class="token comment">/// </summary></span><br /> <span class="token keyword">public</span> <span class="token function">TestAttribute</span><span class="token punctuation">(</span><span class="token class-name"><span class="token keyword">long</span></span> TimeOut<span class="token operator">=</span><span class="token number">0</span><span class="token punctuation">)</span><br /> <span class="token punctuation">:</span> <span class="token keyword">base</span><span class="token punctuation">(</span><span class="token punctuation">)</span><br /> <span class="token punctuation">{</span><br /> Skip <span class="token operator">=</span> <span class="token boolean">false</span><span class="token punctuation">;</span><br /> <span class="token keyword">this</span><span class="token punctuation">.</span>TimeOut <span class="token operator">=</span> TimeOut<span class="token punctuation">;</span><br /> <span class="token punctuation">}</span><br /> <br /> <span class="token comment">/// <summary></span><br /> <span class="token comment">/// Constructor</span><br /> <span class="token comment">/// </summary></span><br /> <span class="token comment">/// <param name="ReasonForSkipping">Reason for skipping this test</param></span><br /> <span class="token keyword">public</span> <span class="token function">TestAttribute</span><span class="token punctuation">(</span><span class="token class-name"><span class="token keyword">string</span></span> ReasonForSkipping<span class="token punctuation">,</span><span class="token class-name"><span class="token keyword">long</span></span> TimeOut<span class="token operator">=</span><span class="token number">0</span><span class="token punctuation">)</span><br /> <span class="token punctuation">:</span> <span class="token keyword">base</span><span class="token punctuation">(</span><span class="token punctuation">)</span><br /> <span class="token punctuation">{</span><br /> <span class="token keyword">this</span><span class="token punctuation">.</span>Skip <span class="token operator">=</span> <span class="token boolean">true</span><span class="token punctuation">;</span><br /> <span class="token keyword">this</span><span class="token punctuation">.</span>ReasonForSkipping <span class="token operator">=</span> ReasonForSkipping<span class="token punctuation">;</span><br /> <span class="token keyword">this</span><span class="token punctuation">.</span>TimeOut <span class="token operator">=</span> TimeOut<span class="token punctuation">;</span><br /> <span class="token punctuation">}</span><br /> <br /> <span class="token preprocessor property">#<span class="token directive keyword">endregion</span></span><br /> <br /> <span class="token preprocessor property">#<span class="token directive keyword">region</span> Properties</span><br /> <br /> <span class="token comment">/// <summary></span><br /> <span class="token comment">/// Determines if the test should be skipped</span><br /> <span class="token comment">/// </summary></span><br /> <span class="token keyword">public</span> <span class="token return-type class-name"><span class="token keyword">bool</span></span> Skip <span class="token punctuation">{</span> <span class="token keyword">get</span><span class="token punctuation">;</span> <span class="token keyword">private</span> <span class="token keyword">set</span><span class="token punctuation">;</span> <span class="token punctuation">}</span><br /> <br /> <span class="token comment">/// <summary></span><br /> <span class="token comment">/// The reason for skipping this test</span><br /> <span class="token comment">/// </summary></span><br /> <span class="token keyword">public</span> <span class="token return-type class-name"><span class="token keyword">string</span></span> ReasonForSkipping <span class="token punctuation">{</span> <span class="token keyword">get</span><span class="token punctuation">;</span> <span class="token keyword">private</span> <span class="token keyword">set</span><span class="token punctuation">;</span> <span class="token punctuation">}</span><br /> <br /> <span class="token comment">/// <summary></span><br /> <span class="token comment">/// If it takes longer than this, consider it a timeout/failed test</span><br /> <span class="token comment">/// </summary></span><br /> <span class="token keyword">public</span> <span class="token return-type class-name"><span class="token keyword">long</span></span> TimeOut <span class="token punctuation">{</span> <span class="token keyword">get</span><span class="token punctuation">;</span> <span class="token keyword">private</span> <span class="token keyword">set</span><span class="token punctuation">;</span> <span class="token punctuation">}</span><br /> <br /> <span class="token preprocessor property">#<span class="token directive keyword">endregion</span></span><br /> <span class="token punctuation">}</span><br /> <span class="token punctuation">}</span></code></pre>
<p>With this attribute, we can mark a method to be run by the system. For instance:</p>
<pre class="language-csharp"><code class="language-csharp"> <span class="token keyword">class</span> <span class="token class-name">Example</span><br /> <span class="token punctuation">{</span><br /> <span class="token keyword">public</span> <span class="token return-type class-name"><span class="token keyword">void</span></span> <span class="token function">DoesNotRun</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">{</span><span class="token punctuation">}</span><br /> \<span class="token punctuation">[</span>Test\<span class="token punctuation">]</span><br /> <span class="token keyword">public</span> <span class="token return-type class-name"><span class="token keyword">void</span></span> <span class="token function">Runs</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">{</span><span class="token punctuation">}</span><br /> <span class="token punctuation">}</span></code></pre>
<p>In this case Runs would be called by the system and DoesNotRun would not be. You can also tell the system to skip a test by giving an explanation. You can also give it an amount of time for it to wait. If it takes longer than a specified time, the test is considered a failure. The last bit of code that is of interest is when an error is detected (and thus the individual test is considered a failure), we need some way to record this. We do this with the aid of Output:</p>
<pre class="language-csharp"><code class="language-csharp"> <span class="token preprocessor property">#<span class="token directive keyword">region</span> Usings</span><br /> <span class="token keyword">using</span> <span class="token namespace">System</span><span class="token punctuation">;</span><br /> <span class="token keyword">using</span> <span class="token namespace">System<span class="token punctuation">.</span>Collections<span class="token punctuation">.</span>Generic</span><span class="token punctuation">;</span><br /> <span class="token keyword">using</span> <span class="token namespace">System<span class="token punctuation">.</span>Linq</span><span class="token punctuation">;</span><br /> <span class="token keyword">using</span> <span class="token namespace">System<span class="token punctuation">.</span>Text</span><span class="token punctuation">;</span><br /> <span class="token keyword">using</span> <span class="token namespace">MoonUnit<span class="token punctuation">.</span>Exceptions</span><span class="token punctuation">;</span><br /> <span class="token keyword">using</span> <span class="token namespace">System<span class="token punctuation">.</span>Reflection</span><span class="token punctuation">;</span><br /> <span class="token preprocessor property">#<span class="token directive keyword">endregion</span></span><br /> <br /> <span class="token keyword">namespace</span> <span class="token namespace">MoonUnit<span class="token punctuation">.</span>InternalClasses</span><br /> <span class="token punctuation">{</span><br /> <span class="token comment">/// <summary></span><br /> <span class="token comment">/// Output class</span><br /> <span class="token comment">/// </summary></span><br /> <span class="token keyword">internal</span> <span class="token keyword">class</span> <span class="token class-name">Output</span><br /> <span class="token punctuation">{</span><br /> <span class="token preprocessor property">#<span class="token directive keyword">region</span> Constructor</span><br /> <br /> <span class="token keyword">public</span> <span class="token function">Output</span><span class="token punctuation">(</span><span class="token punctuation">)</span><br /> <span class="token punctuation">{</span><br /> MethodsCalled <span class="token operator">=</span> <span class="token keyword">new</span> <span class="token constructor-invocation class-name">List<span class="token punctuation"><</span>TestMethod<span class="token punctuation">></span></span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">;</span><br /> <span class="token punctuation">}</span><br /> <br /> <span class="token preprocessor property">#<span class="token directive keyword">endregion</span></span><br /> <br /> <span class="token preprocessor property">#<span class="token directive keyword">region</span> Functions</span><br /> <br /> <span class="token keyword">public</span> <span class="token return-type class-name"><span class="token keyword">void</span></span> <span class="token function">MethodCalled</span><span class="token punctuation">(</span><span class="token class-name">MethodInfo</span> MethodInformation<span class="token punctuation">,</span> <span class="token class-name">Exception</span> Exception<span class="token operator">=</span><span class="token keyword">null</span><span class="token punctuation">)</span><br /> <span class="token punctuation">{</span><br /> MethodsCalled<span class="token punctuation">.</span><span class="token function">Add</span><span class="token punctuation">(</span><span class="token keyword">new</span> <span class="token constructor-invocation class-name">TestMethod</span><span class="token punctuation">(</span>MethodInformation<span class="token punctuation">,</span> Exception<span class="token punctuation">)</span><span class="token punctuation">)</span><span class="token punctuation">;</span><br /> <span class="token punctuation">}</span><br /> <br /> <span class="token keyword">public</span> <span class="token keyword">override</span> <span class="token return-type class-name"><span class="token keyword">string</span></span> <span class="token function">ToString</span><span class="token punctuation">(</span><span class="token punctuation">)</span><br /> <span class="token punctuation">{</span><br /> <span class="token class-name"><span class="token keyword">string</span></span> AssemblyLocation <span class="token operator">=</span> Assembly<span class="token punctuation">.</span><span class="token function">GetAssembly</span><span class="token punctuation">(</span><span class="token keyword">this</span><span class="token punctuation">.</span><span class="token function">GetType</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">)</span><span class="token punctuation">.</span>Location<span class="token punctuation">;</span><br /> <span class="token class-name">AssemblyName</span> Name <span class="token operator">=</span> AssemblyName<span class="token punctuation">.</span><span class="token function">GetAssemblyName</span><span class="token punctuation">(</span>AssemblyLocation<span class="token punctuation">)</span><span class="token punctuation">;</span><br /> <span class="token class-name">StringBuilder</span> Builder <span class="token operator">=</span> <span class="token keyword">new</span> <span class="token constructor-invocation class-name">StringBuilder</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">;</span><br /> Builder<span class="token punctuation">.</span><span class="token function">Append</span><span class="token punctuation">(</span><span class="token string">"<?xml version=\\"</span><span class="token number">1.0</span>\\" encoding<span class="token operator">=</span>\\"UTF<span class="token operator">-</span><span class="token number">8</span>\\" <span class="token punctuation">?</span><span class="token operator">></span>"<span class="token punctuation">)</span><span class="token punctuation">;</span><br /> Builder<span class="token punctuation">.</span><span class="token function">Append</span><span class="token punctuation">(</span><span class="token keyword">string</span><span class="token punctuation">.</span><span class="token function">Format</span><span class="token punctuation">(</span><span class="token string">"<MoonUnit><Header><FileLocation>{0}</FileLocation><Version>{1}</Version></Header><Tests>"</span><span class="token punctuation">,</span> AssemblyLocation<span class="token punctuation">,</span> Name<span class="token punctuation">.</span>Version<span class="token punctuation">)</span><span class="token punctuation">)</span><span class="token punctuation">;</span><br /> <span class="token keyword">foreach</span> <span class="token punctuation">(</span><span class="token class-name">TestMethod</span> Method <span class="token keyword">in</span> MethodsCalled<span class="token punctuation">)</span><br /> <span class="token punctuation">{</span><br /> Builder<span class="token punctuation">.</span><span class="token function">Append</span><span class="token punctuation">(</span>Method<span class="token punctuation">.</span><span class="token function">ToString</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">)</span><span class="token punctuation">;</span><br /> <span class="token punctuation">}</span><br /> Builder<span class="token punctuation">.</span><span class="token function">Append</span><span class="token punctuation">(</span><span class="token string">"</Tests><Footer></Footer></MoonUnit>"</span><span class="token punctuation">)</span><span class="token punctuation">;</span><br /> <span class="token keyword">return</span> Builder<span class="token punctuation">.</span><span class="token function">ToString</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">;</span><br /> <span class="token punctuation">}</span><br /> <br /> <span class="token preprocessor property">#<span class="token directive keyword">endregion</span></span><br /> <br /> <span class="token preprocessor property">#<span class="token directive keyword">region</span> Properties</span><br /> <br /> <span class="token keyword">public</span> <span class="token keyword">virtual</span> <span class="token return-type class-name">List<span class="token punctuation"><</span>TestMethod<span class="token punctuation">></span></span> MethodsCalled <span class="token punctuation">{</span> <span class="token keyword">get</span><span class="token punctuation">;</span> <span class="token keyword">private</span> <span class="token keyword">set</span><span class="token punctuation">;</span> <span class="token punctuation">}</span><br /> <br /> <span class="token preprocessor property">#<span class="token directive keyword">endregion</span></span><br /> <span class="token punctuation">}</span><br /> <span class="token punctuation">}</span></code></pre>
<p>This class simply gets called when a test method is called and the result, it then stores the results in a list and can later export the results into an XML string. The individual test records are stored in the following class:</p>
<pre class="language-csharp"><code class="language-csharp"> <span class="token preprocessor property">#<span class="token directive keyword">region</span> Usings</span><br /> <span class="token keyword">using</span> <span class="token namespace">System</span><span class="token punctuation">;</span><br /> <span class="token keyword">using</span> <span class="token namespace">System<span class="token punctuation">.</span>Collections<span class="token punctuation">.</span>Generic</span><span class="token punctuation">;</span><br /> <span class="token keyword">using</span> <span class="token namespace">System<span class="token punctuation">.</span>Linq</span><span class="token punctuation">;</span><br /> <span class="token keyword">using</span> <span class="token namespace">System<span class="token punctuation">.</span>Text</span><span class="token punctuation">;</span><br /> <span class="token keyword">using</span> <span class="token namespace">MoonUnit<span class="token punctuation">.</span>Exceptions</span><span class="token punctuation">;</span><br /> <span class="token keyword">using</span> <span class="token namespace">System<span class="token punctuation">.</span>Reflection</span><span class="token punctuation">;</span><br /> <span class="token preprocessor property">#<span class="token directive keyword">endregion</span></span><br /> <br /> <span class="token keyword">namespace</span> <span class="token namespace">MoonUnit<span class="token punctuation">.</span>InternalClasses</span><br /> <span class="token punctuation">{</span><br /> <span class="token comment">/// <summary></span><br /> <span class="token comment">/// Holds information about test methods</span><br /> <span class="token comment">/// </summary></span><br /> <span class="token keyword">internal</span> <span class="token keyword">class</span> <span class="token class-name">TestMethod</span><br /> <span class="token punctuation">{</span><br /> <span class="token preprocessor property">#<span class="token directive keyword">region</span> Constructor</span><br /> <br /> <br /> <span class="token keyword">public</span> <span class="token function">TestMethod</span><span class="token punctuation">(</span><span class="token class-name">MethodInfo</span> MethodInformation<span class="token punctuation">,</span><span class="token class-name">Exception</span> Exception<span class="token punctuation">)</span><br /> <span class="token punctuation">{</span><br /> <span class="token keyword">this</span><span class="token punctuation">.</span>MethodInformation <span class="token operator">=</span> MethodInformation<span class="token punctuation">;</span><br /> <span class="token keyword">this</span><span class="token punctuation">.</span>Exception <span class="token operator">=</span> Exception<span class="token punctuation">;</span><br /> <span class="token punctuation">}</span><br /> <br /> <span class="token preprocessor property">#<span class="token directive keyword">endregion</span></span><br /> <br /> <span class="token preprocessor property">#<span class="token directive keyword">region</span> Functions</span><br /> <br /> <span class="token keyword">public</span> <span class="token keyword">override</span> <span class="token return-type class-name"><span class="token keyword">string</span></span> <span class="token function">ToString</span><span class="token punctuation">(</span><span class="token punctuation">)</span><br /> <span class="token punctuation">{</span><br /> <span class="token class-name">StringBuilder</span> Builder <span class="token operator">=</span> <span class="token keyword">new</span> <span class="token constructor-invocation class-name">StringBuilder</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">;</span><br /> Builder<span class="token punctuation">.</span><span class="token function">Append</span><span class="token punctuation">(</span><span class="token keyword">string</span><span class="token punctuation">.</span><span class="token function">Format</span><span class="token punctuation">(</span><span class="token string">"<Test><Class name=\\"</span><span class="token punctuation">{</span><span class="token number">0</span><span class="token punctuation">}</span>\\" <span class="token operator">/</span><span class="token operator">></span><span class="token operator"><</span><span class="token class-name">Method</span> name<span class="token operator">=</span>\\"<span class="token punctuation">{</span><span class="token number">1</span><span class="token punctuation">}</span>\\" <span class="token operator">/</span><span class="token operator">></span>"<span class="token punctuation">,</span><br /> MethodInformation<span class="token punctuation">.</span>DeclaringType<span class="token punctuation">.</span>Name<span class="token punctuation">,</span><br /> MethodInformation<span class="token punctuation">.</span>Name<span class="token punctuation">)</span><span class="token punctuation">)</span><span class="token punctuation">;</span><br /> <span class="token keyword">if</span> <span class="token punctuation">(</span>Exception <span class="token operator">==</span> <span class="token keyword">null</span><span class="token punctuation">)</span><br /> Builder<span class="token punctuation">.</span><span class="token function">Append</span><span class="token punctuation">(</span><span class="token string">"<Passed />"</span><span class="token punctuation">)</span><span class="token punctuation">;</span><br /> <span class="token keyword">else</span><br /> Builder<span class="token punctuation">.</span><span class="token function">Append</span><span class="token punctuation">(</span><span class="token keyword">string</span><span class="token punctuation">.</span><span class="token function">Format</span><span class="token punctuation">(</span><span class="token string">"<Failed>{0}</Failed>"</span><span class="token punctuation">,</span> Exception<span class="token punctuation">.</span><span class="token function">ToString</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">)</span><span class="token punctuation">)</span><span class="token punctuation">;</span><br /> Builder<span class="token punctuation">.</span><span class="token function">Append</span><span class="token punctuation">(</span><span class="token string">"</Test>"</span><span class="token punctuation">)</span><span class="token punctuation">;</span><br /> <span class="token keyword">return</span> Builder<span class="token punctuation">.</span><span class="token function">ToString</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">;</span><br /> <span class="token punctuation">}</span><br /> <br /> <span class="token preprocessor property">#<span class="token directive keyword">endregion</span></span><br /> <br /> <span class="token preprocessor property">#<span class="token directive keyword">region</span> Properties</span><br /> <br /> <span class="token keyword">public</span> <span class="token keyword">virtual</span> <span class="token return-type class-name">MethodInfo</span> MethodInformation <span class="token punctuation">{</span> <span class="token keyword">get</span><span class="token punctuation">;</span> <span class="token keyword">private</span> <span class="token keyword">set</span><span class="token punctuation">;</span> <span class="token punctuation">}</span><br /> <br /> <span class="token keyword">public</span> <span class="token keyword">virtual</span> <span class="token return-type class-name">Exception</span> Exception <span class="token punctuation">{</span> <span class="token keyword">get</span><span class="token punctuation">;</span> <span class="token keyword">set</span><span class="token punctuation">;</span> <span class="token punctuation">}</span><br /> <br /> <span class="token preprocessor property">#<span class="token directive keyword">endregion</span></span><br /> <span class="token punctuation">}</span><br /> <span class="token punctuation">}</span></code></pre>
<p>This class simply stores the method information and the result for an individual test and can export that data it to a string later. That's it. With these four classes, we have our set of classes for finding tests to run, running them, and storing the results. That just leaves us with assertions and exceptions. Assertions are simply predicates that should be true at a specific position in our code. Which really just means they're a set of functions that determine if something is truly in the state that we're expecting. In some systems like nUnit, there's like 60 of these functions (most are overloaded versions of themselves). In xUnit, there's much fewer (mostly because they use generics, etc. to achieve the same things). In our case we're going to use the xUnit style (in fact many of them are the same name and look about the same, because... Well... There's not much to them really). Anyway, let's take a look at a couple:</p>
<pre class="language-csharp"><code class="language-csharp"> <span class="token preprocessor property">#<span class="token directive keyword">region</span> Usings</span><br /> <span class="token keyword">using</span> <span class="token namespace">System</span><span class="token punctuation">;</span><br /> <span class="token keyword">using</span> <span class="token namespace">System<span class="token punctuation">.</span>Collections<span class="token punctuation">.</span>Generic</span><span class="token punctuation">;</span><br /> <span class="token keyword">using</span> <span class="token namespace">System<span class="token punctuation">.</span>Linq</span><span class="token punctuation">;</span><br /> <span class="token keyword">using</span> <span class="token namespace">System<span class="token punctuation">.</span>Text</span><span class="token punctuation">;</span><br /> <span class="token keyword">using</span> <span class="token namespace">MoonUnit<span class="token punctuation">.</span>Exceptions</span><span class="token punctuation">;</span><br /> <span class="token keyword">using</span> <span class="token namespace">System<span class="token punctuation">.</span>Collections</span><span class="token punctuation">;</span><br /> <span class="token keyword">using</span> <span class="token namespace">System<span class="token punctuation">.</span>Text<span class="token punctuation">.</span>RegularExpressions</span><span class="token punctuation">;</span><br /> <span class="token preprocessor property">#<span class="token directive keyword">endregion</span></span><br /> <br /> <span class="token keyword">namespace</span> <span class="token namespace">MoonUnit</span><br /> <span class="token punctuation">{</span><br /> <span class="token comment">/// <summary></span><br /> <span class="token comment">/// Used to make assertions</span><br /> <span class="token comment">/// </summary></span><br /> <span class="token keyword">public</span> <span class="token keyword">static</span> <span class="token keyword">class</span> <span class="token class-name">Assert</span><br /> <span class="token punctuation">{</span><br /> <span class="token preprocessor property">#<span class="token directive keyword">region</span> Functions</span><br /> <br /> <span class="token preprocessor property">#<span class="token directive keyword">region</span> DoesNotThrow</span><br /> <br /> <span class="token comment">/// <summary></span><br /> <span class="token comment">/// Used when a specific type of exception is not expected</span><br /> <span class="token comment">/// </summary></span><br /> <span class="token comment">/// <typeparam name="T">Type of the exception</typeparam></span><br /> <span class="token comment">/// <param name="Delegate">Delegate called to test</param></span><br /> <span class="token comment">/// <param name="UserFailedMessage">Message passed to the output in the case of a failed test</param></span><br /> <span class="token keyword">public</span> <span class="token keyword">static</span> <span class="token return-type class-name"><span class="token keyword">void</span></span> <span class="token generic-method"><span class="token function">DoesNotThrow</span><span class="token generic class-name"><span class="token punctuation"><</span>T<span class="token punctuation">></span></span></span><span class="token punctuation">(</span><span class="token class-name">VoidDelegate</span> Delegate<span class="token punctuation">,</span> <span class="token class-name"><span class="token keyword">string</span></span> UserFailedMessage <span class="token operator">=</span> <span class="token string">"Assert.DoesNotThrow<T>() Failed"</span><span class="token punctuation">)</span><br /> <span class="token punctuation">{</span><br /> <span class="token keyword">try</span><br /> <span class="token punctuation">{</span><br /> <span class="token function">Delegate</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">;</span><br /> <span class="token punctuation">}</span><br /> <span class="token keyword">catch</span> <span class="token punctuation">(</span><span class="token class-name">Exception</span> e<span class="token punctuation">)</span><br /> <span class="token punctuation">{</span><br /> <span class="token keyword">if</span> <span class="token punctuation">(</span>e <span class="token keyword">is</span> <span class="token class-name">T</span><span class="token punctuation">)</span><br /> <span class="token keyword">throw</span> <span class="token keyword">new</span> <span class="token constructor-invocation class-name">DoesNotThrow</span><span class="token punctuation">(</span><span class="token keyword">typeof</span><span class="token punctuation">(</span><span class="token type-expression class-name">T</span><span class="token punctuation">)</span><span class="token punctuation">,</span> e<span class="token punctuation">,</span> UserFailedMessage<span class="token punctuation">)</span><span class="token punctuation">;</span><br /> <span class="token punctuation">}</span><br /> <span class="token punctuation">}</span><br /> <br /> <span class="token comment">/// <summary></span><br /> <span class="token comment">/// Used when a specific type of exception is not expected and a return value is expected when it does not occur.</span><br /> <span class="token comment">/// </summary></span><br /> <span class="token comment">/// <typeparam name="T">Exception type</typeparam></span><br /> <span class="token comment">/// <typeparam name="R">Return type</typeparam></span><br /> <span class="token comment">/// <param name="Delegate">Delegate that returns a value</param></span><br /> <span class="token comment">/// <param name="UserFailedMessage">Message passed to the output in the case of a failed test</param></span><br /> <span class="token comment">/// <returns>Returns the value returned by the delegate or thw appropriate exception</returns></span><br /> <span class="token keyword">public</span> <span class="token keyword">static</span> <span class="token return-type class-name">R</span> <span class="token generic-method"><span class="token function">DoesNotThrow</span><span class="token generic class-name"><span class="token punctuation"><</span>T<span class="token punctuation">,</span> R<span class="token punctuation">></span></span></span><span class="token punctuation">(</span><span class="token class-name">ReturnObjectDelegate<span class="token punctuation"><</span>R<span class="token punctuation">></span></span> Delegate<span class="token punctuation">,</span> <span class="token class-name"><span class="token keyword">string</span></span> UserFailedMessage <span class="token operator">=</span> <span class="token string">"Assert.DoesNotThrow<T,R>() Failed"</span><span class="token punctuation">)</span><br /> <span class="token punctuation">{</span><br /> <span class="token keyword">try</span><br /> <span class="token punctuation">{</span><br /> <span class="token keyword">return</span> <span class="token function">Delegate</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">;</span><br /> <span class="token punctuation">}</span><br /> <span class="token keyword">catch</span> <span class="token punctuation">(</span><span class="token class-name">Exception</span> e<span class="token punctuation">)</span><br /> <span class="token punctuation">{</span><br /> <span class="token keyword">if</span> <span class="token punctuation">(</span>e <span class="token keyword">is</span> <span class="token class-name">T</span><span class="token punctuation">)</span><br /> <span class="token keyword">throw</span> <span class="token keyword">new</span> <span class="token constructor-invocation class-name">DoesNotThrow</span><span class="token punctuation">(</span><span class="token keyword">typeof</span><span class="token punctuation">(</span><span class="token type-expression class-name">T</span><span class="token punctuation">)</span><span class="token punctuation">,</span> e<span class="token punctuation">,</span> UserFailedMessage<span class="token punctuation">)</span><span class="token punctuation">;</span><br /> <span class="token punctuation">}</span><br /> <span class="token keyword">return</span> <span class="token keyword">default</span><span class="token punctuation">(</span><span class="token type-expression class-name">R</span><span class="token punctuation">)</span><span class="token punctuation">;</span><br /> <span class="token punctuation">}</span><br /> <br /> <span class="token preprocessor property">#<span class="token directive keyword">endregion</span></span><br /> <br /> <span class="token preprocessor property">#<span class="token directive keyword">region</span> Empty</span><br /> <br /> <span class="token comment">/// <summary></span><br /> <span class="token comment">/// Determines if an IEnumerable is empty or not</span><br /> <span class="token comment">/// </summary></span><br /> <span class="token comment">/// <param name="Collection">Collection to check</param></span><br /> <span class="token comment">/// <param name="UserFailedMessage">Message passed to the output in the case of a failed test</param></span><br /> <span class="token keyword">public</span> <span class="token keyword">static</span> <span class="token return-type class-name"><span class="token keyword">void</span></span> <span class="token function">Empty</span><span class="token punctuation">(</span><span class="token class-name">IEnumerable</span> Collection<span class="token punctuation">,</span> <span class="token class-name"><span class="token keyword">string</span></span> UserFailedMessage <span class="token operator">=</span> <span class="token string">"Assert.Empty() Failed"</span><span class="token punctuation">)</span><br /> <span class="token punctuation">{</span><br /> <span class="token keyword">if</span> <span class="token punctuation">(</span>Collection <span class="token operator">==</span> <span class="token keyword">null</span><span class="token punctuation">)</span><br /> <span class="token keyword">throw</span> <span class="token keyword">new</span> <span class="token constructor-invocation class-name">ArgumentNullException</span><span class="token punctuation">(</span><span class="token string">"Collection"</span><span class="token punctuation">)</span><span class="token punctuation">;</span><br /> <span class="token keyword">foreach</span> <span class="token punctuation">(</span><span class="token class-name"><span class="token keyword">object</span></span> Object <span class="token keyword">in</span> Collection<span class="token punctuation">)</span><br /> <span class="token keyword">throw</span> <span class="token keyword">new</span> <span class="token constructor-invocation class-name">NotEmpty</span><span class="token punctuation">(</span>Collection<span class="token punctuation">,</span>UserFailedMessage<span class="token punctuation">)</span><span class="token punctuation">;</span><br /> <span class="token punctuation">}</span><br /> <br /> <span class="token preprocessor property">#<span class="token directive keyword">endregion</span></span><br /> <br /> <span class="token preprocessor property">#<span class="token directive keyword">region</span> Equal</span><br /> <br /> <span class="token comment">/// <summary></span><br /> <span class="token comment">/// Determines if two objects are equal</span><br /> <span class="token comment">/// </summary></span><br /> <span class="token comment">/// <typeparam name="T">Object type</typeparam></span><br /> <span class="token comment">/// <param name="Expected">Expected result</param></span><br /> <span class="token comment">/// <param name="Result">Actual result</param></span><br /> <span class="token comment">/// <param name="UserFailedMessage">Message passed to the output in the case of a failed test</param></span><br /> <span class="token keyword">public</span> <span class="token keyword">static</span> <span class="token return-type class-name"><span class="token keyword">void</span></span> <span class="token generic-method"><span class="token function">Equal</span><span class="token generic class-name"><span class="token punctuation"><</span>T<span class="token punctuation">></span></span></span><span class="token punctuation">(</span><span class="token class-name">T</span> Expected<span class="token punctuation">,</span> <span class="token class-name">T</span> Result<span class="token punctuation">,</span><span class="token class-name"><span class="token keyword">string</span></span> UserFailedMessage<span class="token operator">=</span><span class="token string">"Assert.Equal() Failed"</span><span class="token punctuation">)</span><br /> <span class="token punctuation">{</span><br /> <span class="token function">Equal</span><span class="token punctuation">(</span>Expected<span class="token punctuation">,</span> Result<span class="token punctuation">,</span> <span class="token keyword">new</span> <span class="token constructor-invocation class-name">InternalClasses<span class="token punctuation">.</span>EqualityComparer<span class="token punctuation"><</span>T<span class="token punctuation">></span></span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">,</span> UserFailedMessage<span class="token punctuation">)</span><span class="token punctuation">;</span><br /> <span class="token punctuation">}</span><br /> <br /> <span class="token comment">/// <summary></span><br /> <span class="token comment">/// Determines if two objects are equal</span><br /> <span class="token comment">/// </summary></span><br /> <span class="token comment">/// <typeparam name="T">Object type</typeparam></span><br /> <span class="token comment">/// <param name="Expected">Expected result</param></span><br /> <span class="token comment">/// <param name="Result">Actual result</param></span><br /> <span class="token comment">/// <param name="Comparer">Comparer used to compare the objects</param></span><br /> <span class="token comment">/// <param name="UserFailedMessage">Message passed to the output in the case of a failed test</param></span><br /> <span class="token keyword">public</span> <span class="token keyword">static</span> <span class="token return-type class-name"><span class="token keyword">void</span></span> <span class="token generic-method"><span class="token function">Equal</span><span class="token generic class-name"><span class="token punctuation"><</span>T<span class="token punctuation">></span></span></span><span class="token punctuation">(</span><span class="token class-name">T</span> Expected<span class="token punctuation">,</span> <span class="token class-name">T</span> Result<span class="token punctuation">,</span> <span class="token class-name">IEqualityComparer<span class="token punctuation"><</span>T<span class="token punctuation">></span></span> Comparer<span class="token punctuation">,</span> <span class="token class-name"><span class="token keyword">string</span></span> UserFailedMessage <span class="token operator">=</span> <span class="token string">"Assert.Equal() Failed"</span><span class="token punctuation">)</span><br /> <span class="token punctuation">{</span><br /> <span class="token keyword">if</span> <span class="token punctuation">(</span><span class="token operator">!</span>Comparer<span class="token punctuation">.</span><span class="token function">Equals</span><span class="token punctuation">(</span>Expected<span class="token punctuation">,</span> Result<span class="token punctuation">)</span><span class="token punctuation">)</span><br /> <span class="token keyword">throw</span> <span class="token keyword">new</span> <span class="token constructor-invocation class-name">NotEqual</span><span class="token punctuation">(</span>Expected<span class="token punctuation">,</span> Result<span class="token punctuation">,</span> UserFailedMessage<span class="token punctuation">)</span><span class="token punctuation">;</span><br /> <span class="token punctuation">}</span><br /> <br /> <span class="token preprocessor property">#<span class="token directive keyword">endregion</span></span><br /> <br /> <span class="token preprocessor property">#<span class="token directive keyword">region</span> False</span><br /> <br /> <span class="token comment">/// <summary></span><br /> <span class="token comment">/// Determins if something is false</span><br /> <span class="token comment">/// </summary></span><br /> <span class="token comment">/// <param name="Value">Value</param></span><br /> <span class="token comment">/// <param name="UserFailedMessage">Message passed to the output in the case of a failed test</param></span><br /> <span class="token keyword">public</span> <span class="token keyword">static</span> <span class="token return-type class-name"><span class="token keyword">void</span></span> <span class="token function">False</span><span class="token punctuation">(</span><span class="token class-name"><span class="token keyword">bool</span></span> Value<span class="token punctuation">,</span> <span class="token class-name"><span class="token keyword">string</span></span> UserFailedMessage <span class="token operator">=</span> <span class="token string">"Assert.False() Failed"</span><span class="token punctuation">)</span><br /> <span class="token punctuation">{</span><br /> <span class="token keyword">if</span> <span class="token punctuation">(</span>Value<span class="token punctuation">)</span><br /> <span class="token keyword">throw</span> <span class="token keyword">new</span> <span class="token constructor-invocation class-name">NotFalse</span><span class="token punctuation">(</span>UserFailedMessage<span class="token punctuation">)</span><span class="token punctuation">;</span><br /> <span class="token punctuation">}</span><br /> <br /> <span class="token preprocessor property">#<span class="token directive keyword">endregion</span></span><br /> <br /> <span class="token preprocessor property">#<span class="token directive keyword">endregion</span></span><br /> <span class="token punctuation">}</span><br /> <span class="token punctuation">}</span></code></pre>
<p>The code above only contains four of the assertions that I've added to the system. Anyway, the basic Assert class is static with a number of static functions. In this case we're looking at DoesNotThrow, Empty, Equal, and False. DoesNotThrow takes in a delegate, which it calls, and sees if it throws a specific error, the Empty function just checks if an IEnumerable is empty (not null, but empty), the equal function checks if two items are equal using an IEqualityComparer, and False just checks if a boolean value is false. Every single assertion is like this, very simple, maybe 5 lines of code, and that's it. The Equals function (and others like it) are a bit more complex as you need to write an IEqualityComparer but I've written one that the system will use by default:</p>
<pre class="language-csharp"><code class="language-csharp"> <span class="token preprocessor property">#<span class="token directive keyword">region</span> Usings</span><br /> <span class="token keyword">using</span> <span class="token namespace">System</span><span class="token punctuation">;</span><br /> <span class="token keyword">using</span> <span class="token namespace">System<span class="token punctuation">.</span>Collections<span class="token punctuation">.</span>Generic</span><span class="token punctuation">;</span><br /> <span class="token keyword">using</span> <span class="token namespace">System<span class="token punctuation">.</span>Linq</span><span class="token punctuation">;</span><br /> <span class="token keyword">using</span> <span class="token namespace">System<span class="token punctuation">.</span>Text</span><span class="token punctuation">;</span><br /> <span class="token keyword">using</span> <span class="token namespace">MoonUnit<span class="token punctuation">.</span>Exceptions</span><span class="token punctuation">;</span><br /> <span class="token keyword">using</span> <span class="token namespace">System<span class="token punctuation">.</span>Reflection</span><span class="token punctuation">;</span><br /> <span class="token keyword">using</span> <span class="token namespace">System<span class="token punctuation">.</span>Collections</span><span class="token punctuation">;</span><br /> <span class="token preprocessor property">#<span class="token directive keyword">endregion</span></span><br /> <br /> <span class="token keyword">namespace</span> <span class="token namespace">MoonUnit<span class="token punctuation">.</span>InternalClasses</span><br /> <span class="token punctuation">{</span><br /> <span class="token comment">/// <summary></span><br /> <span class="token comment">/// Internal equality comparer</span><br /> <span class="token comment">/// </summary></span><br /> <span class="token comment">/// <typeparam name="T">Data type</typeparam></span><br /> <span class="token keyword">internal</span> <span class="token keyword">class</span> <span class="token class-name">EqualityComparer<span class="token punctuation"><</span>T<span class="token punctuation">></span></span><span class="token punctuation">:</span><span class="token type-list"><span class="token class-name">IEqualityComparer<span class="token punctuation"><</span>T<span class="token punctuation">></span></span></span><br /> <span class="token punctuation">{</span><br /> <span class="token preprocessor property">#<span class="token directive keyword">region</span> Functions</span><br /> <br /> <span class="token keyword">public</span> <span class="token return-type class-name"><span class="token keyword">bool</span></span> <span class="token function">Equals</span><span class="token punctuation">(</span><span class="token class-name">T</span> x<span class="token punctuation">,</span> <span class="token class-name">T</span> y<span class="token punctuation">)</span><br /> <span class="token punctuation">{</span><br /> <span class="token keyword">if</span> <span class="token punctuation">(</span><span class="token operator">!</span><span class="token keyword">typeof</span><span class="token punctuation">(</span><span class="token type-expression class-name">T</span><span class="token punctuation">)</span><span class="token punctuation">.</span>IsValueType<br /> <span class="token operator">||</span> <span class="token punctuation">(</span><span class="token keyword">typeof</span><span class="token punctuation">(</span><span class="token type-expression class-name">T</span><span class="token punctuation">)</span><span class="token punctuation">.</span>IsGenericType<br /> <span class="token operator">&&</span> <span class="token keyword">typeof</span><span class="token punctuation">(</span><span class="token type-expression class-name">T</span><span class="token punctuation">)</span><span class="token punctuation">.</span><span class="token function">GetGenericTypeDefinition</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">.</span><span class="token function">IsAssignableFrom</span><span class="token punctuation">(</span><span class="token keyword">typeof</span><span class="token punctuation">(</span><span class="token type-expression class-name">Nullable<span class="token punctuation"><</span><span class="token punctuation">></span></span><span class="token punctuation">)</span><span class="token punctuation">)</span><span class="token punctuation">)</span><span class="token punctuation">)</span><br /> <span class="token punctuation">{</span><br /> <span class="token keyword">if</span> <span class="token punctuation">(</span>Object<span class="token punctuation">.</span><span class="token function">Equals</span><span class="token punctuation">(</span>x<span class="token punctuation">,</span> <span class="token keyword">default</span><span class="token punctuation">(</span><span class="token type-expression class-name">T</span><span class="token punctuation">)</span><span class="token punctuation">)</span><span class="token punctuation">)</span><br /> <span class="token keyword">return</span> Object<span class="token punctuation">.</span><span class="token function">Equals</span><span class="token punctuation">(</span>y<span class="token punctuation">,</span> <span class="token keyword">default</span><span class="token punctuation">(</span><span class="token type-expression class-name">T</span><span class="token punctuation">)</span><span class="token punctuation">)</span><span class="token punctuation">;</span><br /> <span class="token keyword">if</span> <span class="token punctuation">(</span>Object<span class="token punctuation">.</span><span class="token function">Equals</span><span class="token punctuation">(</span>y<span class="token punctuation">,</span> <span class="token keyword">default</span><span class="token punctuation">(</span><span class="token type-expression class-name">T</span><span class="token punctuation">)</span><span class="token punctuation">)</span><span class="token punctuation">)</span><br /> <span class="token keyword">return</span> <span class="token boolean">false</span><span class="token punctuation">;</span><br /> <span class="token punctuation">}</span><br /> <span class="token keyword">if</span> <span class="token punctuation">(</span>x<span class="token punctuation">.</span><span class="token function">GetType</span><span class="token punctuation">(</span><span class="token punctuation">)</span> <span class="token operator">!=</span> y<span class="token punctuation">.</span><span class="token function">GetType</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">)</span><br /> <span class="token keyword">return</span> <span class="token boolean">false</span><span class="token punctuation">;</span><br /> <span class="token keyword">if</span> <span class="token punctuation">(</span>x <span class="token keyword">is</span> <span class="token class-name">IEnumerable</span> <span class="token operator">&&</span> y <span class="token keyword">is</span> <span class="token class-name">IEnumerable</span><span class="token punctuation">)</span><br /> <span class="token punctuation">{</span><br /> <span class="token class-name">EqualityComparer<span class="token punctuation"><</span><span class="token keyword">object</span>\<span class="token punctuation">></span></span> Comparer <span class="token operator">=</span> <span class="token keyword">new</span> <span class="token constructor-invocation class-name">EqualityComparer<span class="token punctuation"><</span><span class="token keyword">object</span>\<span class="token punctuation">></span></span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">;</span><br /> <span class="token class-name">IEnumerator</span> XEnumerator <span class="token operator">=</span> <span class="token punctuation">(</span><span class="token punctuation">(</span>IEnumerable<span class="token punctuation">)</span>x<span class="token punctuation">)</span><span class="token punctuation">.</span><span class="token function">GetEnumerator</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">;</span><br /> <span class="token class-name">IEnumerator</span> YEnumerator <span class="token operator">=</span> <span class="token punctuation">(</span><span class="token punctuation">(</span>IEnumerable<span class="token punctuation">)</span>y<span class="token punctuation">)</span><span class="token punctuation">.</span><span class="token function">GetEnumerator</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">;</span><br /> <span class="token keyword">while</span> <span class="token punctuation">(</span><span class="token boolean">true</span><span class="token punctuation">)</span><br /> <span class="token punctuation">{</span><br /> <span class="token class-name"><span class="token keyword">bool</span></span> XFinished <span class="token operator">=</span> <span class="token operator">!</span>XEnumerator<span class="token punctuation">.</span><span class="token function">MoveNext</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">;</span><br /> <span class="token class-name"><span class="token keyword">bool</span></span> YFinished <span class="token operator">=</span> <span class="token operator">!</span>YEnumerator<span class="token punctuation">.</span><span class="token function">MoveNext</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">;</span><br /> <span class="token keyword">if</span> <span class="token punctuation">(</span>XFinished <span class="token operator">||</span> YFinished<span class="token punctuation">)</span><br /> <span class="token keyword">return</span> XFinished <span class="token operator">&</span> YFinished<span class="token punctuation">;</span><br /> <span class="token keyword">if</span> <span class="token punctuation">(</span><span class="token operator">!</span>Comparer<span class="token punctuation">.</span><span class="token function">Equals</span><span class="token punctuation">(</span>XEnumerator<span class="token punctuation">.</span>Current<span class="token punctuation">,</span> YEnumerator<span class="token punctuation">.</span>Current<span class="token punctuation">)</span><span class="token punctuation">)</span><br /> <span class="token keyword">return</span> <span class="token boolean">false</span><span class="token punctuation">;</span><br /> <span class="token punctuation">}</span><br /> <span class="token punctuation">}</span><br /> <span class="token keyword">if</span> <span class="token punctuation">(</span>x <span class="token keyword">is</span> <span class="token class-name">IEquatable<span class="token punctuation"><</span>T<span class="token punctuation">></span></span><span class="token punctuation">)</span><br /> <span class="token keyword">return</span> <span class="token punctuation">(</span><span class="token punctuation">(</span>IEquatable<span class="token operator"><</span>T<span class="token operator">></span><span class="token punctuation">)</span>x<span class="token punctuation">)</span><span class="token punctuation">.</span><span class="token function">Equals</span><span class="token punctuation">(</span>y<span class="token punctuation">)</span><span class="token punctuation">;</span><br /> <span class="token keyword">if</span> <span class="token punctuation">(</span>x <span class="token keyword">is</span> <span class="token class-name">IComparable<span class="token punctuation"><</span>T<span class="token punctuation">></span></span><span class="token punctuation">)</span><br /> <span class="token keyword">return</span> <span class="token punctuation">(</span><span class="token punctuation">(</span>IComparable<span class="token operator"><</span>T<span class="token operator">></span><span class="token punctuation">)</span>x<span class="token punctuation">)</span><span class="token punctuation">.</span><span class="token function">CompareTo</span><span class="token punctuation">(</span>y<span class="token punctuation">)</span> <span class="token operator">==</span> <span class="token number">0</span><span class="token punctuation">;</span><br /> <span class="token keyword">if</span> <span class="token punctuation">(</span>x <span class="token keyword">is</span> <span class="token class-name">IComparable</span><span class="token punctuation">)</span><br /> <span class="token keyword">return</span> <span class="token punctuation">(</span><span class="token punctuation">(</span>IComparable<span class="token punctuation">)</span>x<span class="token punctuation">)</span><span class="token punctuation">.</span><span class="token function">CompareTo</span><span class="token punctuation">(</span>y<span class="token punctuation">)</span> <span class="token operator">==</span> <span class="token number">0</span><span class="token punctuation">;</span><br /> <span class="token keyword">return</span> x<span class="token punctuation">.</span><span class="token function">Equals</span><span class="token punctuation">(</span>y<span class="token punctuation">)</span><span class="token punctuation">;</span><br /> <span class="token punctuation">}</span><br /> <br /> <span class="token keyword">public</span> <span class="token return-type class-name"><span class="token keyword">int</span></span> <span class="token function">GetHashCode</span><span class="token punctuation">(</span><span class="token class-name">T</span> obj<span class="token punctuation">)</span><br /> <span class="token punctuation">{</span><br /> <span class="token keyword">throw</span> <span class="token keyword">new</span> <span class="token constructor-invocation class-name">NotImplementedException</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">;</span><br /> <span class="token punctuation">}</span><br /> <br /> <span class="token preprocessor property">#<span class="token directive keyword">endregion</span></span><br /> <span class="token punctuation">}</span><br /> <span class="token punctuation">}</span></code></pre>
<p>Oh and if you're at all experienced with xUnit's code base, it's pretty much the same as the one they use. Slightly different but there's only so many ways to write these things. Anyway, if you look at the code, if the assertion fails you will notice that it throws an exception. These exceptions use the following base class:</p>
<pre class="language-csharp"><code class="language-csharp"> <span class="token preprocessor property">#<span class="token directive keyword">region</span> Usings</span><br /> <span class="token keyword">using</span> <span class="token namespace">System</span><span class="token punctuation">;</span><br /> <span class="token keyword">using</span> <span class="token namespace">System<span class="token punctuation">.</span>Collections<span class="token punctuation">.</span>Generic</span><span class="token punctuation">;</span><br /> <span class="token keyword">using</span> <span class="token namespace">System<span class="token punctuation">.</span>Linq</span><span class="token punctuation">;</span><br /> <span class="token keyword">using</span> <span class="token namespace">System<span class="token punctuation">.</span>Text</span><span class="token punctuation">;</span><br /> <span class="token preprocessor property">#<span class="token directive keyword">endregion</span></span><br /> <br /> <span class="token keyword">namespace</span> <span class="token namespace">MoonUnit<span class="token punctuation">.</span>BaseClasses</span><br /> <span class="token punctuation">{</span><br /> <span class="token comment">/// <summary></span><br /> <span class="token comment">/// Base exception class</span><br /> <span class="token comment">/// </summary></span><br /> <span class="token keyword">public</span> <span class="token keyword">class</span> <span class="token class-name">BaseException</span><span class="token punctuation">:</span><span class="token type-list"><span class="token class-name">Exception</span></span><br /> <span class="token punctuation">{</span><br /> <span class="token preprocessor property">#<span class="token directive keyword">region</span> Constructor</span><br /> <br /> <span class="token comment">/// <summary></span><br /> <span class="token comment">/// Constructor</span><br /> <span class="token comment">/// </summary></span><br /> <span class="token comment">/// <param name="ExceptionText">Exception Text</param></span><br /> <span class="token comment">/// <param name="Expected">Expected value</param></span><br /> <span class="token comment">/// <param name="Result">Actual result</param></span><br /> <span class="token keyword">public</span> <span class="token function">BaseException</span><span class="token punctuation">(</span><span class="token class-name"><span class="token keyword">object</span></span> Expected<span class="token punctuation">,</span> <span class="token class-name"><span class="token keyword">object</span></span> Result<span class="token punctuation">,</span><span class="token class-name"><span class="token keyword">string</span></span> ExceptionText<span class="token punctuation">)</span><br /> <span class="token punctuation">:</span> <span class="token keyword">base</span><span class="token punctuation">(</span>ExceptionText<span class="token punctuation">)</span><br /> <span class="token punctuation">{</span><br /> <span class="token keyword">this</span><span class="token punctuation">.</span>Expected <span class="token operator">=</span> Expected<span class="token punctuation">;</span><br /> <span class="token keyword">this</span><span class="token punctuation">.</span>Result <span class="token operator">=</span> Result<span class="token punctuation">;</span><br /> <span class="token punctuation">}</span><br /> <br /> <span class="token preprocessor property">#<span class="token directive keyword">endregion</span></span><br /> <br /> <span class="token preprocessor property">#<span class="token directive keyword">region</span> Properties</span><br /> <br /> <span class="token comment">/// <summary></span><br /> <span class="token comment">/// Expected result</span><br /> <span class="token comment">/// </summary></span><br /> <span class="token keyword">public</span> <span class="token keyword">virtual</span> <span class="token return-type class-name"><span class="token keyword">object</span></span> Expected <span class="token punctuation">{</span> <span class="token keyword">get</span><span class="token punctuation">;</span> <span class="token keyword">private</span> <span class="token keyword">set</span><span class="token punctuation">;</span> <span class="token punctuation">}</span><br /> <br /> <span class="token comment">/// <summary></span><br /> <span class="token comment">/// Actual result</span><br /> <span class="token comment">/// </summary></span><br /> <span class="token keyword">public</span> <span class="token keyword">virtual</span> <span class="token return-type class-name"><span class="token keyword">object</span></span> Result <span class="token punctuation">{</span> <span class="token keyword">get</span><span class="token punctuation">;</span> <span class="token keyword">private</span> <span class="token keyword">set</span><span class="token punctuation">;</span> <span class="token punctuation">}</span><br /> <br /> <span class="token preprocessor property">#<span class="token directive keyword">endregion</span></span><br /> <br /> <span class="token preprocessor property">#<span class="token directive keyword">region</span> Functions</span><br /> <br /> <span class="token keyword">public</span> <span class="token keyword">override</span> <span class="token return-type class-name"><span class="token keyword">string</span></span> <span class="token function">ToString</span><span class="token punctuation">(</span><span class="token punctuation">)</span><br /> <span class="token punctuation">{</span><br /> <span class="token class-name">StringBuilder</span> Builder <span class="token operator">=</span> <span class="token keyword">new</span> <span class="token constructor-invocation class-name">StringBuilder</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">;</span><br /> Builder<span class="token punctuation">.</span><span class="token function">Append</span><span class="token punctuation">(</span><span class="token keyword">string</span><span class="token punctuation">.</span><span class="token function">Format</span><span class="token punctuation">(</span><span class="token string">"<Expected>{0}</Expected><Result>{1}</Result><ErrorText>{2}</ErrorText><Trace>{3}</Trace><ErrorType>{4}</ErrorType>"</span><span class="token punctuation">,</span><br /> Expected<span class="token punctuation">,</span> <br /> Result<span class="token punctuation">,</span> <br /> <span class="token keyword">this</span><span class="token punctuation">.</span>Message<span class="token punctuation">,</span> <br /> <span class="token keyword">this</span><span class="token punctuation">.</span>StackTrace<span class="token punctuation">,</span><br /> <span class="token keyword">this</span><span class="token punctuation">.</span><span class="token function">GetType</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">.</span>Name<span class="token punctuation">)</span><span class="token punctuation">)</span><span class="token punctuation">;</span><br /> <span class="token keyword">return</span> Builder<span class="token punctuation">.</span><span class="token function">ToString</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">;</span><br /> <span class="token punctuation">}</span><br /> <br /> <span class="token preprocessor property">#<span class="token directive keyword">endregion</span></span><br /> <span class="token punctuation">}</span><br /> <span class="token punctuation">}</span></code></pre>
<p>The exception base class just takes in the expected value and the result and spits out the result to text when ToString is called. Fairly simple. An an example of an exception class would look like this:</p>
<pre class="language-csharp"><code class="language-csharp"> <span class="token preprocessor property">#<span class="token directive keyword">region</span> Usings</span><br /> <span class="token keyword">using</span> <span class="token namespace">System</span><span class="token punctuation">;</span><br /> <span class="token keyword">using</span> <span class="token namespace">System<span class="token punctuation">.</span>Collections<span class="token punctuation">.</span>Generic</span><span class="token punctuation">;</span><br /> <span class="token keyword">using</span> <span class="token namespace">System<span class="token punctuation">.</span>Linq</span><span class="token punctuation">;</span><br /> <span class="token keyword">using</span> <span class="token namespace">System<span class="token punctuation">.</span>Text</span><span class="token punctuation">;</span><br /> <span class="token keyword">using</span> <span class="token namespace">MoonUnit<span class="token punctuation">.</span>BaseClasses</span><span class="token punctuation">;</span><br /> <span class="token preprocessor property">#<span class="token directive keyword">endregion</span></span><br /> <br /> <span class="token keyword">namespace</span> <span class="token namespace">MoonUnit<span class="token punctuation">.</span>Exceptions</span><br /> <span class="token punctuation">{</span><br /> <span class="token comment">/// <summary></span><br /> <span class="token comment">/// Exception thrown if two items are equal</span><br /> <span class="token comment">/// </summary></span><br /> <span class="token keyword">public</span> <span class="token keyword">class</span> <span class="token class-name">Equal</span> <span class="token punctuation">:</span> <span class="token type-list"><span class="token class-name">BaseException</span></span><br /> <span class="token punctuation">{</span><br /> <span class="token preprocessor property">#<span class="token directive keyword">region</span> Constructor</span><br /> <br /> <span class="token comment">/// <summary></span><br /> <span class="token comment">/// Constructor</span><br /> <span class="token comment">/// </summary></span><br /> <span class="token comment">/// <param name="ExceptionText">Exception Text</param></span><br /> <span class="token comment">/// <param name="Expected">Expected value</param></span><br /> <span class="token comment">/// <param name="Result">Actual result</param></span><br /> <span class="token keyword">public</span> <span class="token function">Equal</span><span class="token punctuation">(</span><span class="token class-name"><span class="token keyword">object</span></span> Expected<span class="token punctuation">,</span> <span class="token class-name"><span class="token keyword">object</span></span> Result<span class="token punctuation">,</span><span class="token class-name"><span class="token keyword">string</span></span> ExceptionText<span class="token punctuation">)</span><br /> <span class="token punctuation">:</span> <span class="token keyword">base</span><span class="token punctuation">(</span>Expected<span class="token punctuation">,</span> Result<span class="token punctuation">,</span> ExceptionText<span class="token punctuation">)</span><br /> <span class="token punctuation">{</span><br /> <span class="token punctuation">}</span><br /> <br /> <span class="token preprocessor property">#<span class="token directive keyword">endregion</span></span><br /> <span class="token punctuation">}</span><br /> <span class="token punctuation">}</span></code></pre>
<p>The vast majority of the exception classes just look like that (note that the one above is actually thrown from the NotEqual function that I didn't show you and not the Equal function). So create about 20 assertions, have 20 exceptions that match up, and we're done. With this we can create a class library, have the system load it, look through for our tests and give us results in an XML doc. The only thing left is to write a front end of some description, but I'll leave that for part 2. Oh and if you've paid attention to the namespaces, yes, I have indeed named this thing MoonUnit, and yes I will be releasing this on Codeplex. Anyway, take a look, leave feedback, and happy coding.</p>
Creating iCalendar items in C#
2010-10-15T00:00:00Z
http://www.gutgames.com/post/Creating-iCalendar-Items-in-C/
<p>For a while now whenever I've needed to generate a calendar item, I've used my trusty <a href="http://cul.codeplex.com/SourceControl/changeset/view/62281#707825">vCalendar code</a>. The vCalendar format was simple, rather straightforward and up until recently, without too many faults. However I ran into a project where they wanted to embed html within the calendar item... You see one of the things about the vCalendar format is it can support Base64, 8bit, etc. in the description field but as far as I can tell there isn't any way to tell the client that the description is HTML. Even exporting an item from outlook seems to strip out any HTML that it finds (bullet points become *, etc.). So looking around I found out that you can embed it in an iCalendar item... Which is pretty much just vCalendar 2.0... So in other words it was simple to add to my existing code base:</p>
<pre class="language-csharp"><code class="language-csharp"> <span class="token operator">/</span>\<span class="token operator">*</span><br /> Copyright <span class="token punctuation">(</span>c<span class="token punctuation">)</span> <span class="token number">2010</span> <span class="token operator"><</span><span class="token class-name">a</span> href<span class="token operator">=</span><span class="token string">"http://www.gutgames.com"</span><span class="token operator">></span>James Craig<span class="token operator"><</span><span class="token operator">/</span>a<span class="token operator">></span><br /><br /> Permission <span class="token keyword">is</span> <span class="token class-name">hereby</span> granted<span class="token punctuation">,</span> free <span class="token class-name">of</span> charge<span class="token punctuation">,</span> to any person obtaining a copy<br /> of <span class="token keyword">this</span> software <span class="token keyword">and</span> associated <span class="token return-type class-name">documentation</span> files <span class="token punctuation">(</span>the <span class="token string">"Software"</span><span class="token punctuation">)</span><span class="token punctuation">,</span> <span class="token class-name">to</span> deal<br /> <span class="token keyword">in</span> the Software <span class="token class-name">without</span> restriction<span class="token punctuation">,</span> including without limitation the rights<br /> <span class="token class-name">to</span> use<span class="token punctuation">,</span> copy<span class="token punctuation">,</span> modify<span class="token punctuation">,</span> merge<span class="token punctuation">,</span> publish<span class="token punctuation">,</span> distribute<span class="token punctuation">,</span> sublicense<span class="token punctuation">,</span> <span class="token keyword">and</span><span class="token operator">/</span><span class="token keyword">or</span> sell<br /> copies of <span class="token class-name">the</span> Software<span class="token punctuation">,</span> <span class="token keyword">and</span> to permit persons to whom the Software <span class="token keyword">is</span><br /> <span class="token class-name">furnished</span> to <span class="token keyword">do</span> so<span class="token punctuation">,</span> subject to the <span class="token class-name">following</span> conditions<span class="token punctuation">:</span><br /><br /> The above copyright notice <span class="token keyword">and</span> <span class="token keyword">this</span> permission notice shall <span class="token class-name">be</span> included <span class="token keyword">in</span><br /> all copies <span class="token keyword">or</span> substantial portions of the Software<span class="token punctuation">.</span><br /><br /> THE SOFTWARE IS PROVIDED <span class="token string">"AS IS"</span><span class="token punctuation">,</span> WITHOUT WARRANTY OF <span class="token class-name">ANY</span> KIND<span class="token punctuation">,</span> EXPRESS <span class="token class-name">OR</span><br /> IMPLIED<span class="token punctuation">,</span> INCLUDING BUT NOT LIMITED TO THE WARRANTIES <span class="token class-name">OF</span> MERCHANTABILITY<span class="token punctuation">,</span><br /> FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT<span class="token punctuation">.</span> IN NO EVENT SHALL THE<br /> AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR <span class="token class-name">ANY</span> CLAIM<span class="token punctuation">,</span> DAMAGES OR <span class="token class-name">OTHER</span><br /> LIABILITY<span class="token punctuation">,</span> WHETHER IN AN ACTION <span class="token class-name">OF</span> CONTRACT<span class="token punctuation">,</span> TORT <span class="token class-name">OR</span> OTHERWISE<span class="token punctuation">,</span> <span class="token class-name">ARISING</span> FROM<span class="token punctuation">,</span><br /> OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN<br /> THE SOFTWARE<span class="token punctuation">.</span>\<span class="token operator">*</span><span class="token operator">/</span><br /> <br /> <br /> <br /> <span class="token preprocessor property">#<span class="token directive keyword">region</span> Usings</span><br /> <br /> <span class="token keyword">using</span> <span class="token namespace">System</span><span class="token punctuation">;</span><br /> <br /> <span class="token keyword">using</span> <span class="token namespace">System<span class="token punctuation">.</span>Text</span><span class="token punctuation">;</span><br /> <br /> <span class="token keyword">using</span> <span class="token namespace">System<span class="token punctuation">.</span>Text<span class="token punctuation">.</span>RegularExpressions</span><span class="token punctuation">;</span><br /> <br /> <span class="token preprocessor property">#<span class="token directive keyword">endregion</span></span><br /> <br /> <br /> <br /> <span class="token keyword">namespace</span> <span class="token namespace">Utilities<span class="token punctuation">.</span>FileFormats</span><br /> <br /> <span class="token punctuation">{</span><br /> <br /> <span class="token comment">/// <summary></span><br /> <br /> <span class="token comment">/// Creates a VCalendar item</span><br /> <br /> <span class="token comment">/// </summary></span><br /> <br /> <span class="token keyword">public</span> <span class="token keyword">class</span> <span class="token class-name">VCalendar</span><br /> <br /> <span class="token punctuation">{</span><br /> <br /> <span class="token preprocessor property">#<span class="token directive keyword">region</span> Constructors</span><br /> <br /> <br /> <br /> <span class="token comment">/// <summary></span><br /> <br /> <span class="token comment">/// Constructor</span><br /> <br /> <span class="token comment">/// </summary></span><br /> <br /> <span class="token keyword">public</span> <span class="token function">VCalendar</span><span class="token punctuation">(</span><span class="token punctuation">)</span><br /> <br /> <span class="token punctuation">{</span><br /> <br /> <span class="token punctuation">}</span><br /> <br /> <br /> <br /> <span class="token preprocessor property">#<span class="token directive keyword">endregion</span></span><br /> <br /> <br /> <br /> <span class="token preprocessor property">#<span class="token directive keyword">region</span> Properties</span><br /> <br /> <span class="token comment">/// <summary></span><br /> <br /> <span class="token comment">/// The time zone adjustment for the calendar event</span><br /> <br /> <span class="token comment">/// </summary></span><br /> <br /> <span class="token keyword">public</span> <span class="token return-type class-name"><span class="token keyword">int</span></span> TimeZoneAdjustment<span class="token punctuation">{</span><span class="token keyword">get</span><span class="token punctuation">;</span><span class="token keyword">set</span><span class="token punctuation">;</span><span class="token punctuation">}</span><br /> <br /> <br /> <br /> <span class="token comment">/// <summary></span><br /> <br /> <span class="token comment">/// The start time</span><br /> <br /> <span class="token comment">/// </summary></span><br /> <br /> <span class="token keyword">public</span> <span class="token return-type class-name">DateTime</span> StartTime<span class="token punctuation">{</span><span class="token keyword">get</span><span class="token punctuation">;</span><span class="token keyword">set</span><span class="token punctuation">;</span><span class="token punctuation">}</span><br /> <br /> <br /> <br /> <span class="token comment">/// <summary></span><br /> <br /> <span class="token comment">/// The end time</span><br /> <br /> <span class="token comment">/// </summary></span><br /> <br /> <span class="token keyword">public</span> <span class="token return-type class-name">DateTime</span> EndTime<span class="token punctuation">{</span><span class="token keyword">get</span><span class="token punctuation">;</span><span class="token keyword">set</span><span class="token punctuation">;</span><span class="token punctuation">}</span><br /> <br /> <br /> <br /> <span class="token comment">/// <summary></span><br /> <br /> <span class="token comment">/// The location of the event</span><br /> <br /> <span class="token comment">/// </summary></span><br /> <br /> <span class="token keyword">public</span> <span class="token return-type class-name"><span class="token keyword">string</span></span> Location<span class="token punctuation">{</span><span class="token keyword">get</span><span class="token punctuation">;</span><span class="token keyword">set</span><span class="token punctuation">;</span><span class="token punctuation">}</span><br /> <br /> <br /> <br /> <span class="token comment">/// <summary></span><br /> <br /> <span class="token comment">/// The subject of the item to send</span><br /> <br /> <span class="token comment">/// </summary></span><br /> <br /> <span class="token keyword">public</span> <span class="token return-type class-name"><span class="token keyword">string</span></span> Subject<span class="token punctuation">{</span><span class="token keyword">get</span><span class="token punctuation">;</span><span class="token keyword">set</span><span class="token punctuation">;</span><span class="token punctuation">}</span><br /> <br /> <br /> <br /> <span class="token comment">/// <summary></span><br /> <br /> <span class="token comment">/// The description of the event</span><br /> <br /> <span class="token comment">/// </summary></span><br /> <br /> <span class="token keyword">public</span> <span class="token return-type class-name"><span class="token keyword">string</span></span> Description<span class="token punctuation">{</span><span class="token keyword">get</span><span class="token punctuation">;</span><span class="token keyword">set</span><span class="token punctuation">;</span><span class="token punctuation">}</span><br /> <br /> <br /> <br /> <span class="token keyword">private</span> <span class="token keyword">static</span> <span class="token keyword">readonly</span> Regex STRIP\_HTML\_REGEX <span class="token operator">=</span> <span class="token keyword">new</span> <span class="token constructor-invocation class-name">Regex</span><span class="token punctuation">(</span><span class="token string">"<\[^>\]\*>"</span><span class="token punctuation">,</span> RegexOptions<span class="token punctuation">.</span>Compiled<span class="token punctuation">)</span><span class="token punctuation">;</span><br /> <br /> <br /> <br /> <span class="token preprocessor property">#<span class="token directive keyword">endregion</span></span><br /> <br /> <br /> <br /> <span class="token preprocessor property">#<span class="token directive keyword">region</span> Private Functions</span><br /> <br /> <br /> <br /> <span class="token keyword">private</span> <span class="token return-type class-name"><span class="token keyword">string</span></span> <span class="token function">StripHTML</span><span class="token punctuation">(</span><span class="token class-name"><span class="token keyword">string</span></span> HTML<span class="token punctuation">)</span><br /> <br /> <span class="token punctuation">{</span><br /> <br /> <span class="token keyword">try</span><br /> <br /> <span class="token punctuation">{</span><br /> <br /> <span class="token keyword">if</span> <span class="token punctuation">(</span><span class="token keyword">string</span><span class="token punctuation">.</span><span class="token function">IsNullOrEmpty</span><span class="token punctuation">(</span>HTML<span class="token punctuation">)</span><span class="token punctuation">)</span><br /> <br /> <span class="token keyword">return</span> <span class="token keyword">string</span><span class="token punctuation">.</span>Empty<span class="token punctuation">;</span><br /> <br /> <br /> <br /> HTML <span class="token operator">=</span> STRIP\_HTML\_REGEX<span class="token punctuation">.</span><span class="token function">Replace</span><span class="token punctuation">(</span>HTML<span class="token punctuation">,</span> <span class="token keyword">string</span><span class="token punctuation">.</span>Empty<span class="token punctuation">)</span><span class="token punctuation">;</span><br /> <br /> HTML <span class="token operator">=</span> HTML<span class="token punctuation">.</span><span class="token function">Replace</span><span class="token punctuation">(</span><span class="token string">"&nbsp;"</span><span class="token punctuation">,</span> <span class="token string">" "</span><span class="token punctuation">)</span><span class="token punctuation">;</span><br /> <br /> <span class="token keyword">return</span> HTML<span class="token punctuation">.</span><span class="token function">Replace</span><span class="token punctuation">(</span><span class="token string">"&#160;"</span><span class="token punctuation">,</span> <span class="token keyword">string</span><span class="token punctuation">.</span>Empty<span class="token punctuation">)</span><span class="token punctuation">;</span><br /> <br /> <span class="token punctuation">}</span><br /> <br /> <span class="token keyword">catch</span> <span class="token punctuation">{</span> <span class="token keyword">throw</span><span class="token punctuation">;</span> <span class="token punctuation">}</span><br /> <br /> <span class="token punctuation">}</span><br /> <br /> <br /> <br /> <span class="token keyword">private</span> <span class="token return-type class-name"><span class="token keyword">bool</span></span> <span class="token function">ContainsHTML</span><span class="token punctuation">(</span><span class="token class-name"><span class="token keyword">string</span></span> Input<span class="token punctuation">)</span><br /> <br /> <span class="token punctuation">{</span><br /> <br /> <span class="token keyword">try</span><br /> <br /> <span class="token punctuation">{</span><br /> <br /> <span class="token keyword">if</span> <span class="token punctuation">(</span><span class="token keyword">string</span><span class="token punctuation">.</span><span class="token function">IsNullOrEmpty</span><span class="token punctuation">(</span>Input<span class="token punctuation">)</span><span class="token punctuation">)</span><br /> <br /> <span class="token keyword">return</span> <span class="token boolean">false</span><span class="token punctuation">;</span><br /> <br /> <br /> <br /> <span class="token keyword">return</span> STRIP\_HTML\_REGEX<span class="token punctuation">.</span><span class="token function">IsMatch</span><span class="token punctuation">(</span>Input<span class="token punctuation">)</span><span class="token punctuation">;</span><br /> <br /> <span class="token punctuation">}</span><br /> <br /> <span class="token keyword">catch</span> <span class="token punctuation">{</span> <span class="token keyword">throw</span><span class="token punctuation">;</span> <span class="token punctuation">}</span><br /> <br /> <span class="token punctuation">}</span><br /> <br /> <br /> <br /> <span class="token preprocessor property">#<span class="token directive keyword">endregion</span></span><br /> <br /> <br /> <br /> <span class="token preprocessor property">#<span class="token directive keyword">region</span> Public Functions</span><br /> <br /> <br /> <br /> <span class="token comment">/// <summary></span><br /> <br /> <span class="token comment">/// Returns the VCalendar item</span><br /> <br /> <span class="token comment">/// </summary></span><br /> <br /> <span class="token comment">/// <returns>a string output of the VCalendar item</returns></span><br /> <br /> <span class="token keyword">public</span> <span class="token return-type class-name"><span class="token keyword">string</span></span> <span class="token function">GetVCalendar</span><span class="token punctuation">(</span><span class="token punctuation">)</span><br /> <br /> <span class="token punctuation">{</span><br /> <br /> <span class="token keyword">try</span><br /> <br /> <span class="token punctuation">{</span><br /> <br /> <span class="token class-name">StringBuilder</span> FileOutput <span class="token operator">=</span> <span class="token keyword">new</span> <span class="token constructor-invocation class-name">StringBuilder</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">;</span><br /> <br /> FileOutput<span class="token punctuation">.</span><span class="token function">AppendLine</span><span class="token punctuation">(</span><span class="token string">"BEGIN:VCALENDAR"</span><span class="token punctuation">)</span><span class="token punctuation">;</span><br /> <br /> FileOutput<span class="token punctuation">.</span><span class="token function">AppendLine</span><span class="token punctuation">(</span><span class="token string">"VERSION:1.0"</span><span class="token punctuation">)</span><span class="token punctuation">;</span><br /> <br /> FileOutput<span class="token punctuation">.</span><span class="token function">AppendLine</span><span class="token punctuation">(</span><span class="token string">"BEGIN:VEVENT"</span><span class="token punctuation">)</span><span class="token punctuation">;</span><br /> <br /> StartTime <span class="token operator">=</span> StartTime<span class="token punctuation">.</span><span class="token function">AddHours</span><span class="token punctuation">(</span><span class="token operator">-</span>TimeZoneAdjustment<span class="token punctuation">)</span><span class="token punctuation">;</span><br /> <br /> EndTime <span class="token operator">=</span> EndTime<span class="token punctuation">.</span><span class="token function">AddHours</span><span class="token punctuation">(</span><span class="token operator">-</span>TimeZoneAdjustment<span class="token punctuation">)</span><span class="token punctuation">;</span><br /> <br /> <br /> <br /> <span class="token class-name"><span class="token keyword">string</span></span> Start <span class="token operator">=</span> StartTime<span class="token punctuation">.</span><span class="token function">ToString</span><span class="token punctuation">(</span><span class="token string">"yyyyMMdd"</span><span class="token punctuation">)</span> <span class="token operator">+</span> <span class="token string">"T"</span> <span class="token operator">+</span> StartTime<span class="token punctuation">.</span><span class="token function">ToString</span><span class="token punctuation">(</span><span class="token string">"HHmmss"</span><span class="token punctuation">)</span><span class="token punctuation">;</span><br /> <br /> <span class="token class-name"><span class="token keyword">string</span></span> End <span class="token operator">=</span> EndTime<span class="token punctuation">.</span><span class="token function">ToString</span><span class="token punctuation">(</span><span class="token string">"yyyyMMdd"</span><span class="token punctuation">)</span> <span class="token operator">+</span> <span class="token string">"T"</span> <span class="token operator">+</span> EndTime<span class="token punctuation">.</span><span class="token function">ToString</span><span class="token punctuation">(</span><span class="token string">"HHmmss"</span><span class="token punctuation">)</span><span class="token punctuation">;</span><br /> <br /> FileOutput<span class="token punctuation">.</span><span class="token function">Append</span><span class="token punctuation">(</span><span class="token string">"DTStart:"</span><span class="token punctuation">)</span><span class="token punctuation">.</span><span class="token function">AppendLine</span><span class="token punctuation">(</span>Start<span class="token punctuation">)</span><span class="token punctuation">;</span><br /> <br /> FileOutput<span class="token punctuation">.</span><span class="token function">Append</span><span class="token punctuation">(</span><span class="token string">"DTEnd:"</span><span class="token punctuation">)</span><span class="token punctuation">.</span><span class="token function">AppendLine</span><span class="token punctuation">(</span>End<span class="token punctuation">)</span><span class="token punctuation">;</span><br /> <br /> FileOutput<span class="token punctuation">.</span><span class="token function">Append</span><span class="token punctuation">(</span><span class="token string">"Location;ENCODING=QUOTED-PRINTABLE:"</span><span class="token punctuation">)</span><span class="token punctuation">.</span><span class="token function">AppendLine</span><span class="token punctuation">(</span>Location<span class="token punctuation">)</span><span class="token punctuation">;</span><br /> <br /> FileOutput<span class="token punctuation">.</span><span class="token function">Append</span><span class="token punctuation">(</span><span class="token string">"SUMMARY;ENCODING=QUOTED-PRINTABLE:"</span><span class="token punctuation">)</span><span class="token punctuation">.</span><span class="token function">AppendLine</span><span class="token punctuation">(</span>Subject<span class="token punctuation">)</span><span class="token punctuation">;</span><br /> <br /> FileOutput<span class="token punctuation">.</span><span class="token function">Append</span><span class="token punctuation">(</span><span class="token string">"DESCRIPTION;ENCODING=QUOTED-PRINTABLE:"</span><span class="token punctuation">)</span><span class="token punctuation">.</span><span class="token function">AppendLine</span><span class="token punctuation">(</span>Description<span class="token punctuation">)</span><span class="token punctuation">;</span><br /> <br /> FileOutput<span class="token punctuation">.</span><span class="token function">Append</span><span class="token punctuation">(</span><span class="token string">"UID:"</span><span class="token punctuation">)</span><span class="token punctuation">.</span><span class="token function">Append</span><span class="token punctuation">(</span>Start<span class="token punctuation">)</span><span class="token punctuation">.</span><span class="token function">Append</span><span class="token punctuation">(</span>End<span class="token punctuation">)</span><span class="token punctuation">.</span><span class="token function">AppendLine</span><span class="token punctuation">(</span>Subject<span class="token punctuation">)</span><span class="token punctuation">;</span><br /> <br /> FileOutput<span class="token punctuation">.</span><span class="token function">AppendLine</span><span class="token punctuation">(</span><span class="token string">"PRIORITY:3"</span><span class="token punctuation">)</span><span class="token punctuation">;</span><br /> <br /> FileOutput<span class="token punctuation">.</span><span class="token function">AppendLine</span><span class="token punctuation">(</span><span class="token string">"End:VEVENT"</span><span class="token punctuation">)</span><span class="token punctuation">;</span><br /> <br /> FileOutput<span class="token punctuation">.</span><span class="token function">AppendLine</span><span class="token punctuation">(</span><span class="token string">"End:VCALENDAR"</span><span class="token punctuation">)</span><span class="token punctuation">;</span><br /> <br /> <span class="token keyword">return</span> FileOutput<span class="token punctuation">.</span><span class="token function">ToString</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">;</span><br /> <br /> <span class="token punctuation">}</span><br /> <br /> <span class="token keyword">catch</span> <span class="token punctuation">{</span> <span class="token keyword">throw</span><span class="token punctuation">;</span> <span class="token punctuation">}</span><br /> <br /> <span class="token punctuation">}</span><br /> <br /> <br /> <br /> <span class="token comment">/// <summary></span><br /> <br /> <span class="token comment">/// Returns the ICalendar item</span><br /> <br /> <span class="token comment">/// </summary></span><br /> <br /> <span class="token comment">/// <returns>a string output of the ICalendar item</returns></span><br /> <br /> <span class="token keyword">public</span> <span class="token return-type class-name"><span class="token keyword">string</span></span> <span class="token function">GetICalendar</span><span class="token punctuation">(</span><span class="token punctuation">)</span><br /> <br /> <span class="token punctuation">{</span><br /> <br /> <span class="token keyword">try</span><br /> <br /> <span class="token punctuation">{</span><br /> <br /> <span class="token class-name">StringBuilder</span> FileOutput <span class="token operator">=</span> <span class="token keyword">new</span> <span class="token constructor-invocation class-name">StringBuilder</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">;</span><br /> <br /> FileOutput<span class="token punctuation">.</span><span class="token function">AppendLine</span><span class="token punctuation">(</span><span class="token string">"BEGIN:VCALENDAR"</span><span class="token punctuation">)</span><span class="token punctuation">;</span><br /> <br /> FileOutput<span class="token punctuation">.</span><span class="token function">AppendLine</span><span class="token punctuation">(</span><span class="token string">"PRODID:-//Craigs Utility Library//EN"</span><span class="token punctuation">)</span><span class="token punctuation">;</span><br /> <br /> FileOutput<span class="token punctuation">.</span><span class="token function">AppendLine</span><span class="token punctuation">(</span><span class="token string">"VERSION:2.0"</span><span class="token punctuation">)</span><span class="token punctuation">;</span><br /> <br /> FileOutput<span class="token punctuation">.</span><span class="token function">AppendLine</span><span class="token punctuation">(</span><span class="token string">"METHOD:PUBLISH"</span><span class="token punctuation">)</span><span class="token punctuation">;</span><br /> <br /> StartTime <span class="token operator">=</span> StartTime<span class="token punctuation">.</span><span class="token function">AddHours</span><span class="token punctuation">(</span><span class="token operator">-</span>TimeZoneAdjustment<span class="token punctuation">)</span><span class="token punctuation">;</span><br /> <br /> EndTime <span class="token operator">=</span> EndTime<span class="token punctuation">.</span><span class="token function">AddHours</span><span class="token punctuation">(</span><span class="token operator">-</span>TimeZoneAdjustment<span class="token punctuation">)</span><span class="token punctuation">;</span><br /> <br /> <span class="token class-name"><span class="token keyword">string</span></span> Start <span class="token operator">=</span> StartTime<span class="token punctuation">.</span><span class="token function">ToString</span><span class="token punctuation">(</span><span class="token string">"yyyyMMdd"</span><span class="token punctuation">)</span> <span class="token operator">+</span> <span class="token string">"T"</span> <span class="token operator">+</span> StartTime<span class="token punctuation">.</span><span class="token function">ToString</span><span class="token punctuation">(</span><span class="token string">"HHmmss"</span><span class="token punctuation">)</span><span class="token punctuation">;</span><br /> <br /> <span class="token class-name"><span class="token keyword">string</span></span> End <span class="token operator">=</span> EndTime<span class="token punctuation">.</span><span class="token function">ToString</span><span class="token punctuation">(</span><span class="token string">"yyyyMMdd"</span><span class="token punctuation">)</span> <span class="token operator">+</span> <span class="token string">"T"</span> <span class="token operator">+</span> EndTime<span class="token punctuation">.</span><span class="token function">ToString</span><span class="token punctuation">(</span><span class="token string">"HHmmss"</span><span class="token punctuation">)</span><span class="token punctuation">;</span><br /> <br /> FileOutput<span class="token punctuation">.</span><span class="token function">AppendLine</span><span class="token punctuation">(</span><span class="token string">"BEGIN:VEVENT"</span><span class="token punctuation">)</span><span class="token punctuation">;</span><br /> <br /> FileOutput<span class="token punctuation">.</span><span class="token function">AppendLine</span><span class="token punctuation">(</span><span class="token string">"CLASS:PUBLIC"</span><span class="token punctuation">)</span><span class="token punctuation">;</span><br /> <br /> FileOutput<span class="token punctuation">.</span><span class="token function">Append</span><span class="token punctuation">(</span><span class="token string">"CREATED:"</span><span class="token punctuation">)</span><span class="token punctuation">.</span><span class="token function">AppendLine</span><span class="token punctuation">(</span>DateTime<span class="token punctuation">.</span>Now<span class="token punctuation">.</span><span class="token function">ToString</span><span class="token punctuation">(</span><span class="token string">"yyyyMMddTHHmmssZ"</span><span class="token punctuation">)</span><span class="token punctuation">)</span><span class="token punctuation">;</span><br /> <br /> FileOutput<span class="token punctuation">.</span><span class="token function">AppendLine</span><span class="token punctuation">(</span><span class="token function">StripHTML</span><span class="token punctuation">(</span>Description<span class="token punctuation">.</span><span class="token function">Replace</span><span class="token punctuation">(</span><span class="token string">"<br />"</span><span class="token punctuation">,</span> <span class="token string">"\\\\n"</span><span class="token punctuation">)</span><span class="token punctuation">)</span><span class="token punctuation">)</span><span class="token punctuation">;</span><br /> <br /> FileOutput<span class="token punctuation">.</span><span class="token function">Append</span><span class="token punctuation">(</span><span class="token string">"DTEND:"</span><span class="token punctuation">)</span><span class="token punctuation">.</span><span class="token function">AppendLine</span><span class="token punctuation">(</span>Start<span class="token punctuation">)</span><span class="token punctuation">;</span><br /> <br /> FileOutput<span class="token punctuation">.</span><span class="token function">Append</span><span class="token punctuation">(</span><span class="token string">"DTSTART:"</span><span class="token punctuation">)</span><span class="token punctuation">.</span><span class="token function">AppendLine</span><span class="token punctuation">(</span>End<span class="token punctuation">)</span><span class="token punctuation">;</span><br /> <br /> FileOutput<span class="token punctuation">.</span><span class="token function">Append</span><span class="token punctuation">(</span><span class="token string">"LOCATION:"</span><span class="token punctuation">)</span><span class="token punctuation">.</span><span class="token function">AppendLine</span><span class="token punctuation">(</span>Location<span class="token punctuation">)</span><span class="token punctuation">;</span><br /> <br /> FileOutput<span class="token punctuation">.</span><span class="token function">Append</span><span class="token punctuation">(</span><span class="token string">"SUMMARY;LANGUAGE=en-us:"</span><span class="token punctuation">)</span><span class="token punctuation">.</span><span class="token function">AppendLine</span><span class="token punctuation">(</span>Subject<span class="token punctuation">)</span><span class="token punctuation">;</span><br /> <br /> FileOutput<span class="token punctuation">.</span><span class="token function">Append</span><span class="token punctuation">(</span><span class="token string">"UID:"</span><span class="token punctuation">)</span><span class="token punctuation">.</span><span class="token function">Append</span><span class="token punctuation">(</span>Start<span class="token punctuation">)</span><span class="token punctuation">.</span><span class="token function">Append</span><span class="token punctuation">(</span>End<span class="token punctuation">)</span><span class="token punctuation">.</span><span class="token function">AppendLine</span><span class="token punctuation">(</span>Subject<span class="token punctuation">)</span><span class="token punctuation">;</span><br /> <br /> <span class="token keyword">if</span> <span class="token punctuation">(</span><span class="token function">ContainsHTML</span><span class="token punctuation">(</span>Description<span class="token punctuation">)</span><span class="token punctuation">)</span><br /> <br /> <span class="token punctuation">{</span><br /> <br /> FileOutput<span class="token punctuation">.</span><span class="token function">Append</span><span class="token punctuation">(</span><span class="token string">"X-ALT-DESC;FMTTYPE=text/html:"</span><span class="token punctuation">)</span><span class="token punctuation">.</span><span class="token function">AppendLine</span><span class="token punctuation">(</span>Description<span class="token punctuation">.</span><span class="token function">Replace</span><span class="token punctuation">(</span><span class="token string">"\\n"</span><span class="token punctuation">,</span> <span class="token string">""</span><span class="token punctuation">)</span><span class="token punctuation">)</span><span class="token punctuation">;</span><br /> <br /> <span class="token punctuation">}</span><br /> <br /> <span class="token keyword">else</span><br /> <br /> <span class="token punctuation">{</span><br /> <br /> FileOutput<span class="token punctuation">.</span><span class="token function">Append</span><span class="token punctuation">(</span><span class="token string">"DESCRIPTION:"</span><span class="token punctuation">)</span><span class="token punctuation">.</span><span class="token function">AppendLine</span><span class="token punctuation">(</span>Description<span class="token punctuation">)</span><span class="token punctuation">;</span><br /> <br /> <span class="token punctuation">}</span><br /> <br /> FileOutput<span class="token punctuation">.</span><span class="token function">AppendLine</span><span class="token punctuation">(</span><span class="token string">"BEGIN:VALARM"</span><span class="token punctuation">)</span><span class="token punctuation">;</span><br /> <br /> FileOutput<span class="token punctuation">.</span><span class="token function">AppendLine</span><span class="token punctuation">(</span><span class="token string">"TRIGGER:-PT15M"</span><span class="token punctuation">)</span><span class="token punctuation">;</span><br /> <br /> FileOutput<span class="token punctuation">.</span><span class="token function">AppendLine</span><span class="token punctuation">(</span><span class="token string">"ACTION:DISPLAY"</span><span class="token punctuation">)</span><span class="token punctuation">;</span><br /> <br /> FileOutput<span class="token punctuation">.</span><span class="token function">AppendLine</span><span class="token punctuation">(</span><span class="token string">"DESCRIPTION:Reminder"</span><span class="token punctuation">)</span><span class="token punctuation">;</span><br /> <br /> FileOutput<span class="token punctuation">.</span><span class="token function">AppendLine</span><span class="token punctuation">(</span><span class="token string">"END:VALARM"</span><span class="token punctuation">)</span><span class="token punctuation">;</span><br /> <br /> FileOutput<span class="token punctuation">.</span><span class="token function">AppendLine</span><span class="token punctuation">(</span><span class="token string">"END:VEVENT"</span><span class="token punctuation">)</span><span class="token punctuation">;</span><br /> <br /> FileOutput<span class="token punctuation">.</span><span class="token function">AppendLine</span><span class="token punctuation">(</span><span class="token string">"END:VCALENDAR"</span><span class="token punctuation">)</span><span class="token punctuation">;</span><br /> <br /> <span class="token keyword">return</span> FileOutput<span class="token punctuation">.</span><span class="token function">ToString</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">;</span><br /> <br /> <span class="token punctuation">}</span><br /> <br /> <span class="token keyword">catch</span> <span class="token punctuation">{</span> <span class="token keyword">throw</span><span class="token punctuation">;</span> <span class="token punctuation">}</span><br /> <br /> <span class="token punctuation">}</span><br /> <br /> <br /> <br /> <span class="token comment">/// <summary></span><br /> <br /> <span class="token comment">/// Returns the HCalendar item</span><br /> <br /> <span class="token comment">/// </summary></span><br /> <br /> <span class="token comment">/// <returns>A string output of the HCalendar item</returns></span><br /> <br /> <span class="token keyword">public</span> <span class="token return-type class-name"><span class="token keyword">string</span></span> <span class="token function">GetHCalendar</span><span class="token punctuation">(</span><span class="token punctuation">)</span><br /> <br /> <span class="token punctuation">{</span><br /> <br /> <span class="token keyword">try</span><br /> <br /> <span class="token punctuation">{</span><br /> <br /> <span class="token class-name">StringBuilder</span> Output <span class="token operator">=</span> <span class="token keyword">new</span> <span class="token constructor-invocation class-name">StringBuilder</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">;</span><br /> <br /> Output<span class="token punctuation">.</span><span class="token function">Append</span><span class="token punctuation">(</span><span class="token string">"<div class=\\"</span>vevent\\"<span class="token operator">></span>"<span class="token punctuation">)</span><br /> <br /> <span class="token punctuation">.</span><span class="token function">Append</span><span class="token punctuation">(</span><span class="token string">"<div class=\\"</span>summary\\"<span class="token operator">></span><span class="token string">").Append(Subject).Append("</span><span class="token operator"><</span><span class="token operator">/</span>div<span class="token operator">></span>"<span class="token punctuation">)</span><br /> <br /> <span class="token punctuation">.</span><span class="token function">Append</span><span class="token punctuation">(</span><span class="token string">"<div>Date: <abbr class=\\"</span>dtstart\\" title<span class="token operator">=</span>\\""<span class="token punctuation">)</span><br /> <br /> <span class="token punctuation">.</span><span class="token function">Append</span><span class="token punctuation">(</span>StartTime<span class="token punctuation">.</span><span class="token function">ToString</span><span class="token punctuation">(</span><span class="token string">"MM-dd-yyyy hh:mm tt"</span><span class="token punctuation">)</span><span class="token punctuation">)</span><span class="token punctuation">.</span><span class="token function">Append</span><span class="token punctuation">(</span><span class="token string">"\\"</span><span class="token operator">></span>"<span class="token punctuation">)</span><br /> <br /> <span class="token punctuation">.</span><span class="token function">Append</span><span class="token punctuation">(</span>StartTime<span class="token punctuation">.</span><span class="token function">ToString</span><span class="token punctuation">(</span><span class="token string">"MMMM dd, yyyy hh:mm tt"</span><span class="token punctuation">)</span><span class="token punctuation">)</span><span class="token punctuation">.</span><span class="token function">Append</span><span class="token punctuation">(</span><span class="token string">"</abbr> to "</span><span class="token punctuation">)</span><br /> <br /> <span class="token punctuation">.</span><span class="token function">Append</span><span class="token punctuation">(</span><span class="token string">"<abbr class=\\"</span>dtend\\" title<span class="token operator">=</span>\\"<span class="token string">").Append(EndTime.ToString("</span>MM<span class="token operator">-</span>dd<span class="token operator">-</span><span class="token class-name">yyyy</span> hh<span class="token punctuation">:</span>mm tt"<span class="token punctuation">)</span><span class="token punctuation">)</span><br /> <br /> <span class="token punctuation">.</span><span class="token function">Append</span><span class="token punctuation">(</span><span class="token string">"\\"</span><span class="token operator">></span>"<span class="token punctuation">)</span><span class="token punctuation">;</span><br /> <br /> <span class="token keyword">if</span> <span class="token punctuation">(</span>EndTime<span class="token punctuation">.</span>Year <span class="token operator">!=</span> StartTime<span class="token punctuation">.</span>Year<span class="token punctuation">)</span><br /> <br /> <span class="token punctuation">{</span><br /> <br /> Output<span class="token punctuation">.</span><span class="token function">Append</span><span class="token punctuation">(</span>EndTime<span class="token punctuation">.</span><span class="token function">ToString</span><span class="token punctuation">(</span><span class="token string">"MMMM dd, yyyy hh:mm tt"</span><span class="token punctuation">)</span><span class="token punctuation">)</span><span class="token punctuation">;</span><br /> <br /> <span class="token punctuation">}</span><br /> <br /> <span class="token keyword">else</span> <span class="token keyword">if</span> <span class="token punctuation">(</span>EndTime<span class="token punctuation">.</span>Month <span class="token operator">!=</span> StartTime<span class="token punctuation">.</span>Month<span class="token punctuation">)</span><br /> <br /> <span class="token punctuation">{</span><br /> <br /> Output<span class="token punctuation">.</span><span class="token function">Append</span><span class="token punctuation">(</span>EndTime<span class="token punctuation">.</span><span class="token function">ToString</span><span class="token punctuation">(</span><span class="token string">"MMMM dd hh:mm tt"</span><span class="token punctuation">)</span><span class="token punctuation">)</span><span class="token punctuation">;</span><br /> <br /> <span class="token punctuation">}</span><br /> <br /> <span class="token keyword">else</span> <span class="token keyword">if</span> <span class="token punctuation">(</span>EndTime<span class="token punctuation">.</span>Day <span class="token operator">!=</span> StartTime<span class="token punctuation">.</span>Day<span class="token punctuation">)</span><br /> <br /> <span class="token punctuation">{</span><br /> <br /> Output<span class="token punctuation">.</span><span class="token function">Append</span><span class="token punctuation">(</span>EndTime<span class="token punctuation">.</span><span class="token function">ToString</span><span class="token punctuation">(</span><span class="token string">"dd hh:mm tt"</span><span class="token punctuation">)</span><span class="token punctuation">)</span><span class="token punctuation">;</span><br /> <br /> <span class="token punctuation">}</span><br /> <br /> <span class="token keyword">else</span><br /> <br /> <span class="token punctuation">{</span><br /> <br /> Output<span class="token punctuation">.</span><span class="token function">Append</span><span class="token punctuation">(</span>EndTime<span class="token punctuation">.</span><span class="token function">ToString</span><span class="token punctuation">(</span><span class="token string">"hh:mm tt"</span><span class="token punctuation">)</span><span class="token punctuation">)</span><span class="token punctuation">;</span><br /> <br /> <span class="token punctuation">}</span><br /> <br /> Output<span class="token punctuation">.</span><span class="token function">Append</span><span class="token punctuation">(</span><span class="token string">"</abbr></div>"</span><span class="token punctuation">)</span><span class="token punctuation">;</span><br /> <br /> Output<span class="token punctuation">.</span><span class="token function">Append</span><span class="token punctuation">(</span><span class="token string">"<div>Location: <span class=\\"</span>location\\"<span class="token operator">></span><span class="token string">").Append(Location).Append("</span><span class="token operator"><</span><span class="token operator">/</span>span<span class="token operator">></span><span class="token operator"><</span><span class="token operator">/</span>div<span class="token operator">></span>"<span class="token punctuation">)</span><span class="token punctuation">;</span><br /> <br /> Output<span class="token punctuation">.</span><span class="token function">Append</span><span class="token punctuation">(</span><span class="token string">"<div class=\\"</span>description\\"<span class="token operator">></span><span class="token string">").Append(Description).Append("</span><span class="token operator"><</span><span class="token operator">/</span>div<span class="token operator">></span>"<span class="token punctuation">)</span><span class="token punctuation">;</span><br /> <br /> Output<span class="token punctuation">.</span><span class="token function">Append</span><span class="token punctuation">(</span><span class="token string">"</div>"</span><span class="token punctuation">)</span><span class="token punctuation">;</span><br /> <br /> <span class="token keyword">return</span> Output<span class="token punctuation">.</span><span class="token function">ToString</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">;</span><br /> <br /> <span class="token punctuation">}</span><br /> <br /> <span class="token keyword">catch</span> <span class="token punctuation">{</span> <span class="token keyword">throw</span><span class="token punctuation">;</span> <span class="token punctuation">}</span><br /> <br /> <span class="token punctuation">}</span><br /> <br /> <br /> <br /> <span class="token preprocessor property">#<span class="token directive keyword">endregion</span></span><br /> <br /> <span class="token punctuation">}</span><br /> <br /> <span class="token punctuation">}</span></code></pre>
<p>The code above is actually the same as my previous vCalendar code with a couple of functions added. Not much needed to be changed (1 public function to generate an iCalendar item instead of a vCalendar item and 2 private functions to check if the description is HTML and strip it out in certain situations). But that's all there is to it. So take a look, try it out, leave feedback, and happy coding.</p>
Sobel Edge Detection and Laplace Edge Detection in C#
2010-09-15T00:00:00Z
http://www.gutgames.com/post/Sobel-Edge-Detection-and-Laplace-Edge-Detection-in-C/
<p>A while back I posted a simple way to do edge detection. However, it's not the only way and thanks to a couple of additions to my code base, it's not even the easiest way. It's actually possible to do edge detection using convolution filters. No if statements, etc. and since I have code to <a href="http://www.gutgames.com/post/Matrix-Convolution-Filters-in-C">run a convolution filter laying about</a> it's rather simple to do.</p>
<p>Anyway, there's a couple ways to do edge detection, the first and probably most complicated is Sobel edge detection. If you ever read the code for <a href="http://www.gutgames.com/post/Bump-Map-Creation-Using-C">creating a bump map</a>, you may have remembered at the bottom that I mention a Sobel embossing filter:</p>
<p>1 2 1<br />
0 0 0<br />
-1 -2 -1</p>
<p>This filter looks for differences in the Y direction of an image. With Sobel edge detection, we're going to use this along with the X direction:</p>
<p>-1 0 1<br />
-2 0 2<br />
-1 0 1</p>
<p>We take the resulting images, get each individual pixel and add it to each other. For example Image1(0,0)+Image2(0,0)=Resulting pixel for (0,0). Once we do this, we're done... Well except that we need to ensure that the image that we're dealing with is black and white coming in and we may want to take the negative of the image as it will most likely be black with white lines. But other than that we're done. So let's take a look at the code:</p>
<pre class="language-csharp"><code class="language-csharp"> <span class="token keyword">public</span> <span class="token keyword">static</span> <span class="token return-type class-name">Bitmap</span> <span class="token function">SobelEdgeDetection</span><span class="token punctuation">(</span><span class="token class-name">Bitmap</span> Input<span class="token punctuation">)</span><br /> <br /> <span class="token punctuation">{</span><br /> <br /> <span class="token keyword">try</span><br /> <br /> <span class="token punctuation">{</span><br /> <br /> <span class="token keyword">using</span> <span class="token punctuation">(</span><span class="token class-name">Bitmap</span> TempImage <span class="token operator">=</span> <span class="token function">ConvertBlackAndWhite</span><span class="token punctuation">(</span>Input<span class="token punctuation">)</span><span class="token punctuation">)</span><br /> <br /> <span class="token punctuation">{</span><br /> <br /> <span class="token class-name">Filter</span> TempFilter <span class="token operator">=</span> <span class="token keyword">new</span> <span class="token constructor-invocation class-name">Filter</span><span class="token punctuation">(</span><span class="token number">3</span><span class="token punctuation">,</span> <span class="token number">3</span><span class="token punctuation">)</span><span class="token punctuation">;</span><br /> <br /> TempFilter<span class="token punctuation">.</span>MyFilter\<span class="token punctuation">[</span><span class="token number">0</span><span class="token punctuation">,</span> <span class="token number">0</span>\<span class="token punctuation">]</span> <span class="token operator">=</span> <span class="token operator">-</span><span class="token number">1</span><span class="token punctuation">;</span><br /> <br /> TempFilter<span class="token punctuation">.</span>MyFilter\<span class="token punctuation">[</span><span class="token number">0</span><span class="token punctuation">,</span> <span class="token number">1</span>\<span class="token punctuation">]</span> <span class="token operator">=</span> <span class="token number">0</span><span class="token punctuation">;</span><br /> <br /> TempFilter<span class="token punctuation">.</span>MyFilter\<span class="token punctuation">[</span><span class="token number">0</span><span class="token punctuation">,</span> <span class="token number">2</span>\<span class="token punctuation">]</span> <span class="token operator">=</span> <span class="token number">1</span><span class="token punctuation">;</span><br /> <br /> TempFilter<span class="token punctuation">.</span>MyFilter\<span class="token punctuation">[</span><span class="token number">1</span><span class="token punctuation">,</span> <span class="token number">0</span>\<span class="token punctuation">]</span> <span class="token operator">=</span> <span class="token operator">-</span><span class="token number">2</span><span class="token punctuation">;</span><br /> <br /> TempFilter<span class="token punctuation">.</span>MyFilter\<span class="token punctuation">[</span><span class="token number">1</span><span class="token punctuation">,</span> <span class="token number">1</span>\<span class="token punctuation">]</span> <span class="token operator">=</span> <span class="token number">0</span><span class="token punctuation">;</span><br /> <br /> TempFilter<span class="token punctuation">.</span>MyFilter\<span class="token punctuation">[</span><span class="token number">1</span><span class="token punctuation">,</span> <span class="token number">2</span>\<span class="token punctuation">]</span> <span class="token operator">=</span> <span class="token number">2</span><span class="token punctuation">;</span><br /> <br /> TempFilter<span class="token punctuation">.</span>MyFilter\<span class="token punctuation">[</span><span class="token number">2</span><span class="token punctuation">,</span> <span class="token number">0</span>\<span class="token punctuation">]</span> <span class="token operator">=</span> <span class="token operator">-</span><span class="token number">1</span><span class="token punctuation">;</span><br /> <br /> TempFilter<span class="token punctuation">.</span>MyFilter\<span class="token punctuation">[</span><span class="token number">2</span><span class="token punctuation">,</span> <span class="token number">1</span>\<span class="token punctuation">]</span> <span class="token operator">=</span> <span class="token number">0</span><span class="token punctuation">;</span><br /> <br /> TempFilter<span class="token punctuation">.</span>MyFilter\<span class="token punctuation">[</span><span class="token number">2</span><span class="token punctuation">,</span> <span class="token number">2</span>\<span class="token punctuation">]</span> <span class="token operator">=</span> <span class="token number">1</span><span class="token punctuation">;</span><br /> <br /> TempFilter<span class="token punctuation">.</span>Absolute <span class="token operator">=</span> <span class="token boolean">true</span><span class="token punctuation">;</span><br /> <br /> <span class="token keyword">using</span> <span class="token punctuation">(</span><span class="token class-name">Bitmap</span> TempImageX <span class="token operator">=</span> TempFilter<span class="token punctuation">.</span><span class="token function">ApplyFilter</span><span class="token punctuation">(</span>TempImage<span class="token punctuation">)</span><span class="token punctuation">)</span><br /> <br /> <span class="token punctuation">{</span><br /> <br /> TempFilter <span class="token operator">=</span> <span class="token keyword">new</span> <span class="token constructor-invocation class-name">Filter</span><span class="token punctuation">(</span><span class="token number">3</span><span class="token punctuation">,</span> <span class="token number">3</span><span class="token punctuation">)</span><span class="token punctuation">;</span><br /> <br /> TempFilter<span class="token punctuation">.</span>MyFilter\<span class="token punctuation">[</span><span class="token number">0</span><span class="token punctuation">,</span> <span class="token number">0</span>\<span class="token punctuation">]</span> <span class="token operator">=</span> <span class="token number">1</span><span class="token punctuation">;</span><br /> <br /> TempFilter<span class="token punctuation">.</span>MyFilter\<span class="token punctuation">[</span><span class="token number">0</span><span class="token punctuation">,</span> <span class="token number">1</span>\<span class="token punctuation">]</span> <span class="token operator">=</span> <span class="token number">2</span><span class="token punctuation">;</span><br /> <br /> TempFilter<span class="token punctuation">.</span>MyFilter\<span class="token punctuation">[</span><span class="token number">0</span><span class="token punctuation">,</span> <span class="token number">2</span>\<span class="token punctuation">]</span> <span class="token operator">=</span> <span class="token number">1</span><span class="token punctuation">;</span><br /> <br /> TempFilter<span class="token punctuation">.</span>MyFilter\<span class="token punctuation">[</span><span class="token number">1</span><span class="token punctuation">,</span> <span class="token number">0</span>\<span class="token punctuation">]</span> <span class="token operator">=</span> <span class="token number">0</span><span class="token punctuation">;</span><br /> <br /> TempFilter<span class="token punctuation">.</span>MyFilter\<span class="token punctuation">[</span><span class="token number">1</span><span class="token punctuation">,</span> <span class="token number">1</span>\<span class="token punctuation">]</span> <span class="token operator">=</span> <span class="token number">0</span><span class="token punctuation">;</span><br /> <br /> TempFilter<span class="token punctuation">.</span>MyFilter\<span class="token punctuation">[</span><span class="token number">1</span><span class="token punctuation">,</span> <span class="token number">2</span>\<span class="token punctuation">]</span> <span class="token operator">=</span> <span class="token number">0</span><span class="token punctuation">;</span><br /> <br /> TempFilter<span class="token punctuation">.</span>MyFilter\<span class="token punctuation">[</span><span class="token number">2</span><span class="token punctuation">,</span> <span class="token number">0</span>\<span class="token punctuation">]</span> <span class="token operator">=</span> <span class="token operator">-</span><span class="token number">1</span><span class="token punctuation">;</span><br /> <br /> TempFilter<span class="token punctuation">.</span>MyFilter\<span class="token punctuation">[</span><span class="token number">2</span><span class="token punctuation">,</span> <span class="token number">1</span>\<span class="token punctuation">]</span> <span class="token operator">=</span> <span class="token operator">-</span><span class="token number">2</span><span class="token punctuation">;</span><br /> <br /> TempFilter<span class="token punctuation">.</span>MyFilter\<span class="token punctuation">[</span><span class="token number">2</span><span class="token punctuation">,</span> <span class="token number">2</span>\<span class="token punctuation">]</span> <span class="token operator">=</span> <span class="token operator">-</span><span class="token number">1</span><span class="token punctuation">;</span><br /> <br /> TempFilter<span class="token punctuation">.</span>Absolute <span class="token operator">=</span> <span class="token boolean">true</span><span class="token punctuation">;</span><br /> <br /> <span class="token keyword">using</span> <span class="token punctuation">(</span><span class="token class-name">Bitmap</span> TempImageY <span class="token operator">=</span> TempFilter<span class="token punctuation">.</span><span class="token function">ApplyFilter</span><span class="token punctuation">(</span>TempImage<span class="token punctuation">)</span><span class="token punctuation">)</span><br /> <br /> <span class="token punctuation">{</span><br /> <br /> <span class="token keyword">using</span> <span class="token punctuation">(</span><span class="token class-name">Bitmap</span> NewBitmap <span class="token operator">=</span> <span class="token keyword">new</span> <span class="token constructor-invocation class-name">Bitmap</span><span class="token punctuation">(</span>TempImage<span class="token punctuation">.</span>Width<span class="token punctuation">,</span> TempImage<span class="token punctuation">.</span>Height<span class="token punctuation">)</span><span class="token punctuation">)</span><br /> <br /> <span class="token punctuation">{</span><br /> <br /> <span class="token class-name">BitmapData</span> NewData <span class="token operator">=</span> Image<span class="token punctuation">.</span><span class="token function">LockImage</span><span class="token punctuation">(</span>NewBitmap<span class="token punctuation">)</span><span class="token punctuation">;</span><br /> <br /> <span class="token class-name">BitmapData</span> OldData1 <span class="token operator">=</span> Image<span class="token punctuation">.</span><span class="token function">LockImage</span><span class="token punctuation">(</span>TempImageX<span class="token punctuation">)</span><span class="token punctuation">;</span><br /> <br /> <span class="token class-name">BitmapData</span> OldData2 <span class="token operator">=</span> Image<span class="token punctuation">.</span><span class="token function">LockImage</span><span class="token punctuation">(</span>TempImageY<span class="token punctuation">)</span><span class="token punctuation">;</span><br /> <br /> <span class="token class-name"><span class="token keyword">int</span></span> NewPixelSize <span class="token operator">=</span> Image<span class="token punctuation">.</span><span class="token function">GetPixelSize</span><span class="token punctuation">(</span>NewData<span class="token punctuation">)</span><span class="token punctuation">;</span><br /> <br /> <span class="token class-name"><span class="token keyword">int</span></span> OldPixelSize1 <span class="token operator">=</span> Image<span class="token punctuation">.</span><span class="token function">GetPixelSize</span><span class="token punctuation">(</span>OldData1<span class="token punctuation">)</span><span class="token punctuation">;</span><br /> <br /> <span class="token class-name"><span class="token keyword">int</span></span> OldPixelSize2 <span class="token operator">=</span> Image<span class="token punctuation">.</span><span class="token function">GetPixelSize</span><span class="token punctuation">(</span>OldData2<span class="token punctuation">)</span><span class="token punctuation">;</span><br /> <br /> <span class="token keyword">for</span> <span class="token punctuation">(</span><span class="token class-name"><span class="token keyword">int</span></span> x <span class="token operator">=</span> <span class="token number">0</span><span class="token punctuation">;</span> x <span class="token operator"><</span> NewBitmap<span class="token punctuation">.</span>Width<span class="token punctuation">;</span> <span class="token operator">++</span>x<span class="token punctuation">)</span><br /> <br /> <span class="token punctuation">{</span><br /> <br /> <span class="token keyword">for</span> <span class="token punctuation">(</span><span class="token class-name"><span class="token keyword">int</span></span> y <span class="token operator">=</span> <span class="token number">0</span><span class="token punctuation">;</span> y <span class="token operator"><</span> NewBitmap<span class="token punctuation">.</span>Height<span class="token punctuation">;</span> <span class="token operator">++</span>y<span class="token punctuation">)</span><br /> <br /> <span class="token punctuation">{</span><br /> <br /> <span class="token class-name">Color</span> Pixel1 <span class="token operator">=</span> Image<span class="token punctuation">.</span><span class="token function">GetPixel</span><span class="token punctuation">(</span>OldData1<span class="token punctuation">,</span> x<span class="token punctuation">,</span> y<span class="token punctuation">,</span> OldPixelSize1<span class="token punctuation">)</span><span class="token punctuation">;</span><br /> <br /> <span class="token class-name">Color</span> Pixel2 <span class="token operator">=</span> Image<span class="token punctuation">.</span><span class="token function">GetPixel</span><span class="token punctuation">(</span>OldData2<span class="token punctuation">,</span> x<span class="token punctuation">,</span> y<span class="token punctuation">,</span> OldPixelSize2<span class="token punctuation">)</span><span class="token punctuation">;</span><br /> <br /> Image<span class="token punctuation">.</span><span class="token function">SetPixel</span><span class="token punctuation">(</span>NewData<span class="token punctuation">,</span> x<span class="token punctuation">,</span> y<span class="token punctuation">,</span><br /> <br /> Color<span class="token punctuation">.</span><span class="token function">FromArgb</span><span class="token punctuation">(</span>Math<span class="token punctuation">.</span>MathHelper<span class="token punctuation">.</span><span class="token function">Clamp</span><span class="token punctuation">(</span>Pixel1<span class="token punctuation">.</span>R <span class="token operator">+</span> Pixel2<span class="token punctuation">.</span>R<span class="token punctuation">,</span> <span class="token number">255</span><span class="token punctuation">,</span> <span class="token number">0</span><span class="token punctuation">)</span><span class="token punctuation">,</span><br /> <br /> Math<span class="token punctuation">.</span>MathHelper<span class="token punctuation">.</span><span class="token function">Clamp</span><span class="token punctuation">(</span>Pixel1<span class="token punctuation">.</span>G <span class="token operator">+</span> Pixel2<span class="token punctuation">.</span>G<span class="token punctuation">,</span> <span class="token number">255</span><span class="token punctuation">,</span> <span class="token number">0</span><span class="token punctuation">)</span><span class="token punctuation">,</span><br /> <br /> Math<span class="token punctuation">.</span>MathHelper<span class="token punctuation">.</span><span class="token function">Clamp</span><span class="token punctuation">(</span>Pixel1<span class="token punctuation">.</span>B <span class="token operator">+</span> Pixel2<span class="token punctuation">.</span>B<span class="token punctuation">,</span> <span class="token number">255</span><span class="token punctuation">,</span> <span class="token number">0</span><span class="token punctuation">)</span><span class="token punctuation">)</span><span class="token punctuation">,</span><br /> <br /> NewPixelSize<span class="token punctuation">)</span><span class="token punctuation">;</span><br /> <br /> <span class="token punctuation">}</span><br /> <br /> <span class="token punctuation">}</span><br /> <br /> Image<span class="token punctuation">.</span><span class="token function">UnlockImage</span><span class="token punctuation">(</span>NewBitmap<span class="token punctuation">,</span> NewData<span class="token punctuation">)</span><span class="token punctuation">;</span><br /> <br /> Image<span class="token punctuation">.</span><span class="token function">UnlockImage</span><span class="token punctuation">(</span>TempImageX<span class="token punctuation">,</span> OldData1<span class="token punctuation">)</span><span class="token punctuation">;</span><br /> <br /> Image<span class="token punctuation">.</span><span class="token function">UnlockImage</span><span class="token punctuation">(</span>TempImageY<span class="token punctuation">,</span> OldData2<span class="token punctuation">)</span><span class="token punctuation">;</span><br /> <br /> <span class="token keyword">return</span> Image<span class="token punctuation">.</span><span class="token function">Negative</span><span class="token punctuation">(</span>NewBitmap<span class="token punctuation">)</span><span class="token punctuation">;</span><br /> <br /> <span class="token punctuation">}</span><br /> <br /> <span class="token punctuation">}</span><br /> <br /> <span class="token punctuation">}</span><br /> <br /> <span class="token punctuation">}</span><br /> <br /> <span class="token punctuation">}</span><br /> <br /> <span class="token keyword">catch</span> <span class="token punctuation">{</span> <span class="token keyword">throw</span><span class="token punctuation">;</span> <span class="token punctuation">}</span><br /> <br /> <span class="token punctuation">}</span><br /></code></pre>
<p>The code above uses some code that you'll need from my utility library, but the two files are <a href="http://cul.codeplex.com/SourceControl/changeset/view/61004#707831">here</a> and <a href="http://cul.codeplex.com/SourceControl/changeset/view/61004#707933">here</a>. In fact that actually contains the final bits of code. Anyway the code above, as I said, takes the image, converts it to black and white, runs the X direction filter and Y direction filter (note that it sets the Absolute property on these filters as this will help us detect edges in all four directions while only running two filters), adds the pixels together, and then returns the negative of the resulting image.</p>
<p>That's a lot of steps and if I didn't have the code already there, it would be a pain to write. However there is a simpler approach that you can use for edge detection. It tends to result in slightly less optimal results, but it only uses one filter (so you skip the addition phase also). This approach is referred to as Laplace. So let's look at the code to accomplish this approach:</p>
<pre class="language-csharp"><code class="language-csharp"> <span class="token keyword">public</span> <span class="token keyword">static</span> <span class="token return-type class-name">Bitmap</span> <span class="token function">LaplaceEdgeDetection</span><span class="token punctuation">(</span><span class="token class-name">Bitmap</span> Image<span class="token punctuation">)</span><br /> <br /> <span class="token punctuation">{</span><br /> <br /> <span class="token keyword">try</span><br /> <br /> <span class="token punctuation">{</span><br /> <br /> <span class="token keyword">using</span> <span class="token punctuation">(</span><span class="token class-name">Bitmap</span> TempImage <span class="token operator">=</span> <span class="token function">ConvertBlackAndWhite</span><span class="token punctuation">(</span>Image<span class="token punctuation">)</span><span class="token punctuation">)</span><br /> <br /> <span class="token punctuation">{</span><br /> <br /> <span class="token class-name">Filter</span> TempFilter <span class="token operator">=</span> <span class="token keyword">new</span> <span class="token constructor-invocation class-name">Filter</span><span class="token punctuation">(</span><span class="token number">5</span><span class="token punctuation">,</span> <span class="token number">5</span><span class="token punctuation">)</span><span class="token punctuation">;</span><br /> <br /> TempFilter<span class="token punctuation">.</span>MyFilter\<span class="token punctuation">[</span><span class="token number">0</span><span class="token punctuation">,</span> <span class="token number">0</span>\<span class="token punctuation">]</span> <span class="token operator">=</span> <span class="token operator">-</span><span class="token number">1</span><span class="token punctuation">;</span><br /> <br /> TempFilter<span class="token punctuation">.</span>MyFilter\<span class="token punctuation">[</span><span class="token number">0</span><span class="token punctuation">,</span> <span class="token number">1</span>\<span class="token punctuation">]</span> <span class="token operator">=</span> <span class="token operator">-</span><span class="token number">1</span><span class="token punctuation">;</span><br /> <br /> TempFilter<span class="token punctuation">.</span>MyFilter\<span class="token punctuation">[</span><span class="token number">0</span><span class="token punctuation">,</span> <span class="token number">2</span>\<span class="token punctuation">]</span> <span class="token operator">=</span> <span class="token operator">-</span><span class="token number">1</span><span class="token punctuation">;</span><br /> <br /> TempFilter<span class="token punctuation">.</span>MyFilter\<span class="token punctuation">[</span><span class="token number">0</span><span class="token punctuation">,</span> <span class="token number">3</span>\<span class="token punctuation">]</span> <span class="token operator">=</span> <span class="token operator">-</span><span class="token number">1</span><span class="token punctuation">;</span><br /> <br /> TempFilter<span class="token punctuation">.</span>MyFilter\<span class="token punctuation">[</span><span class="token number">0</span><span class="token punctuation">,</span> <span class="token number">4</span>\<span class="token punctuation">]</span> <span class="token operator">=</span> <span class="token operator">-</span><span class="token number">1</span><span class="token punctuation">;</span><br /> <br /> TempFilter<span class="token punctuation">.</span>MyFilter\<span class="token punctuation">[</span><span class="token number">1</span><span class="token punctuation">,</span> <span class="token number">0</span>\<span class="token punctuation">]</span> <span class="token operator">=</span> <span class="token operator">-</span><span class="token number">1</span><span class="token punctuation">;</span><br /> <br /> TempFilter<span class="token punctuation">.</span>MyFilter\<span class="token punctuation">[</span><span class="token number">1</span><span class="token punctuation">,</span> <span class="token number">1</span>\<span class="token punctuation">]</span> <span class="token operator">=</span> <span class="token operator">-</span><span class="token number">1</span><span class="token punctuation">;</span><br /> <br /> TempFilter<span class="token punctuation">.</span>MyFilter\<span class="token punctuation">[</span><span class="token number">1</span><span class="token punctuation">,</span> <span class="token number">2</span>\<span class="token punctuation">]</span> <span class="token operator">=</span> <span class="token operator">-</span><span class="token number">1</span><span class="token punctuation">;</span><br /> <br /> TempFilter<span class="token punctuation">.</span>MyFilter\<span class="token punctuation">[</span><span class="token number">1</span><span class="token punctuation">,</span> <span class="token number">3</span>\<span class="token punctuation">]</span> <span class="token operator">=</span> <span class="token operator">-</span><span class="token number">1</span><span class="token punctuation">;</span><br /> <br /> TempFilter<span class="token punctuation">.</span>MyFilter\<span class="token punctuation">[</span><span class="token number">1</span><span class="token punctuation">,</span> <span class="token number">4</span>\<span class="token punctuation">]</span> <span class="token operator">=</span> <span class="token operator">-</span><span class="token number">1</span><span class="token punctuation">;</span><br /> <br /> TempFilter<span class="token punctuation">.</span>MyFilter\<span class="token punctuation">[</span><span class="token number">2</span><span class="token punctuation">,</span> <span class="token number">0</span>\<span class="token punctuation">]</span> <span class="token operator">=</span> <span class="token operator">-</span><span class="token number">1</span><span class="token punctuation">;</span><br /> <br /> TempFilter<span class="token punctuation">.</span>MyFilter\<span class="token punctuation">[</span><span class="token number">2</span><span class="token punctuation">,</span> <span class="token number">1</span>\<span class="token punctuation">]</span> <span class="token operator">=</span> <span class="token operator">-</span><span class="token number">1</span><span class="token punctuation">;</span><br /> <br /> TempFilter<span class="token punctuation">.</span>MyFilter\<span class="token punctuation">[</span><span class="token number">2</span><span class="token punctuation">,</span> <span class="token number">2</span>\<span class="token punctuation">]</span> <span class="token operator">=</span> <span class="token number">24</span><span class="token punctuation">;</span><br /> <br /> TempFilter<span class="token punctuation">.</span>MyFilter\<span class="token punctuation">[</span><span class="token number">2</span><span class="token punctuation">,</span> <span class="token number">3</span>\<span class="token punctuation">]</span> <span class="token operator">=</span> <span class="token operator">-</span><span class="token number">1</span><span class="token punctuation">;</span><br /> <br /> TempFilter<span class="token punctuation">.</span>MyFilter\<span class="token punctuation">[</span><span class="token number">2</span><span class="token punctuation">,</span> <span class="token number">4</span>\<span class="token punctuation">]</span> <span class="token operator">=</span> <span class="token operator">-</span><span class="token number">1</span><span class="token punctuation">;</span><br /> <br /> TempFilter<span class="token punctuation">.</span>MyFilter\<span class="token punctuation">[</span><span class="token number">3</span><span class="token punctuation">,</span> <span class="token number">0</span>\<span class="token punctuation">]</span> <span class="token operator">=</span> <span class="token operator">-</span><span class="token number">1</span><span class="token punctuation">;</span><br /> <br /> TempFilter<span class="token punctuation">.</span>MyFilter\<span class="token punctuation">[</span><span class="token number">3</span><span class="token punctuation">,</span> <span class="token number">1</span>\<span class="token punctuation">]</span> <span class="token operator">=</span> <span class="token operator">-</span><span class="token number">1</span><span class="token punctuation">;</span><br /> <br /> TempFilter<span class="token punctuation">.</span>MyFilter\<span class="token punctuation">[</span><span class="token number">3</span><span class="token punctuation">,</span> <span class="token number">2</span>\<span class="token punctuation">]</span> <span class="token operator">=</span> <span class="token operator">-</span><span class="token number">1</span><span class="token punctuation">;</span><br /> <br /> TempFilter<span class="token punctuation">.</span>MyFilter\<span class="token punctuation">[</span><span class="token number">3</span><span class="token punctuation">,</span> <span class="token number">3</span>\<span class="token punctuation">]</span> <span class="token operator">=</span> <span class="token operator">-</span><span class="token number">1</span><span class="token punctuation">;</span><br /> <br /> TempFilter<span class="token punctuation">.</span>MyFilter\<span class="token punctuation">[</span><span class="token number">3</span><span class="token punctuation">,</span> <span class="token number">4</span>\<span class="token punctuation">]</span> <span class="token operator">=</span> <span class="token operator">-</span><span class="token number">1</span><span class="token punctuation">;</span><br /> <br /> TempFilter<span class="token punctuation">.</span>MyFilter\<span class="token punctuation">[</span><span class="token number">4</span><span class="token punctuation">,</span> <span class="token number">0</span>\<span class="token punctuation">]</span> <span class="token operator">=</span> <span class="token operator">-</span><span class="token number">1</span><span class="token punctuation">;</span><br /> <br /> TempFilter<span class="token punctuation">.</span>MyFilter\<span class="token punctuation">[</span><span class="token number">4</span><span class="token punctuation">,</span> <span class="token number">1</span>\<span class="token punctuation">]</span> <span class="token operator">=</span> <span class="token operator">-</span><span class="token number">1</span><span class="token punctuation">;</span><br /> <br /> TempFilter<span class="token punctuation">.</span>MyFilter\<span class="token punctuation">[</span><span class="token number">4</span><span class="token punctuation">,</span> <span class="token number">2</span>\<span class="token punctuation">]</span> <span class="token operator">=</span> <span class="token operator">-</span><span class="token number">1</span><span class="token punctuation">;</span><br /> <br /> TempFilter<span class="token punctuation">.</span>MyFilter\<span class="token punctuation">[</span><span class="token number">4</span><span class="token punctuation">,</span> <span class="token number">3</span>\<span class="token punctuation">]</span> <span class="token operator">=</span> <span class="token operator">-</span><span class="token number">1</span><span class="token punctuation">;</span><br /> <br /> TempFilter<span class="token punctuation">.</span>MyFilter\<span class="token punctuation">[</span><span class="token number">4</span><span class="token punctuation">,</span> <span class="token number">4</span>\<span class="token punctuation">]</span> <span class="token operator">=</span> <span class="token operator">-</span><span class="token number">1</span><span class="token punctuation">;</span><br /> <br /> <span class="token keyword">using</span> <span class="token punctuation">(</span><span class="token class-name">Bitmap</span> NewImage <span class="token operator">=</span> TempFilter<span class="token punctuation">.</span><span class="token function">ApplyFilter</span><span class="token punctuation">(</span>TempImage<span class="token punctuation">)</span><span class="token punctuation">)</span><br /> <br /> <span class="token punctuation">{</span><br /> <br /> <span class="token keyword">return</span> <span class="token function">Negative</span><span class="token punctuation">(</span>NewImage<span class="token punctuation">)</span><span class="token punctuation">;</span><br /> <br /> <span class="token punctuation">}</span><br /> <br /> <span class="token punctuation">}</span><br /> <br /> <span class="token punctuation">}</span><br /> <br /> <span class="token keyword">catch</span> <span class="token punctuation">{</span> <span class="token keyword">throw</span><span class="token punctuation">;</span> <span class="token punctuation">}</span><br /> <br /> <span class="token punctuation">}</span></code></pre>
<p>As you can see, we still have to convert the image to black and white, set up our filter and run it, and return the negative, but that's it. The filter itself is different from the Sobel one. It's 5x5 and looks like this:</p>
<p>-1 -1 -1 -1 -1<br />
-1 -1 -1 -1 -1<br />
-1 -1 24 -1 -1<br />
-1 -1 -1 -1 -1<br />
-1 -1 -1 -1 -1</p>
<p>Since it only uses the one filter, it does tend to pick up noise a bit more (hence I said it tends to be suboptimal). But it's fast, which is always nice. But that's all there is to it. Download the code from the links I provided above (should direct you to the Codeplex repository), try it out, and happy coding.</p>
Finding a List of Anagrams in C#
2009-10-29T00:00:00Z
http://www.gutgames.com/post/Finding-List-of-Anagrams-in-C/
<p>This is a very simple algorithm that I created for a game that I'm working on. The game is a word game for smaller children and one of the things that it needs to do is anagrams. So I had to come up with a function to help me find them:</p>
<pre class="language-csharp"><code class="language-csharp"> <span class="token keyword">public</span> <span class="token keyword">static</span> <span class="token return-type class-name">Dictionary<span class="token punctuation"><</span><span class="token keyword">string</span><span class="token punctuation">,</span> System<span class="token punctuation">.</span>Collections<span class="token punctuation">.</span>Generic<span class="token punctuation">.</span>List<span class="token punctuation"><</span><span class="token keyword">string</span><span class="token punctuation">></span><span class="token punctuation">></span></span> <span class="token function">GetAnagramEquivalents</span><span class="token punctuation">(</span><span class="token class-name">System<span class="token punctuation">.</span>Collections<span class="token punctuation">.</span>Generic<span class="token punctuation">.</span>List<span class="token punctuation"><</span><span class="token keyword">string</span><span class="token punctuation">></span></span> InputArray<span class="token punctuation">)</span><br /> <span class="token punctuation">{</span><br /> <span class="token class-name">Dictionary<span class="token punctuation"><</span><span class="token keyword">string</span><span class="token punctuation">,</span> System<span class="token punctuation">.</span>Collections<span class="token punctuation">.</span>Generic<span class="token punctuation">.</span>List<span class="token punctuation"><</span><span class="token keyword">string</span><span class="token punctuation">></span><span class="token punctuation">></span></span> ReturnList <span class="token operator">=</span> <span class="token keyword">new</span> <span class="token constructor-invocation class-name">Dictionary<span class="token punctuation"><</span><span class="token keyword">string</span><span class="token punctuation">,</span> System<span class="token punctuation">.</span>Collections<span class="token punctuation">.</span>Generic<span class="token punctuation">.</span>List<span class="token punctuation"><</span><span class="token keyword">string</span><span class="token punctuation">></span><span class="token punctuation">></span></span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">;</span><br /> <span class="token keyword">for</span> <span class="token punctuation">(</span><span class="token class-name"><span class="token keyword">int</span></span> x <span class="token operator">=</span> <span class="token number">0</span><span class="token punctuation">;</span> x <span class="token operator"><</span> InputArray<span class="token punctuation">.</span>Count<span class="token punctuation">;</span> <span class="token operator">++</span>x<span class="token punctuation">)</span><br /> <span class="token punctuation">{</span><br /> <span class="token class-name"><span class="token keyword">char</span><span class="token punctuation">[</span><span class="token punctuation">]</span></span> InputCharArray<span class="token operator">=</span>InputArray<span class="token punctuation">[</span>x<span class="token punctuation">]</span><span class="token punctuation">.</span><span class="token function">ToCharArray</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">;</span><br /> Array<span class="token punctuation">.</span><span class="token function">Sort</span><span class="token punctuation">(</span>InputCharArray<span class="token punctuation">)</span><span class="token punctuation">;</span><br /> <span class="token class-name"><span class="token keyword">string</span></span> InputString <span class="token operator">=</span> <span class="token keyword">new</span> <span class="token constructor-invocation class-name"><span class="token keyword">string</span></span><span class="token punctuation">(</span>InputCharArray<span class="token punctuation">)</span><span class="token punctuation">;</span><br /> <span class="token keyword">if</span> <span class="token punctuation">(</span>ReturnList<span class="token punctuation">.</span><span class="token function">ContainsKey</span><span class="token punctuation">(</span>InputString<span class="token punctuation">)</span><span class="token punctuation">)</span><br /> <span class="token punctuation">{</span><br /> ReturnList<span class="token punctuation">[</span>InputString<span class="token punctuation">]</span><span class="token punctuation">.</span><span class="token function">Add</span><span class="token punctuation">(</span>InputArray<span class="token punctuation">[</span>x<span class="token punctuation">]</span><span class="token punctuation">)</span><span class="token punctuation">;</span><br /> <span class="token punctuation">}</span><br /> <span class="token keyword">else</span><br /> <span class="token punctuation">{</span><br /> ReturnList<span class="token punctuation">.</span><span class="token function">Add</span><span class="token punctuation">(</span>InputString<span class="token punctuation">,</span> <span class="token keyword">new</span> <span class="token constructor-invocation class-name">System<span class="token punctuation">.</span>Collections<span class="token punctuation">.</span>Generic<span class="token punctuation">.</span>List<span class="token punctuation"><</span><span class="token keyword">string</span><span class="token punctuation">></span></span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">)</span><span class="token punctuation">;</span><br /> ReturnList<span class="token punctuation">[</span>InputString<span class="token punctuation">]</span><span class="token punctuation">.</span><span class="token function">Add</span><span class="token punctuation">(</span>InputArray<span class="token punctuation">[</span>x<span class="token punctuation">]</span><span class="token punctuation">)</span><span class="token punctuation">;</span><br /> <span class="token punctuation">}</span><br /> <span class="token punctuation">}</span><br /> <span class="token keyword">return</span> ReturnList<span class="token punctuation">;</span><br /> <span class="token punctuation">}</span></code></pre>
<p>The code above is very basic. But the general idea is that with a set of words, if you sort the letters in alphabetical order you end up with an equivalent string. For instance both car and arc would be acr when sorted. Thus they are equivalent and anagrams of one another. So all you need to do is pass in a list of words and it passes back a dictionary of anagrams. That's all there is to it. So try it out, leave feedback, and happy coding.</p>
Deserializing/Serializing SOAP Messages in C#
2009-07-24T00:00:00Z
http://www.gutgames.com/post/DeserializingSerializing-SOAP-Messages-in-C/
<p>For those of you that don't know what SOAP is, SOAP is an XML based syntax that allows programs communicate with one another. In other words, just like RSS, etc. it is just another XML document with specific syntax. There really isn't much to it, but serializing/deserializing them can be a pain. Luckily for us .Net has a built in class for us. Specifically in the System.Runtime.Serialization.Formatters.Soap namespace (you may need to add a reference to it). So let's look at how to use this class:</p>
<pre class="language-csharp"><code class="language-csharp"> <span class="token comment">/// <summary></span><br /> <span class="token comment">/// Converts a SOAP string to an object</span><br /> <span class="token comment">/// </summary></span><br /> <span class="token comment">/// <typeparam name="T">Object type</typeparam></span><br /> <span class="token comment">/// <param name="SOAP">SOAP string</param></span><br /> <span class="token comment">/// <returns>The object of the specified type</returns></span><br /> <span class="token keyword">public</span> <span class="token keyword">static</span> <span class="token return-type class-name">T</span> <span class="token generic-method"><span class="token function">SOAPToObject</span><span class="token generic class-name"><span class="token punctuation"><</span>T<span class="token punctuation">></span></span></span><span class="token punctuation">(</span><span class="token class-name"><span class="token keyword">string</span></span> SOAP<span class="token punctuation">)</span><br /> <span class="token punctuation">{</span><br /> <span class="token keyword">if</span> <span class="token punctuation">(</span><span class="token keyword">string</span><span class="token punctuation">.</span><span class="token function">IsNullOrEmpty</span><span class="token punctuation">(</span>SOAP<span class="token punctuation">)</span><span class="token punctuation">)</span><br /> <span class="token punctuation">{</span><br /> <span class="token keyword">throw</span> <span class="token keyword">new</span> <span class="token constructor-invocation class-name">ArgumentException</span><span class="token punctuation">(</span><span class="token string">"SOAP can not be null/empty"</span><span class="token punctuation">)</span><span class="token punctuation">;</span><br /> <span class="token punctuation">}</span><br /> <span class="token keyword">using</span> <span class="token punctuation">(</span><span class="token class-name">MemoryStream</span> Stream <span class="token operator">=</span> <span class="token keyword">new</span> <span class="token constructor-invocation class-name">MemoryStream</span><span class="token punctuation">(</span>UTF8Encoding<span class="token punctuation">.</span>UTF8<span class="token punctuation">.</span><span class="token function">GetBytes</span><span class="token punctuation">(</span>SOAP<span class="token punctuation">)</span><span class="token punctuation">)</span><span class="token punctuation">)</span><br /> <span class="token punctuation">{</span><br /> <span class="token class-name">SoapFormatter</span> Formatter <span class="token operator">=</span> <span class="token keyword">new</span> <span class="token constructor-invocation class-name">SoapFormatter</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">;</span><br /> <span class="token keyword">return</span> <span class="token punctuation">(</span>T<span class="token punctuation">)</span>Formatter<span class="token punctuation">.</span><span class="token function">Deserialize</span><span class="token punctuation">(</span>Stream<span class="token punctuation">)</span><span class="token punctuation">;</span><br /> <span class="token punctuation">}</span><br /> <span class="token punctuation">}</span><br /> <br /> <span class="token comment">/// <summary></span><br /> <span class="token comment">/// Converts an object to a SOAP string</span><br /> <span class="token comment">/// </summary></span><br /> <span class="token comment">/// <param name="Object">Object to serialize</param></span><br /> <span class="token comment">/// <returns>The serialized string</returns></span><br /> <span class="token keyword">public</span> <span class="token keyword">static</span> <span class="token return-type class-name"><span class="token keyword">string</span></span> <span class="token function">ObjectToSOAP</span><span class="token punctuation">(</span><span class="token class-name"><span class="token keyword">object</span></span> Object<span class="token punctuation">)</span><br /> <span class="token punctuation">{</span><br /> <span class="token keyword">if</span> <span class="token punctuation">(</span>Object <span class="token operator">==</span> <span class="token keyword">null</span><span class="token punctuation">)</span><br /> <span class="token punctuation">{</span><br /> <span class="token keyword">throw</span> <span class="token keyword">new</span> <span class="token constructor-invocation class-name">ArgumentException</span><span class="token punctuation">(</span><span class="token string">"Object can not be null"</span><span class="token punctuation">)</span><span class="token punctuation">;</span><br /> <span class="token punctuation">}</span><br /> <span class="token keyword">using</span> <span class="token punctuation">(</span><span class="token class-name">MemoryStream</span> Stream <span class="token operator">=</span> <span class="token keyword">new</span> <span class="token constructor-invocation class-name">MemoryStream</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">)</span><br /> <span class="token punctuation">{</span><br /> <span class="token class-name">SoapFormatter</span> Serializer <span class="token operator">=</span> <span class="token keyword">new</span> <span class="token constructor-invocation class-name">SoapFormatter</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">;</span><br /> Serializer<span class="token punctuation">.</span><span class="token function">Serialize</span><span class="token punctuation">(</span>Stream<span class="token punctuation">,</span> Object<span class="token punctuation">)</span><span class="token punctuation">;</span><br /> Stream<span class="token punctuation">.</span><span class="token function">Flush</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">;</span><br /> <span class="token keyword">return</span> UTF8Encoding<span class="token punctuation">.</span>UTF8<span class="token punctuation">.</span><span class="token function">GetString</span><span class="token punctuation">(</span>Stream<span class="token punctuation">.</span><span class="token function">GetBuffer</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">,</span> <span class="token number">0</span><span class="token punctuation">,</span> <span class="token punctuation">(</span><span class="token keyword">int</span><span class="token punctuation">)</span>Stream<span class="token punctuation">.</span>Position<span class="token punctuation">)</span><span class="token punctuation">;</span><br /> <span class="token punctuation">}</span><br /> <span class="token punctuation">}</span></code></pre>
<p>It's pretty simple and if you've done XML or binary serialization in .Net, it's going to look fairly similar. Anyway, I can't believe how long it took me before I ran into a project that actually required SOAP. But I finally ran into one and decided to go about writing a couple of generic functions to help me out in serializing and deserializing the objects and will hopefully help you out as well. So try it out, leave feedback, and happy coding.</p>
Creating an ORM in C# - Part 7
2009-07-09T00:00:00Z
http://www.gutgames.com/post/Creating-an-ORM-in-C-Part-7/
<p>If you've yet to read the previous portions of this series, this one is just going to be confusing. So read the previous ones. Anyway, this is the final entry in the series. Today I cover select statements and also the cache. In other words, this is a long one (potentially). Anyway, let's start with a small recap.</p>
<p>HaterAide was started to handle my ORM needs since I wasn't happy with most of the options out there. The system uses a base class, reflection, and generics to map a class to a set of tables in a database. Database and table where covered along with the creation/use of select, insert, delete, and update stored procedures. In other words our basic functionality is covered at this point with one exception. The only select statement that the code covers is when you know the ID of the object that you want. Since that's almost never the case, let's look at how to go about getting something a bit more complex.</p>
<p>If you look at the various ORMs out there, most of them out there require you to either write SQL or their own query language to get anything remotely complex out of them. And since I'm trying to hide as much of the back end as possible, I decided to ignore this route. Instead I came up with a set of objects to help me out with queries.</p>
<pre class="language-csharp"><code class="language-csharp"> <span class="token keyword">public</span> <span class="token keyword">class</span> <span class="token class-name">And<span class="token punctuation"><</span>T<span class="token punctuation">></span></span> <span class="token punctuation">:</span> <span class="token type-list"><span class="token class-name">IClause<span class="token punctuation"><</span>T<span class="token punctuation">></span></span></span><br /> <span class="token punctuation">{</span><br /> <span class="token keyword">public</span> <span class="token function">And</span><span class="token punctuation">(</span><span class="token class-name">IClause<span class="token punctuation"><</span>T<span class="token punctuation">></span></span> WhereStatement1<span class="token punctuation">,</span> <span class="token class-name">IClause<span class="token punctuation"><</span>T<span class="token punctuation">></span></span> WhereStatement2<span class="token punctuation">)</span><br /> <span class="token punctuation">:</span> <span class="token keyword">base</span><span class="token punctuation">(</span><span class="token punctuation">)</span><br /> <span class="token punctuation">{</span><br /> \_WhereStatement1 <span class="token operator">=</span> WhereStatement1<span class="token punctuation">;</span><br /> \_WhereStatement2 <span class="token operator">=</span> WhereStatement2<span class="token punctuation">;</span><br /> <span class="token punctuation">}</span><br /> <br /> <span class="token keyword">protected</span> IClause<span class="token operator"><</span>T<span class="token operator">></span> \_WhereStatement1 <span class="token operator">=</span> <span class="token keyword">null</span><span class="token punctuation">;</span><br /> <span class="token keyword">protected</span> IClause<span class="token operator"><</span>T<span class="token operator">></span> \_WhereStatement2 <span class="token operator">=</span> <span class="token keyword">null</span><span class="token punctuation">;</span><br /> <br /> <span class="token keyword">internal</span> <span class="token keyword">override</span> <span class="token return-type class-name"><span class="token keyword">void</span></span> <span class="token function">SetupSQL</span><span class="token punctuation">(</span><span class="token class-name">SQLHelper</span> Helper<span class="token punctuation">,</span><span class="token class-name">Class</span> Class<span class="token punctuation">)</span><br /> <span class="token punctuation">{</span><br /> \_WhereStatement1<span class="token punctuation">.</span><span class="token function">SetupSQL</span><span class="token punctuation">(</span>Helper<span class="token punctuation">,</span>Class<span class="token punctuation">)</span><span class="token punctuation">;</span><br /> \_WhereStatement2<span class="token punctuation">.</span><span class="token function">SetupSQL</span><span class="token punctuation">(</span>Helper<span class="token punctuation">,</span>Class<span class="token punctuation">)</span><span class="token punctuation">;</span><br /> <span class="token punctuation">}</span><br /> <br /> <span class="token keyword">public</span> <span class="token keyword">override</span> <span class="token return-type class-name"><span class="token keyword">string</span></span> <span class="token function">ToString</span><span class="token punctuation">(</span><span class="token punctuation">)</span><br /> <span class="token punctuation">{</span><br /> <span class="token class-name">StringBuilder</span> Builder <span class="token operator">=</span> <span class="token keyword">new</span> <span class="token constructor-invocation class-name">StringBuilder</span><span class="token punctuation">(</span>\_ColumnName<span class="token punctuation">)</span><span class="token punctuation">;</span><br /> Builder<span class="token punctuation">.</span><span class="token function">Append</span><span class="token punctuation">(</span><span class="token string">"("</span> <span class="token operator">+</span> \_WhereStatement1<span class="token punctuation">.</span><span class="token function">ToString</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">)</span><span class="token punctuation">;</span><br /> Builder<span class="token punctuation">.</span><span class="token function">Append</span><span class="token punctuation">(</span><span class="token string">" AND "</span><span class="token punctuation">)</span><span class="token punctuation">;</span><br /> Builder<span class="token punctuation">.</span><span class="token function">Append</span><span class="token punctuation">(</span>\_WhereStatement2<span class="token punctuation">.</span><span class="token function">ToString</span><span class="token punctuation">(</span><span class="token punctuation">)</span> <span class="token operator">+</span> <span class="token string">")"</span><span class="token punctuation">)</span><span class="token punctuation">;</span><br /> <span class="token keyword">return</span> Builder<span class="token punctuation">.</span><span class="token function">ToString</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">;</span><br /> <span class="token punctuation">}</span><br /> <span class="token punctuation">}</span> <br /> <br /> <span class="token keyword">public</span> <span class="token keyword">class</span> <span class="token class-name">Or<span class="token punctuation"><</span>T<span class="token punctuation">></span></span> <span class="token punctuation">:</span> <span class="token type-list"><span class="token class-name">IClause<span class="token punctuation"><</span>T<span class="token punctuation">></span></span></span><br /> <span class="token punctuation">{</span><br /> <span class="token keyword">public</span> <span class="token function">Or</span><span class="token punctuation">(</span><span class="token class-name">IClause<span class="token punctuation"><</span>T<span class="token punctuation">></span></span> WhereStatement1<span class="token punctuation">,</span> <span class="token class-name">IClause<span class="token punctuation"><</span>T<span class="token punctuation">></span></span> WhereStatement2<span class="token punctuation">)</span><br /> <span class="token punctuation">:</span> <span class="token keyword">base</span><span class="token punctuation">(</span><span class="token punctuation">)</span><br /> <span class="token punctuation">{</span><br /> \_WhereStatement1 <span class="token operator">=</span> WhereStatement1<span class="token punctuation">;</span><br /> \_WhereStatement2 <span class="token operator">=</span> WhereStatement2<span class="token punctuation">;</span><br /> <span class="token punctuation">}</span><br /> <br /> <span class="token keyword">protected</span> IClause<span class="token operator"><</span>T<span class="token operator">></span> \_WhereStatement1 <span class="token operator">=</span> <span class="token keyword">null</span><span class="token punctuation">;</span><br /> <span class="token keyword">protected</span> IClause<span class="token operator"><</span>T<span class="token operator">></span> \_WhereStatement2 <span class="token operator">=</span> <span class="token keyword">null</span><span class="token punctuation">;</span><br /> <br /> <span class="token keyword">internal</span> <span class="token keyword">override</span> <span class="token return-type class-name"><span class="token keyword">void</span></span> <span class="token function">SetupSQL</span><span class="token punctuation">(</span><span class="token class-name">SQLHelper</span> Helper<span class="token punctuation">,</span><span class="token class-name">Class</span> Class<span class="token punctuation">)</span><br /> <span class="token punctuation">{</span><br /> \_WhereStatement1<span class="token punctuation">.</span><span class="token function">SetupSQL</span><span class="token punctuation">(</span>Helper<span class="token punctuation">,</span>Class<span class="token punctuation">)</span><span class="token punctuation">;</span><br /> \_WhereStatement2<span class="token punctuation">.</span><span class="token function">SetupSQL</span><span class="token punctuation">(</span>Helper<span class="token punctuation">,</span>Class<span class="token punctuation">)</span><span class="token punctuation">;</span><br /> <span class="token punctuation">}</span><br /> <br /> <span class="token keyword">public</span> <span class="token keyword">override</span> <span class="token return-type class-name"><span class="token keyword">string</span></span> <span class="token function">ToString</span><span class="token punctuation">(</span><span class="token punctuation">)</span><br /> <span class="token punctuation">{</span><br /> <span class="token class-name">StringBuilder</span> Builder <span class="token operator">=</span> <span class="token keyword">new</span> <span class="token constructor-invocation class-name">StringBuilder</span><span class="token punctuation">(</span>\_ColumnName<span class="token punctuation">)</span><span class="token punctuation">;</span><br /> Builder<span class="token punctuation">.</span><span class="token function">Append</span><span class="token punctuation">(</span><span class="token string">"("</span> <span class="token operator">+</span> \_WhereStatement1<span class="token punctuation">.</span><span class="token function">ToString</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">)</span><span class="token punctuation">;</span><br /> Builder<span class="token punctuation">.</span><span class="token function">Append</span><span class="token punctuation">(</span><span class="token string">" OR "</span><span class="token punctuation">)</span><span class="token punctuation">;</span><br /> Builder<span class="token punctuation">.</span><span class="token function">Append</span><span class="token punctuation">(</span>\_WhereStatement2<span class="token punctuation">.</span><span class="token function">ToString</span><span class="token punctuation">(</span><span class="token punctuation">)</span> <span class="token operator">+</span> <span class="token string">")"</span><span class="token punctuation">)</span><span class="token punctuation">;</span><br /> <span class="token keyword">return</span> Builder<span class="token punctuation">.</span><span class="token function">ToString</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">;</span><br /> <span class="token punctuation">}</span><br /> <span class="token punctuation">}</span> <br /> <br /> <span class="token keyword">public</span> <span class="token keyword">class</span> <span class="token class-name">Where<span class="token punctuation"><</span>T<span class="token punctuation">></span></span> <span class="token punctuation">:</span> <span class="token type-list"><span class="token class-name">IClause<span class="token punctuation"><</span>T<span class="token punctuation">></span></span></span><br /> <span class="token punctuation">{</span><br /> <span class="token keyword">public</span> <span class="token function">Where</span><span class="token punctuation">(</span><span class="token class-name">Expression<span class="token punctuation"><</span>Func<span class="token punctuation"><</span>T<span class="token punctuation">,</span> <span class="token keyword">object</span>\<span class="token punctuation">></span><span class="token punctuation">></span></span> Expression<span class="token punctuation">,</span> <span class="token class-name">HaterAide<span class="token punctuation">.</span>SQL<span class="token punctuation">.</span>Enums<span class="token punctuation">.</span>Operators</span> Constraint<span class="token punctuation">,</span> <span class="token class-name"><span class="token keyword">object</span></span> Value<span class="token punctuation">)</span><br /> <span class="token punctuation">:</span> <span class="token keyword">base</span><span class="token punctuation">(</span>Expression<span class="token punctuation">,</span> Constraint<span class="token punctuation">,</span> Value<span class="token punctuation">)</span><br /> <span class="token punctuation">{</span><br /> <br /> <span class="token punctuation">}</span><br /> <br /> <span class="token keyword">public</span> <span class="token function">Where</span><span class="token punctuation">(</span><span class="token class-name">Expression<span class="token punctuation"><</span>Func<span class="token punctuation"><</span>T<span class="token punctuation">,</span> <span class="token keyword">object</span>\<span class="token punctuation">></span><span class="token punctuation">></span></span> Expression<span class="token punctuation">,</span> <span class="token class-name">HaterAide<span class="token punctuation">.</span>SQL<span class="token punctuation">.</span>Enums<span class="token punctuation">.</span>Operators</span> Constraint<span class="token punctuation">,</span> <span class="token class-name"><span class="token keyword">object</span></span> Value1<span class="token punctuation">,</span> <span class="token class-name"><span class="token keyword">object</span></span> Value2<span class="token punctuation">)</span><br /> <span class="token punctuation">:</span> <span class="token keyword">base</span><span class="token punctuation">(</span>Expression<span class="token punctuation">,</span> Constraint<span class="token punctuation">,</span> Value1<span class="token punctuation">)</span><br /> <span class="token punctuation">{</span><br /> \_Value2 <span class="token operator">=</span> Value2<span class="token punctuation">;</span><br /> <span class="token punctuation">}</span><br /> <br /> <span class="token keyword">protected</span> <span class="token keyword">object</span> \_Value2 <span class="token operator">=</span> <span class="token keyword">null</span><span class="token punctuation">;</span><br /> <br /> <span class="token keyword">internal</span> <span class="token keyword">override</span> <span class="token return-type class-name"><span class="token keyword">void</span></span> <span class="token function">SetupSQL</span><span class="token punctuation">(</span><span class="token class-name">SQLHelper</span> Helper<span class="token punctuation">,</span><span class="token class-name">Class</span> Class<span class="token punctuation">)</span><br /> <span class="token punctuation">{</span><br /> <span class="token keyword">if</span> <span class="token punctuation">(</span>\_ColumnType<span class="token punctuation">.</span>FullName<span class="token punctuation">.</span><span class="token function">Equals</span><span class="token punctuation">(</span><span class="token string">"System.String"</span><span class="token punctuation">,</span> StringComparison<span class="token punctuation">.</span>CurrentCultureIgnoreCase<span class="token punctuation">)</span><span class="token punctuation">)</span><br /> <span class="token punctuation">{</span><br /> <span class="token keyword">if</span> <span class="token punctuation">(</span>\_Constraint <span class="token operator">==</span> Enums<span class="token punctuation">.</span>Operators<span class="token punctuation">.</span>Between<span class="token punctuation">)</span><br /> <span class="token punctuation">{</span><br /> Helper<span class="token punctuation">.</span><span class="token function">AddParameter</span><span class="token punctuation">(</span><span class="token string">"@"</span> <span class="token operator">+</span> \_ColumnName <span class="token operator">+</span> <span class="token string">"1"</span><span class="token punctuation">,</span> <span class="token punctuation">(</span><span class="token keyword">string</span><span class="token punctuation">)</span>\_Value<span class="token punctuation">,</span> <span class="token number">255</span><span class="token punctuation">)</span><span class="token punctuation">;</span><br /> Helper<span class="token punctuation">.</span><span class="token function">AddParameter</span><span class="token punctuation">(</span><span class="token string">"@"</span> <span class="token operator">+</span> \_ColumnName <span class="token operator">+</span> <span class="token string">"2"</span><span class="token punctuation">,</span> <span class="token punctuation">(</span><span class="token keyword">string</span><span class="token punctuation">)</span>\_Value2<span class="token punctuation">,</span> <span class="token number">255</span><span class="token punctuation">)</span><span class="token punctuation">;</span><br /> <span class="token punctuation">}</span><br /> <span class="token keyword">else</span><br /> <span class="token punctuation">{</span><br /> Helper<span class="token punctuation">.</span><span class="token function">AddParameter</span><span class="token punctuation">(</span><span class="token string">"@"</span> <span class="token operator">+</span> \_ColumnName<span class="token punctuation">,</span> <span class="token punctuation">(</span><span class="token keyword">string</span><span class="token punctuation">)</span>\_Value<span class="token punctuation">,</span> <span class="token number">255</span><span class="token punctuation">)</span><span class="token punctuation">;</span><br /> <span class="token punctuation">}</span><br /> <span class="token punctuation">}</span><br /> <span class="token keyword">else</span><br /> <span class="token punctuation">{</span><br /> <span class="token keyword">if</span> <span class="token punctuation">(</span>\_Constraint <span class="token operator">==</span> Enums<span class="token punctuation">.</span>Operators<span class="token punctuation">.</span>Between<span class="token punctuation">)</span><br /> <span class="token punctuation">{</span><br /> Helper<span class="token punctuation">.</span><span class="token function">AddParameter</span><span class="token punctuation">(</span><span class="token string">"@"</span> <span class="token operator">+</span> \_ColumnName <span class="token operator">+</span> <span class="token string">"1"</span><span class="token punctuation">,</span> \_Value<span class="token punctuation">,</span> GlobalFunctions<span class="token punctuation">.</span><span class="token function">GetSQLType</span><span class="token punctuation">(</span>\_ColumnType<span class="token punctuation">)</span><span class="token punctuation">)</span><span class="token punctuation">;</span><br /> Helper<span class="token punctuation">.</span><span class="token function">AddParameter</span><span class="token punctuation">(</span><span class="token string">"@"</span> <span class="token operator">+</span> \_ColumnName <span class="token operator">+</span> <span class="token string">"2"</span><span class="token punctuation">,</span> \_Value2<span class="token punctuation">,</span> GlobalFunctions<span class="token punctuation">.</span><span class="token function">GetSQLType</span><span class="token punctuation">(</span>\_ColumnType<span class="token punctuation">)</span><span class="token punctuation">)</span><span class="token punctuation">;</span><br /> <span class="token punctuation">}</span><br /> <span class="token keyword">else</span><br /> <span class="token punctuation">{</span><br /> Helper<span class="token punctuation">.</span><span class="token function">AddParameter</span><span class="token punctuation">(</span><span class="token string">"@"</span> <span class="token operator">+</span> \_ColumnName<span class="token punctuation">,</span> \_Value<span class="token punctuation">,</span> GlobalFunctions<span class="token punctuation">.</span><span class="token function">GetSQLType</span><span class="token punctuation">(</span>\_ColumnType<span class="token punctuation">)</span><span class="token punctuation">)</span><span class="token punctuation">;</span><br /> <span class="token punctuation">}</span><br /> <span class="token punctuation">}</span><br /> <span class="token punctuation">}</span><br /> <br /> <span class="token keyword">public</span> <span class="token keyword">override</span> <span class="token return-type class-name"><span class="token keyword">string</span></span> <span class="token function">ToString</span><span class="token punctuation">(</span><span class="token punctuation">)</span><br /> <span class="token punctuation">{</span><br /> <span class="token class-name">StringBuilder</span> Builder<span class="token operator">=</span><span class="token keyword">new</span> <span class="token constructor-invocation class-name">StringBuilder</span><span class="token punctuation">(</span>\_ColumnName<span class="token punctuation">)</span><span class="token punctuation">;</span><br /> <span class="token keyword">if</span> <span class="token punctuation">(</span>\_Constraint <span class="token operator">==</span> Enums<span class="token punctuation">.</span>Operators<span class="token punctuation">.</span>Equals<span class="token punctuation">)</span><br /> <span class="token punctuation">{</span><br /> Builder<span class="token punctuation">.</span><span class="token function">Append</span><span class="token punctuation">(</span><span class="token string">"="</span><span class="token punctuation">)</span><span class="token punctuation">;</span><br /> <span class="token punctuation">}</span><br /> <span class="token keyword">else</span> <span class="token keyword">if</span> <span class="token punctuation">(</span>\_Constraint <span class="token operator">==</span> Enums<span class="token punctuation">.</span>Operators<span class="token punctuation">.</span>GreaterThan<span class="token punctuation">)</span><br /> <span class="token punctuation">{</span><br /> Builder<span class="token punctuation">.</span><span class="token function">Append</span><span class="token punctuation">(</span><span class="token string">">"</span><span class="token punctuation">)</span><span class="token punctuation">;</span><br /> <span class="token punctuation">}</span><br /> <span class="token keyword">else</span> <span class="token keyword">if</span> <span class="token punctuation">(</span>\_Constraint <span class="token operator">==</span> Enums<span class="token punctuation">.</span>Operators<span class="token punctuation">.</span>GreaterThanOrEqual<span class="token punctuation">)</span><br /> <span class="token punctuation">{</span><br /> Builder<span class="token punctuation">.</span><span class="token function">Append</span><span class="token punctuation">(</span><span class="token string">">="</span><span class="token punctuation">)</span><span class="token punctuation">;</span><br /> <span class="token punctuation">}</span><br /> <span class="token keyword">else</span> <span class="token keyword">if</span> <span class="token punctuation">(</span>\_Constraint <span class="token operator">==</span> Enums<span class="token punctuation">.</span>Operators<span class="token punctuation">.</span>LessThan<span class="token punctuation">)</span><br /> <span class="token punctuation">{</span><br /> Builder<span class="token punctuation">.</span><span class="token function">Append</span><span class="token punctuation">(</span><span class="token string">"<"</span><span class="token punctuation">)</span><span class="token punctuation">;</span><br /> <span class="token punctuation">}</span><br /> <span class="token keyword">else</span> <span class="token keyword">if</span> <span class="token punctuation">(</span>\_Constraint <span class="token operator">==</span> Enums<span class="token punctuation">.</span>Operators<span class="token punctuation">.</span>LessThanOrEqual<span class="token punctuation">)</span><br /> <span class="token punctuation">{</span><br /> Builder<span class="token punctuation">.</span><span class="token function">Append</span><span class="token punctuation">(</span><span class="token string">"<="</span><span class="token punctuation">)</span><span class="token punctuation">;</span><br /> <span class="token punctuation">}</span><br /> <span class="token keyword">else</span> <span class="token keyword">if</span> <span class="token punctuation">(</span>\_Constraint <span class="token operator">==</span> Enums<span class="token punctuation">.</span>Operators<span class="token punctuation">.</span>Like<span class="token punctuation">)</span><br /> <span class="token punctuation">{</span><br /> Builder<span class="token punctuation">.</span><span class="token function">Append</span><span class="token punctuation">(</span><span class="token string">" LIKE "</span><span class="token punctuation">)</span><span class="token punctuation">;</span><br /> <span class="token punctuation">}</span><br /> <span class="token keyword">else</span> <span class="token keyword">if</span> <span class="token punctuation">(</span>\_Constraint <span class="token operator">==</span> Enums<span class="token punctuation">.</span>Operators<span class="token punctuation">.</span>NotEqual<span class="token punctuation">)</span><br /> <span class="token punctuation">{</span><br /> Builder<span class="token punctuation">.</span><span class="token function">Append</span><span class="token punctuation">(</span><span class="token string">"<>"</span><span class="token punctuation">)</span><span class="token punctuation">;</span><br /> <span class="token punctuation">}</span><br /> <br /> <span class="token keyword">if</span> <span class="token punctuation">(</span>\_Constraint <span class="token operator">==</span> Enums<span class="token punctuation">.</span>Operators<span class="token punctuation">.</span>Between<span class="token punctuation">)</span><br /> <span class="token punctuation">{</span><br /> Builder<span class="token punctuation">.</span><span class="token function">Append</span><span class="token punctuation">(</span><span class="token string">" BETWEEN "</span><span class="token punctuation">)</span><span class="token punctuation">;</span><br /> Builder<span class="token punctuation">.</span><span class="token function">Append</span><span class="token punctuation">(</span><span class="token string">"@"</span> <span class="token operator">+</span> \_ColumnName <span class="token operator">+</span> <span class="token string">"1"</span><span class="token punctuation">)</span><span class="token punctuation">;</span><br /> Builder<span class="token punctuation">.</span><span class="token function">Append</span><span class="token punctuation">(</span><span class="token string">" AND "</span><span class="token punctuation">)</span><span class="token punctuation">;</span><br /> Builder<span class="token punctuation">.</span><span class="token function">Append</span><span class="token punctuation">(</span><span class="token string">"@"</span> <span class="token operator">+</span> \_ColumnName <span class="token operator">+</span> <span class="token string">"2"</span><span class="token punctuation">)</span><span class="token punctuation">;</span><br /> <span class="token punctuation">}</span><br /> <span class="token keyword">else</span><br /> <span class="token punctuation">{</span><br /> Builder<span class="token punctuation">.</span><span class="token function">Append</span><span class="token punctuation">(</span><span class="token string">"@"</span> <span class="token operator">+</span> \_ColumnName<span class="token punctuation">)</span><span class="token punctuation">;</span><br /> <span class="token punctuation">}</span><br /> <span class="token keyword">return</span> Builder<span class="token punctuation">.</span><span class="token function">ToString</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">;</span><br /> <span class="token punctuation">}</span><br /> <span class="token punctuation">}</span></code></pre>
<p>There are a couple of enums as well but these classes are all that's really needed for a simple query. The where clause takes in an expression just like the mapping class, an Operator (equals, less than, like, etc.), and a value to compare it to (in the case of between, it takes two values). These can then be joined together with ANDs and ORs to form more complex queries. So you want to find the brown widget that has the blue handle? No problem. What about ordering the items? That's where this class comes in.</p>
<pre class="language-csharp"><code class="language-csharp"> <span class="token keyword">public</span> <span class="token keyword">class</span> <span class="token class-name">OrderBy<span class="token punctuation"><</span>T<span class="token punctuation">></span></span> <span class="token punctuation">:</span> <span class="token type-list"><span class="token class-name">IClause<span class="token punctuation"><</span>T<span class="token punctuation">></span></span></span><br /> <span class="token punctuation">{</span><br /> <span class="token keyword">public</span> <span class="token function">OrderBy</span><span class="token punctuation">(</span><span class="token class-name">Expression<span class="token punctuation"><</span>Func<span class="token punctuation"><</span>T<span class="token punctuation">,</span> <span class="token keyword">object</span>\<span class="token punctuation">></span><span class="token punctuation">></span></span> Expression<span class="token punctuation">,</span> <span class="token class-name">Direction</span> Direction<span class="token punctuation">,</span> <span class="token class-name">IClause<span class="token punctuation"><</span>T<span class="token punctuation">></span></span> NestedOrderBy<span class="token punctuation">)</span><br /> <span class="token punctuation">:</span> <span class="token keyword">base</span><span class="token punctuation">(</span>Expression<span class="token punctuation">,</span> Enums<span class="token punctuation">.</span>Operators<span class="token punctuation">.</span>Equals<span class="token punctuation">,</span> <span class="token keyword">null</span><span class="token punctuation">)</span><br /> <span class="token punctuation">{</span><br /> <span class="token keyword">this</span><span class="token punctuation">.</span>\_NestedOrderBy <span class="token operator">=</span> NestedOrderBy<span class="token punctuation">;</span><br /> <span class="token keyword">this</span><span class="token punctuation">.</span>\_Direction <span class="token operator">=</span> Direction<span class="token punctuation">;</span><br /> <span class="token punctuation">}</span><br /> <br /> <span class="token keyword">protected</span> IClause<span class="token operator"><</span>T<span class="token operator">></span> \_NestedOrderBy<span class="token punctuation">;</span><br /> <span class="token keyword">protected</span> Direction \_Direction<span class="token punctuation">;</span><br /> <br /> <span class="token keyword">public</span> <span class="token keyword">override</span> <span class="token return-type class-name"><span class="token keyword">string</span></span> <span class="token function">ToString</span><span class="token punctuation">(</span><span class="token punctuation">)</span><br /> <span class="token punctuation">{</span><br /> <span class="token class-name">StringBuilder</span> Builder <span class="token operator">=</span> <span class="token keyword">new</span> <span class="token constructor-invocation class-name">StringBuilder</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">;</span><br /> Builder<span class="token punctuation">.</span><span class="token function">Append</span><span class="token punctuation">(</span>\_ColumnName<span class="token punctuation">)</span><span class="token punctuation">;</span><br /> <span class="token keyword">if</span> <span class="token punctuation">(</span>\_Direction <span class="token operator">==</span> Direction<span class="token punctuation">.</span>Ascending<span class="token punctuation">)</span><br /> <span class="token punctuation">{</span><br /> Builder<span class="token punctuation">.</span><span class="token function">Append</span><span class="token punctuation">(</span><span class="token string">" ASC"</span><span class="token punctuation">)</span><span class="token punctuation">;</span><br /> <span class="token punctuation">}</span><br /> <span class="token keyword">else</span><br /> <span class="token punctuation">{</span><br /> Builder<span class="token punctuation">.</span><span class="token function">Append</span><span class="token punctuation">(</span><span class="token string">" DESC"</span><span class="token punctuation">)</span><span class="token punctuation">;</span><br /> <span class="token punctuation">}</span><br /> <span class="token keyword">if</span> <span class="token punctuation">(</span>\_NestedOrderBy <span class="token operator">!=</span> <span class="token keyword">null</span><span class="token punctuation">)</span><br /> <span class="token punctuation">{</span><br /> Builder<span class="token punctuation">.</span><span class="token function">Append</span><span class="token punctuation">(</span><span class="token string">","</span> <span class="token operator">+</span> \_NestedOrderBy<span class="token punctuation">)</span><span class="token punctuation">;</span><br /> <span class="token punctuation">}</span><br /> <span class="token keyword">return</span> Builder<span class="token punctuation">.</span><span class="token function">ToString</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">;</span><br /> <span class="token punctuation">}</span><br /> <span class="token punctuation">}</span></code></pre>
<p>Very simple, uses the same unary expression set up. It also allows for nested items, with the outside items having more weight than the nested OrderBy objects. And all of this gets inputted to a new select function, SelectWhere, that is viewable in the code below. And just like the previous functions in the Session class, it calls the provider, which calls the SQL builder, which calls a newly created class.</p>
<pre class="language-csharp"><code class="language-csharp"> <span class="token keyword">internal</span> <span class="token keyword">class</span> <span class="token class-name">SelectWhere</span><span class="token punctuation">:</span><span class="token type-list"><span class="token class-name">IStatement</span></span><br /> <span class="token punctuation">{</span><br /> <span class="token keyword">public</span> <span class="token function">SelectWhere</span><span class="token punctuation">(</span><span class="token class-name">Class</span> Class<span class="token punctuation">,</span> <span class="token class-name">ClassManager</span> Manager<span class="token punctuation">)</span><br /> <span class="token punctuation">:</span> <span class="token keyword">base</span><span class="token punctuation">(</span>Class<span class="token punctuation">,</span> Manager<span class="token punctuation">)</span><br /> <span class="token punctuation">{</span><br /> <span class="token punctuation">}</span><br /> <br /> <span class="token keyword">public</span> <span class="token return-type class-name">List<span class="token punctuation"><</span>T<span class="token punctuation">></span></span> <span class="token generic-method"><span class="token function">Select</span><span class="token generic class-name"><span class="token punctuation"><</span>T<span class="token punctuation">></span></span></span><span class="token punctuation">(</span><span class="token class-name">SQLHelper</span> Helper<span class="token punctuation">,</span> <span class="token class-name">IClause<span class="token punctuation"><</span>T<span class="token punctuation">></span></span> WhereClause<span class="token punctuation">,</span> <span class="token class-name">IClause<span class="token punctuation"><</span>T<span class="token punctuation">></span></span> OrderByClause<span class="token punctuation">)</span><br /> <span class="token punctuation">{</span><br /> <span class="token class-name">Session</span> TempSession <span class="token operator">=</span> Factory<span class="token punctuation">.</span><span class="token function">CreateSession</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">;</span><br /> <span class="token class-name">List<span class="token punctuation"><</span>T<span class="token punctuation">></span></span> ReturnList <span class="token operator">=</span> <span class="token keyword">new</span> <span class="token constructor-invocation class-name">List<span class="token punctuation"><</span>T<span class="token punctuation">></span></span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">;</span><br /> <span class="token keyword">try</span><br /> <span class="token punctuation">{</span><br /> <span class="token class-name">StringBuilder</span> Builder<span class="token operator">=</span><span class="token keyword">new</span> <span class="token constructor-invocation class-name">StringBuilder</span><span class="token punctuation">(</span><span class="token string">"SELECT "</span><span class="token operator">+</span>\_Class<span class="token punctuation">.</span>IDField<span class="token punctuation">.</span>Name<span class="token operator">+</span><span class="token string">" FROM "</span><span class="token operator">+</span>\_Class<span class="token punctuation">.</span>OriginalType<span class="token punctuation">.</span>Name<span class="token punctuation">)</span><span class="token punctuation">;</span><br /> <span class="token keyword">if</span> <span class="token punctuation">(</span>WhereClause <span class="token operator">!=</span> <span class="token keyword">null</span><span class="token punctuation">)</span><br /> <span class="token punctuation">{</span><br /> Builder<span class="token punctuation">.</span><span class="token function">Append</span><span class="token punctuation">(</span><span class="token string">" WHERE "</span> <span class="token operator">+</span> WhereClause<span class="token punctuation">.</span><span class="token function">ToString</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">)</span><span class="token punctuation">;</span><br /> <span class="token punctuation">}</span><br /> <span class="token keyword">if</span> <span class="token punctuation">(</span>OrderByClause <span class="token operator">!=</span> <span class="token keyword">null</span><span class="token punctuation">)</span><br /> <span class="token punctuation">{</span><br /> Builder<span class="token punctuation">.</span><span class="token function">Append</span><span class="token punctuation">(</span><span class="token string">" ORDER BY "</span> <span class="token operator">+</span> OrderByClause<span class="token punctuation">.</span><span class="token function">ToString</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">)</span><span class="token punctuation">;</span><br /> <span class="token punctuation">}</span><br /> Helper<span class="token punctuation">.</span>Command <span class="token operator">=</span> Builder<span class="token punctuation">.</span><span class="token function">ToString</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">;</span><br /> Helper<span class="token punctuation">.</span>CommandType <span class="token operator">=</span> CommandType<span class="token punctuation">.</span>Text<span class="token punctuation">;</span><br /> Helper<span class="token punctuation">.</span><span class="token function">ClearParameters</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">;</span><br /> Helper<span class="token punctuation">.</span><span class="token function">Open</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">;</span><br /> WhereClause<span class="token punctuation">.</span><span class="token function">SetupSQL</span><span class="token punctuation">(</span>Helper<span class="token punctuation">,</span> \_Class<span class="token punctuation">)</span><span class="token punctuation">;</span><br /> Helper<span class="token punctuation">.</span><span class="token function">ExecuteReader</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">;</span><br /> <span class="token keyword">while</span> <span class="token punctuation">(</span>Helper<span class="token punctuation">.</span><span class="token function">Read</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">)</span><br /> <span class="token punctuation">{</span><br /> <span class="token class-name"><span class="token keyword">object</span></span> ID <span class="token operator">=</span> Helper<span class="token punctuation">.</span><span class="token function">GetParameter</span><span class="token punctuation">(</span>\_Class<span class="token punctuation">.</span>IDField<span class="token punctuation">.</span>Name<span class="token punctuation">,</span> <span class="token keyword">null</span><span class="token punctuation">)</span><span class="token punctuation">;</span><br /> <span class="token class-name">T</span> TempObject <span class="token operator">=</span> <span class="token keyword">default</span><span class="token punctuation">(</span><span class="token type-expression class-name">T</span><span class="token punctuation">)</span><span class="token punctuation">;</span><br /> TempSession<span class="token punctuation">.</span><span class="token generic-method"><span class="token function">Select</span><span class="token generic class-name"><span class="token punctuation"><</span>T<span class="token punctuation">></span></span></span><span class="token punctuation">(</span>ID<span class="token punctuation">,</span> <span class="token keyword">out</span> TempObject<span class="token punctuation">)</span><span class="token punctuation">;</span><br /> ReturnList<span class="token punctuation">.</span><span class="token function">Add</span><span class="token punctuation">(</span>TempObject<span class="token punctuation">)</span><span class="token punctuation">;</span><br /> <span class="token punctuation">}</span><br /> <span class="token punctuation">}</span><br /> <span class="token keyword">catch</span> <span class="token punctuation">{</span> <span class="token punctuation">}</span><br /> <span class="token keyword">finally</span> <span class="token punctuation">{</span> Helper<span class="token punctuation">.</span><span class="token function">Close</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token punctuation">}</span><br /> <span class="token keyword">return</span> ReturnList<span class="token punctuation">;</span><br /> <span class="token punctuation">}</span><br /> <span class="token punctuation">}</span></code></pre>
<p>And as you can see, all the class does is runs a query to find a list of objects that fulfill the query. So that's it for basic queries. For anything more complex, I realized that I needed to be able to create my own stored procedures and call them. That's even simpler.</p>
<pre class="language-csharp"><code class="language-csharp"> <span class="token keyword">internal</span> <span class="token keyword">class</span> <span class="token class-name">SelectStoredProcedure</span> <span class="token punctuation">:</span> <span class="token type-list"><span class="token class-name">IStatement</span></span><br /> <span class="token punctuation">{</span><br /> <span class="token keyword">public</span> <span class="token function">SelectStoredProcedure</span><span class="token punctuation">(</span><span class="token class-name">Class</span> Class<span class="token punctuation">,</span> <span class="token class-name">ClassManager</span> Manager<span class="token punctuation">)</span><br /> <span class="token punctuation">:</span> <span class="token keyword">base</span><span class="token punctuation">(</span>Class<span class="token punctuation">,</span> Manager<span class="token punctuation">)</span><br /> <span class="token punctuation">{</span><br /> <span class="token punctuation">}</span><br /> <br /> <span class="token keyword">public</span> <span class="token return-type class-name">List<span class="token punctuation"><</span>T<span class="token punctuation">></span></span> <span class="token generic-method"><span class="token function">Select</span><span class="token generic class-name"><span class="token punctuation"><</span>T<span class="token punctuation">></span></span></span><span class="token punctuation">(</span><span class="token class-name">SQLHelper</span> Helper<span class="token punctuation">,</span> <span class="token class-name">List<span class="token punctuation"><</span>IVariable<span class="token punctuation">></span></span> Variables<span class="token punctuation">,</span> <span class="token class-name"><span class="token keyword">string</span></span> StoredProcedure<span class="token punctuation">)</span><br /> <span class="token punctuation">{</span><br /> <span class="token class-name">Session</span> TempSession <span class="token operator">=</span> Factory<span class="token punctuation">.</span><span class="token function">CreateSession</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">;</span><br /> <span class="token class-name">List<span class="token punctuation"><</span>T<span class="token punctuation">></span></span> ReturnList <span class="token operator">=</span> <span class="token keyword">new</span> <span class="token constructor-invocation class-name">List<span class="token punctuation"><</span>T<span class="token punctuation">></span></span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">;</span><br /> <span class="token keyword">try</span><br /> <span class="token punctuation">{</span><br /> Helper<span class="token punctuation">.</span>Command <span class="token operator">=</span> StoredProcedure<span class="token punctuation">;</span><br /> Helper<span class="token punctuation">.</span>CommandType <span class="token operator">=</span> CommandType<span class="token punctuation">.</span>StoredProcedure<span class="token punctuation">;</span><br /> Helper<span class="token punctuation">.</span><span class="token function">ClearParameters</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">;</span><br /> Helper<span class="token punctuation">.</span><span class="token function">Open</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">;</span><br /> <span class="token keyword">foreach</span><span class="token punctuation">(</span><span class="token class-name">IVariable</span> Variable <span class="token keyword">in</span> Variables<span class="token punctuation">)</span><br /> <span class="token punctuation">{</span><br /> Variable<span class="token punctuation">.</span><span class="token function">SetupSQL</span><span class="token punctuation">(</span>Helper<span class="token punctuation">)</span><span class="token punctuation">;</span><br /> <span class="token punctuation">}</span><br /> Helper<span class="token punctuation">.</span><span class="token function">ExecuteReader</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">;</span><br /> <span class="token keyword">while</span> <span class="token punctuation">(</span>Helper<span class="token punctuation">.</span><span class="token function">Read</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">)</span><br /> <span class="token punctuation">{</span><br /> <span class="token class-name"><span class="token keyword">object</span></span> ID <span class="token operator">=</span> Helper<span class="token punctuation">.</span><span class="token function">GetParameter</span><span class="token punctuation">(</span>\_Class<span class="token punctuation">.</span>IDField<span class="token punctuation">.</span>Name<span class="token punctuation">,</span> <span class="token keyword">null</span><span class="token punctuation">)</span><span class="token punctuation">;</span><br /> <span class="token class-name">T</span> TempObject <span class="token operator">=</span> <span class="token keyword">default</span><span class="token punctuation">(</span><span class="token type-expression class-name">T</span><span class="token punctuation">)</span><span class="token punctuation">;</span><br /> TempSession<span class="token punctuation">.</span><span class="token generic-method"><span class="token function">Select</span><span class="token generic class-name"><span class="token punctuation"><</span>T<span class="token punctuation">></span></span></span><span class="token punctuation">(</span>ID<span class="token punctuation">,</span> <span class="token keyword">out</span> TempObject<span class="token punctuation">)</span><span class="token punctuation">;</span><br /> ReturnList<span class="token punctuation">.</span><span class="token function">Add</span><span class="token punctuation">(</span>TempObject<span class="token punctuation">)</span><span class="token punctuation">;</span><br /> <span class="token punctuation">}</span><br /> <span class="token punctuation">}</span><br /> <span class="token keyword">catch</span> <span class="token punctuation">{</span> <span class="token punctuation">}</span><br /> <span class="token keyword">finally</span> <span class="token punctuation">{</span> Helper<span class="token punctuation">.</span><span class="token function">Close</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token punctuation">}</span><br /> <span class="token keyword">return</span> ReturnList<span class="token punctuation">;</span><br /> <span class="token punctuation">}</span><br /> <span class="token punctuation">}</span></code></pre>
<p>The function just needs to know the name of the stored procedure and a list of variables.</p>
<pre class="language-csharp"><code class="language-csharp"> <span class="token keyword">public</span> <span class="token keyword">class</span> <span class="token class-name">Variable</span><span class="token punctuation">:</span><span class="token type-list"><span class="token class-name">IVariable</span></span><br /> <span class="token punctuation">{</span><br /> <span class="token keyword">public</span> <span class="token function">Variable</span><span class="token punctuation">(</span><span class="token class-name"><span class="token keyword">string</span></span> Name<span class="token punctuation">,</span> <span class="token class-name"><span class="token keyword">object</span></span> Value<span class="token punctuation">,</span><span class="token class-name">SqlDbType</span> DataType<span class="token punctuation">)</span><br /> <span class="token punctuation">:</span> <span class="token keyword">base</span><span class="token punctuation">(</span>Name<span class="token punctuation">,</span> Value<span class="token punctuation">,</span>DataType<span class="token punctuation">)</span><br /> <span class="token punctuation">{</span><br /> <span class="token punctuation">}</span><br /> <br /> <span class="token keyword">internal</span> <span class="token keyword">override</span> <span class="token return-type class-name"><span class="token keyword">void</span></span> <span class="token function">SetupSQL</span><span class="token punctuation">(</span><span class="token class-name">SQLHelper</span> Helper<span class="token punctuation">)</span><br /> <span class="token punctuation">{</span><br /> Helper<span class="token punctuation">.</span><span class="token function">AddParameter</span><span class="token punctuation">(</span>\_Name<span class="token punctuation">,</span> \_Value<span class="token punctuation">,</span> \_DataType<span class="token punctuation">)</span><span class="token punctuation">;</span><br /> <span class="token punctuation">}</span><br /> <span class="token punctuation">}</span></code></pre>
<p>The variable class is just a holder for the name of the field, the value, and the SQL type. That's it. Now if you paid attention, you'll notice that each of these approaches only query the ID fields for the objects. Once it has the ID field, it calls the select function that already exists. The main reason for this is the simple fact that I'm lazy and didn't want to rewrite all that code again. The second reason is how I've set up the cache.<br />
The caching system that I've set up uses the same provider model that the SQL uses (so I'm going to skip that portion). Instead I'm just going to show you the actual class in charge of caching.</p>
<pre class="language-csharp"><code class="language-csharp"> <span class="token keyword">internal</span> <span class="token keyword">class</span> <span class="token class-name">ASPNetCache</span><span class="token punctuation">:</span><span class="token type-list"><span class="token class-name">ICache</span></span><br /> <span class="token punctuation">{</span><br /> <span class="token keyword">public</span> <span class="token keyword">override</span> <span class="token return-type class-name"><span class="token keyword">bool</span></span> <span class="token function">Exists</span><span class="token punctuation">(</span><span class="token class-name"><span class="token keyword">string</span></span> Name<span class="token punctuation">)</span><br /> <span class="token punctuation">{</span><br /> <span class="token keyword">try</span><br /> <span class="token punctuation">{</span><br /> <span class="token keyword">if</span> <span class="token punctuation">(</span>HttpContext<span class="token punctuation">.</span>Current<span class="token punctuation">.</span>Cache\<span class="token punctuation">[</span>Name\<span class="token punctuation">]</span> <span class="token operator">!=</span> <span class="token keyword">null</span><span class="token punctuation">)</span><br /> <span class="token punctuation">{</span><br /> <span class="token keyword">return</span> <span class="token boolean">true</span><span class="token punctuation">;</span><br /> <span class="token punctuation">}</span><br /> <span class="token punctuation">}</span><br /> <span class="token keyword">catch</span> <span class="token punctuation">{</span> <span class="token punctuation">}</span><br /> <span class="token keyword">return</span> <span class="token boolean">false</span><span class="token punctuation">;</span><br /> <span class="token punctuation">}</span><br /> <br /> <span class="token keyword">public</span> <span class="token keyword">override</span> <span class="token return-type class-name"><span class="token keyword">void</span></span> <span class="token function">Save</span><span class="token punctuation">(</span><span class="token class-name"><span class="token keyword">string</span></span> Name<span class="token punctuation">,</span> <span class="token class-name"><span class="token keyword">object</span></span> Value<span class="token punctuation">)</span><br /> <span class="token punctuation">{</span><br /> <span class="token keyword">if</span> <span class="token punctuation">(</span><span class="token function">Exists</span><span class="token punctuation">(</span>Name<span class="token punctuation">)</span><span class="token punctuation">)</span><br /> <span class="token punctuation">{</span><br /> HttpContext<span class="token punctuation">.</span>Current<span class="token punctuation">.</span>Cache\<span class="token punctuation">[</span>Name\<span class="token punctuation">]</span> <span class="token operator">=</span> Value<span class="token punctuation">;</span><br /> <span class="token punctuation">}</span><br /> <span class="token keyword">else</span><br /> <span class="token punctuation">{</span><br /> HttpContext<span class="token punctuation">.</span>Current<span class="token punctuation">.</span>Cache<span class="token punctuation">.</span><span class="token function">Insert</span><span class="token punctuation">(</span>Name<span class="token punctuation">,</span> Value<span class="token punctuation">,</span> <span class="token keyword">null</span><span class="token punctuation">,</span><br /> System<span class="token punctuation">.</span>Web<span class="token punctuation">.</span>Caching<span class="token punctuation">.</span>Cache<span class="token punctuation">.</span>NoAbsoluteExpiration<span class="token punctuation">,</span><br /> TimeSpan<span class="token punctuation">.</span><span class="token function">FromHours</span><span class="token punctuation">(</span><span class="token number">1.0</span><span class="token punctuation">)</span><span class="token punctuation">)</span><span class="token punctuation">;</span><br /> <span class="token punctuation">}</span><br /> <span class="token punctuation">}</span><br /> <br /> <span class="token keyword">public</span> <span class="token keyword">override</span> <span class="token return-type class-name"><span class="token keyword">void</span></span> <span class="token function">Delete</span><span class="token punctuation">(</span><span class="token class-name"><span class="token keyword">string</span></span> Name<span class="token punctuation">)</span><br /> <span class="token punctuation">{</span><br /> <span class="token keyword">if</span> <span class="token punctuation">(</span><span class="token function">Exists</span><span class="token punctuation">(</span>Name<span class="token punctuation">)</span><span class="token punctuation">)</span><br /> <span class="token punctuation">{</span><br /> HttpContext<span class="token punctuation">.</span>Current<span class="token punctuation">.</span>Cache<span class="token punctuation">.</span><span class="token function">Remove</span><span class="token punctuation">(</span>Name<span class="token punctuation">)</span><span class="token punctuation">;</span><br /> <span class="token punctuation">}</span><br /> <span class="token punctuation">}</span><br /> <br /> <span class="token keyword">public</span> <span class="token keyword">override</span> <span class="token keyword">object</span> <span class="token keyword">this</span>\<span class="token punctuation">[</span><span class="token keyword">string</span> Name\<span class="token punctuation">]</span><br /> <span class="token punctuation">{</span><br /> <span class="token keyword">get</span> <span class="token punctuation">{</span> <span class="token keyword">return</span> HttpContext<span class="token punctuation">.</span>Current<span class="token punctuation">.</span>Cache\<span class="token punctuation">[</span>Name\<span class="token punctuation">]</span><span class="token punctuation">;</span> <span class="token punctuation">}</span><br /> <span class="token punctuation">}</span><br /> <span class="token punctuation">}</span></code></pre>
<p>As you can see there are only three functions and one property. Save, Delete, and a retrieve. I like to keep code simple when possible and this was about as simple as I could make it. So what does this have to do with everything going through the Select function? Well let's look at a scenario.</p>
<p>Let's say that you have a table that holds three items. I make a query against their IDs, which thanks to our cache, places them in there without too much of an issue. Now let's say that I make a query that asks the system for two of those items. The cache is rather dumb so unless we know before hand that the query is going to return something already in memory, we're left with making the query and storing that in memory. So now we have 5 objects in memory. Now let's say we update one of the objects and the object is stored twice in the system. When we save, it's easy to tell that the item is there the first time because we queried against the ID, but what about the other instance? So either we search all of the objects in all of the stored queries, or I have to make that cache a lot smarter, OR I simply force everything through that select statement and simply store the information once. I chose the easy route.</p>
<p>So we delete the item from the cache when we delete from the database, update it when we save, and store it in the database when we call select. That's it, we're done. After the cache is in place, we have a library that will work as a simple ORM. I have no freakin' clue how well it will do in the real world but, hey, I just wanted to see what went into making an ORM. Although I do have a project lined up where I plan to use it and improve upon it. I even see some areas where I could improve the system (and I'm sure everyone else out there sees the giant logic holes and issues that I've set up for myself as well). Anyway, download the code, take a look, leave feedback, and happy coding.</p>
Creating an ORM in C# - Part 6
2009-07-06T00:00:00Z
http://www.gutgames.com/post/Creating-an-ORM-in-C-Part-6/
<p>As always, I'm going to assume that you looked at the previous entries. So if you haven't, go take a look. This entry is just an addition to the last one (I would almost consider labeling it 5.5 instead of 6 actually). The last part of this series dealt with one to one class mappings and how we can deal with them in our relational database. It turns out it's fairly simple, with just a slight change from normal data (especially considering we implemented lazy loading). However I didn't get to the many to one and many to many mappings.<br />
When dealing with one to one mappings, we could simply store the information as an extra entry in the table. With many to many though, that isn't an option. Instead we're basically dealing with a list. And like the lists that we've already dealt with, we need to set it up as a separate table. Thankfully, since we've already dealt with lists we're most of the way there. Anyway, let's start with the reflection and code generation:</p>
<pre class="language-csharp"><code class="language-csharp"> <span class="token keyword">private</span> <span class="token return-type class-name"><span class="token keyword">void</span></span> <span class="token function">SetupManyToManyProperty</span><span class="token punctuation">(</span><span class="token class-name">ILGenerator</span> Generator<span class="token punctuation">,</span><span class="token class-name">Type</span> OriginalType<span class="token punctuation">)</span><br /> <span class="token punctuation">{</span><br /> <span class="token class-name">Label</span> ExitIfStatement <span class="token operator">=</span> Generator<span class="token punctuation">.</span><span class="token function">DefineLabel</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">;</span><br /> <span class="token class-name">Label</span> ExitIf2Statement <span class="token operator">=</span> Generator<span class="token punctuation">.</span><span class="token function">DefineLabel</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">;</span><br /> <span class="token class-name">Label</span> ExitStatement <span class="token operator">=</span> Generator<span class="token punctuation">.</span><span class="token function">DefineLabel</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">;</span><br /> Generator<span class="token punctuation">.</span><span class="token function">DeclareLocal</span><span class="token punctuation">(</span>Field<span class="token punctuation">.</span>FieldType<span class="token punctuation">)</span><span class="token punctuation">;</span><br /> Generator<span class="token punctuation">.</span><span class="token function">DeclareLocal</span><span class="token punctuation">(</span><span class="token keyword">typeof</span><span class="token punctuation">(</span><span class="token type-expression class-name"><span class="token keyword">bool</span></span><span class="token punctuation">)</span><span class="token punctuation">)</span><span class="token punctuation">;</span><br /> Generator<span class="token punctuation">.</span><span class="token function">Emit</span><span class="token punctuation">(</span>OpCodes<span class="token punctuation">.</span>Nop<span class="token punctuation">)</span><span class="token punctuation">;</span><br /> Generator<span class="token punctuation">.</span><span class="token function">Emit</span><span class="token punctuation">(</span>OpCodes<span class="token punctuation">.</span>Ldarg\_0<span class="token punctuation">)</span><span class="token punctuation">;</span><br /> Generator<span class="token punctuation">.</span><span class="token function">Emit</span><span class="token punctuation">(</span>OpCodes<span class="token punctuation">.</span>Ldfld<span class="token punctuation">,</span> Field<span class="token punctuation">.</span>FieldBuilder<span class="token punctuation">)</span><span class="token punctuation">;</span><br /> Generator<span class="token punctuation">.</span><span class="token function">Emit</span><span class="token punctuation">(</span>OpCodes<span class="token punctuation">.</span>Ldnull<span class="token punctuation">)</span><span class="token punctuation">;</span><br /> Generator<span class="token punctuation">.</span><span class="token function">Emit</span><span class="token punctuation">(</span>OpCodes<span class="token punctuation">.</span>Ceq<span class="token punctuation">)</span><span class="token punctuation">;</span><br /> Generator<span class="token punctuation">.</span><span class="token function">Emit</span><span class="token punctuation">(</span>OpCodes<span class="token punctuation">.</span>Ldc\_I4\_0<span class="token punctuation">)</span><span class="token punctuation">;</span><br /> Generator<span class="token punctuation">.</span><span class="token function">Emit</span><span class="token punctuation">(</span>OpCodes<span class="token punctuation">.</span>Ceq<span class="token punctuation">)</span><span class="token punctuation">;</span><br /> Generator<span class="token punctuation">.</span><span class="token function">Emit</span><span class="token punctuation">(</span>OpCodes<span class="token punctuation">.</span>Stloc\_1<span class="token punctuation">)</span><span class="token punctuation">;</span><br /> Generator<span class="token punctuation">.</span><span class="token function">Emit</span><span class="token punctuation">(</span>OpCodes<span class="token punctuation">.</span>Ldloc\_1<span class="token punctuation">)</span><span class="token punctuation">;</span><br /> Generator<span class="token punctuation">.</span><span class="token function">Emit</span><span class="token punctuation">(</span>OpCodes<span class="token punctuation">.</span>Brtrue\_S<span class="token punctuation">,</span> ExitIfStatement<span class="token punctuation">)</span><span class="token punctuation">;</span><br /> Generator<span class="token punctuation">.</span><span class="token function">Emit</span><span class="token punctuation">(</span>OpCodes<span class="token punctuation">.</span>Nop<span class="token punctuation">)</span><span class="token punctuation">;</span><br /> Generator<span class="token punctuation">.</span><span class="token function">Emit</span><span class="token punctuation">(</span>OpCodes<span class="token punctuation">.</span>Call<span class="token punctuation">,</span> <span class="token keyword">typeof</span><span class="token punctuation">(</span><span class="token type-expression class-name">HaterAide<span class="token punctuation">.</span>Factory</span><span class="token punctuation">)</span><span class="token punctuation">.</span><span class="token function">GetMethod</span><span class="token punctuation">(</span><span class="token string">"CreateSession"</span><span class="token punctuation">)</span><span class="token punctuation">)</span><span class="token punctuation">;</span><br /> Generator<span class="token punctuation">.</span><span class="token function">Emit</span><span class="token punctuation">(</span>OpCodes<span class="token punctuation">.</span>Ldarg\_0<span class="token punctuation">)</span><span class="token punctuation">;</span><br /> Generator<span class="token punctuation">.</span><span class="token function">Emit</span><span class="token punctuation">(</span>OpCodes<span class="token punctuation">.</span>Ldfld<span class="token punctuation">,</span> IDField<span class="token punctuation">.</span>FieldBuilder<span class="token punctuation">)</span><span class="token punctuation">;</span><br /> Generator<span class="token punctuation">.</span><span class="token function">Emit</span><span class="token punctuation">(</span>OpCodes<span class="token punctuation">.</span>Box<span class="token punctuation">,</span> IDField<span class="token punctuation">.</span>FieldType<span class="token punctuation">)</span><span class="token punctuation">;</span><br /> Generator<span class="token punctuation">.</span><span class="token function">Emit</span><span class="token punctuation">(</span>OpCodes<span class="token punctuation">.</span>Ldarg\_0<span class="token punctuation">)</span><span class="token punctuation">;</span><br /> Generator<span class="token punctuation">.</span><span class="token function">Emit</span><span class="token punctuation">(</span>OpCodes<span class="token punctuation">.</span>Ldflda<span class="token punctuation">,</span> Field<span class="token punctuation">.</span>FieldBuilder<span class="token punctuation">)</span><span class="token punctuation">;</span><br /> Generator<span class="token punctuation">.</span><span class="token function">Emit</span><span class="token punctuation">(</span>OpCodes<span class="token punctuation">.</span>Ldstr<span class="token punctuation">,</span> \_Attribute<span class="token punctuation">.</span>Name<span class="token punctuation">)</span><span class="token punctuation">;</span><br /> <span class="token class-name">MethodInfo</span> TempMethod <span class="token operator">=</span> <span class="token keyword">typeof</span><span class="token punctuation">(</span><span class="token type-expression class-name">HaterAide<span class="token punctuation">.</span>Session</span><span class="token punctuation">)</span><span class="token punctuation">.</span><span class="token function">GetMethod</span><span class="token punctuation">(</span><span class="token string">"SelectList"</span><span class="token punctuation">)</span><span class="token punctuation">;</span><br /> TempMethod <span class="token operator">=</span> TempMethod<span class="token punctuation">.</span><span class="token function">MakeGenericMethod</span><span class="token punctuation">(</span><span class="token keyword">new</span> Type\<span class="token punctuation">[</span>\<span class="token punctuation">]</span> <span class="token punctuation">{</span> OriginalType<span class="token punctuation">,</span> Field<span class="token punctuation">.</span>FieldType<span class="token punctuation">.</span><span class="token function">GetGenericArguments</span><span class="token punctuation">(</span><span class="token punctuation">)</span>\<span class="token punctuation">[</span><span class="token number">0</span>\<span class="token punctuation">]</span> <span class="token punctuation">}</span><span class="token punctuation">)</span><span class="token punctuation">;</span><br /> Generator<span class="token punctuation">.</span><span class="token function">Emit</span><span class="token punctuation">(</span>OpCodes<span class="token punctuation">.</span>Callvirt<span class="token punctuation">,</span> TempMethod<span class="token punctuation">)</span><span class="token punctuation">;</span><br /> Generator<span class="token punctuation">.</span><span class="token function">Emit</span><span class="token punctuation">(</span>OpCodes<span class="token punctuation">.</span>Nop<span class="token punctuation">)</span><span class="token punctuation">;</span><br /> Generator<span class="token punctuation">.</span><span class="token function">Emit</span><span class="token punctuation">(</span>OpCodes<span class="token punctuation">.</span>Nop<span class="token punctuation">)</span><span class="token punctuation">;</span><br /> Generator<span class="token punctuation">.</span><span class="token function">MarkLabel</span><span class="token punctuation">(</span>ExitIfStatement<span class="token punctuation">)</span><span class="token punctuation">;</span><br /> Generator<span class="token punctuation">.</span><span class="token function">Emit</span><span class="token punctuation">(</span>OpCodes<span class="token punctuation">.</span>Ldarg\_0<span class="token punctuation">)</span><span class="token punctuation">;</span><br /> Generator<span class="token punctuation">.</span><span class="token function">Emit</span><span class="token punctuation">(</span>OpCodes<span class="token punctuation">.</span>Ldfld<span class="token punctuation">,</span> Field<span class="token punctuation">.</span>FieldBuilder<span class="token punctuation">)</span><span class="token punctuation">;</span><br /> Generator<span class="token punctuation">.</span><span class="token function">Emit</span><span class="token punctuation">(</span>OpCodes<span class="token punctuation">.</span>Ldnull<span class="token punctuation">)</span><span class="token punctuation">;</span><br /> Generator<span class="token punctuation">.</span><span class="token function">Emit</span><span class="token punctuation">(</span>OpCodes<span class="token punctuation">.</span>Ceq<span class="token punctuation">)</span><span class="token punctuation">;</span><br /> Generator<span class="token punctuation">.</span><span class="token function">Emit</span><span class="token punctuation">(</span>OpCodes<span class="token punctuation">.</span>Ldc\_I4\_0<span class="token punctuation">)</span><span class="token punctuation">;</span><br /> Generator<span class="token punctuation">.</span><span class="token function">Emit</span><span class="token punctuation">(</span>OpCodes<span class="token punctuation">.</span>Ceq<span class="token punctuation">)</span><span class="token punctuation">;</span><br /> Generator<span class="token punctuation">.</span><span class="token function">Emit</span><span class="token punctuation">(</span>OpCodes<span class="token punctuation">.</span>Stloc\_1<span class="token punctuation">)</span><span class="token punctuation">;</span><br /> Generator<span class="token punctuation">.</span><span class="token function">Emit</span><span class="token punctuation">(</span>OpCodes<span class="token punctuation">.</span>Ldloc\_1<span class="token punctuation">)</span><span class="token punctuation">;</span><br /> Generator<span class="token punctuation">.</span><span class="token function">Emit</span><span class="token punctuation">(</span>OpCodes<span class="token punctuation">.</span>Brtrue\_S<span class="token punctuation">,</span> ExitIf2Statement<span class="token punctuation">)</span><span class="token punctuation">;</span><br /> Generator<span class="token punctuation">.</span><span class="token function">Emit</span><span class="token punctuation">(</span>OpCodes<span class="token punctuation">.</span>Nop<span class="token punctuation">)</span><span class="token punctuation">;</span><br /> Generator<span class="token punctuation">.</span><span class="token function">Emit</span><span class="token punctuation">(</span>OpCodes<span class="token punctuation">.</span>Ldarg\_0<span class="token punctuation">)</span><span class="token punctuation">;</span><br /> Generator<span class="token punctuation">.</span><span class="token function">Emit</span><span class="token punctuation">(</span>OpCodes<span class="token punctuation">.</span>Newobj<span class="token punctuation">,</span> Field<span class="token punctuation">.</span>FieldType<span class="token punctuation">.</span><span class="token function">GetConstructor</span><span class="token punctuation">(</span><span class="token keyword">new</span> Type\<span class="token punctuation">[</span><span class="token number">0</span>\<span class="token punctuation">]</span> <span class="token punctuation">{</span> <span class="token punctuation">}</span><span class="token punctuation">)</span><span class="token punctuation">)</span><span class="token punctuation">;</span><br /> Generator<span class="token punctuation">.</span><span class="token function">Emit</span><span class="token punctuation">(</span>OpCodes<span class="token punctuation">.</span>Stfld<span class="token punctuation">,</span> Field<span class="token punctuation">.</span>FieldBuilder<span class="token punctuation">)</span><span class="token punctuation">;</span><br /> Generator<span class="token punctuation">.</span><span class="token function">Emit</span><span class="token punctuation">(</span>OpCodes<span class="token punctuation">.</span>Nop<span class="token punctuation">)</span><span class="token punctuation">;</span><br /> Generator<span class="token punctuation">.</span><span class="token function">MarkLabel</span><span class="token punctuation">(</span>ExitIf2Statement<span class="token punctuation">)</span><span class="token punctuation">;</span><br /> Generator<span class="token punctuation">.</span><span class="token function">Emit</span><span class="token punctuation">(</span>OpCodes<span class="token punctuation">.</span>Ldarg\_0<span class="token punctuation">)</span><span class="token punctuation">;</span><br /> Generator<span class="token punctuation">.</span><span class="token function">Emit</span><span class="token punctuation">(</span>OpCodes<span class="token punctuation">.</span>Ldfld<span class="token punctuation">,</span> Field<span class="token punctuation">.</span>FieldBuilder<span class="token punctuation">)</span><span class="token punctuation">;</span><br /> Generator<span class="token punctuation">.</span><span class="token function">Emit</span><span class="token punctuation">(</span>OpCodes<span class="token punctuation">.</span>Stloc\_0<span class="token punctuation">)</span><span class="token punctuation">;</span><br /> Generator<span class="token punctuation">.</span><span class="token function">Emit</span><span class="token punctuation">(</span>OpCodes<span class="token punctuation">.</span>Br\_S<span class="token punctuation">,</span> ExitStatement<span class="token punctuation">)</span><span class="token punctuation">;</span><br /> Generator<span class="token punctuation">.</span><span class="token function">MarkLabel</span><span class="token punctuation">(</span>ExitStatement<span class="token punctuation">)</span><span class="token punctuation">;</span><br /> Generator<span class="token punctuation">.</span><span class="token function">Emit</span><span class="token punctuation">(</span>OpCodes<span class="token punctuation">.</span>Ldloc\_0<span class="token punctuation">)</span><span class="token punctuation">;</span><br /> Generator<span class="token punctuation">.</span><span class="token function">Emit</span><span class="token punctuation">(</span>OpCodes<span class="token punctuation">.</span>Ret<span class="token punctuation">)</span><span class="token punctuation">;</span><br /> <span class="token punctuation">}</span></code></pre>
<p>If you compared this to the one to one mapping, you actually wouldn't see much in terms of change. There is one change though, instead of getting the Select function, we are looking for the SelectList function in the Session class. And since the Session class is just a proxy, we may as well take a look at what it ends up calling:</p>
<pre class="language-csharp"><code class="language-csharp"> <span class="token keyword">internal</span> <span class="token keyword">override</span> <span class="token return-type class-name"><span class="token keyword">object</span></span> <span class="token generic-method"><span class="token function">SelectListByID</span><span class="token generic class-name"><span class="token punctuation"><</span>T1<span class="token punctuation">,</span> T2<span class="token punctuation">></span></span></span><span class="token punctuation">(</span><span class="token class-name"><span class="token keyword">object</span></span> IDValue<span class="token punctuation">,</span> <span class="token class-name"><span class="token keyword">string</span></span> FieldName<span class="token punctuation">)</span><br /> <span class="token punctuation">{</span><br /> <span class="token class-name">Class</span> TempInputClassDefinition <span class="token operator">=</span> <span class="token keyword">null</span><span class="token punctuation">;</span><br /> <span class="token class-name">Class</span> TempOutputClassDefinition <span class="token operator">=</span> <span class="token keyword">null</span><span class="token punctuation">;</span><br /> <span class="token keyword">try</span><br /> <span class="token punctuation">{</span><br /> TempInputClassDefinition <span class="token operator">=</span> ClassManager\<span class="token punctuation">[</span><span class="token keyword">typeof</span><span class="token punctuation">(</span><span class="token type-expression class-name">T1</span><span class="token punctuation">)</span>\<span class="token punctuation">]</span><span class="token punctuation">;</span><br /> TempOutputClassDefinition <span class="token operator">=</span> ClassManager\<span class="token punctuation">[</span><span class="token keyword">typeof</span><span class="token punctuation">(</span><span class="token type-expression class-name">T2</span><span class="token punctuation">)</span>\<span class="token punctuation">]</span><span class="token punctuation">;</span><br /> <span class="token punctuation">}</span><br /> <span class="token keyword">catch</span> <span class="token punctuation">{</span> TempInputClassDefinition <span class="token operator">=</span> <span class="token keyword">null</span><span class="token punctuation">;</span> TempOutputClassDefinition <span class="token operator">=</span> <span class="token keyword">null</span><span class="token punctuation">;</span> <span class="token punctuation">}</span><br /> <span class="token keyword">return</span> SQLBuilder<span class="token punctuation">.</span><span class="token generic-method"><span class="token function">SelectListByID</span><span class="token generic class-name"><span class="token punctuation"><</span>T2<span class="token punctuation">></span></span></span><span class="token punctuation">(</span>ConnectionString<span class="token punctuation">,</span> IDValue<span class="token punctuation">,</span> TempInputClassDefinition<span class="token punctuation">,</span> TempOutputClassDefinition<span class="token punctuation">,</span> ClassManager<span class="token punctuation">,</span> FieldName<span class="token punctuation">)</span><span class="token punctuation">;</span><br /> <span class="token punctuation">}</span></code></pre>
<p>This in turn calls:</p>
<pre class="language-csharp"><code class="language-csharp"> <span class="token keyword">internal</span> <span class="token keyword">static</span> <span class="token return-type class-name"><span class="token keyword">object</span></span> <span class="token generic-method"><span class="token function">SelectListByID</span><span class="token generic class-name"><span class="token punctuation"><</span>T<span class="token punctuation">></span></span></span><span class="token punctuation">(</span><span class="token class-name"><span class="token keyword">string</span></span> ConnectionString<span class="token punctuation">,</span> <span class="token class-name"><span class="token keyword">object</span></span> IDValue<span class="token punctuation">,</span><br /> <span class="token class-name">Class</span> TempInputClassDefinition<span class="token punctuation">,</span> <span class="token class-name">Class</span> TempOutputClassDefinition<span class="token punctuation">,</span> <span class="token class-name">ClassManager</span> ClassManager<span class="token punctuation">,</span><span class="token class-name"><span class="token keyword">string</span></span> FieldName<span class="token punctuation">)</span><br /> <span class="token punctuation">{</span><br /> <span class="token class-name">Utilities<span class="token punctuation">.</span>SQLHelper<span class="token punctuation">.</span>SQLHelper</span> Helper <span class="token operator">=</span> <span class="token keyword">new</span> <span class="token constructor-invocation class-name">Utilities<span class="token punctuation">.</span>SQLHelper<span class="token punctuation">.</span>SQLHelper</span><span class="token punctuation">(</span><span class="token string">""</span><span class="token punctuation">,</span> ConnectionString<span class="token punctuation">,</span> CommandType<span class="token punctuation">.</span>Text<span class="token punctuation">)</span><span class="token punctuation">;</span><br /> <span class="token class-name">SelectManyToMany</span> TempSelect <span class="token operator">=</span> <span class="token keyword">new</span> <span class="token constructor-invocation class-name">SelectManyToMany</span><span class="token punctuation">(</span>TempInputClassDefinition<span class="token punctuation">,</span> TempOutputClassDefinition<span class="token punctuation">,</span> ClassManager<span class="token punctuation">,</span> FieldName<span class="token punctuation">)</span><span class="token punctuation">;</span><br /> <span class="token keyword">return</span> TempSelect<span class="token punctuation">.</span><span class="token generic-method"><span class="token function">SelectByID</span><span class="token generic class-name"><span class="token punctuation"><</span>T<span class="token punctuation">></span></span></span><span class="token punctuation">(</span>IDValue<span class="token punctuation">,</span> Helper<span class="token punctuation">)</span><span class="token punctuation">;</span><br /> <span class="token punctuation">}</span></code></pre>
<p>Which in turn builds a SelectManyToMany class:</p>
<pre class="language-csharp"><code class="language-csharp"> <span class="token keyword">internal</span> <span class="token keyword">class</span> <span class="token class-name">SelectManyToMany</span><span class="token punctuation">:</span><span class="token type-list"><span class="token class-name">IStatement</span></span><br /> <span class="token punctuation">{</span><br /> <span class="token keyword">public</span> <span class="token function">SelectManyToMany</span><span class="token punctuation">(</span><span class="token class-name">Class</span> InputClass<span class="token punctuation">,</span><span class="token class-name">Class</span> OutputClass<span class="token punctuation">,</span> <span class="token class-name">ClassManager</span> Manager<span class="token punctuation">,</span><span class="token class-name"><span class="token keyword">string</span></span> FieldName<span class="token punctuation">)</span><br /> <span class="token punctuation">:</span> <span class="token keyword">base</span><span class="token punctuation">(</span>InputClass<span class="token punctuation">,</span> Manager<span class="token punctuation">)</span><br /> <span class="token punctuation">{</span><br /> <span class="token keyword">this</span><span class="token punctuation">.</span>\_OutputClass <span class="token operator">=</span> OutputClass<span class="token punctuation">;</span><br /> <span class="token keyword">this</span><span class="token punctuation">.</span>\_FieldName <span class="token operator">=</span> FieldName<span class="token punctuation">;</span><br /> <span class="token punctuation">}</span> <br /> <br /> <span class="token keyword">private</span> Class \_OutputClass <span class="token operator">=</span> <span class="token keyword">null</span><span class="token punctuation">;</span><br /> <span class="token keyword">private</span> <span class="token keyword">string</span> \_FieldName <span class="token operator">=</span> <span class="token string">""</span><span class="token punctuation">;</span> <br /> <br /> <span class="token keyword">public</span> <span class="token return-type class-name"><span class="token keyword">object</span></span> <span class="token generic-method"><span class="token function">SelectByID</span><span class="token generic class-name"><span class="token punctuation"><</span>T<span class="token punctuation">></span></span></span><span class="token punctuation">(</span><span class="token class-name"><span class="token keyword">object</span></span> IDValue<span class="token punctuation">,</span> <span class="token class-name">SQLHelper</span> Helper<span class="token punctuation">)</span><br /> <span class="token punctuation">{</span><br /> <span class="token class-name">List<span class="token punctuation"><</span>T<span class="token punctuation">></span></span> ReturnList <span class="token operator">=</span> <span class="token keyword">new</span> <span class="token constructor-invocation class-name">List<span class="token punctuation"><</span>T<span class="token punctuation">></span></span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">;</span> <br /> <br /> <span class="token keyword">foreach</span><span class="token punctuation">(</span><span class="token class-name">Property</span> TempProperty <span class="token keyword">in</span> \_Class<span class="token punctuation">.</span>Properties<span class="token punctuation">)</span><br /> <span class="token punctuation">{</span><br /> <span class="token keyword">if</span><span class="token punctuation">(</span>TempProperty<span class="token punctuation">.</span>Attribute<span class="token punctuation">.</span>Name<span class="token punctuation">.</span><span class="token function">Equals</span><span class="token punctuation">(</span>\_FieldName<span class="token punctuation">)</span><span class="token punctuation">)</span><br /> <span class="token punctuation">{</span><br /> Helper<span class="token punctuation">.</span>Command<span class="token operator">=</span>TempProperty<span class="token punctuation">.</span>Attribute<span class="token punctuation">.</span>MappedProperty<span class="token operator">+</span><span class="token string">"\_Select\_"</span><span class="token operator">+</span>\_Class<span class="token punctuation">.</span>OriginalType<span class="token punctuation">.</span>Name<span class="token punctuation">;</span><br /> Helper<span class="token punctuation">.</span>CommandType<span class="token operator">=</span>CommandType<span class="token punctuation">.</span>StoredProcedure<span class="token punctuation">;</span><br /> <span class="token keyword">break</span><span class="token punctuation">;</span><br /> <span class="token punctuation">}</span><br /> <span class="token punctuation">}</span><br /> <span class="token class-name">List<span class="token punctuation"><</span><span class="token keyword">object</span>\<span class="token punctuation">></span></span> IDList <span class="token operator">=</span> <span class="token function">LoadIDList</span><span class="token punctuation">(</span>IDValue<span class="token punctuation">,</span> Helper<span class="token punctuation">,</span> ReturnList<span class="token punctuation">)</span><span class="token punctuation">;</span><br /> ReturnList<span class="token operator">=</span><span class="token function">LoadList</span><span class="token punctuation">(</span>IDList<span class="token punctuation">,</span>Helper<span class="token punctuation">,</span>ReturnList<span class="token punctuation">)</span><span class="token punctuation">;</span> <br /> <span class="token keyword">return</span> ReturnList<span class="token punctuation">;</span><br /> <span class="token punctuation">}</span> <br /> <br /> <span class="token keyword">private</span> <span class="token return-type class-name">List<span class="token punctuation"><</span>T<span class="token punctuation">></span></span> <span class="token generic-method"><span class="token function">LoadList</span><span class="token generic class-name"><span class="token punctuation"><</span>T<span class="token punctuation">></span></span></span><span class="token punctuation">(</span><span class="token class-name">List<span class="token punctuation"><</span><span class="token keyword">object</span>\<span class="token punctuation">></span></span> IDList<span class="token punctuation">,</span><span class="token class-name">SQLHelper</span> Helper<span class="token punctuation">,</span><span class="token class-name">List<span class="token punctuation"><</span>T<span class="token punctuation">></span></span> ReturnList<span class="token punctuation">)</span><br /> <span class="token punctuation">{</span><br /> <span class="token class-name">Session</span> TempSession<span class="token operator">=</span>Factory<span class="token punctuation">.</span><span class="token function">CreateSession</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">;</span><br /> <span class="token keyword">foreach</span> <span class="token punctuation">(</span><span class="token class-name"><span class="token keyword">object</span></span> ID <span class="token keyword">in</span> IDList<span class="token punctuation">)</span><br /> <span class="token punctuation">{</span><br /> <span class="token class-name">T</span> ClassInstance <span class="token operator">=</span> <span class="token punctuation">(</span>T<span class="token punctuation">)</span>Activator<span class="token punctuation">.</span><span class="token function">CreateInstance</span><span class="token punctuation">(</span>\_OutputClass<span class="token punctuation">.</span>DerivedType<span class="token punctuation">)</span><span class="token punctuation">;</span><br /> TempSession<span class="token punctuation">.</span><span class="token generic-method"><span class="token function">Select</span><span class="token generic class-name"><span class="token punctuation"><</span>T<span class="token punctuation">></span></span></span><span class="token punctuation">(</span>ID<span class="token punctuation">,</span> <span class="token keyword">out</span> ClassInstance<span class="token punctuation">)</span><span class="token punctuation">;</span><br /> ReturnList<span class="token punctuation">.</span><span class="token function">Add</span><span class="token punctuation">(</span>ClassInstance<span class="token punctuation">)</span><span class="token punctuation">;</span><br /> <span class="token punctuation">}</span><br /> <span class="token keyword">return</span> ReturnList<span class="token punctuation">;</span><br /> <span class="token punctuation">}</span> <br /> <span class="token keyword">private</span> <span class="token return-type class-name">List<span class="token punctuation"><</span><span class="token keyword">object</span>\<span class="token punctuation">></span></span> <span class="token generic-method"><span class="token function">LoadIDList</span><span class="token generic class-name"><span class="token punctuation"><</span>T<span class="token punctuation">></span></span></span><span class="token punctuation">(</span><span class="token class-name"><span class="token keyword">object</span></span> IDValue<span class="token punctuation">,</span> <span class="token class-name">SQLHelper</span> Helper<span class="token punctuation">,</span> <span class="token class-name">List<span class="token punctuation"><</span>T<span class="token punctuation">></span></span> ReturnList<span class="token punctuation">)</span><br /> <span class="token punctuation">{</span><br /> <span class="token class-name">List<span class="token punctuation"><</span><span class="token keyword">object</span>\<span class="token punctuation">></span></span> IDList <span class="token operator">=</span> <span class="token keyword">new</span> <span class="token constructor-invocation class-name">List<span class="token punctuation"><</span><span class="token keyword">object</span>\<span class="token punctuation">></span></span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">;</span><br /> <span class="token class-name">IDataType</span> IDField<span class="token operator">=</span>GlobalFunctions<span class="token punctuation">.</span><span class="token function">GetSQLType</span><span class="token punctuation">(</span>\_Class<span class="token punctuation">.</span>IDField<span class="token punctuation">,</span>\_Class<span class="token punctuation">,</span>\_Manager<span class="token punctuation">)</span><span class="token punctuation">;</span><br /> <span class="token keyword">try</span><br /> <span class="token punctuation">{</span><br /> Helper<span class="token punctuation">.</span><span class="token function">Open</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">;</span><br /> Helper<span class="token punctuation">.</span><span class="token function">AddParameter</span><span class="token punctuation">(</span><span class="token string">"@"</span> <span class="token operator">+</span> \_Class<span class="token punctuation">.</span>OriginalType<span class="token punctuation">.</span>Name <span class="token operator">+</span> <span class="token string">"\_"</span> <span class="token operator">+</span> IDField<span class="token punctuation">.</span>Name<span class="token punctuation">,</span> IDValue<span class="token punctuation">,</span> IDField<span class="token punctuation">.</span>DataType<span class="token punctuation">)</span><span class="token punctuation">;</span><br /> Helper<span class="token punctuation">.</span><span class="token function">ExecuteReader</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">;</span><br /> <span class="token keyword">while</span> <span class="token punctuation">(</span>Helper<span class="token punctuation">.</span><span class="token function">Read</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">)</span><br /> <span class="token punctuation">{</span><br /> IDList<span class="token punctuation">.</span><span class="token function">Add</span><span class="token punctuation">(</span>Helper<span class="token punctuation">.</span><span class="token function">GetParameter</span><span class="token punctuation">(</span>\_OutputClass<span class="token punctuation">.</span>OriginalType<span class="token punctuation">.</span>Name <span class="token operator">+</span> <span class="token string">"\_"</span> <span class="token operator">+</span> \_OutputClass<span class="token punctuation">.</span>IDField<span class="token punctuation">.</span>Name<span class="token punctuation">,</span> <span class="token keyword">null</span><span class="token punctuation">)</span><span class="token punctuation">)</span><span class="token punctuation">;</span><br /> <span class="token punctuation">}</span><br /> <span class="token punctuation">}</span><br /> <span class="token keyword">catch</span> <span class="token punctuation">{</span> <span class="token punctuation">}</span><br /> <span class="token keyword">finally</span> <span class="token punctuation">{</span> Helper<span class="token punctuation">.</span><span class="token function">Close</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token punctuation">}</span><br /> <span class="token keyword">return</span> IDList<span class="token punctuation">;</span><br /> <span class="token punctuation">}</span><br /> <span class="token punctuation">}</span></code></pre>
<p>The class works like the other IStatement classes. The big difference is that it loads a list instead of a single item. In fact since we already have a select function for a single entity, all it does is loads the list of IDs from the database and calls select on the individual IDs.<br />
So we can load the items, but at present we have no table to actually pull the IDs from, we have no way to save them, etc. So let's start going down that road by defining a many to many data type.</p>
<pre class="language-csharp"><code class="language-csharp"> <span class="token keyword">internal</span> <span class="token keyword">class</span> <span class="token class-name">ManyToManyClassType</span><span class="token punctuation">:</span><span class="token type-list"><span class="token class-name">IDataType</span></span><br /> <span class="token punctuation">{</span><br /> <span class="token keyword">public</span> <span class="token function">ManyToManyClassType</span><span class="token punctuation">(</span><span class="token class-name">Attribute</span> Attribute<span class="token punctuation">,</span> <span class="token class-name">Class</span> Class<span class="token punctuation">,</span> <span class="token class-name">ClassManager</span> Manager<span class="token punctuation">)</span><br /> <span class="token punctuation">:</span> <span class="token keyword">base</span><span class="token punctuation">(</span>Attribute<span class="token punctuation">)</span><br /> <span class="token punctuation">{</span><br /> <span class="token class-name">Type</span> MappedType <span class="token operator">=</span> Attribute<span class="token punctuation">.</span>Type<span class="token punctuation">.</span><span class="token function">GetGenericArguments</span><span class="token punctuation">(</span><span class="token punctuation">)</span>\<span class="token punctuation">[</span><span class="token number">0</span>\<span class="token punctuation">]</span><span class="token punctuation">;</span><br /> <span class="token class-name">Class</span> MappedClass <span class="token operator">=</span> Manager\<span class="token punctuation">[</span>MappedType\<span class="token punctuation">]</span><span class="token punctuation">;</span><br /> \_Class <span class="token operator">=</span> Class<span class="token punctuation">;</span><br /> \_Manager <span class="token operator">=</span> Manager<span class="token punctuation">;</span><br /> \_MappedClass <span class="token operator">=</span> MappedClass<span class="token punctuation">;</span> <br /> <br /> MappedIDField <span class="token operator">=</span> GlobalFunctions<span class="token punctuation">.</span><span class="token function">GetSQLType</span><span class="token punctuation">(</span>MappedClass<span class="token punctuation">.</span>IDField<span class="token punctuation">,</span> MappedClass<span class="token punctuation">,</span> Manager<span class="token punctuation">)</span><span class="token punctuation">;</span><br /> IDField <span class="token operator">=</span> GlobalFunctions<span class="token punctuation">.</span><span class="token function">GetSQLType</span><span class="token punctuation">(</span>Class<span class="token punctuation">.</span>IDField<span class="token punctuation">,</span> Class<span class="token punctuation">,</span> Manager<span class="token punctuation">)</span><span class="token punctuation">;</span><br /> IDField<span class="token punctuation">.</span>Constraints<span class="token punctuation">.</span><span class="token function">Clear</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">;</span><br /> MappedIDField<span class="token punctuation">.</span>Constraints<span class="token punctuation">.</span><span class="token function">Clear</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">;</span><br /> <span class="token punctuation">}</span> <br /> <br /> <span class="token keyword">public</span> <span class="token return-type class-name">IDataType</span> IDField <span class="token punctuation">{</span> <span class="token keyword">get</span><span class="token punctuation">;</span> <span class="token keyword">set</span><span class="token punctuation">;</span> <span class="token punctuation">}</span><br /> <span class="token keyword">public</span> <span class="token return-type class-name">IDataType</span> MappedIDField <span class="token punctuation">{</span> <span class="token keyword">get</span><span class="token punctuation">;</span> <span class="token keyword">set</span><span class="token punctuation">;</span> <span class="token punctuation">}</span><br /> <span class="token keyword">public</span> Class \_Class <span class="token operator">=</span> <span class="token keyword">null</span><span class="token punctuation">;</span><br /> <span class="token keyword">public</span> Class \_MappedClass <span class="token operator">=</span> <span class="token keyword">null</span><span class="token punctuation">;</span><br /> <span class="token keyword">public</span> ClassManager \_Manager <span class="token operator">=</span> <span class="token keyword">null</span><span class="token punctuation">;</span> <br /> <br /> <span class="token keyword">public</span> <span class="token keyword">override</span> <span class="token return-type class-name"><span class="token keyword">string</span></span> <span class="token function">CreateTableCommand</span><span class="token punctuation">(</span><span class="token punctuation">)</span><br /> <span class="token punctuation">{</span><br /> <span class="token class-name">StringBuilder</span> Builder <span class="token operator">=</span> <span class="token keyword">new</span> <span class="token constructor-invocation class-name">StringBuilder</span><span class="token punctuation">(</span><span class="token string">"CREATE TABLE "</span> <span class="token operator">+</span> Attribute<span class="token punctuation">.</span>MappedProperty <span class="token operator">+</span> <span class="token string">"("</span> <span class="token operator">+</span> Name <span class="token operator">+</span> <span class="token string">"ID int IDENTITY,"</span><span class="token punctuation">)</span><span class="token punctuation">;</span><br /> Builder<span class="token punctuation">.</span><span class="token function">Append</span><span class="token punctuation">(</span>\_Class<span class="token punctuation">.</span>OriginalType<span class="token punctuation">.</span>Name <span class="token operator">+</span> <span class="token string">"\_"</span> <span class="token operator">+</span> IDField<span class="token punctuation">.</span><span class="token function">CreateTableCommand</span><span class="token punctuation">(</span><span class="token punctuation">)</span> <span class="token operator">+</span> <span class="token string">","</span><span class="token punctuation">)</span><span class="token punctuation">;</span><br /> Builder<span class="token punctuation">.</span><span class="token function">Append</span><span class="token punctuation">(</span>\_MappedClass<span class="token punctuation">.</span>OriginalType<span class="token punctuation">.</span>Name <span class="token operator">+</span> <span class="token string">"\_"</span> <span class="token operator">+</span> MappedIDField<span class="token punctuation">.</span><span class="token function">CreateTableCommand</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">)</span><span class="token punctuation">;</span><br /> Builder<span class="token punctuation">.</span><span class="token function">Append</span><span class="token punctuation">(</span><span class="token string">", PRIMARY KEY("</span> <span class="token operator">+</span> Name <span class="token operator">+</span> <span class="token string">"ID)"</span><span class="token punctuation">)</span><span class="token punctuation">;</span><br /> Builder<span class="token punctuation">.</span><span class="token function">Append</span><span class="token punctuation">(</span><span class="token string">")"</span><span class="token punctuation">)</span><span class="token punctuation">;</span><br /> <span class="token keyword">return</span> Builder<span class="token punctuation">.</span><span class="token function">ToString</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">;</span><br /> <span class="token punctuation">}</span> <br /> <br /> <span class="token keyword">public</span> <span class="token keyword">override</span> <span class="token return-type class-name"><span class="token keyword">string</span></span> <span class="token function">CreateInsertCommand</span><span class="token punctuation">(</span><span class="token punctuation">)</span><br /> <span class="token punctuation">{</span><br /> <span class="token class-name">StringBuilder</span> Builder <span class="token operator">=</span> <span class="token keyword">new</span> <span class="token constructor-invocation class-name">StringBuilder</span><span class="token punctuation">(</span><span class="token string">"EXEC dbo.sp\_executesql @statement = N'CREATE PROCEDURE dbo."</span> <span class="token operator">+</span> Attribute<span class="token punctuation">.</span>MappedProperty <span class="token operator">+</span> <span class="token string">"\_Insert\\n"</span><span class="token punctuation">)</span><span class="token punctuation">;</span><br /> Builder<span class="token punctuation">.</span><span class="token function">Append</span><span class="token punctuation">(</span>IDField<span class="token punctuation">.</span><span class="token function">CreateStoredProcedureParameter</span><span class="token punctuation">(</span><span class="token boolean">false</span><span class="token punctuation">,</span> <span class="token boolean">true</span><span class="token punctuation">)</span><span class="token punctuation">.</span><span class="token function">Replace</span><span class="token punctuation">(</span><span class="token string">"@"</span><span class="token punctuation">,</span> <span class="token string">"@"</span> <span class="token operator">+</span> \_Class<span class="token punctuation">.</span>OriginalType<span class="token punctuation">.</span>Name <span class="token operator">+</span> <span class="token string">"\_"</span><span class="token punctuation">)</span> <span class="token operator">+</span> <span class="token string">",\\n"</span><span class="token punctuation">)</span><span class="token punctuation">;</span><br /> Builder<span class="token punctuation">.</span><span class="token function">Append</span><span class="token punctuation">(</span>MappedIDField<span class="token punctuation">.</span><span class="token function">CreateStoredProcedureParameter</span><span class="token punctuation">(</span><span class="token boolean">false</span><span class="token punctuation">,</span> <span class="token boolean">true</span><span class="token punctuation">)</span><span class="token punctuation">.</span><span class="token function">Replace</span><span class="token punctuation">(</span><span class="token string">"@"</span><span class="token punctuation">,</span> <span class="token string">"@"</span> <span class="token operator">+</span> \_MappedClass<span class="token punctuation">.</span>OriginalType<span class="token punctuation">.</span>Name <span class="token operator">+</span> <span class="token string">"\_"</span><span class="token punctuation">)</span><span class="token punctuation">)</span><span class="token punctuation">;</span><br /> Builder<span class="token punctuation">.</span><span class="token function">Append</span><span class="token punctuation">(</span><span class="token string">"\\nAS\\nINSERT INTO "</span> <span class="token operator">+</span> Attribute<span class="token punctuation">.</span>MappedProperty <span class="token operator">+</span> <span class="token string">"("</span><span class="token punctuation">)</span><span class="token punctuation">;</span><br /> Builder<span class="token punctuation">.</span><span class="token function">Append</span><span class="token punctuation">(</span>\_Class<span class="token punctuation">.</span>OriginalType<span class="token punctuation">.</span>Name <span class="token operator">+</span> <span class="token string">"\_"</span> <span class="token operator">+</span> IDField<span class="token punctuation">.</span>Name <span class="token operator">+</span> <span class="token string">","</span><span class="token punctuation">)</span><span class="token punctuation">;</span><br /> Builder<span class="token punctuation">.</span><span class="token function">Append</span><span class="token punctuation">(</span>\_MappedClass<span class="token punctuation">.</span>OriginalType<span class="token punctuation">.</span>Name <span class="token operator">+</span> <span class="token string">"\_"</span> <span class="token operator">+</span> MappedIDField<span class="token punctuation">.</span>Name <span class="token operator">+</span> <span class="token string">") VALUES ("</span><span class="token punctuation">)</span><span class="token punctuation">;</span><br /> Builder<span class="token punctuation">.</span><span class="token function">Append</span><span class="token punctuation">(</span><span class="token string">"@"</span><span class="token operator">+</span>\_Class<span class="token punctuation">.</span>OriginalType<span class="token punctuation">.</span>Name <span class="token operator">+</span> <span class="token string">"\_"</span> <span class="token operator">+</span> IDField<span class="token punctuation">.</span>Name <span class="token operator">+</span> <span class="token string">","</span><span class="token punctuation">)</span><span class="token punctuation">;</span><br /> Builder<span class="token punctuation">.</span><span class="token function">Append</span><span class="token punctuation">(</span><span class="token string">"@"</span> <span class="token operator">+</span> \_MappedClass<span class="token punctuation">.</span>OriginalType<span class="token punctuation">.</span>Name <span class="token operator">+</span> <span class="token string">"\_"</span> <span class="token operator">+</span> MappedIDField<span class="token punctuation">.</span>Name <span class="token operator">+</span> <span class="token string">")\\nRETURN'\\n"</span><span class="token punctuation">)</span><span class="token punctuation">;</span><br /> <span class="token keyword">return</span> Builder<span class="token punctuation">.</span><span class="token function">ToString</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">;</span><br /> <span class="token punctuation">}</span> <br /> <br /> <span class="token keyword">public</span> <span class="token keyword">override</span> <span class="token return-type class-name"><span class="token keyword">string</span></span> <span class="token function">CreateDeleteCommand</span><span class="token punctuation">(</span><span class="token punctuation">)</span><br /> <span class="token punctuation">{</span><br /> <span class="token class-name">StringBuilder</span> Builder <span class="token operator">=</span> <span class="token keyword">new</span> <span class="token constructor-invocation class-name">StringBuilder</span><span class="token punctuation">(</span><span class="token string">"EXEC dbo.sp\_executesql @statement = N'CREATE PROCEDURE dbo."</span> <span class="token operator">+</span> Attribute<span class="token punctuation">.</span>MappedProperty <span class="token operator">+</span> <span class="token string">"\_Delete\_"</span> <span class="token operator">+</span> \_Class<span class="token punctuation">.</span>OriginalType<span class="token punctuation">.</span>Name <span class="token operator">+</span> <span class="token string">"\\n"</span><span class="token punctuation">)</span><span class="token punctuation">;</span><br /> <span class="token class-name">StringBuilder</span> MappedBuilder <span class="token operator">=</span> <span class="token keyword">new</span> <span class="token constructor-invocation class-name">StringBuilder</span><span class="token punctuation">(</span><span class="token string">"EXEC dbo.sp\_executesql @statement = N'CREATE PROCEDURE dbo."</span> <span class="token operator">+</span> Attribute<span class="token punctuation">.</span>MappedProperty <span class="token operator">+</span> <span class="token string">"\_Delete\_"</span> <span class="token operator">+</span> \_MappedClass<span class="token punctuation">.</span>OriginalType<span class="token punctuation">.</span>Name <span class="token operator">+</span> <span class="token string">"\\n"</span><span class="token punctuation">)</span><span class="token punctuation">;</span> <br /> <br /> Builder<span class="token punctuation">.</span><span class="token function">Append</span><span class="token punctuation">(</span>IDField<span class="token punctuation">.</span><span class="token function">CreateStoredProcedureParameter</span><span class="token punctuation">(</span><span class="token boolean">false</span><span class="token punctuation">,</span> <span class="token boolean">true</span><span class="token punctuation">)</span><span class="token punctuation">.</span><span class="token function">Replace</span><span class="token punctuation">(</span><span class="token string">"@"</span><span class="token punctuation">,</span> <span class="token string">"@"</span> <span class="token operator">+</span> \_Class<span class="token punctuation">.</span>OriginalType<span class="token punctuation">.</span>Name <span class="token operator">+</span> <span class="token string">"\_"</span><span class="token punctuation">)</span> <span class="token operator">+</span> <span class="token string">",\\n"</span><span class="token punctuation">)</span><span class="token punctuation">;</span><br /> MappedBuilder<span class="token punctuation">.</span><span class="token function">Append</span><span class="token punctuation">(</span>MappedIDField<span class="token punctuation">.</span><span class="token function">CreateStoredProcedureParameter</span><span class="token punctuation">(</span><span class="token boolean">false</span><span class="token punctuation">,</span> <span class="token boolean">true</span><span class="token punctuation">)</span><span class="token punctuation">.</span><span class="token function">Replace</span><span class="token punctuation">(</span><span class="token string">"@"</span><span class="token punctuation">,</span> <span class="token string">"@"</span> <span class="token operator">+</span> \_MappedClass<span class="token punctuation">.</span>OriginalType<span class="token punctuation">.</span>Name <span class="token operator">+</span> <span class="token string">"\_"</span><span class="token punctuation">)</span><span class="token punctuation">)</span><span class="token punctuation">;</span> <br /> <br /> Builder<span class="token punctuation">.</span><span class="token function">Append</span><span class="token punctuation">(</span><span class="token string">"\\nAS\\nDELETE FROM "</span> <span class="token operator">+</span> Attribute<span class="token punctuation">.</span>MappedProperty <span class="token operator">+</span> <span class="token string">" WHERE "</span><span class="token punctuation">)</span><span class="token punctuation">;</span><br /> MappedBuilder<span class="token punctuation">.</span><span class="token function">Append</span><span class="token punctuation">(</span><span class="token string">"\\nAS\\nDELETE FROM "</span> <span class="token operator">+</span> Attribute<span class="token punctuation">.</span>MappedProperty <span class="token operator">+</span> <span class="token string">" WHERE "</span><span class="token punctuation">)</span><span class="token punctuation">;</span> <br /> <br /> Builder<span class="token punctuation">.</span><span class="token function">Append</span><span class="token punctuation">(</span>\_Class<span class="token punctuation">.</span>OriginalType<span class="token punctuation">.</span>Name <span class="token operator">+</span> <span class="token string">"\_"</span> <span class="token operator">+</span> IDField<span class="token punctuation">.</span>Name <span class="token operator">+</span> <span class="token string">"="</span><span class="token punctuation">)</span><span class="token punctuation">;</span><br /> Builder<span class="token punctuation">.</span><span class="token function">Append</span><span class="token punctuation">(</span><span class="token string">"@"</span> <span class="token operator">+</span> \_Class<span class="token punctuation">.</span>OriginalType<span class="token punctuation">.</span>Name <span class="token operator">+</span> <span class="token string">"\_"</span> <span class="token operator">+</span> IDField<span class="token punctuation">.</span>Name <span class="token operator">+</span> <span class="token string">"\\nRETURN'\\n"</span><span class="token punctuation">)</span><span class="token punctuation">;</span> <br /> <br /> MappedBuilder<span class="token punctuation">.</span><span class="token function">Append</span><span class="token punctuation">(</span>\_MappedClass<span class="token punctuation">.</span>OriginalType<span class="token punctuation">.</span>Name <span class="token operator">+</span> <span class="token string">"\_"</span> <span class="token operator">+</span> MappedIDField<span class="token punctuation">.</span>Name <span class="token operator">+</span> <span class="token string">"="</span><span class="token punctuation">)</span><span class="token punctuation">;</span><br /> MappedBuilder<span class="token punctuation">.</span><span class="token function">Append</span><span class="token punctuation">(</span><span class="token string">"@"</span> <span class="token operator">+</span> \_MappedClass<span class="token punctuation">.</span>OriginalType<span class="token punctuation">.</span>Name <span class="token operator">+</span> <span class="token string">"\_"</span> <span class="token operator">+</span> MappedIDField<span class="token punctuation">.</span>Name <span class="token operator">+</span> <span class="token string">"\\nRETURN'\\n"</span><span class="token punctuation">)</span><span class="token punctuation">;</span> <br /> <br /> <span class="token keyword">return</span> Builder<span class="token punctuation">.</span><span class="token function">ToString</span><span class="token punctuation">(</span><span class="token punctuation">)</span> <span class="token operator">+</span> MappedBuilder<span class="token punctuation">.</span><span class="token function">ToString</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">;</span><br /> <span class="token punctuation">}</span> <br /> <br /> <span class="token keyword">public</span> <span class="token keyword">override</span> <span class="token return-type class-name"><span class="token keyword">string</span></span> <span class="token function">CreateSelectCommand</span><span class="token punctuation">(</span><span class="token punctuation">)</span><br /> <span class="token punctuation">{</span><br /> <span class="token class-name">StringBuilder</span> Builder <span class="token operator">=</span> <span class="token keyword">new</span> <span class="token constructor-invocation class-name">StringBuilder</span><span class="token punctuation">(</span><span class="token string">"EXEC dbo.sp\_executesql @statement = N'CREATE PROCEDURE dbo."</span> <span class="token operator">+</span> Attribute<span class="token punctuation">.</span>MappedProperty <span class="token operator">+</span> <span class="token string">"\_Select\_"</span> <span class="token operator">+</span> \_Class<span class="token punctuation">.</span>OriginalType<span class="token punctuation">.</span>Name <span class="token operator">+</span> <span class="token string">"\\n"</span><span class="token punctuation">)</span><span class="token punctuation">;</span><br /> <span class="token class-name">StringBuilder</span> MappedBuilder <span class="token operator">=</span> <span class="token keyword">new</span> <span class="token constructor-invocation class-name">StringBuilder</span><span class="token punctuation">(</span><span class="token string">"EXEC dbo.sp\_executesql @statement = N'CREATE PROCEDURE dbo."</span> <span class="token operator">+</span> Attribute<span class="token punctuation">.</span>MappedProperty <span class="token operator">+</span> <span class="token string">"\_Select\_"</span> <span class="token operator">+</span> \_MappedClass<span class="token punctuation">.</span>OriginalType<span class="token punctuation">.</span>Name <span class="token operator">+</span> <span class="token string">"\\n"</span><span class="token punctuation">)</span><span class="token punctuation">;</span><br /> <br /> Builder<span class="token punctuation">.</span><span class="token function">Append</span><span class="token punctuation">(</span>IDField<span class="token punctuation">.</span><span class="token function">CreateStoredProcedureParameter</span><span class="token punctuation">(</span><span class="token boolean">false</span><span class="token punctuation">,</span> <span class="token boolean">true</span><span class="token punctuation">)</span><span class="token punctuation">.</span><span class="token function">Replace</span><span class="token punctuation">(</span><span class="token string">"@"</span><span class="token punctuation">,</span> <span class="token string">"@"</span> <span class="token operator">+</span> \_Class<span class="token punctuation">.</span>OriginalType<span class="token punctuation">.</span>Name <span class="token operator">+</span> <span class="token string">"\_"</span><span class="token punctuation">)</span> <span class="token operator">+</span> <span class="token string">"\\n"</span><span class="token punctuation">)</span><span class="token punctuation">;</span><br /> MappedBuilder<span class="token punctuation">.</span><span class="token function">Append</span><span class="token punctuation">(</span>MappedIDField<span class="token punctuation">.</span><span class="token function">CreateStoredProcedureParameter</span><span class="token punctuation">(</span><span class="token boolean">false</span><span class="token punctuation">,</span> <span class="token boolean">true</span><span class="token punctuation">)</span><span class="token punctuation">.</span><span class="token function">Replace</span><span class="token punctuation">(</span><span class="token string">"@"</span><span class="token punctuation">,</span> <span class="token string">"@"</span> <span class="token operator">+</span> \_MappedClass<span class="token punctuation">.</span>OriginalType<span class="token punctuation">.</span>Name <span class="token operator">+</span> <span class="token string">"\_"</span><span class="token punctuation">)</span> <span class="token operator">+</span> <span class="token string">"\\n"</span><span class="token punctuation">)</span><span class="token punctuation">;</span> <br /> <br /> Builder<span class="token punctuation">.</span><span class="token function">Append</span><span class="token punctuation">(</span><span class="token string">"\\nAS\\nSELECT "</span><span class="token operator">+</span>\_Class<span class="token punctuation">.</span>OriginalType<span class="token punctuation">.</span>Name<span class="token operator">+</span><span class="token string">"\_"</span><span class="token operator">+</span>IDField<span class="token punctuation">.</span>Name<span class="token operator">+</span><span class="token string">","</span><span class="token operator">+</span>\_MappedClass<span class="token punctuation">.</span>OriginalType<span class="token punctuation">.</span>Name<span class="token operator">+</span><span class="token string">"\_"</span><span class="token operator">+</span>MappedIDField<span class="token punctuation">.</span>Name<span class="token operator">+</span><span class="token string">" FROM "</span><span class="token operator">+</span>Attribute<span class="token punctuation">.</span>MappedProperty<span class="token punctuation">)</span><span class="token punctuation">;</span><br /> Builder<span class="token punctuation">.</span><span class="token function">Append</span><span class="token punctuation">(</span><span class="token string">" WHERE "</span><span class="token operator">+</span>\_Class<span class="token punctuation">.</span>OriginalType<span class="token punctuation">.</span>Name<span class="token operator">+</span><span class="token string">"\_"</span><span class="token operator">+</span>IDField<span class="token punctuation">.</span>Name<span class="token operator">+</span><span class="token string">"=@"</span><span class="token operator">+</span>\_Class<span class="token punctuation">.</span>OriginalType<span class="token punctuation">.</span>Name<span class="token operator">+</span><span class="token string">"\_"</span><span class="token operator">+</span>IDField<span class="token punctuation">.</span>Name<span class="token punctuation">)</span><span class="token punctuation">;</span> <br /> <br /> MappedBuilder<span class="token punctuation">.</span><span class="token function">Append</span><span class="token punctuation">(</span><span class="token string">"\\nAS\\nSELECT "</span> <span class="token operator">+</span> \_Class<span class="token punctuation">.</span>OriginalType<span class="token punctuation">.</span>Name <span class="token operator">+</span> <span class="token string">"\_"</span> <span class="token operator">+</span> IDField<span class="token punctuation">.</span>Name <span class="token operator">+</span> <span class="token string">","</span> <span class="token operator">+</span> \_MappedClass<span class="token punctuation">.</span>OriginalType<span class="token punctuation">.</span>Name <span class="token operator">+</span> <span class="token string">"\_"</span> <span class="token operator">+</span> MappedIDField<span class="token punctuation">.</span>Name <span class="token operator">+</span> <span class="token string">" FROM "</span> <span class="token operator">+</span> Attribute<span class="token punctuation">.</span>MappedProperty<span class="token punctuation">)</span><span class="token punctuation">;</span><br /> MappedBuilder<span class="token punctuation">.</span><span class="token function">Append</span><span class="token punctuation">(</span><span class="token string">" WHERE "</span> <span class="token operator">+</span> \_MappedClass<span class="token punctuation">.</span>OriginalType<span class="token punctuation">.</span>Name <span class="token operator">+</span> <span class="token string">"\_"</span> <span class="token operator">+</span> MappedIDField<span class="token punctuation">.</span>Name <span class="token operator">+</span> <span class="token string">"=@"</span> <span class="token operator">+</span> \_MappedClass<span class="token punctuation">.</span>OriginalType<span class="token punctuation">.</span>Name <span class="token operator">+</span> <span class="token string">"\_"</span> <span class="token operator">+</span> MappedIDField<span class="token punctuation">.</span>Name<span class="token punctuation">)</span><span class="token punctuation">;</span> <br /> <br /> Builder<span class="token punctuation">.</span><span class="token function">Append</span><span class="token punctuation">(</span><span class="token string">"\\nRETURN'\\n"</span><span class="token punctuation">)</span><span class="token punctuation">;</span><br /> MappedBuilder<span class="token punctuation">.</span><span class="token function">Append</span><span class="token punctuation">(</span><span class="token string">"\\nRETURN'\\n"</span><span class="token punctuation">)</span><span class="token punctuation">;</span><br /> <span class="token keyword">return</span> Builder<span class="token punctuation">.</span><span class="token function">ToString</span><span class="token punctuation">(</span><span class="token punctuation">)</span> <span class="token operator">+</span> MappedBuilder<span class="token punctuation">.</span><span class="token function">ToString</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">;</span><br /> <span class="token punctuation">}</span><br /> <span class="token punctuation">}</span></code></pre>
<p>We did something similar with one to one mapped classes. As you can see we have our create table command, insert command, etc. And all we need to do is add the type to what our GlobalFunctions class returns and our statements should pick it up automatically (with some minor changes which you can find in the code linked to below). The big changes come when we actually try to save the item.</p>
<pre class="language-csharp"><code class="language-csharp"> <span class="token keyword">private</span> <span class="token return-type class-name"><span class="token keyword">void</span></span> <span class="token function">SetupLists</span><span class="token punctuation">(</span><span class="token class-name"><span class="token keyword">object</span></span> Object<span class="token punctuation">,</span> <span class="token class-name">SQLHelper</span> Helper<span class="token punctuation">,</span> <span class="token class-name">Type</span> ObjectType<span class="token punctuation">)</span><br /> <span class="token punctuation">{</span><br /> <span class="token keyword">foreach</span> <span class="token punctuation">(</span><span class="token class-name">IDataType</span> Column <span class="token keyword">in</span> Columns<span class="token punctuation">)</span><br /> <span class="token punctuation">{</span><br /> <span class="token keyword">if</span> <span class="token punctuation">(</span>Column <span class="token operator">!=</span> <span class="token keyword">null</span> <span class="token operator">&&</span> Column <span class="token keyword">is</span> <span class="token class-name">ManyToManyClassType</span><span class="token punctuation">)</span><br /> <span class="token punctuation">{</span><br /> <span class="token class-name">ManyToManyClassType</span> ManyToManyColumn <span class="token operator">=</span> <span class="token punctuation">(</span><span class="token punctuation">(</span>ManyToManyClassType<span class="token punctuation">)</span>Column<span class="token punctuation">)</span><span class="token punctuation">;</span><br /> <span class="token class-name">PropertyInfo</span> IDPropertyInfo <span class="token operator">=</span> ObjectType<span class="token punctuation">.</span><span class="token function">GetProperty</span><span class="token punctuation">(</span>ManyToManyColumn<span class="token punctuation">.</span>\_Class<span class="token punctuation">.</span>IDField<span class="token punctuation">.</span>Name<span class="token punctuation">)</span><span class="token punctuation">;</span><br /> <span class="token class-name"><span class="token keyword">object</span></span> IDValue <span class="token operator">=</span> IDPropertyInfo<span class="token punctuation">.</span><span class="token function">GetValue</span><span class="token punctuation">(</span>Object<span class="token punctuation">,</span> <span class="token keyword">null</span><span class="token punctuation">)</span><span class="token punctuation">;</span><br /> Helper<span class="token punctuation">.</span>Command <span class="token operator">=</span> Column<span class="token punctuation">.</span>Attribute<span class="token punctuation">.</span>MappedProperty <span class="token operator">+</span> <span class="token string">"\_Insert"</span><span class="token punctuation">;</span><br /> <span class="token class-name">PropertyInfo</span> ListInfo <span class="token operator">=</span> ObjectType<span class="token punctuation">.</span><span class="token function">GetProperty</span><span class="token punctuation">(</span>Column<span class="token punctuation">.</span>Attribute<span class="token punctuation">.</span>Name<span class="token punctuation">)</span><span class="token punctuation">;</span><br /> <span class="token class-name"><span class="token keyword">object</span></span> ListValue <span class="token operator">=</span> ListInfo<span class="token punctuation">.</span><span class="token function">GetValue</span><span class="token punctuation">(</span>Object<span class="token punctuation">,</span> <span class="token keyword">null</span><span class="token punctuation">)</span><span class="token punctuation">;</span><br /> <span class="token keyword">if</span> <span class="token punctuation">(</span>ListValue <span class="token operator">!=</span> <span class="token keyword">null</span><span class="token punctuation">)</span><br /> <span class="token punctuation">{</span><br /> <span class="token class-name">Type</span> ListType <span class="token operator">=</span> ListValue<span class="token punctuation">.</span><span class="token function">GetType</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">;</span><br /> <span class="token class-name">PropertyInfo</span> IndexProperty <span class="token operator">=</span> ListType<span class="token punctuation">.</span><span class="token function">GetProperty</span><span class="token punctuation">(</span><span class="token string">"Item"</span><span class="token punctuation">)</span><span class="token punctuation">;</span><br /> <span class="token class-name">PropertyInfo</span> CountProperty <span class="token operator">=</span> ListType<span class="token punctuation">.</span><span class="token function">GetProperty</span><span class="token punctuation">(</span><span class="token string">"Count"</span><span class="token punctuation">)</span><span class="token punctuation">;</span><br /> <span class="token class-name"><span class="token keyword">int</span></span> Count <span class="token operator">=</span> <span class="token punctuation">(</span><span class="token keyword">int</span><span class="token punctuation">)</span>CountProperty<span class="token punctuation">.</span><span class="token function">GetValue</span><span class="token punctuation">(</span>ListValue<span class="token punctuation">,</span> <span class="token keyword">null</span><span class="token punctuation">)</span><span class="token punctuation">;</span><br /> <span class="token class-name">Type</span> MappedObjectType <span class="token operator">=</span> ManyToManyColumn<span class="token punctuation">.</span>\_MappedClass<span class="token punctuation">.</span>OriginalType<span class="token punctuation">;</span><br /> <span class="token class-name">PropertyInfo</span> MappedIDPropertyInfo <span class="token operator">=</span> MappedObjectType<span class="token punctuation">.</span><span class="token function">GetProperty</span><span class="token punctuation">(</span>ManyToManyColumn<span class="token punctuation">.</span>\_MappedClass<span class="token punctuation">.</span>IDField<span class="token punctuation">.</span>Name<span class="token punctuation">)</span><span class="token punctuation">;</span><br /> <span class="token keyword">for</span> <span class="token punctuation">(</span><span class="token class-name"><span class="token keyword">int</span></span> x <span class="token operator">=</span> <span class="token number">0</span><span class="token punctuation">;</span> x <span class="token operator"><</span> Count<span class="token punctuation">;</span> <span class="token operator">++</span>x<span class="token punctuation">)</span><br /> <span class="token punctuation">{</span><br /> <span class="token class-name"><span class="token keyword">object</span></span> MappedClassObject <span class="token operator">=</span> IndexProperty<span class="token punctuation">.</span><span class="token function">GetValue</span><span class="token punctuation">(</span>ListValue<span class="token punctuation">,</span> <span class="token keyword">new</span> <span class="token keyword">object</span>\<span class="token punctuation">[</span>\<span class="token punctuation">]</span> <span class="token punctuation">{</span> x <span class="token punctuation">}</span><span class="token punctuation">)</span><span class="token punctuation">;</span><br /> <span class="token class-name"><span class="token keyword">object</span></span> MappedClassID <span class="token operator">=</span> MappedIDPropertyInfo<span class="token punctuation">.</span><span class="token function">GetValue</span><span class="token punctuation">(</span>MappedClassObject<span class="token punctuation">,</span> <span class="token keyword">null</span><span class="token punctuation">)</span><span class="token punctuation">;</span><br /> <span class="token keyword">try</span><br /> <span class="token punctuation">{</span><br /> Helper<span class="token punctuation">.</span><span class="token function">Open</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">;</span><br /> Helper<span class="token punctuation">.</span><span class="token function">ClearParameters</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">;</span><br /> Helper<span class="token punctuation">.</span><span class="token function">AddParameter</span><span class="token punctuation">(</span><span class="token string">"@"</span> <span class="token operator">+</span> ManyToManyColumn<span class="token punctuation">.</span>\_Class<span class="token punctuation">.</span>OriginalType<span class="token punctuation">.</span>Name <span class="token operator">+</span> <span class="token string">"\_"</span> <span class="token operator">+</span> ManyToManyColumn<span class="token punctuation">.</span>\_Class<span class="token punctuation">.</span>IDField<span class="token punctuation">.</span>Name<span class="token punctuation">,</span> IDValue<span class="token punctuation">,</span> ManyToManyColumn<span class="token punctuation">.</span>IDField<span class="token punctuation">.</span>DataType<span class="token punctuation">)</span><span class="token punctuation">;</span><br /> Helper<span class="token punctuation">.</span><span class="token function">AddParameter</span><span class="token punctuation">(</span><span class="token string">"@"</span> <span class="token operator">+</span> ManyToManyColumn<span class="token punctuation">.</span>\_MappedClass<span class="token punctuation">.</span>OriginalType<span class="token punctuation">.</span>Name <span class="token operator">+</span> <span class="token string">"\_"</span> <span class="token operator">+</span> ManyToManyColumn<span class="token punctuation">.</span>\_MappedClass<span class="token punctuation">.</span>IDField<span class="token punctuation">.</span>Name<span class="token punctuation">,</span> MappedClassID<span class="token punctuation">,</span> ManyToManyColumn<span class="token punctuation">.</span>MappedIDField<span class="token punctuation">.</span>DataType<span class="token punctuation">)</span><span class="token punctuation">;</span><br /> Helper<span class="token punctuation">.</span><span class="token function">ExecuteNonQuery</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">;</span><br /> <span class="token punctuation">}</span><br /> <span class="token keyword">catch</span> <span class="token punctuation">{</span> <span class="token punctuation">}</span><br /> <span class="token keyword">finally</span> <span class="token punctuation">{</span> Helper<span class="token punctuation">.</span><span class="token function">Close</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token punctuation">}</span><br /> <span class="token punctuation">}</span><br /> <span class="token punctuation">}</span><br /> <span class="token punctuation">}</span><br /> <span class="token keyword">else</span> <span class="token keyword">if</span> <span class="token punctuation">(</span>Column <span class="token operator">!=</span> <span class="token keyword">null</span> <span class="token operator">&&</span> <span class="token punctuation">(</span>Column <span class="token keyword">is</span> <span class="token class-name">List</span><span class="token punctuation">)</span><span class="token punctuation">)</span><span class="token comment">//|| Column is ManyToManyClassType))</span><br /> <span class="token punctuation">{</span><br /> <span class="token class-name"><span class="token keyword">string</span></span> IDName <span class="token operator">=</span> <span class="token punctuation">(</span><span class="token punctuation">(</span>List<span class="token punctuation">)</span>Column<span class="token punctuation">)</span><span class="token punctuation">.</span>IDName<span class="token punctuation">;</span><br /> <span class="token class-name">SqlDbType</span> IDType <span class="token operator">=</span> <span class="token punctuation">(</span><span class="token punctuation">(</span>List<span class="token punctuation">)</span>Column<span class="token punctuation">)</span><span class="token punctuation">.</span>IDType<span class="token punctuation">;</span><br /> <span class="token class-name"><span class="token keyword">string</span></span> DataName <span class="token operator">=</span> <span class="token punctuation">(</span><span class="token punctuation">(</span>List<span class="token punctuation">)</span>Column<span class="token punctuation">)</span><span class="token punctuation">.</span>DataName<span class="token punctuation">;</span><br /> <span class="token class-name">SqlDbType</span> DataType <span class="token operator">=</span> <span class="token punctuation">(</span><span class="token punctuation">(</span>List<span class="token punctuation">)</span>Column<span class="token punctuation">)</span><span class="token punctuation">.</span>DataType<span class="token punctuation">;</span><br /> <span class="token class-name"><span class="token keyword">int</span></span> DataSize <span class="token operator">=</span> <span class="token punctuation">(</span><span class="token punctuation">(</span>List<span class="token punctuation">)</span>Column<span class="token punctuation">)</span><span class="token punctuation">.</span>Size<span class="token punctuation">;</span> <br /> <br /> <span class="token class-name">PropertyInfo</span> IDPropertyInfo <span class="token operator">=</span> ObjectType<span class="token punctuation">.</span><span class="token function">GetProperty</span><span class="token punctuation">(</span>IDName<span class="token punctuation">)</span><span class="token punctuation">;</span><br /> <span class="token class-name"><span class="token keyword">object</span></span> IDValue <span class="token operator">=</span> IDPropertyInfo<span class="token punctuation">.</span><span class="token function">GetValue</span><span class="token punctuation">(</span>Object<span class="token punctuation">,</span> <span class="token keyword">null</span><span class="token punctuation">)</span><span class="token punctuation">;</span> <br /> <br /> Helper<span class="token punctuation">.</span>Command <span class="token operator">=</span> Column<span class="token punctuation">.</span>Name <span class="token operator">+</span> <span class="token string">"\_Insert"</span><span class="token punctuation">;</span> <br /> <br /> <span class="token class-name">PropertyInfo</span> PropertyInfo <span class="token operator">=</span> ObjectType<span class="token punctuation">.</span><span class="token function">GetProperty</span><span class="token punctuation">(</span>Column<span class="token punctuation">.</span>Attribute<span class="token punctuation">.</span>Name<span class="token punctuation">)</span><span class="token punctuation">;</span><br /> <span class="token class-name"><span class="token keyword">object</span></span> ListValue <span class="token operator">=</span> PropertyInfo<span class="token punctuation">.</span><span class="token function">GetValue</span><span class="token punctuation">(</span>Object<span class="token punctuation">,</span> <span class="token keyword">null</span><span class="token punctuation">)</span><span class="token punctuation">;</span><br /> <span class="token keyword">if</span> <span class="token punctuation">(</span>ListValue <span class="token operator">!=</span> <span class="token keyword">null</span><span class="token punctuation">)</span><br /> <span class="token punctuation">{</span><br /> <span class="token class-name">Type</span> ListType <span class="token operator">=</span> ListValue<span class="token punctuation">.</span><span class="token function">GetType</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">;</span><br /> <span class="token class-name">PropertyInfo</span> IndexProperty <span class="token operator">=</span> ListType<span class="token punctuation">.</span><span class="token function">GetProperty</span><span class="token punctuation">(</span><span class="token string">"Item"</span><span class="token punctuation">)</span><span class="token punctuation">;</span><br /> <span class="token class-name">PropertyInfo</span> CountProperty <span class="token operator">=</span> ListType<span class="token punctuation">.</span><span class="token function">GetProperty</span><span class="token punctuation">(</span><span class="token string">"Count"</span><span class="token punctuation">)</span><span class="token punctuation">;</span><br /> <span class="token class-name"><span class="token keyword">int</span></span> Count <span class="token operator">=</span> <span class="token punctuation">(</span><span class="token keyword">int</span><span class="token punctuation">)</span>CountProperty<span class="token punctuation">.</span><span class="token function">GetValue</span><span class="token punctuation">(</span>ListValue<span class="token punctuation">,</span> <span class="token keyword">null</span><span class="token punctuation">)</span><span class="token punctuation">;</span><br /> <span class="token keyword">for</span> <span class="token punctuation">(</span><span class="token class-name"><span class="token keyword">int</span></span> x <span class="token operator">=</span> <span class="token number">0</span><span class="token punctuation">;</span> x <span class="token operator"><</span> Count<span class="token punctuation">;</span> <span class="token operator">++</span>x<span class="token punctuation">)</span><br /> <span class="token punctuation">{</span><br /> <span class="token keyword">try</span><br /> <span class="token punctuation">{</span><br /> Helper<span class="token punctuation">.</span><span class="token function">Open</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">;</span><br /> Helper<span class="token punctuation">.</span><span class="token function">ClearParameters</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">;</span><br /> Helper<span class="token punctuation">.</span><span class="token function">AddParameter</span><span class="token punctuation">(</span><span class="token string">"@"</span> <span class="token operator">+</span> IDName<span class="token punctuation">,</span> IDValue<span class="token punctuation">,</span> IDType<span class="token punctuation">)</span><span class="token punctuation">;</span><br /> <span class="token keyword">if</span> <span class="token punctuation">(</span>DataType <span class="token operator">==</span> SqlDbType<span class="token punctuation">.</span>NVarChar<span class="token punctuation">)</span><br /> <span class="token punctuation">{</span><br /> Helper<span class="token punctuation">.</span><span class="token function">AddParameter</span><span class="token punctuation">(</span><span class="token string">"@"</span> <span class="token operator">+</span> DataName<span class="token punctuation">,</span> <span class="token punctuation">(</span><span class="token keyword">string</span><span class="token punctuation">)</span>IndexProperty<span class="token punctuation">.</span><span class="token function">GetValue</span><span class="token punctuation">(</span>ListValue<span class="token punctuation">,</span> <span class="token keyword">new</span> <span class="token keyword">object</span>\<span class="token punctuation">[</span>\<span class="token punctuation">]</span> <span class="token punctuation">{</span> x <span class="token punctuation">}</span><span class="token punctuation">)</span><span class="token punctuation">,</span> DataSize<span class="token punctuation">)</span><span class="token punctuation">;</span><br /> <span class="token punctuation">}</span><br /> <span class="token keyword">else</span><br /> <span class="token punctuation">{</span><br /> Helper<span class="token punctuation">.</span><span class="token function">AddParameter</span><span class="token punctuation">(</span><span class="token string">"@"</span> <span class="token operator">+</span> DataName<span class="token punctuation">,</span> IndexProperty<span class="token punctuation">.</span><span class="token function">GetValue</span><span class="token punctuation">(</span>ListValue<span class="token punctuation">,</span> <span class="token keyword">new</span> <span class="token keyword">object</span>\<span class="token punctuation">[</span>\<span class="token punctuation">]</span> <span class="token punctuation">{</span> x <span class="token punctuation">}</span><span class="token punctuation">)</span><span class="token punctuation">,</span> DataType<span class="token punctuation">)</span><span class="token punctuation">;</span><br /> <span class="token punctuation">}</span><br /> Helper<span class="token punctuation">.</span><span class="token function">ExecuteNonQuery</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">;</span><br /> <span class="token punctuation">}</span><br /> <span class="token keyword">catch</span> <span class="token punctuation">{</span> <span class="token punctuation">}</span><br /> <span class="token keyword">finally</span> <span class="token punctuation">{</span> Helper<span class="token punctuation">.</span><span class="token function">Close</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token punctuation">}</span><br /> <span class="token punctuation">}</span><br /> <span class="token punctuation">}</span><br /> <span class="token punctuation">}</span><br /> <span class="token punctuation">}</span><br /> <span class="token punctuation">}</span></code></pre>
<p>You will see that we check if we're dealing with a ManyToManyClassType and if we are we find the list object, get each individual item, etc. in a similar manner to all lists thus far. However we have an added step of finding the ID for each individual object and inserting that into the table instead of the whole object. All we need to worry about is saving the connection to the correct object. The reason for this is that the object is already saved in another table. Our code for cascading a save handles this for us with only a little bit of extra code:</p>
<pre class="language-csharp"><code class="language-csharp"> <span class="token keyword">private</span> <span class="token return-type class-name"><span class="token keyword">void</span></span> <span class="token function">CascadeSave</span><span class="token punctuation">(</span><span class="token class-name"><span class="token keyword">object</span></span> Object<span class="token punctuation">,</span> <span class="token class-name">Type</span> ObjectType<span class="token punctuation">)</span><br /> <span class="token punctuation">{</span><br /> <span class="token class-name">Session</span> TempSession <span class="token operator">=</span> Factory<span class="token punctuation">.</span><span class="token function">CreateSession</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">;</span><br /> <span class="token keyword">foreach</span> <span class="token punctuation">(</span><span class="token class-name">IDataType</span> Column <span class="token keyword">in</span> Columns<span class="token punctuation">)</span><br /> <span class="token punctuation">{</span><br /> <span class="token keyword">if</span> <span class="token punctuation">(</span>Column<span class="token punctuation">.</span>Attribute<span class="token punctuation">.</span>Cascade<span class="token punctuation">)</span><br /> <span class="token punctuation">{</span><br /> <span class="token class-name">PropertyInfo</span> Property <span class="token operator">=</span> ObjectType<span class="token punctuation">.</span><span class="token function">GetProperty</span><span class="token punctuation">(</span>Column<span class="token punctuation">.</span>Name<span class="token punctuation">)</span><span class="token punctuation">;</span><br /> <span class="token class-name"><span class="token keyword">object</span></span> Value<span class="token operator">=</span>Property<span class="token punctuation">.</span><span class="token function">GetValue</span><span class="token punctuation">(</span>Object<span class="token punctuation">,</span><span class="token keyword">null</span><span class="token punctuation">)</span><span class="token punctuation">;</span><br /> <span class="token keyword">if</span> <span class="token punctuation">(</span>Value <span class="token operator">!=</span> <span class="token keyword">null</span><span class="token punctuation">)</span><br /> <span class="token punctuation">{</span><br /> <span class="token keyword">if</span> <span class="token punctuation">(</span>Column <span class="token keyword">is</span> <span class="token class-name">ManyToManyClassType</span><span class="token punctuation">)</span><br /> <span class="token punctuation">{</span><br /> <span class="token class-name">ManyToManyClassType</span> ManyToManyColumn <span class="token operator">=</span> <span class="token punctuation">(</span><span class="token punctuation">(</span>ManyToManyClassType<span class="token punctuation">)</span>Column<span class="token punctuation">)</span><span class="token punctuation">;</span><br /> <span class="token class-name">Type</span> ListType <span class="token operator">=</span> Value<span class="token punctuation">.</span><span class="token function">GetType</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">;</span><br /> <span class="token class-name">PropertyInfo</span> IndexProperty <span class="token operator">=</span> ListType<span class="token punctuation">.</span><span class="token function">GetProperty</span><span class="token punctuation">(</span><span class="token string">"Item"</span><span class="token punctuation">)</span><span class="token punctuation">;</span><br /> <span class="token class-name">PropertyInfo</span> CountProperty <span class="token operator">=</span> ListType<span class="token punctuation">.</span><span class="token function">GetProperty</span><span class="token punctuation">(</span><span class="token string">"Count"</span><span class="token punctuation">)</span><span class="token punctuation">;</span><br /> <span class="token class-name"><span class="token keyword">int</span></span> Count <span class="token operator">=</span> <span class="token punctuation">(</span><span class="token keyword">int</span><span class="token punctuation">)</span>CountProperty<span class="token punctuation">.</span><span class="token function">GetValue</span><span class="token punctuation">(</span>Value<span class="token punctuation">,</span> <span class="token keyword">null</span><span class="token punctuation">)</span><span class="token punctuation">;</span><br /> <span class="token class-name">Type</span> MappedObjectType <span class="token operator">=</span> ManyToManyColumn<span class="token punctuation">.</span>\_MappedClass<span class="token punctuation">.</span>OriginalType<span class="token punctuation">;</span><br /> <span class="token keyword">for</span> <span class="token punctuation">(</span><span class="token class-name"><span class="token keyword">int</span></span> x <span class="token operator">=</span> <span class="token number">0</span><span class="token punctuation">;</span> x <span class="token operator"><</span> Count<span class="token punctuation">;</span> <span class="token operator">++</span>x<span class="token punctuation">)</span><br /> <span class="token punctuation">{</span><br /> <span class="token class-name"><span class="token keyword">object</span></span> MappedClassObject <span class="token operator">=</span> IndexProperty<span class="token punctuation">.</span><span class="token function">GetValue</span><span class="token punctuation">(</span>Value<span class="token punctuation">,</span> <span class="token keyword">new</span> <span class="token keyword">object</span>\<span class="token punctuation">[</span>\<span class="token punctuation">]</span> <span class="token punctuation">{</span> x <span class="token punctuation">}</span><span class="token punctuation">)</span><span class="token punctuation">;</span><br /> TempSession<span class="token punctuation">.</span><span class="token function">Save</span><span class="token punctuation">(</span>MappedClassObject<span class="token punctuation">)</span><span class="token punctuation">;</span><br /> <span class="token punctuation">}</span><br /> <span class="token punctuation">}</span><br /> <span class="token keyword">else</span><br /> <span class="token punctuation">{</span><br /> TempSession<span class="token punctuation">.</span><span class="token function">Save</span><span class="token punctuation">(</span>Value<span class="token punctuation">)</span><span class="token punctuation">;</span><br /> <span class="token punctuation">}</span><br /> <span class="token punctuation">}</span><br /> <span class="token punctuation">}</span><br /> <span class="token punctuation">}</span><br /> <span class="token punctuation">}</span></code></pre>
<p>I've only shown you the insert function but the delete and update work in a similar manner. With that we have our insert, update, delete, and select functions working for many to many mappings. Now what about many to one?</p>
<p>To be honest, I've seen many to one mappings dealt with in many different ways. The most popular is to treat them as one sided one to one mappings when saving the data. For instance, let's assume we have a parent item that has multiple child items. The parent wouldn't save anything extra in this scenario; instead the child items would hold a link back to the parent item.</p>
<p>This works the vast majority of the time but I find that there is an issue if ever the code needs to change from a many to one to a many to many mapping (since that's usually more common than a switch to a one to one mapping). So I decided to simply treat it like a many to many mapping. It gets its own table to store the links, its own stored procedures, etc. The only caveat is when we're saving, deleting, loading, etc. we have to check whether we're dealing with a list or a single item. If it's a list, we deal with it exactly as if it were a many to many mapping. In the single item scenario we treat it like a many to many mapping but we skip the reflection portions that deal with the list object. So half of the time we call Select and half the time we call SelectList. That's it really.</p>
<p>So at this point we can load, save, and delete pretty much anything we want. So on to dealing with the Caching right? Not quite. Sadly at this point we can only load a single item by its ID. That isn't exactly the most useful way to get our information. We still need to add a way to deal with that. That will be next time, but after that we're ready to deal with the Cache. Or at least I think so unless something comes up. So take a look at the code, leave feedback, and happy coding.</p>
Creating an ORM in C# - Part 5
2009-06-30T00:00:00Z
http://www.gutgames.com/post/Creating-an-ORM-in-C-Part-5/
<p>Today I finally got around to adding support for classes... Well straight one to one mappings anyway, many to many and many to one are a bit trickier so I've put those off for another post. As always, you may want to read the earlier posts if you haven't already. But in this post I'm going to cover loading of classes, lazy loading, and cascading updates/inserts.</p>
<p>Basically when you think about it, as far as our CRM is concerned, a class is just another data type. However unlike say an int, we really don't want to load it when the rest of the class is loaded. I mean we can but that would potentially cause issues (we might end up loading our entire database or even end up in an endless loop of loading). So what most people do to combat this is use something called lazy loading. Lazy loading is simply a design pattern where you load/initialize an object only when it is needed. So how do we go about setting up our system to do lazy loading?</p>
<pre class="language-csharp"><code class="language-csharp"> <span class="token keyword">public</span> <span class="token function">Property</span><span class="token punctuation">(</span><span class="token class-name">Attribute</span> Attribute<span class="token punctuation">,</span> <span class="token class-name">TypeBuilder</span> TypeBuilder<span class="token punctuation">,</span> <span class="token class-name">FieldBuilder</span> ChangedField<span class="token punctuation">,</span><span class="token class-name">ClassManager</span> Manager<span class="token punctuation">)</span><br /> <span class="token punctuation">{</span><br /> Field <span class="token operator">=</span> <span class="token keyword">new</span> <span class="token constructor-invocation class-name">Field</span><span class="token punctuation">(</span>Attribute<span class="token punctuation">,</span> TypeBuilder<span class="token punctuation">,</span> FieldAttributes<span class="token punctuation">.</span>Private<span class="token punctuation">)</span><span class="token punctuation">;</span><br /> <span class="token keyword">if</span> <span class="token punctuation">(</span>Attribute<span class="token punctuation">.</span>AttributeType <span class="token operator">==</span> AttributeType<span class="token punctuation">.</span>Map<span class="token punctuation">)</span><br /> <span class="token punctuation">{</span><br /> <span class="token class-name">Attribute</span> TempIDAttribute <span class="token operator">=</span> <span class="token keyword">new</span> <span class="token constructor-invocation class-name">Attribute</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">;</span><br /> TempIDAttribute<span class="token punctuation">.</span>AttributeType <span class="token operator">=</span> Attribute<span class="token punctuation">.</span>AttributeType<span class="token punctuation">;</span><br /> <span class="token class-name">Class</span> TempClass <span class="token operator">=</span> Manager\<span class="token punctuation">[</span>Attribute<span class="token punctuation">.</span>Type\<span class="token punctuation">]</span><span class="token punctuation">;</span><br /> <span class="token keyword">foreach</span> <span class="token punctuation">(</span><span class="token class-name">Property</span> TempProperty <span class="token keyword">in</span> TempClass<span class="token punctuation">.</span>Properties<span class="token punctuation">)</span><br /> <span class="token punctuation">{</span><br /> <span class="token keyword">if</span> <span class="token punctuation">(</span>TempProperty<span class="token punctuation">.</span>Attribute<span class="token punctuation">.</span>AttributeType <span class="token operator">==</span> AttributeType<span class="token punctuation">.</span>ID<span class="token punctuation">)</span><br /> <span class="token punctuation">{</span><br /> TempIDAttribute<span class="token punctuation">.</span>Type <span class="token operator">=</span> TempProperty<span class="token punctuation">.</span>Attribute<span class="token punctuation">.</span>Type<span class="token punctuation">;</span><br /> <span class="token punctuation">}</span><br /> <span class="token punctuation">}</span><br /> TempIDAttribute<span class="token punctuation">.</span>Name <span class="token operator">=</span> Attribute<span class="token punctuation">.</span>Name <span class="token operator">+</span> <span class="token string">"ID"</span><span class="token punctuation">;</span><br /> IDField <span class="token operator">=</span> <span class="token keyword">new</span> <span class="token constructor-invocation class-name">Field</span><span class="token punctuation">(</span>TempIDAttribute<span class="token punctuation">,</span> TypeBuilder<span class="token punctuation">,</span> FieldAttributes<span class="token punctuation">.</span>Public<span class="token punctuation">)</span><span class="token punctuation">;</span><br /> <span class="token punctuation">}</span><br /> <span class="token class-name">MethodAttributes</span> GetSetAttributes <span class="token operator">=</span> MethodAttributes<span class="token punctuation">.</span>Public <span class="token operator">|</span> MethodAttributes<span class="token punctuation">.</span>SpecialName <span class="token operator">|</span> MethodAttributes<span class="token punctuation">.</span>HideBySig <span class="token operator">|</span> MethodAttributes<span class="token punctuation">.</span>Virtual<span class="token punctuation">;</span><br /> <span class="token class-name">MethodBuilder</span> ValuePropertyGet <span class="token operator">=</span> TypeBuilder<span class="token punctuation">.</span><span class="token function">DefineMethod</span><span class="token punctuation">(</span><span class="token string">"get\_"</span> <span class="token operator">+</span> Attribute<span class="token punctuation">.</span>Name<span class="token punctuation">,</span> GetSetAttributes<span class="token punctuation">,</span> Attribute<span class="token punctuation">.</span>Type<span class="token punctuation">,</span> Type<span class="token punctuation">.</span>EmptyTypes<span class="token punctuation">)</span><span class="token punctuation">;</span><br /> <span class="token class-name">ILGenerator</span> Generator <span class="token operator">=</span> ValuePropertyGet<span class="token punctuation">.</span><span class="token function">GetILGenerator</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">;</span><br /> <span class="token keyword">if</span> <span class="token punctuation">(</span>Attribute<span class="token punctuation">.</span>AttributeType <span class="token operator">==</span> AttributeType<span class="token punctuation">.</span>Map<span class="token punctuation">)</span><br /> <span class="token punctuation">{</span><br /> <span class="token class-name">Label</span> ExitIfStatement <span class="token operator">=</span> Generator<span class="token punctuation">.</span><span class="token function">DefineLabel</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">;</span><br /> <span class="token class-name">Label</span> ExitIf2Statement <span class="token operator">=</span> Generator<span class="token punctuation">.</span><span class="token function">DefineLabel</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">;</span><br /> <span class="token class-name">Label</span> ExitStatement <span class="token operator">=</span> Generator<span class="token punctuation">.</span><span class="token function">DefineLabel</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">;</span><br /> Generator<span class="token punctuation">.</span><span class="token function">DeclareLocal</span><span class="token punctuation">(</span>Field<span class="token punctuation">.</span>FieldType<span class="token punctuation">)</span><span class="token punctuation">;</span><br /> Generator<span class="token punctuation">.</span><span class="token function">DeclareLocal</span><span class="token punctuation">(</span><span class="token keyword">typeof</span><span class="token punctuation">(</span><span class="token type-expression class-name"><span class="token keyword">bool</span></span><span class="token punctuation">)</span><span class="token punctuation">)</span><span class="token punctuation">;</span><br /> Generator<span class="token punctuation">.</span><span class="token function">Emit</span><span class="token punctuation">(</span>OpCodes<span class="token punctuation">.</span>Nop<span class="token punctuation">)</span><span class="token punctuation">;</span><br /> Generator<span class="token punctuation">.</span><span class="token function">Emit</span><span class="token punctuation">(</span>OpCodes<span class="token punctuation">.</span>Ldarg\_0<span class="token punctuation">)</span><span class="token punctuation">;</span><br /> Generator<span class="token punctuation">.</span><span class="token function">Emit</span><span class="token punctuation">(</span>OpCodes<span class="token punctuation">.</span>Ldfld<span class="token punctuation">,</span> Field<span class="token punctuation">.</span>FieldBuilder<span class="token punctuation">)</span><span class="token punctuation">;</span><br /> Generator<span class="token punctuation">.</span><span class="token function">Emit</span><span class="token punctuation">(</span>OpCodes<span class="token punctuation">.</span>Ldnull<span class="token punctuation">)</span><span class="token punctuation">;</span><br /> Generator<span class="token punctuation">.</span><span class="token function">Emit</span><span class="token punctuation">(</span>OpCodes<span class="token punctuation">.</span>Ceq<span class="token punctuation">)</span><span class="token punctuation">;</span><br /> Generator<span class="token punctuation">.</span><span class="token function">Emit</span><span class="token punctuation">(</span>OpCodes<span class="token punctuation">.</span>Ldc\_I4\_0<span class="token punctuation">)</span><span class="token punctuation">;</span><br /> Generator<span class="token punctuation">.</span><span class="token function">Emit</span><span class="token punctuation">(</span>OpCodes<span class="token punctuation">.</span>Ceq<span class="token punctuation">)</span><span class="token punctuation">;</span><br /> Generator<span class="token punctuation">.</span><span class="token function">Emit</span><span class="token punctuation">(</span>OpCodes<span class="token punctuation">.</span>Stloc\_1<span class="token punctuation">)</span><span class="token punctuation">;</span><br /> Generator<span class="token punctuation">.</span><span class="token function">Emit</span><span class="token punctuation">(</span>OpCodes<span class="token punctuation">.</span>Ldloc\_1<span class="token punctuation">)</span><span class="token punctuation">;</span><br /> Generator<span class="token punctuation">.</span><span class="token function">Emit</span><span class="token punctuation">(</span>OpCodes<span class="token punctuation">.</span>Brtrue\_S<span class="token punctuation">,</span> ExitIfStatement<span class="token punctuation">)</span><span class="token punctuation">;</span><br /> Generator<span class="token punctuation">.</span><span class="token function">Emit</span><span class="token punctuation">(</span>OpCodes<span class="token punctuation">.</span>Nop<span class="token punctuation">)</span><span class="token punctuation">;</span><br /> Generator<span class="token punctuation">.</span><span class="token function">Emit</span><span class="token punctuation">(</span>OpCodes<span class="token punctuation">.</span>Call<span class="token punctuation">,</span> <span class="token keyword">typeof</span><span class="token punctuation">(</span><span class="token type-expression class-name">HaterAide<span class="token punctuation">.</span>Factory</span><span class="token punctuation">)</span><span class="token punctuation">.</span><span class="token function">GetMethod</span><span class="token punctuation">(</span><span class="token string">"CreateSession"</span><span class="token punctuation">)</span><span class="token punctuation">)</span><span class="token punctuation">;</span><br /> Generator<span class="token punctuation">.</span><span class="token function">Emit</span><span class="token punctuation">(</span>OpCodes<span class="token punctuation">.</span>Ldarg\_0<span class="token punctuation">)</span><span class="token punctuation">;</span><br /> Generator<span class="token punctuation">.</span><span class="token function">Emit</span><span class="token punctuation">(</span>OpCodes<span class="token punctuation">.</span>Ldfld<span class="token punctuation">,</span> IDField<span class="token punctuation">.</span>FieldBuilder<span class="token punctuation">)</span><span class="token punctuation">;</span><br /> Generator<span class="token punctuation">.</span><span class="token function">Emit</span><span class="token punctuation">(</span>OpCodes<span class="token punctuation">.</span>Box<span class="token punctuation">,</span> IDField<span class="token punctuation">.</span>FieldType<span class="token punctuation">)</span><span class="token punctuation">;</span><br /> Generator<span class="token punctuation">.</span><span class="token function">Emit</span><span class="token punctuation">(</span>OpCodes<span class="token punctuation">.</span>Ldarg\_0<span class="token punctuation">)</span><span class="token punctuation">;</span><br /> Generator<span class="token punctuation">.</span><span class="token function">Emit</span><span class="token punctuation">(</span>OpCodes<span class="token punctuation">.</span>Ldflda<span class="token punctuation">,</span> Field<span class="token punctuation">.</span>FieldBuilder<span class="token punctuation">)</span><span class="token punctuation">;</span><br /> <span class="token class-name">MethodInfo</span> TempMethod <span class="token operator">=</span> <span class="token keyword">typeof</span><span class="token punctuation">(</span><span class="token type-expression class-name">HaterAide<span class="token punctuation">.</span>Session</span><span class="token punctuation">)</span><span class="token punctuation">.</span><span class="token function">GetMethod</span><span class="token punctuation">(</span><span class="token string">"Select"</span><span class="token punctuation">)</span><span class="token punctuation">;</span><br /> TempMethod <span class="token operator">=</span> TempMethod<span class="token punctuation">.</span><span class="token function">MakeGenericMethod</span><span class="token punctuation">(</span><span class="token keyword">new</span> Type\<span class="token punctuation">[</span>\<span class="token punctuation">]</span> <span class="token punctuation">{</span> Field<span class="token punctuation">.</span>FieldType <span class="token punctuation">}</span><span class="token punctuation">)</span><span class="token punctuation">;</span><br /> Generator<span class="token punctuation">.</span><span class="token function">Emit</span><span class="token punctuation">(</span>OpCodes<span class="token punctuation">.</span>Callvirt<span class="token punctuation">,</span> TempMethod<span class="token punctuation">)</span><span class="token punctuation">;</span><br /> Generator<span class="token punctuation">.</span><span class="token function">Emit</span><span class="token punctuation">(</span>OpCodes<span class="token punctuation">.</span>Nop<span class="token punctuation">)</span><span class="token punctuation">;</span><br /> Generator<span class="token punctuation">.</span><span class="token function">Emit</span><span class="token punctuation">(</span>OpCodes<span class="token punctuation">.</span>Nop<span class="token punctuation">)</span><span class="token punctuation">;</span><br /> Generator<span class="token punctuation">.</span><span class="token function">MarkLabel</span><span class="token punctuation">(</span>ExitIfStatement<span class="token punctuation">)</span><span class="token punctuation">;</span><br /> Generator<span class="token punctuation">.</span><span class="token function">Emit</span><span class="token punctuation">(</span>OpCodes<span class="token punctuation">.</span>Ldarg\_0<span class="token punctuation">)</span><span class="token punctuation">;</span><br /> Generator<span class="token punctuation">.</span><span class="token function">Emit</span><span class="token punctuation">(</span>OpCodes<span class="token punctuation">.</span>Ldfld<span class="token punctuation">,</span> Field<span class="token punctuation">.</span>FieldBuilder<span class="token punctuation">)</span><span class="token punctuation">;</span><br /> Generator<span class="token punctuation">.</span><span class="token function">Emit</span><span class="token punctuation">(</span>OpCodes<span class="token punctuation">.</span>Ldnull<span class="token punctuation">)</span><span class="token punctuation">;</span><br /> Generator<span class="token punctuation">.</span><span class="token function">Emit</span><span class="token punctuation">(</span>OpCodes<span class="token punctuation">.</span>Ceq<span class="token punctuation">)</span><span class="token punctuation">;</span><br /> Generator<span class="token punctuation">.</span><span class="token function">Emit</span><span class="token punctuation">(</span>OpCodes<span class="token punctuation">.</span>Ldc\_I4\_0<span class="token punctuation">)</span><span class="token punctuation">;</span><br /> Generator<span class="token punctuation">.</span><span class="token function">Emit</span><span class="token punctuation">(</span>OpCodes<span class="token punctuation">.</span>Ceq<span class="token punctuation">)</span><span class="token punctuation">;</span><br /> Generator<span class="token punctuation">.</span><span class="token function">Emit</span><span class="token punctuation">(</span>OpCodes<span class="token punctuation">.</span>Stloc\_1<span class="token punctuation">)</span><span class="token punctuation">;</span><br /> Generator<span class="token punctuation">.</span><span class="token function">Emit</span><span class="token punctuation">(</span>OpCodes<span class="token punctuation">.</span>Ldloc\_1<span class="token punctuation">)</span><span class="token punctuation">;</span><br /> Generator<span class="token punctuation">.</span><span class="token function">Emit</span><span class="token punctuation">(</span>OpCodes<span class="token punctuation">.</span>Brtrue\_S<span class="token punctuation">,</span> ExitIf2Statement<span class="token punctuation">)</span><span class="token punctuation">;</span><br /> Generator<span class="token punctuation">.</span><span class="token function">Emit</span><span class="token punctuation">(</span>OpCodes<span class="token punctuation">.</span>Nop<span class="token punctuation">)</span><span class="token punctuation">;</span><br /> Generator<span class="token punctuation">.</span><span class="token function">Emit</span><span class="token punctuation">(</span>OpCodes<span class="token punctuation">.</span>Ldarg\_0<span class="token punctuation">)</span><span class="token punctuation">;</span><br /> Generator<span class="token punctuation">.</span><span class="token function">Emit</span><span class="token punctuation">(</span>OpCodes<span class="token punctuation">.</span>Newobj<span class="token punctuation">,</span> Field<span class="token punctuation">.</span>FieldType<span class="token punctuation">.</span><span class="token function">GetConstructor</span><span class="token punctuation">(</span><span class="token keyword">new</span> Type\<span class="token punctuation">[</span><span class="token number">0</span>\<span class="token punctuation">]</span> <span class="token punctuation">{</span> <span class="token punctuation">}</span><span class="token punctuation">)</span><span class="token punctuation">)</span><span class="token punctuation">;</span><br /> Generator<span class="token punctuation">.</span><span class="token function">Emit</span><span class="token punctuation">(</span>OpCodes<span class="token punctuation">.</span>Stfld<span class="token punctuation">,</span> Field<span class="token punctuation">.</span>FieldBuilder<span class="token punctuation">)</span><span class="token punctuation">;</span><br /> Generator<span class="token punctuation">.</span><span class="token function">Emit</span><span class="token punctuation">(</span>OpCodes<span class="token punctuation">.</span>Nop<span class="token punctuation">)</span><span class="token punctuation">;</span><br /> Generator<span class="token punctuation">.</span><span class="token function">MarkLabel</span><span class="token punctuation">(</span>ExitIf2Statement<span class="token punctuation">)</span><span class="token punctuation">;</span><br /> Generator<span class="token punctuation">.</span><span class="token function">Emit</span><span class="token punctuation">(</span>OpCodes<span class="token punctuation">.</span>Ldarg\_0<span class="token punctuation">)</span><span class="token punctuation">;</span><br /> Generator<span class="token punctuation">.</span><span class="token function">Emit</span><span class="token punctuation">(</span>OpCodes<span class="token punctuation">.</span>Ldfld<span class="token punctuation">,</span> Field<span class="token punctuation">.</span>FieldBuilder<span class="token punctuation">)</span><span class="token punctuation">;</span><br /> Generator<span class="token punctuation">.</span><span class="token function">Emit</span><span class="token punctuation">(</span>OpCodes<span class="token punctuation">.</span>Stloc\_0<span class="token punctuation">)</span><span class="token punctuation">;</span><br /> Generator<span class="token punctuation">.</span><span class="token function">Emit</span><span class="token punctuation">(</span>OpCodes<span class="token punctuation">.</span>Br\_S<span class="token punctuation">,</span> ExitStatement<span class="token punctuation">)</span><span class="token punctuation">;</span><br /> Generator<span class="token punctuation">.</span><span class="token function">MarkLabel</span><span class="token punctuation">(</span>ExitStatement<span class="token punctuation">)</span><span class="token punctuation">;</span><br /> Generator<span class="token punctuation">.</span><span class="token function">Emit</span><span class="token punctuation">(</span>OpCodes<span class="token punctuation">.</span>Ldloc\_0<span class="token punctuation">)</span><span class="token punctuation">;</span><br /> Generator<span class="token punctuation">.</span><span class="token function">Emit</span><span class="token punctuation">(</span>OpCodes<span class="token punctuation">.</span>Ret<span class="token punctuation">)</span><span class="token punctuation">;</span><br /> <span class="token punctuation">}</span><br /> <span class="token keyword">else</span><br /> <span class="token punctuation">{</span><br /> Generator<span class="token punctuation">.</span><span class="token function">Emit</span><span class="token punctuation">(</span>OpCodes<span class="token punctuation">.</span>Ldarg\_0<span class="token punctuation">)</span><span class="token punctuation">;</span><br /> Generator<span class="token punctuation">.</span><span class="token function">Emit</span><span class="token punctuation">(</span>OpCodes<span class="token punctuation">.</span>Ldfld<span class="token punctuation">,</span> Field<span class="token punctuation">.</span>FieldBuilder<span class="token punctuation">)</span><span class="token punctuation">;</span><br /> Generator<span class="token punctuation">.</span><span class="token function">Emit</span><span class="token punctuation">(</span>OpCodes<span class="token punctuation">.</span>Ret<span class="token punctuation">)</span><span class="token punctuation">;</span><br /> <span class="token punctuation">}</span> <br /> <br /> <br /> <span class="token class-name">MethodBuilder</span> ValuePropertySet <span class="token operator">=</span> TypeBuilder<span class="token punctuation">.</span><span class="token function">DefineMethod</span><span class="token punctuation">(</span><span class="token string">"set\_"</span> <span class="token operator">+</span> Attribute<span class="token punctuation">.</span>Name<span class="token punctuation">,</span> GetSetAttributes<span class="token punctuation">,</span> <span class="token keyword">null</span><span class="token punctuation">,</span> <span class="token keyword">new</span> Type\<span class="token punctuation">[</span>\<span class="token punctuation">]</span> <span class="token punctuation">{</span> Attribute<span class="token punctuation">.</span>Type <span class="token punctuation">}</span><span class="token punctuation">)</span><span class="token punctuation">;</span> <br /> <br /> Generator <span class="token operator">=</span> ValuePropertySet<span class="token punctuation">.</span><span class="token function">GetILGenerator</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">;</span> <br /> <br /> Generator<span class="token punctuation">.</span><span class="token function">Emit</span><span class="token punctuation">(</span>OpCodes<span class="token punctuation">.</span>Ldarg\_0<span class="token punctuation">)</span><span class="token punctuation">;</span><br /> Generator<span class="token punctuation">.</span><span class="token function">Emit</span><span class="token punctuation">(</span>OpCodes<span class="token punctuation">.</span>Ldarg\_1<span class="token punctuation">)</span><span class="token punctuation">;</span><br /> Generator<span class="token punctuation">.</span><span class="token function">Emit</span><span class="token punctuation">(</span>OpCodes<span class="token punctuation">.</span>Stfld<span class="token punctuation">,</span> Field<span class="token punctuation">.</span>FieldBuilder<span class="token punctuation">)</span><span class="token punctuation">;</span><br /> Generator<span class="token punctuation">.</span><span class="token function">Emit</span><span class="token punctuation">(</span>OpCodes<span class="token punctuation">.</span>Ldarg\_0<span class="token punctuation">)</span><span class="token punctuation">;</span><br /> Generator<span class="token punctuation">.</span><span class="token function">Emit</span><span class="token punctuation">(</span>OpCodes<span class="token punctuation">.</span>Ldfld<span class="token punctuation">,</span> ChangedField<span class="token punctuation">)</span><span class="token punctuation">;</span><br /> Generator<span class="token punctuation">.</span><span class="token function">Emit</span><span class="token punctuation">(</span>OpCodes<span class="token punctuation">.</span>Ldstr<span class="token punctuation">,</span> Attribute<span class="token punctuation">.</span>Name<span class="token punctuation">)</span><span class="token punctuation">;</span><br /> Generator<span class="token punctuation">.</span><span class="token function">Emit</span><span class="token punctuation">(</span>OpCodes<span class="token punctuation">.</span>Callvirt<span class="token punctuation">,</span> <span class="token keyword">typeof</span><span class="token punctuation">(</span><span class="token type-expression class-name">List<span class="token punctuation"><</span><span class="token keyword">string</span>\<span class="token punctuation">></span></span><span class="token punctuation">)</span><span class="token punctuation">.</span><span class="token function">GetMethod</span><span class="token punctuation">(</span><span class="token string">"Add"</span><span class="token punctuation">)</span><span class="token punctuation">)</span><span class="token punctuation">;</span><br /> Generator<span class="token punctuation">.</span><span class="token function">Emit</span><span class="token punctuation">(</span>OpCodes<span class="token punctuation">.</span>Ret<span class="token punctuation">)</span><span class="token punctuation">;</span> <br /> <br /> \_Attribute <span class="token operator">=</span> Attribute<span class="token punctuation">;</span><br /> <span class="token punctuation">}</span></code></pre>
<p>As you can see above the Property constructor has been changed slightly. There are two sections that check if the attribute type is a mapping. These are our updates to deal with classes. The first section defines an ID field (the ID of the mapped class will go there when we load it). The second section is the actual code for getting the object. It checks whether the object is null, if it is null it loads the object and saves it for later (by creating a session object and simply calling Select), however if it is still null it creates a default object. Either way, it returns whatever is held in the object. Now the only tricky thing in here is the fact that Select is a generic function. It took me a good hour to figure out that while I could get the function itself easily enough that I had to define what type it should use. That's done with the MakeGenericMethod call. It seems simple once you've seen it but you'll hit your head against the wall for a while if you don't know what to do as the exceptions that are returned are fairly useless...</p>
<p>Anyway, that's it; we now have lazy loading and classes working... Ok, we still have some slight issues with the database, but the lazy loading is set up and our reflection is working properly. At this point though, we aren't setting up the tables or stored procedures to hold the class mappings. So how do we do this? Well because of how I've set up the SQL building, all we really need to do is create a new data type:</p>
<pre class="language-csharp"><code class="language-csharp"> <span class="token keyword">internal</span> <span class="token keyword">class</span> <span class="token class-name">MapClassType</span><span class="token punctuation">:</span><span class="token type-list"><span class="token class-name">IDataType</span></span><br /> <span class="token punctuation">{</span><br /> <span class="token keyword">public</span> <span class="token function">MapClassType</span><span class="token punctuation">(</span><span class="token class-name">Attribute</span> Attribute<span class="token punctuation">,</span> <span class="token class-name">Reflection<span class="token punctuation">.</span>Class</span> Class<span class="token punctuation">,</span> <span class="token class-name">ClassManager</span> Manager<span class="token punctuation">)</span><br /> <span class="token punctuation">:</span> <span class="token keyword">base</span><span class="token punctuation">(</span>Attribute<span class="token punctuation">)</span><br /> <span class="token punctuation">{</span><br /> \_Class <span class="token operator">=</span> Class<span class="token punctuation">;</span><br /> \_Manager <span class="token operator">=</span> Manager<span class="token punctuation">;</span> <br /> <br /> MappedClass <span class="token operator">=</span> \_Manager\<span class="token punctuation">[</span>Attribute<span class="token punctuation">.</span>Type\<span class="token punctuation">]</span><span class="token punctuation">;</span><br /> MappedDataType <span class="token operator">=</span> GlobalFunctions<span class="token punctuation">.</span><span class="token function">GetSQLType</span><span class="token punctuation">(</span>MappedClass<span class="token punctuation">.</span>IDField<span class="token punctuation">,</span> MappedClass<span class="token punctuation">,</span> \_Manager<span class="token punctuation">)</span><span class="token punctuation">;</span><br /> DataType <span class="token operator">=</span> MappedDataType<span class="token punctuation">.</span>DataType<span class="token punctuation">;</span><br /> Type <span class="token operator">=</span> MappedDataType<span class="token punctuation">.</span>Type<span class="token punctuation">;</span><br /> <span class="token punctuation">}</span> <br /> <br /> <span class="token keyword">private</span> Class \_Class <span class="token operator">=</span> <span class="token keyword">null</span><span class="token punctuation">;</span><br /> <span class="token keyword">private</span> ClassManager \_Manager <span class="token operator">=</span> <span class="token keyword">null</span><span class="token punctuation">;</span><br /> <span class="token keyword">public</span> <span class="token return-type class-name">Class</span> MappedClass <span class="token punctuation">{</span> <span class="token keyword">get</span><span class="token punctuation">;</span> <span class="token keyword">set</span><span class="token punctuation">;</span> <span class="token punctuation">}</span><br /> <span class="token keyword">public</span> <span class="token return-type class-name">IDataType</span> MappedDataType <span class="token punctuation">{</span> <span class="token keyword">get</span><span class="token punctuation">;</span> <span class="token keyword">set</span><span class="token punctuation">;</span> <span class="token punctuation">}</span> <br /> <br /> <span class="token keyword">public</span> <span class="token keyword">override</span> <span class="token return-type class-name"><span class="token keyword">string</span></span> <span class="token function">CreateTableCommand</span><span class="token punctuation">(</span><span class="token punctuation">)</span><br /> <span class="token punctuation">{</span><br /> <span class="token class-name">StringBuilder</span> Builder <span class="token operator">=</span> <span class="token keyword">new</span> <span class="token constructor-invocation class-name">StringBuilder</span><span class="token punctuation">(</span>Name <span class="token operator">+</span> <span class="token string">" "</span> <span class="token operator">+</span> MappedDataType<span class="token punctuation">.</span>Type<span class="token punctuation">)</span><span class="token punctuation">;</span><br /> <span class="token keyword">return</span> Builder<span class="token punctuation">.</span><span class="token function">ToString</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">;</span><br /> <span class="token punctuation">}</span><br /> <span class="token punctuation">}</span> <br /> <br /> <span class="token keyword">internal</span> <span class="token keyword">static</span> <span class="token keyword">class</span> <span class="token class-name">GlobalFunctions</span><br /> <span class="token punctuation">{</span><br /> <span class="token keyword">public</span> <span class="token keyword">static</span> <span class="token return-type class-name">IDataType</span> <span class="token function">GetSQLType</span><span class="token punctuation">(</span><span class="token class-name">Attribute</span> Attribute<span class="token punctuation">,</span><span class="token class-name">Class</span> Class<span class="token punctuation">,</span><span class="token class-name">ClassManager</span> Manager<span class="token punctuation">)</span><br /> <span class="token punctuation">{</span><br /> <span class="token keyword">if</span> <span class="token punctuation">(</span>Attribute<span class="token punctuation">.</span>Type<span class="token punctuation">.</span>FullName<span class="token punctuation">.</span><span class="token function">Equals</span><span class="token punctuation">(</span><span class="token string">"System.Int32"</span><span class="token punctuation">,</span> StringComparison<span class="token punctuation">.</span>CurrentCultureIgnoreCase<span class="token punctuation">)</span><span class="token punctuation">)</span><br /> <span class="token punctuation">{</span><br /> <span class="token keyword">return</span> <span class="token keyword">new</span> <span class="token constructor-invocation class-name">HaterAide<span class="token punctuation">.</span>SQL<span class="token punctuation">.</span>SQLServer<span class="token punctuation">.</span>Statements<span class="token punctuation">.</span>DataTypes<span class="token punctuation">.</span>Int</span><span class="token punctuation">(</span>Attribute<span class="token punctuation">)</span><span class="token punctuation">;</span><br /> <span class="token punctuation">}</span><br /> <span class="token keyword">else</span> <span class="token keyword">if</span> <span class="token punctuation">(</span>Attribute<span class="token punctuation">.</span>Type<span class="token punctuation">.</span>FullName<span class="token punctuation">.</span><span class="token function">Equals</span><span class="token punctuation">(</span><span class="token string">"System.String"</span><span class="token punctuation">,</span> StringComparison<span class="token punctuation">.</span>CurrentCultureIgnoreCase<span class="token punctuation">)</span><span class="token punctuation">)</span><br /> <span class="token punctuation">{</span><br /> <span class="token keyword">return</span> <span class="token keyword">new</span> <span class="token constructor-invocation class-name">HaterAide<span class="token punctuation">.</span>SQL<span class="token punctuation">.</span>SQLServer<span class="token punctuation">.</span>Statements<span class="token punctuation">.</span>DataTypes<span class="token punctuation">.</span>NVarChar</span><span class="token punctuation">(</span>Attribute<span class="token punctuation">)</span><span class="token punctuation">;</span><br /> <span class="token punctuation">}</span><br /> <span class="token keyword">else</span> <span class="token keyword">if</span> <span class="token punctuation">(</span>Attribute<span class="token punctuation">.</span>Type<span class="token punctuation">.</span>FullName<span class="token punctuation">.</span><span class="token function">Equals</span><span class="token punctuation">(</span><span class="token string">"System.Single"</span><span class="token punctuation">,</span> StringComparison<span class="token punctuation">.</span>CurrentCultureIgnoreCase<span class="token punctuation">)</span><span class="token punctuation">)</span><br /> <span class="token punctuation">{</span><br /> <span class="token keyword">return</span> <span class="token keyword">new</span> <span class="token constructor-invocation class-name">HaterAide<span class="token punctuation">.</span>SQL<span class="token punctuation">.</span>SQLServer<span class="token punctuation">.</span>Statements<span class="token punctuation">.</span>DataTypes<span class="token punctuation">.</span>Float</span><span class="token punctuation">(</span>Attribute<span class="token punctuation">)</span><span class="token punctuation">;</span><br /> <span class="token punctuation">}</span><br /> <span class="token keyword">else</span> <span class="token keyword">if</span> <span class="token punctuation">(</span>Attribute<span class="token punctuation">.</span>Type<span class="token punctuation">.</span>FullName<span class="token punctuation">.</span><span class="token function">Equals</span><span class="token punctuation">(</span><span class="token string">"System.Double"</span><span class="token punctuation">,</span> StringComparison<span class="token punctuation">.</span>CurrentCultureIgnoreCase<span class="token punctuation">)</span><span class="token punctuation">)</span><br /> <span class="token punctuation">{</span><br /> <span class="token keyword">return</span> <span class="token keyword">new</span> <span class="token constructor-invocation class-name">HaterAide<span class="token punctuation">.</span>SQL<span class="token punctuation">.</span>SQLServer<span class="token punctuation">.</span>Statements<span class="token punctuation">.</span>DataTypes<span class="token punctuation">.</span>Float</span><span class="token punctuation">(</span>Attribute<span class="token punctuation">)</span><span class="token punctuation">;</span><br /> <span class="token punctuation">}</span><br /> <span class="token keyword">else</span> <span class="token keyword">if</span> <span class="token punctuation">(</span>Attribute<span class="token punctuation">.</span>Type<span class="token punctuation">.</span>FullName<span class="token punctuation">.</span><span class="token function">Equals</span><span class="token punctuation">(</span><span class="token string">"System.Boolean"</span><span class="token punctuation">,</span> StringComparison<span class="token punctuation">.</span>CurrentCultureIgnoreCase<span class="token punctuation">)</span><span class="token punctuation">)</span><br /> <span class="token punctuation">{</span><br /> <span class="token keyword">return</span> <span class="token keyword">new</span> <span class="token constructor-invocation class-name">HaterAide<span class="token punctuation">.</span>SQL<span class="token punctuation">.</span>SQLServer<span class="token punctuation">.</span>Statements<span class="token punctuation">.</span>DataTypes<span class="token punctuation">.</span>Bit</span><span class="token punctuation">(</span>Attribute<span class="token punctuation">)</span><span class="token punctuation">;</span><br /> <span class="token punctuation">}</span><br /> <span class="token keyword">else</span> <span class="token keyword">if</span> <span class="token punctuation">(</span>Attribute<span class="token punctuation">.</span>Type<span class="token punctuation">.</span>FullName<span class="token punctuation">.</span><span class="token function">StartsWith</span><span class="token punctuation">(</span><span class="token string">"System.DateTime"</span><span class="token punctuation">,</span> StringComparison<span class="token punctuation">.</span>CurrentCultureIgnoreCase<span class="token punctuation">)</span><span class="token punctuation">)</span><br /> <span class="token punctuation">{</span><br /> <span class="token keyword">return</span> <span class="token keyword">new</span> <span class="token constructor-invocation class-name">HaterAide<span class="token punctuation">.</span>SQL<span class="token punctuation">.</span>SQLServer<span class="token punctuation">.</span>Statements<span class="token punctuation">.</span>DataTypes<span class="token punctuation">.</span>DateTime</span><span class="token punctuation">(</span>Attribute<span class="token punctuation">)</span><span class="token punctuation">;</span><br /> <span class="token punctuation">}</span><br /> <span class="token keyword">else</span> <span class="token keyword">if</span> <span class="token punctuation">(</span>Attribute<span class="token punctuation">.</span>Type<span class="token punctuation">.</span>FullName<span class="token punctuation">.</span><span class="token function">StartsWith</span><span class="token punctuation">(</span><span class="token string">"System.Guid"</span><span class="token punctuation">,</span> StringComparison<span class="token punctuation">.</span>CurrentCultureIgnoreCase<span class="token punctuation">)</span><span class="token punctuation">)</span><br /> <span class="token punctuation">{</span><br /> <span class="token keyword">return</span> <span class="token keyword">new</span> <span class="token constructor-invocation class-name">HaterAide<span class="token punctuation">.</span>SQL<span class="token punctuation">.</span>SQLServer<span class="token punctuation">.</span>Statements<span class="token punctuation">.</span>DataTypes<span class="token punctuation">.</span>UniqueIdentifier</span><span class="token punctuation">(</span>Attribute<span class="token punctuation">)</span><span class="token punctuation">;</span><br /> <span class="token punctuation">}</span><br /> <span class="token keyword">else</span> <span class="token keyword">if</span> <span class="token punctuation">(</span>Attribute<span class="token punctuation">.</span>Type<span class="token punctuation">.</span>FullName<span class="token punctuation">.</span><span class="token function">StartsWith</span><span class="token punctuation">(</span><span class="token string">"System.Collections.Generic.List"</span><span class="token punctuation">,</span> StringComparison<span class="token punctuation">.</span>CurrentCultureIgnoreCase<span class="token punctuation">)</span><span class="token punctuation">)</span><br /> <span class="token punctuation">{</span><br /> <span class="token keyword">return</span> <span class="token keyword">new</span> <span class="token constructor-invocation class-name">HaterAide<span class="token punctuation">.</span>SQL<span class="token punctuation">.</span>SQLServer<span class="token punctuation">.</span>Statements<span class="token punctuation">.</span>DataTypes<span class="token punctuation">.</span>List</span><span class="token punctuation">(</span>Attribute<span class="token punctuation">,</span> Class<span class="token punctuation">,</span> Manager<span class="token punctuation">)</span><span class="token punctuation">;</span><br /> <span class="token punctuation">}</span><br /> <span class="token keyword">if</span> <span class="token punctuation">(</span>Attribute<span class="token punctuation">.</span>AttributeType <span class="token operator">==</span> AttributeType<span class="token punctuation">.</span>Map<span class="token punctuation">)</span><br /> <span class="token punctuation">{</span><br /> <span class="token keyword">return</span> <span class="token keyword">new</span> <span class="token constructor-invocation class-name">HaterAide<span class="token punctuation">.</span>SQL<span class="token punctuation">.</span>SQLServer<span class="token punctuation">.</span>Statements<span class="token punctuation">.</span>DataTypes<span class="token punctuation">.</span>MapClassType</span><span class="token punctuation">(</span>Attribute<span class="token punctuation">,</span> Class<span class="token punctuation">,</span> Manager<span class="token punctuation">)</span><span class="token punctuation">;</span><br /> <span class="token punctuation">}</span><br /> <span class="token keyword">return</span> <span class="token keyword">null</span><span class="token punctuation">;</span><br /> <span class="token punctuation">}</span><br /> <span class="token punctuation">}</span></code></pre>
<p>As you can see, it acts similarly to the List class in that it doesn't use its own information but instead uses the ID field of the class that it maps to. And after we add it to the global function so that it's being returned, Insert, Select, Update, and Delete classes will simply pick it up and use it properly for the table/stored procedures that are created.<br />
So we have our table that can store the class's ID so that it can load and map the classes properly. However we now have to deal with the more annoying part. We need to actually set up the various stored procedures such that they can use the ID properly.</p>
<pre class="language-csharp"><code class="language-csharp"> <span class="token keyword">private</span> <span class="token return-type class-name"><span class="token keyword">void</span></span> <span class="token function">SetupProperties</span><span class="token punctuation">(</span><span class="token class-name"><span class="token keyword">object</span></span> Object<span class="token punctuation">,</span> <span class="token class-name">SQLHelper</span> Helper<span class="token punctuation">,</span> <span class="token class-name">Type</span> ObjectType<span class="token punctuation">)</span><br /> <span class="token punctuation">{</span><br /> <span class="token keyword">foreach</span> <span class="token punctuation">(</span><span class="token class-name">IDataType</span> Column <span class="token keyword">in</span> Columns<span class="token punctuation">)</span><br /> <span class="token punctuation">{</span><br /> <span class="token keyword">if</span> <span class="token punctuation">(</span>Column <span class="token operator">!=</span> <span class="token keyword">null</span> <span class="token operator">&&</span> Column <span class="token keyword">is</span> <span class="token class-name">MapClassType</span><span class="token punctuation">)</span><br /> <span class="token punctuation">{</span><br /> <span class="token class-name">MapClassType</span> TempColumn <span class="token operator">=</span> <span class="token punctuation">(</span>MapClassType<span class="token punctuation">)</span>Column<span class="token punctuation">;</span><br /> <span class="token class-name"><span class="token keyword">object</span></span> MappedObject<span class="token operator">=</span>ObjectType<span class="token punctuation">.</span><span class="token function">GetProperty</span><span class="token punctuation">(</span>TempColumn<span class="token punctuation">.</span>Name<span class="token punctuation">)</span><span class="token punctuation">.</span><span class="token function">GetValue</span><span class="token punctuation">(</span>Object<span class="token punctuation">,</span><span class="token keyword">null</span><span class="token punctuation">)</span><span class="token punctuation">;</span><br /> <span class="token keyword">if</span> <span class="token punctuation">(</span>MappedObject <span class="token operator">!=</span> <span class="token keyword">null</span><span class="token punctuation">)</span><br /> <span class="token punctuation">{</span><br /> <span class="token class-name">Type</span> MappedObjectType <span class="token operator">=</span> MappedObject<span class="token punctuation">.</span><span class="token function">GetType</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">;</span><br /> <span class="token class-name"><span class="token keyword">object</span></span> Value <span class="token operator">=</span> MappedObjectType<span class="token punctuation">.</span><span class="token function">GetProperty</span><span class="token punctuation">(</span>TempColumn<span class="token punctuation">.</span>MappedClass<span class="token punctuation">.</span>IDField<span class="token punctuation">.</span>Name<span class="token punctuation">)</span><span class="token punctuation">.</span><span class="token function">GetValue</span><span class="token punctuation">(</span>MappedObject<span class="token punctuation">,</span> <span class="token keyword">null</span><span class="token punctuation">)</span><span class="token punctuation">;</span><br /> Helper<span class="token punctuation">.</span><span class="token function">AddParameter</span><span class="token punctuation">(</span><span class="token string">"@"</span> <span class="token operator">+</span> TempColumn<span class="token punctuation">.</span>Name<span class="token punctuation">,</span> Value<span class="token punctuation">,</span> TempColumn<span class="token punctuation">.</span>MappedDataType<span class="token punctuation">.</span>DataType<span class="token punctuation">)</span><span class="token punctuation">;</span><br /> <span class="token punctuation">}</span><br /> <span class="token keyword">else</span> <span class="token keyword">if</span><span class="token punctuation">(</span>TempColumn<span class="token punctuation">.</span>MappedDataType<span class="token punctuation">.</span>DataType<span class="token operator">==</span>SqlDbType<span class="token punctuation">.</span>Int<span class="token punctuation">)</span><br /> <span class="token punctuation">{</span><br /> Helper<span class="token punctuation">.</span><span class="token function">AddParameter</span><span class="token punctuation">(</span><span class="token string">"@"</span> <span class="token operator">+</span> TempColumn<span class="token punctuation">.</span>Name<span class="token punctuation">,</span> <span class="token number">0</span><span class="token punctuation">,</span> TempColumn<span class="token punctuation">.</span>MappedDataType<span class="token punctuation">.</span>DataType<span class="token punctuation">)</span><span class="token punctuation">;</span><br /> <span class="token punctuation">}</span><br /> <span class="token keyword">else</span> <span class="token keyword">if</span> <span class="token punctuation">(</span>TempColumn<span class="token punctuation">.</span>MappedDataType<span class="token punctuation">.</span>DataType <span class="token operator">==</span> SqlDbType<span class="token punctuation">.</span>UniqueIdentifier<span class="token punctuation">)</span><br /> <span class="token punctuation">{</span><br /> Helper<span class="token punctuation">.</span><span class="token function">AddParameter</span><span class="token punctuation">(</span><span class="token string">"@"</span> <span class="token operator">+</span> TempColumn<span class="token punctuation">.</span>Name<span class="token punctuation">,</span> Guid<span class="token punctuation">.</span>Empty<span class="token punctuation">,</span> TempColumn<span class="token punctuation">.</span>MappedDataType<span class="token punctuation">.</span>DataType<span class="token punctuation">)</span><span class="token punctuation">;</span><br /> <span class="token punctuation">}</span><br /> <span class="token punctuation">}</span><br /> <span class="token keyword">else</span> <span class="token keyword">if</span> <span class="token punctuation">(</span>Column <span class="token operator">!=</span> <span class="token keyword">null</span> <span class="token operator">&&</span> <span class="token operator">!</span>Column<span class="token punctuation">.</span>Type<span class="token punctuation">.</span><span class="token function">Equals</span><span class="token punctuation">(</span><span class="token string">"List"</span><span class="token punctuation">,</span> StringComparison<span class="token punctuation">.</span>CurrentCultureIgnoreCase<span class="token punctuation">)</span><span class="token punctuation">)</span><br /> <span class="token punctuation">{</span><br /> <span class="token class-name">PropertyInfo</span> PropertyInfo <span class="token operator">=</span> ObjectType<span class="token punctuation">.</span><span class="token function">GetProperty</span><span class="token punctuation">(</span>Column<span class="token punctuation">.</span>Name<span class="token punctuation">)</span><span class="token punctuation">;</span><br /> <span class="token class-name"><span class="token keyword">object</span></span> Value <span class="token operator">=</span> PropertyInfo<span class="token punctuation">.</span><span class="token function">GetValue</span><span class="token punctuation">(</span>Object<span class="token punctuation">,</span> <span class="token keyword">null</span><span class="token punctuation">)</span><span class="token punctuation">;</span><br /> <span class="token keyword">if</span> <span class="token punctuation">(</span>Column <span class="token keyword">is</span> <span class="token class-name">NVarChar</span> <span class="token operator">&&</span> <span class="token operator">!</span>Column<span class="token punctuation">.</span>IsPrimaryKey<span class="token punctuation">)</span><br /> <span class="token punctuation">{</span><br /> <span class="token keyword">foreach</span> <span class="token punctuation">(</span><span class="token class-name">IConstraint</span> Constraint <span class="token keyword">in</span> Column<span class="token punctuation">.</span>Constraints<span class="token punctuation">)</span><br /> <span class="token punctuation">{</span><br /> <span class="token keyword">if</span> <span class="token punctuation">(</span>Constraint <span class="token keyword">is</span> <span class="token class-name">Size</span><span class="token punctuation">)</span><br /> <span class="token punctuation">{</span><br /> Helper<span class="token punctuation">.</span><span class="token function">AddParameter</span><span class="token punctuation">(</span><span class="token string">"@"</span> <span class="token operator">+</span> Column<span class="token punctuation">.</span>Name<span class="token punctuation">,</span> <span class="token punctuation">(</span><span class="token keyword">string</span><span class="token punctuation">)</span>Value<span class="token punctuation">,</span> <span class="token punctuation">(</span><span class="token punctuation">(</span>Size<span class="token punctuation">)</span>Constraint<span class="token punctuation">)</span><span class="token punctuation">.</span>Length<span class="token punctuation">)</span><span class="token punctuation">;</span><br /> <span class="token keyword">break</span><span class="token punctuation">;</span><br /> <span class="token punctuation">}</span><br /> <span class="token punctuation">}</span><br /> <span class="token punctuation">}</span><br /> <span class="token keyword">else</span> <span class="token keyword">if</span> <span class="token punctuation">(</span><span class="token operator">!</span>Column<span class="token punctuation">.</span>IsPrimaryKey<span class="token punctuation">)</span><br /> <span class="token punctuation">{</span><br /> Helper<span class="token punctuation">.</span><span class="token function">AddParameter</span><span class="token punctuation">(</span><span class="token string">"@"</span> <span class="token operator">+</span> Column<span class="token punctuation">.</span>Name<span class="token punctuation">,</span> Value<span class="token punctuation">,</span> Column<span class="token punctuation">.</span>DataType<span class="token punctuation">)</span><span class="token punctuation">;</span><br /> <span class="token punctuation">}</span><br /> <span class="token punctuation">}</span><br /> <span class="token punctuation">}</span><br /> <span class="token punctuation">}</span></code></pre>
<p>Above is a function from the Insert class. The function looks for nonlist items and adds them to the stored procedure. The top part checks if the individual column is a mapped class. Inside that if statement, it first gets the object's value. If the object is not null it gets the object's ID field and the value of that field. It then adds that value into the stored procedure. A similar addition is made to the Update class. The Delete class doesn't require any updates at all since the only thing the stored procedure cares about is the ID of the class. The Select class is slightly different.</p>
<pre class="language-csharp"><code class="language-csharp"> <span class="token keyword">private</span> <span class="token return-type class-name"><span class="token keyword">object</span></span> <span class="token function">LoadMainClass</span><span class="token punctuation">(</span><span class="token class-name"><span class="token keyword">object</span></span> IDValue<span class="token punctuation">,</span> <span class="token class-name">SQLHelper</span> Helper<span class="token punctuation">,</span> <span class="token class-name"><span class="token keyword">object</span></span> ClassInstance<span class="token punctuation">,</span> <span class="token class-name">IDataType</span> IDField<span class="token punctuation">)</span><br /> <span class="token punctuation">{</span><br /> <span class="token keyword">try</span><br /> <span class="token punctuation">{</span><br /> Helper<span class="token punctuation">.</span><span class="token function">Open</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">;</span><br /> <span class="token keyword">if</span> <span class="token punctuation">(</span>IDField <span class="token keyword">is</span> <span class="token class-name">NVarChar</span><span class="token punctuation">)</span><br /> <span class="token punctuation">{</span><br /> <span class="token keyword">foreach</span> <span class="token punctuation">(</span><span class="token class-name">IConstraint</span> Constraint <span class="token keyword">in</span> IDField<span class="token punctuation">.</span>Constraints<span class="token punctuation">)</span><br /> <span class="token punctuation">{</span><br /> <span class="token keyword">if</span> <span class="token punctuation">(</span>Constraint <span class="token keyword">is</span> <span class="token class-name">Size</span><span class="token punctuation">)</span><br /> <span class="token punctuation">{</span><br /> Helper<span class="token punctuation">.</span><span class="token function">AddParameter</span><span class="token punctuation">(</span><span class="token string">"@"</span> <span class="token operator">+</span> IDField<span class="token punctuation">.</span>Name<span class="token punctuation">,</span> <span class="token punctuation">(</span><span class="token keyword">string</span><span class="token punctuation">)</span>IDValue<span class="token punctuation">,</span> <span class="token punctuation">(</span><span class="token punctuation">(</span>Size<span class="token punctuation">)</span>Constraint<span class="token punctuation">)</span><span class="token punctuation">.</span>Length<span class="token punctuation">)</span><span class="token punctuation">;</span><br /> <span class="token punctuation">}</span><br /> <span class="token punctuation">}</span><br /> <span class="token punctuation">}</span><br /> <span class="token keyword">else</span><br /> <span class="token punctuation">{</span><br /> Helper<span class="token punctuation">.</span><span class="token function">AddParameter</span><span class="token punctuation">(</span><span class="token string">"@"</span> <span class="token operator">+</span> IDField<span class="token punctuation">.</span>Name<span class="token punctuation">,</span> IDValue<span class="token punctuation">,</span> IDField<span class="token punctuation">.</span>DataType<span class="token punctuation">)</span><span class="token punctuation">;</span><br /> <span class="token punctuation">}</span><br /> Helper<span class="token punctuation">.</span><span class="token function">ExecuteReader</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">;</span><br /> <span class="token keyword">if</span> <span class="token punctuation">(</span>Helper<span class="token punctuation">.</span><span class="token function">Read</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">)</span><br /> <span class="token punctuation">{</span><br /> ClassInstance <span class="token operator">=</span> Activator<span class="token punctuation">.</span><span class="token function">CreateInstance</span><span class="token punctuation">(</span>\_Class<span class="token punctuation">.</span>DerivedType<span class="token punctuation">)</span><span class="token punctuation">;</span><br /> <span class="token keyword">foreach</span> <span class="token punctuation">(</span><span class="token class-name">IDataType</span> Column <span class="token keyword">in</span> Columns<span class="token punctuation">)</span><br /> <span class="token punctuation">{</span><br /> <span class="token keyword">if</span> <span class="token punctuation">(</span>Column <span class="token operator">!=</span> <span class="token keyword">null</span> <span class="token operator">&&</span> Column <span class="token keyword">is</span> <span class="token class-name">MapClassType</span><span class="token punctuation">)</span><br /> <span class="token punctuation">{</span><br /> <span class="token class-name">FieldInfo</span> TempField <span class="token operator">=</span> \_Class<span class="token punctuation">.</span>DerivedType<span class="token punctuation">.</span><span class="token function">GetField</span><span class="token punctuation">(</span><span class="token string">"\_"</span> <span class="token operator">+</span> Column<span class="token punctuation">.</span>Name <span class="token operator">+</span> <span class="token string">"IDDerived"</span><span class="token punctuation">)</span><span class="token punctuation">;</span><br /> TempField<span class="token punctuation">.</span><span class="token function">SetValue</span><span class="token punctuation">(</span>ClassInstance<span class="token punctuation">,</span> Helper<span class="token punctuation">.</span><span class="token function">GetParameter</span><span class="token punctuation">(</span>Column<span class="token punctuation">.</span>Name<span class="token punctuation">,</span> <span class="token keyword">null</span><span class="token punctuation">)</span><span class="token punctuation">)</span><span class="token punctuation">;</span><br /> <span class="token punctuation">}</span><br /> <span class="token keyword">else</span> <span class="token keyword">if</span> <span class="token punctuation">(</span>Column <span class="token operator">!=</span> <span class="token keyword">null</span> <span class="token operator">&&</span> <span class="token operator">!</span>Column<span class="token punctuation">.</span>Type<span class="token punctuation">.</span><span class="token function">Equals</span><span class="token punctuation">(</span><span class="token string">"List"</span><span class="token punctuation">,</span> StringComparison<span class="token punctuation">.</span>CurrentCultureIgnoreCase<span class="token punctuation">)</span><span class="token punctuation">)</span><br /> <span class="token punctuation">{</span><br /> <span class="token class-name">PropertyInfo</span> TempProperty <span class="token operator">=</span> \_Class<span class="token punctuation">.</span>DerivedType<span class="token punctuation">.</span><span class="token function">GetProperty</span><span class="token punctuation">(</span>Column<span class="token punctuation">.</span>Name<span class="token punctuation">)</span><span class="token punctuation">;</span><br /> <span class="token keyword">if</span> <span class="token punctuation">(</span>TempProperty<span class="token punctuation">.</span>PropertyType<span class="token punctuation">.</span>FullName<span class="token punctuation">.</span><span class="token function">Equals</span><span class="token punctuation">(</span><span class="token string">"System.Single"</span><span class="token punctuation">,</span> StringComparison<span class="token punctuation">.</span>CurrentCultureIgnoreCase<span class="token punctuation">)</span><span class="token punctuation">)</span><br /> <span class="token punctuation">{</span><br /> TempProperty<span class="token punctuation">.</span><span class="token function">SetValue</span><span class="token punctuation">(</span>ClassInstance<span class="token punctuation">,</span> <span class="token keyword">float</span><span class="token punctuation">.</span><span class="token function">Parse</span><span class="token punctuation">(</span>Helper<span class="token punctuation">.</span><span class="token function">GetParameter</span><span class="token punctuation">(</span>Column<span class="token punctuation">.</span>Name<span class="token punctuation">,</span> <span class="token keyword">null</span><span class="token punctuation">)</span><span class="token punctuation">.</span><span class="token function">ToString</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">)</span><span class="token punctuation">,</span> <span class="token keyword">null</span><span class="token punctuation">)</span><span class="token punctuation">;</span><br /> <span class="token punctuation">}</span><br /> <span class="token keyword">else</span><br /> <span class="token punctuation">{</span><br /> TempProperty<span class="token punctuation">.</span><span class="token function">SetValue</span><span class="token punctuation">(</span>ClassInstance<span class="token punctuation">,</span> Helper<span class="token punctuation">.</span><span class="token function">GetParameter</span><span class="token punctuation">(</span>Column<span class="token punctuation">.</span>Name<span class="token punctuation">,</span> <span class="token keyword">null</span><span class="token punctuation">)</span><span class="token punctuation">,</span> <span class="token keyword">null</span><span class="token punctuation">)</span><span class="token punctuation">;</span><br /> <span class="token punctuation">}</span><br /> <span class="token punctuation">}</span><br /> <span class="token punctuation">}</span><br /> <span class="token punctuation">}</span><br /> <span class="token punctuation">}</span><br /> <span class="token keyword">catch</span> <span class="token punctuation">{</span> <span class="token punctuation">}</span><br /> <span class="token keyword">finally</span> <span class="token punctuation">{</span> Helper<span class="token punctuation">.</span><span class="token function">Close</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token punctuation">}</span><br /> <span class="token keyword">return</span> ClassInstance<span class="token punctuation">;</span><br /> <span class="token punctuation">}</span></code></pre>
<p>Luckily we've set the mapped classes ID field in a predictable manner. So what we do is go through the list of columns like before and if we see a MapClassType object, we get the ID field that we created back in the reflection stage. We then set that value to the ID value that we have stored in our database. We don't load the entire mapped class, just the ID, and we let the lazy loading that we set up before handle the rest.</p>
<p>Now we have our table, our stored procedures, and our lazy loading. That just leaves cascading saving of objects. This is actually slightly more difficult than it may look on the surface. Take for instance two classes, each have a mapping to one another. We save class A which then cascades to class B which then cascades to class A... Yay, infinite loop. Luckily a while back I set up the definitions to take in a boolean stating whether or not to do cascading on a specific property. So we simply set it up such that class B says don't update class A where as class A says cascade down to B. This just means that the person defining the relationship needs to be careful but that's the only issue. So for the Insert and Update classes we simply add a call to the function below from the Run function.</p>
<pre class="language-csharp"><code class="language-csharp"> <span class="token keyword">private</span> <span class="token return-type class-name"><span class="token keyword">void</span></span> <span class="token function">CascadeSave</span><span class="token punctuation">(</span><span class="token class-name"><span class="token keyword">object</span></span> Object<span class="token punctuation">,</span> <span class="token class-name">Type</span> ObjectType<span class="token punctuation">)</span><br /> <span class="token punctuation">{</span><br /> <span class="token class-name">Session</span> TempSession <span class="token operator">=</span> Factory<span class="token punctuation">.</span><span class="token function">CreateSession</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">;</span><br /> <span class="token keyword">foreach</span> <span class="token punctuation">(</span><span class="token class-name">IDataType</span> Column <span class="token keyword">in</span> Columns<span class="token punctuation">)</span><br /> <span class="token punctuation">{</span><br /> <span class="token keyword">if</span> <span class="token punctuation">(</span>Column<span class="token punctuation">.</span>Attribute<span class="token punctuation">.</span>Cascade<span class="token punctuation">)</span><br /> <span class="token punctuation">{</span><br /> <span class="token class-name">PropertyInfo</span> Property <span class="token operator">=</span> ObjectType<span class="token punctuation">.</span><span class="token function">GetProperty</span><span class="token punctuation">(</span>Column<span class="token punctuation">.</span>Name<span class="token punctuation">)</span><span class="token punctuation">;</span><br /> <span class="token class-name"><span class="token keyword">object</span></span> Value<span class="token operator">=</span>Property<span class="token punctuation">.</span><span class="token function">GetValue</span><span class="token punctuation">(</span>Object<span class="token punctuation">,</span><span class="token keyword">null</span><span class="token punctuation">)</span><span class="token punctuation">;</span><br /> <span class="token keyword">if</span> <span class="token punctuation">(</span>Value <span class="token operator">!=</span> <span class="token keyword">null</span><span class="token punctuation">)</span><br /> <span class="token punctuation">{</span><br /> TempSession<span class="token punctuation">.</span><span class="token function">Save</span><span class="token punctuation">(</span>Value<span class="token punctuation">)</span><span class="token punctuation">;</span><br /> <span class="token punctuation">}</span><br /> <span class="token punctuation">}</span><br /> <span class="token punctuation">}</span><br /> <span class="token punctuation">}</span></code></pre>
<p>That's it really. We check our properties, we check if they're null, and we save them. And since we've dealt with the infinite loop issue, we can actually make this function pretty dumb. Now you may assume that we're done but there is yet one more thing that needs to be done. Specifically when we're inserting an object for the first time, there is an issue. You see the order of operations when inserting is we first insert the main class information, we get back our new ID and set that in the object, insert our lists, and then cascade our insertion. Now what happens when the objects that it cascades haven't been saved before? Their ID is going to be the default value (so 0 for an int, etc.). So when we first saved the initial object, all of those mapped classes are pointing to the class with an ID of 0. So how do we fix this? Well after the cascade, these items have an ID as they've been inserted. So at this point all that we need to do is update the main class (we can skip the lists, etc.). So we add this function:</p>
<pre class="language-csharp"><code class="language-csharp"> <span class="token keyword">private</span> <span class="token return-type class-name"><span class="token keyword">void</span></span> <span class="token function">UpdateMainProperties</span><span class="token punctuation">(</span><span class="token class-name"><span class="token keyword">object</span></span> Object<span class="token punctuation">,</span> <span class="token class-name">Type</span> ObjectType<span class="token punctuation">,</span><span class="token class-name">SQLHelper</span> Helper<span class="token punctuation">)</span><br /> <span class="token punctuation">{</span><br /> <span class="token keyword">try</span><br /> <span class="token punctuation">{</span><br /> Helper<span class="token punctuation">.</span>Command <span class="token operator">=</span> \_Class<span class="token punctuation">.</span>OriginalType<span class="token punctuation">.</span>Name <span class="token operator">+</span> <span class="token string">"\_Update"</span><span class="token punctuation">;</span><br /> Helper<span class="token punctuation">.</span><span class="token function">Open</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">;</span><br /> <span class="token keyword">foreach</span> <span class="token punctuation">(</span><span class="token class-name">IDataType</span> Column <span class="token keyword">in</span> Columns<span class="token punctuation">)</span><br /> <span class="token punctuation">{</span><br /> <span class="token keyword">if</span> <span class="token punctuation">(</span>Column <span class="token operator">!=</span> <span class="token keyword">null</span> <span class="token operator">&&</span> Column <span class="token keyword">is</span> <span class="token class-name">MapClassType</span><span class="token punctuation">)</span><br /> <span class="token punctuation">{</span><br /> <span class="token class-name">MapClassType</span> TempColumn <span class="token operator">=</span> <span class="token punctuation">(</span>MapClassType<span class="token punctuation">)</span>Column<span class="token punctuation">;</span><br /> <span class="token class-name"><span class="token keyword">object</span></span> MappedObject <span class="token operator">=</span> ObjectType<span class="token punctuation">.</span><span class="token function">GetProperty</span><span class="token punctuation">(</span>TempColumn<span class="token punctuation">.</span>Name<span class="token punctuation">)</span><span class="token punctuation">.</span><span class="token function">GetValue</span><span class="token punctuation">(</span>Object<span class="token punctuation">,</span> <span class="token keyword">null</span><span class="token punctuation">)</span><span class="token punctuation">;</span><br /> <span class="token keyword">if</span> <span class="token punctuation">(</span>MappedObject <span class="token operator">!=</span> <span class="token keyword">null</span><span class="token punctuation">)</span><br /> <span class="token punctuation">{</span><br /> <span class="token class-name">Type</span> MappedObjectType <span class="token operator">=</span> MappedObject<span class="token punctuation">.</span><span class="token function">GetType</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">;</span><br /> <span class="token class-name"><span class="token keyword">object</span></span> Value <span class="token operator">=</span> MappedObjectType<span class="token punctuation">.</span><span class="token function">GetProperty</span><span class="token punctuation">(</span>TempColumn<span class="token punctuation">.</span>MappedClass<span class="token punctuation">.</span>IDField<span class="token punctuation">.</span>Name<span class="token punctuation">)</span><span class="token punctuation">.</span><span class="token function">GetValue</span><span class="token punctuation">(</span>MappedObject<span class="token punctuation">,</span> <span class="token keyword">null</span><span class="token punctuation">)</span><span class="token punctuation">;</span><br /> Helper<span class="token punctuation">.</span><span class="token function">AddParameter</span><span class="token punctuation">(</span><span class="token string">"@"</span> <span class="token operator">+</span> TempColumn<span class="token punctuation">.</span>Name<span class="token punctuation">,</span> Value<span class="token punctuation">,</span> TempColumn<span class="token punctuation">.</span>MappedDataType<span class="token punctuation">.</span>DataType<span class="token punctuation">)</span><span class="token punctuation">;</span><br /> <span class="token punctuation">}</span><br /> <span class="token keyword">else</span> <span class="token keyword">if</span> <span class="token punctuation">(</span>TempColumn<span class="token punctuation">.</span>MappedDataType<span class="token punctuation">.</span>DataType <span class="token operator">==</span> SqlDbType<span class="token punctuation">.</span>Int<span class="token punctuation">)</span><br /> <span class="token punctuation">{</span><br /> Helper<span class="token punctuation">.</span><span class="token function">AddParameter</span><span class="token punctuation">(</span><span class="token string">"@"</span> <span class="token operator">+</span> TempColumn<span class="token punctuation">.</span>Name<span class="token punctuation">,</span> <span class="token number">0</span><span class="token punctuation">,</span> TempColumn<span class="token punctuation">.</span>MappedDataType<span class="token punctuation">.</span>DataType<span class="token punctuation">)</span><span class="token punctuation">;</span><br /> <span class="token punctuation">}</span><br /> <span class="token keyword">else</span> <span class="token keyword">if</span> <span class="token punctuation">(</span>TempColumn<span class="token punctuation">.</span>MappedDataType<span class="token punctuation">.</span>DataType <span class="token operator">==</span> SqlDbType<span class="token punctuation">.</span>UniqueIdentifier<span class="token punctuation">)</span><br /> <span class="token punctuation">{</span><br /> Helper<span class="token punctuation">.</span><span class="token function">AddParameter</span><span class="token punctuation">(</span><span class="token string">"@"</span> <span class="token operator">+</span> TempColumn<span class="token punctuation">.</span>Name<span class="token punctuation">,</span> Guid<span class="token punctuation">.</span>Empty<span class="token punctuation">,</span> TempColumn<span class="token punctuation">.</span>MappedDataType<span class="token punctuation">.</span>DataType<span class="token punctuation">)</span><span class="token punctuation">;</span><br /> <span class="token punctuation">}</span><br /> <span class="token punctuation">}</span><br /> <span class="token keyword">else</span> <span class="token keyword">if</span> <span class="token punctuation">(</span>Column <span class="token operator">!=</span> <span class="token keyword">null</span> <span class="token operator">&&</span> <span class="token operator">!</span>Column<span class="token punctuation">.</span>Type<span class="token punctuation">.</span><span class="token function">Equals</span><span class="token punctuation">(</span><span class="token string">"List"</span><span class="token punctuation">,</span> StringComparison<span class="token punctuation">.</span>CurrentCultureIgnoreCase<span class="token punctuation">)</span><span class="token punctuation">)</span><br /> <span class="token punctuation">{</span><br /> <span class="token class-name">PropertyInfo</span> PropertyInfo <span class="token operator">=</span> ObjectType<span class="token punctuation">.</span><span class="token function">GetProperty</span><span class="token punctuation">(</span>Column<span class="token punctuation">.</span>Name<span class="token punctuation">)</span><span class="token punctuation">;</span><br /> <span class="token class-name"><span class="token keyword">object</span></span> Value <span class="token operator">=</span> PropertyInfo<span class="token punctuation">.</span><span class="token function">GetValue</span><span class="token punctuation">(</span>Object<span class="token punctuation">,</span> <span class="token keyword">null</span><span class="token punctuation">)</span><span class="token punctuation">;</span><br /> <span class="token keyword">if</span> <span class="token punctuation">(</span>Column <span class="token keyword">is</span> <span class="token class-name">NVarChar</span> <span class="token operator">&&</span> <span class="token operator">!</span>Column<span class="token punctuation">.</span>IsPrimaryKey<span class="token punctuation">)</span><br /> <span class="token punctuation">{</span><br /> <span class="token keyword">foreach</span> <span class="token punctuation">(</span><span class="token class-name">IConstraint</span> Constraint <span class="token keyword">in</span> Column<span class="token punctuation">.</span>Constraints<span class="token punctuation">)</span><br /> <span class="token punctuation">{</span><br /> <span class="token keyword">if</span> <span class="token punctuation">(</span>Constraint <span class="token keyword">is</span> <span class="token class-name">Size</span><span class="token punctuation">)</span><br /> <span class="token punctuation">{</span><br /> Helper<span class="token punctuation">.</span><span class="token function">AddParameter</span><span class="token punctuation">(</span><span class="token string">"@"</span> <span class="token operator">+</span> Column<span class="token punctuation">.</span>Name<span class="token punctuation">,</span> <span class="token punctuation">(</span><span class="token keyword">string</span><span class="token punctuation">)</span>Value<span class="token punctuation">,</span> <span class="token punctuation">(</span><span class="token punctuation">(</span>Size<span class="token punctuation">)</span>Constraint<span class="token punctuation">)</span><span class="token punctuation">.</span>Length<span class="token punctuation">)</span><span class="token punctuation">;</span><br /> <span class="token keyword">break</span><span class="token punctuation">;</span><br /> <span class="token punctuation">}</span><br /> <span class="token punctuation">}</span><br /> <span class="token punctuation">}</span><br /> <span class="token keyword">else</span><br /> <span class="token punctuation">{</span><br /> Helper<span class="token punctuation">.</span><span class="token function">AddParameter</span><span class="token punctuation">(</span><span class="token string">"@"</span> <span class="token operator">+</span> Column<span class="token punctuation">.</span>Name<span class="token punctuation">,</span> Value<span class="token punctuation">,</span> Column<span class="token punctuation">.</span>DataType<span class="token punctuation">)</span><span class="token punctuation">;</span><br /> <span class="token punctuation">}</span><br /> <span class="token punctuation">}</span><br /> <span class="token punctuation">}</span><br /> Helper<span class="token punctuation">.</span><span class="token function">ExecuteNonQuery</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">;</span><br /> <span class="token punctuation">}</span><br /> <span class="token keyword">catch</span> <span class="token punctuation">{</span> <span class="token punctuation">}</span><br /> <span class="token keyword">finally</span> <span class="token punctuation">{</span> Helper<span class="token punctuation">.</span><span class="token function">Close</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token punctuation">}</span><br /> <span class="token punctuation">}</span></code></pre>
<p>We could simply call Save again but our system is pretty dumb and would simply call cascade again. We don't want to deal with that so a simple update function works well enough. And with that function we're finally done with classes. Well one to one mapped classes anyway. We have yet to deal with the pain which is many to many and many to one. But hey, the CRM is getting closer to being done. So give it a try, leave feedback, and happy coding.</p>
Creating an ORM in C# - Part 4
2009-06-25T00:00:00Z
http://www.gutgames.com/post/Creating-an-ORM-in-C-Part-4/
<p>If you have yet to read the first three parts of this series, go back and do so. Not because the code in this section isn't readable without it, but because each article builds on the ones before it. Anyway, today I'm showing the stored procedures that the system defines as well as the insert/saving and selecting of an item.</p>
<p>Anyway, in the last article, we used an IStatement class called CreateTable in our building of the SQL to build each table. It has been modified slightly if you go back and look at it but it's generally the same as in the last article. Anyway, along with creating a table, we can define four functions that the system will need to be able to do, insert, update, delete, and select. With the exception of the select statements, these functions really aren't going to change much and as such I've decided that instead of creating the functions each time, I would simply use stored procedures. So let's look at how the stored procedures are created:</p>
<pre class="language-csharp"><code class="language-csharp"> <span class="token keyword">internal</span> <span class="token keyword">static</span> <span class="token keyword">class</span> <span class="token class-name">SQLBuilder</span><br /> <span class="token punctuation">{</span><br /> <span class="token keyword">public</span> <span class="token keyword">static</span> <span class="token return-type class-name"><span class="token keyword">void</span></span> <span class="token function">CreateStoredProcedures</span><span class="token punctuation">(</span><span class="token class-name"><span class="token keyword">string</span></span> ConnectionString<span class="token punctuation">,</span> <span class="token class-name">Class</span> Class<span class="token punctuation">,</span> <span class="token class-name">ClassManager</span> Manager<span class="token punctuation">,</span> <span class="token class-name"><span class="token keyword">bool</span></span> RecreateIfExists<span class="token punctuation">)</span><br /> <span class="token punctuation">{</span><br /> <span class="token function">CreateInsertStoredProcedures</span><span class="token punctuation">(</span>ConnectionString<span class="token punctuation">,</span> Class<span class="token punctuation">,</span> Manager<span class="token punctuation">)</span><span class="token punctuation">;</span><br /> <span class="token function">CreateUpdateStoredProcedures</span><span class="token punctuation">(</span>ConnectionString<span class="token punctuation">,</span> Class<span class="token punctuation">,</span> Manager<span class="token punctuation">)</span><span class="token punctuation">;</span><br /> <span class="token function">CreateDeleteStoredProcedures</span><span class="token punctuation">(</span>ConnectionString<span class="token punctuation">,</span> Class<span class="token punctuation">,</span> Manager<span class="token punctuation">)</span><span class="token punctuation">;</span><br /> <span class="token function">CreateSelectStoredProcedures</span><span class="token punctuation">(</span>ConnectionString<span class="token punctuation">,</span> Class<span class="token punctuation">,</span> Manager<span class="token punctuation">)</span><span class="token punctuation">;</span><br /> <span class="token punctuation">}</span> <br /> <br /> <span class="token keyword">private</span> <span class="token keyword">static</span> <span class="token return-type class-name"><span class="token keyword">void</span></span> <span class="token function">CreateSelectStoredProcedures</span><span class="token punctuation">(</span><span class="token class-name"><span class="token keyword">string</span></span> ConnectionString<span class="token punctuation">,</span> <span class="token class-name">Class</span> Class<span class="token punctuation">,</span> <span class="token class-name">ClassManager</span> Manager<span class="token punctuation">)</span><br /> <span class="token punctuation">{</span><br /> <span class="token class-name"><span class="token keyword">bool</span></span> Exists <span class="token operator">=</span> <span class="token boolean">false</span><span class="token punctuation">;</span><br /> <span class="token class-name"><span class="token keyword">string</span></span> ClassName <span class="token operator">=</span> Class<span class="token punctuation">.</span>OriginalType<span class="token punctuation">.</span>Name<span class="token punctuation">;</span><br /> <span class="token class-name">Utilities<span class="token punctuation">.</span>SQLHelper<span class="token punctuation">.</span>SQLHelper</span> Helper <span class="token operator">=</span> <span class="token keyword">new</span> <span class="token constructor-invocation class-name">Utilities<span class="token punctuation">.</span>SQLHelper<span class="token punctuation">.</span>SQLHelper</span><span class="token punctuation">(</span><span class="token string">"Select \* from sys.Procedures where name=@ProcedureName"</span><span class="token punctuation">,</span> ConnectionString<span class="token punctuation">,</span> CommandType<span class="token punctuation">.</span>Text<span class="token punctuation">)</span><span class="token punctuation">;</span><br /> <span class="token keyword">if</span> <span class="token punctuation">(</span><span class="token operator">!</span>Exists<span class="token punctuation">)</span><br /> <span class="token punctuation">{</span><br /> <span class="token class-name">Select</span> SelectStoredProcedures <span class="token operator">=</span> <span class="token keyword">new</span> <span class="token constructor-invocation class-name">Select</span><span class="token punctuation">(</span>Class<span class="token punctuation">,</span> Manager<span class="token punctuation">)</span><span class="token punctuation">;</span><br /> Helper<span class="token punctuation">.</span>Command <span class="token operator">=</span> SelectStoredProcedures<span class="token punctuation">.</span><span class="token function">ToString</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">;</span><br /> <span class="token keyword">try</span><br /> <span class="token punctuation">{</span><br /> Helper<span class="token punctuation">.</span><span class="token function">Open</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">;</span><br /> Helper<span class="token punctuation">.</span><span class="token function">ExecuteNonQuery</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">;</span><br /> <span class="token punctuation">}</span><br /> <span class="token keyword">catch</span> <span class="token punctuation">{</span> <span class="token punctuation">}</span><br /> <span class="token keyword">finally</span> <span class="token punctuation">{</span> Helper<span class="token punctuation">.</span><span class="token function">Close</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token punctuation">}</span><br /> <span class="token punctuation">}</span><br /> <span class="token punctuation">}</span> <br /> <br /> <span class="token keyword">private</span> <span class="token keyword">static</span> <span class="token return-type class-name"><span class="token keyword">void</span></span> <span class="token function">CreateDeleteStoredProcedures</span><span class="token punctuation">(</span><span class="token class-name"><span class="token keyword">string</span></span> ConnectionString<span class="token punctuation">,</span> <span class="token class-name">Class</span> Class<span class="token punctuation">,</span> <span class="token class-name">ClassManager</span> Manager<span class="token punctuation">)</span><br /> <span class="token punctuation">{</span><br /> <span class="token class-name"><span class="token keyword">bool</span></span> Exists <span class="token operator">=</span> <span class="token boolean">false</span><span class="token punctuation">;</span><br /> <span class="token class-name"><span class="token keyword">string</span></span> ClassName <span class="token operator">=</span> Class<span class="token punctuation">.</span>OriginalType<span class="token punctuation">.</span>Name<span class="token punctuation">;</span><br /> <span class="token class-name">Utilities<span class="token punctuation">.</span>SQLHelper<span class="token punctuation">.</span>SQLHelper</span> Helper <span class="token operator">=</span> <span class="token keyword">new</span> <span class="token constructor-invocation class-name">Utilities<span class="token punctuation">.</span>SQLHelper<span class="token punctuation">.</span>SQLHelper</span><span class="token punctuation">(</span><span class="token string">"Select \* from sys.Procedures where name=@ProcedureName"</span><span class="token punctuation">,</span> ConnectionString<span class="token punctuation">,</span> CommandType<span class="token punctuation">.</span>Text<span class="token punctuation">)</span><span class="token punctuation">;</span><br /> <span class="token keyword">if</span> <span class="token punctuation">(</span><span class="token operator">!</span>Exists<span class="token punctuation">)</span><br /> <span class="token punctuation">{</span><br /> <span class="token class-name">Delete</span> DeleteStoredProcedures <span class="token operator">=</span> <span class="token keyword">new</span> <span class="token constructor-invocation class-name">Delete</span><span class="token punctuation">(</span>Class<span class="token punctuation">,</span> Manager<span class="token punctuation">)</span><span class="token punctuation">;</span><br /> Helper<span class="token punctuation">.</span>Command <span class="token operator">=</span> DeleteStoredProcedures<span class="token punctuation">.</span><span class="token function">ToString</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">;</span><br /> <span class="token keyword">try</span><br /> <span class="token punctuation">{</span><br /> Helper<span class="token punctuation">.</span><span class="token function">Open</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">;</span><br /> Helper<span class="token punctuation">.</span><span class="token function">ExecuteNonQuery</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">;</span><br /> <span class="token punctuation">}</span><br /> <span class="token keyword">catch</span> <span class="token punctuation">{</span> <span class="token punctuation">}</span><br /> <span class="token keyword">finally</span> <span class="token punctuation">{</span> Helper<span class="token punctuation">.</span><span class="token function">Close</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token punctuation">}</span><br /> <span class="token punctuation">}</span><br /> <span class="token punctuation">}</span> <br /> <br /> <span class="token keyword">private</span> <span class="token keyword">static</span> <span class="token return-type class-name"><span class="token keyword">void</span></span> <span class="token function">CreateUpdateStoredProcedures</span><span class="token punctuation">(</span><span class="token class-name"><span class="token keyword">string</span></span> ConnectionString<span class="token punctuation">,</span> <span class="token class-name">Class</span> Class<span class="token punctuation">,</span> <span class="token class-name">ClassManager</span> Manager<span class="token punctuation">)</span><br /> <span class="token punctuation">{</span><br /> <span class="token class-name"><span class="token keyword">bool</span></span> Exists <span class="token operator">=</span> <span class="token boolean">false</span><span class="token punctuation">;</span><br /> <span class="token class-name"><span class="token keyword">string</span></span> ClassName <span class="token operator">=</span> Class<span class="token punctuation">.</span>OriginalType<span class="token punctuation">.</span>Name<span class="token punctuation">;</span><br /> <span class="token class-name">Utilities<span class="token punctuation">.</span>SQLHelper<span class="token punctuation">.</span>SQLHelper</span> Helper <span class="token operator">=</span> <span class="token keyword">new</span> <span class="token constructor-invocation class-name">Utilities<span class="token punctuation">.</span>SQLHelper<span class="token punctuation">.</span>SQLHelper</span><span class="token punctuation">(</span><span class="token string">"Select \* from sys.Procedures where name=@ProcedureName"</span><span class="token punctuation">,</span> ConnectionString<span class="token punctuation">,</span> CommandType<span class="token punctuation">.</span>Text<span class="token punctuation">)</span><span class="token punctuation">;</span><br /> <span class="token keyword">if</span> <span class="token punctuation">(</span><span class="token operator">!</span>Exists<span class="token punctuation">)</span><br /> <span class="token punctuation">{</span><br /> <span class="token class-name">Update</span> UpdateStoredProcedures <span class="token operator">=</span> <span class="token keyword">new</span> <span class="token constructor-invocation class-name">Update</span><span class="token punctuation">(</span>Class<span class="token punctuation">,</span> Manager<span class="token punctuation">)</span><span class="token punctuation">;</span><br /> Helper<span class="token punctuation">.</span>Command <span class="token operator">=</span> UpdateStoredProcedures<span class="token punctuation">.</span><span class="token function">ToString</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">;</span><br /> <span class="token keyword">try</span><br /> <span class="token punctuation">{</span><br /> Helper<span class="token punctuation">.</span><span class="token function">Open</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">;</span><br /> Helper<span class="token punctuation">.</span><span class="token function">ExecuteNonQuery</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">;</span><br /> <span class="token punctuation">}</span><br /> <span class="token keyword">catch</span> <span class="token punctuation">{</span> <span class="token punctuation">}</span><br /> <span class="token keyword">finally</span> <span class="token punctuation">{</span> Helper<span class="token punctuation">.</span><span class="token function">Close</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token punctuation">}</span><br /> <span class="token punctuation">}</span><br /> <span class="token punctuation">}</span> <br /> <br /> <span class="token keyword">private</span> <span class="token keyword">static</span> <span class="token return-type class-name"><span class="token keyword">void</span></span> <span class="token function">CreateInsertStoredProcedures</span><span class="token punctuation">(</span><span class="token class-name"><span class="token keyword">string</span></span> ConnectionString<span class="token punctuation">,</span> <span class="token class-name">Class</span> Class<span class="token punctuation">,</span> <span class="token class-name">ClassManager</span> Manager<span class="token punctuation">)</span><br /> <span class="token punctuation">{</span><br /> <span class="token class-name"><span class="token keyword">bool</span></span> Exists <span class="token operator">=</span> <span class="token boolean">false</span><span class="token punctuation">;</span><br /> <span class="token class-name"><span class="token keyword">string</span></span> ClassName <span class="token operator">=</span> Class<span class="token punctuation">.</span>OriginalType<span class="token punctuation">.</span>Name<span class="token punctuation">;</span><br /> <span class="token class-name">Utilities<span class="token punctuation">.</span>SQLHelper<span class="token punctuation">.</span>SQLHelper</span> Helper <span class="token operator">=</span> <span class="token keyword">new</span> <span class="token constructor-invocation class-name">Utilities<span class="token punctuation">.</span>SQLHelper<span class="token punctuation">.</span>SQLHelper</span><span class="token punctuation">(</span><span class="token string">"Select \* from sys.Procedures where name=@ProcedureName"</span><span class="token punctuation">,</span> ConnectionString<span class="token punctuation">,</span> CommandType<span class="token punctuation">.</span>Text<span class="token punctuation">)</span><span class="token punctuation">;</span><br /> <span class="token keyword">if</span> <span class="token punctuation">(</span><span class="token operator">!</span>Exists<span class="token punctuation">)</span><br /> <span class="token punctuation">{</span><br /> <span class="token class-name">Insert</span> InsertStoredProcedures <span class="token operator">=</span> <span class="token keyword">new</span> <span class="token constructor-invocation class-name">Insert</span><span class="token punctuation">(</span>Class<span class="token punctuation">,</span> Manager<span class="token punctuation">)</span><span class="token punctuation">;</span><br /> Helper<span class="token punctuation">.</span>Command <span class="token operator">=</span> InsertStoredProcedures<span class="token punctuation">.</span><span class="token function">ToString</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">;</span><br /> <span class="token keyword">try</span><br /> <span class="token punctuation">{</span><br /> Helper<span class="token punctuation">.</span><span class="token function">Open</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">;</span><br /> Helper<span class="token punctuation">.</span><span class="token function">ExecuteNonQuery</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">;</span><br /> <span class="token punctuation">}</span><br /> <span class="token keyword">catch</span> <span class="token punctuation">{</span> <span class="token punctuation">}</span><br /> <span class="token keyword">finally</span> <span class="token punctuation">{</span> Helper<span class="token punctuation">.</span><span class="token function">Close</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token punctuation">}</span><br /> <span class="token punctuation">}</span><br /> <span class="token punctuation">}</span> <br /> <br /> <span class="token keyword">public</span> <span class="token keyword">static</span> <span class="token return-type class-name"><span class="token keyword">void</span></span> <span class="token function">CreateTable</span><span class="token punctuation">(</span><span class="token class-name"><span class="token keyword">string</span></span> ConnectionString<span class="token punctuation">,</span> <span class="token class-name">Class</span> Class<span class="token punctuation">,</span> <span class="token class-name">ClassManager</span> Manager<span class="token punctuation">,</span> <span class="token class-name"><span class="token keyword">bool</span></span> RecreateIfExists<span class="token punctuation">)</span><br /> <span class="token punctuation">{</span><br /> <span class="token class-name"><span class="token keyword">bool</span></span> Exists <span class="token operator">=</span> <span class="token boolean">false</span><span class="token punctuation">;</span><br /> <span class="token class-name"><span class="token keyword">string</span></span> ClassName <span class="token operator">=</span> Class<span class="token punctuation">.</span>OriginalType<span class="token punctuation">.</span>Name<span class="token punctuation">;</span><br /> <span class="token class-name">Utilities<span class="token punctuation">.</span>SQLHelper<span class="token punctuation">.</span>SQLHelper</span> Helper <span class="token operator">=</span> <span class="token keyword">new</span> <span class="token constructor-invocation class-name">Utilities<span class="token punctuation">.</span>SQLHelper<span class="token punctuation">.</span>SQLHelper</span><span class="token punctuation">(</span><span class="token string">"Select \* from sys.Tables where name=@TableID"</span><span class="token punctuation">,</span> ConnectionString<span class="token punctuation">,</span> CommandType<span class="token punctuation">.</span>Text<span class="token punctuation">)</span><span class="token punctuation">;</span><br /> <span class="token keyword">if</span> <span class="token punctuation">(</span><span class="token operator">!</span>RecreateIfExists<span class="token punctuation">)</span><br /> <span class="token punctuation">{</span><br /> <span class="token keyword">try</span><br /> <span class="token punctuation">{</span><br /> Helper<span class="token punctuation">.</span><span class="token function">Open</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">;</span><br /> Helper<span class="token punctuation">.</span><span class="token function">AddParameter</span><span class="token punctuation">(</span><span class="token string">"@TableID"</span><span class="token punctuation">,</span> ClassName<span class="token punctuation">,</span> <span class="token number">200</span><span class="token punctuation">)</span><span class="token punctuation">;</span><br /> Helper<span class="token punctuation">.</span><span class="token function">ExecuteReader</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">;</span><br /> <span class="token keyword">if</span> <span class="token punctuation">(</span>Helper<span class="token punctuation">.</span><span class="token function">Read</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">)</span><br /> <span class="token punctuation">{</span><br /> Exists <span class="token operator">=</span> <span class="token boolean">true</span><span class="token punctuation">;</span><br /> <span class="token punctuation">}</span><br /> <span class="token punctuation">}</span><br /> <span class="token keyword">catch</span> <span class="token punctuation">{</span> <span class="token punctuation">}</span><br /> <span class="token keyword">finally</span> <span class="token punctuation">{</span> Helper<span class="token punctuation">.</span><span class="token function">Close</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token punctuation">}</span><br /> <span class="token punctuation">}</span><br /> <span class="token keyword">if</span> <span class="token punctuation">(</span><span class="token operator">!</span>Exists<span class="token punctuation">)</span><br /> <span class="token punctuation">{</span><br /> <span class="token class-name">CreateTable</span> Table <span class="token operator">=</span> <span class="token keyword">new</span> <span class="token constructor-invocation class-name">CreateTable</span><span class="token punctuation">(</span>Class<span class="token punctuation">,</span> Manager<span class="token punctuation">)</span><span class="token punctuation">;</span><br /> Helper<span class="token punctuation">.</span>Command <span class="token operator">=</span> Table<span class="token punctuation">.</span><span class="token function">ToString</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">;</span><br /> <span class="token keyword">try</span><br /> <span class="token punctuation">{</span><br /> Helper<span class="token punctuation">.</span><span class="token function">Open</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">;</span><br /> Helper<span class="token punctuation">.</span><span class="token function">ExecuteNonQuery</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">;</span><br /> <span class="token punctuation">}</span><br /> <span class="token keyword">catch</span> <span class="token punctuation">{</span> <span class="token punctuation">}</span><br /> <span class="token keyword">finally</span> <span class="token punctuation">{</span> Helper<span class="token punctuation">.</span><span class="token function">Close</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token punctuation">}</span><br /> <span class="token punctuation">}</span><br /> <span class="token punctuation">}</span> <br /> <br /> <span class="token keyword">public</span> <span class="token keyword">static</span> <span class="token return-type class-name"><span class="token keyword">void</span></span> <span class="token function">CreateDatabase</span><span class="token punctuation">(</span><span class="token class-name"><span class="token keyword">string</span></span> ConnectionString<span class="token punctuation">,</span> <span class="token class-name"><span class="token keyword">string</span></span> DatabaseName<span class="token punctuation">,</span> <span class="token class-name"><span class="token keyword">bool</span></span> RecreateIfExists<span class="token punctuation">)</span><br /> <span class="token punctuation">{</span><br /> <span class="token class-name"><span class="token keyword">bool</span></span> Exists <span class="token operator">=</span> <span class="token boolean">false</span><span class="token punctuation">;</span><br /> <span class="token class-name">Utilities<span class="token punctuation">.</span>SQLHelper<span class="token punctuation">.</span>SQLHelper</span> Helper <span class="token operator">=</span> <span class="token keyword">new</span> <span class="token constructor-invocation class-name">Utilities<span class="token punctuation">.</span>SQLHelper<span class="token punctuation">.</span>SQLHelper</span><span class="token punctuation">(</span><span class="token string">"SELECT \* FROM Master.sys.Databases where name=@DatabaseID"</span><span class="token punctuation">,</span> ConnectionString<span class="token punctuation">,</span> CommandType<span class="token punctuation">.</span>Text<span class="token punctuation">)</span><span class="token punctuation">;</span><br /> <span class="token keyword">if</span> <span class="token punctuation">(</span><span class="token operator">!</span>RecreateIfExists<span class="token punctuation">)</span><br /> <span class="token punctuation">{</span><br /> <span class="token keyword">try</span><br /> <span class="token punctuation">{</span><br /> Helper<span class="token punctuation">.</span><span class="token function">Open</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">;</span><br /> Helper<span class="token punctuation">.</span><span class="token function">AddParameter</span><span class="token punctuation">(</span><span class="token string">"@DatabaseID"</span><span class="token punctuation">,</span> DatabaseName<span class="token punctuation">,</span> <span class="token number">100</span><span class="token punctuation">)</span><span class="token punctuation">;</span><br /> Helper<span class="token punctuation">.</span><span class="token function">ExecuteReader</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">;</span><br /> <span class="token keyword">if</span> <span class="token punctuation">(</span>Helper<span class="token punctuation">.</span><span class="token function">Read</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">)</span><br /> <span class="token punctuation">{</span><br /> Exists <span class="token operator">=</span> <span class="token boolean">true</span><span class="token punctuation">;</span><br /> <span class="token punctuation">}</span><br /> <span class="token punctuation">}</span><br /> <span class="token keyword">catch</span> <span class="token punctuation">{</span> <span class="token punctuation">}</span><br /> <span class="token keyword">finally</span> <span class="token punctuation">{</span> Helper<span class="token punctuation">.</span><span class="token function">Close</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token punctuation">}</span><br /> <span class="token punctuation">}</span><br /> <span class="token keyword">if</span> <span class="token punctuation">(</span><span class="token operator">!</span>Exists<span class="token punctuation">)</span><br /> <span class="token punctuation">{</span><br /> Helper<span class="token punctuation">.</span>Command <span class="token operator">=</span> <span class="token string">"CREATE DATABASE "</span> <span class="token operator">+</span> DatabaseName<span class="token punctuation">.</span><span class="token function">Replace</span><span class="token punctuation">(</span><span class="token string">"'"</span><span class="token punctuation">,</span> <span class="token string">""</span><span class="token punctuation">)</span><span class="token punctuation">;</span><br /> <span class="token keyword">try</span><br /> <span class="token punctuation">{</span><br /> Helper<span class="token punctuation">.</span><span class="token function">Open</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">;</span><br /> Helper<span class="token punctuation">.</span><span class="token function">ExecuteNonQuery</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">;</span><br /> <span class="token punctuation">}</span><br /> <span class="token keyword">catch</span> <span class="token punctuation">{</span> <span class="token punctuation">}</span><br /> <span class="token keyword">finally</span> <span class="token punctuation">{</span> Helper<span class="token punctuation">.</span><span class="token function">Close</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token punctuation">}</span><br /> <span class="token punctuation">}</span><br /> <span class="token punctuation">}</span> <br /> <br /> <span class="token keyword">internal</span> <span class="token keyword">static</span> <span class="token return-type class-name"><span class="token keyword">bool</span></span> <span class="token function">Save</span><span class="token punctuation">(</span><span class="token class-name"><span class="token keyword">string</span></span> ConnectionString<span class="token punctuation">,</span> <span class="token class-name"><span class="token keyword">object</span></span> Object<span class="token punctuation">,</span> <span class="token class-name">Class</span> ObjectDefinition<span class="token punctuation">,</span> <span class="token class-name">ClassManager</span> ClassManager<span class="token punctuation">)</span><br /> <span class="token punctuation">{</span><br /> <span class="token class-name">Utilities<span class="token punctuation">.</span>SQLHelper<span class="token punctuation">.</span>SQLHelper</span> Helper <span class="token operator">=</span> <span class="token keyword">new</span> <span class="token constructor-invocation class-name">Utilities<span class="token punctuation">.</span>SQLHelper<span class="token punctuation">.</span>SQLHelper</span><span class="token punctuation">(</span><span class="token string">""</span><span class="token punctuation">,</span> ConnectionString<span class="token punctuation">,</span> CommandType<span class="token punctuation">.</span>Text<span class="token punctuation">)</span><span class="token punctuation">;</span><br /> <span class="token class-name">Insert</span> ObjectInsert <span class="token operator">=</span> <span class="token keyword">new</span> <span class="token constructor-invocation class-name">Insert</span><span class="token punctuation">(</span>ObjectDefinition<span class="token punctuation">,</span> ClassManager<span class="token punctuation">)</span><span class="token punctuation">;</span><br /> ObjectInsert<span class="token punctuation">.</span><span class="token function">Run</span><span class="token punctuation">(</span>Object<span class="token punctuation">,</span> Helper<span class="token punctuation">)</span><span class="token punctuation">;</span><br /> <span class="token keyword">return</span> <span class="token boolean">false</span><span class="token punctuation">;</span><br /> <span class="token punctuation">}</span> <br /> <br /> <span class="token keyword">public</span> <span class="token keyword">static</span> <span class="token return-type class-name"><span class="token keyword">object</span></span> <span class="token function">SelectByID</span><span class="token punctuation">(</span><span class="token class-name"><span class="token keyword">string</span></span> ConnectionString<span class="token punctuation">,</span> <span class="token class-name"><span class="token keyword">object</span></span> IDValue<span class="token punctuation">,</span> <span class="token class-name">Class</span> Class<span class="token punctuation">,</span> <span class="token class-name">ClassManager</span> Manager<span class="token punctuation">)</span><br /> <span class="token punctuation">{</span><br /> <span class="token class-name">Utilities<span class="token punctuation">.</span>SQLHelper<span class="token punctuation">.</span>SQLHelper</span> Helper <span class="token operator">=</span> <span class="token keyword">new</span> <span class="token constructor-invocation class-name">Utilities<span class="token punctuation">.</span>SQLHelper<span class="token punctuation">.</span>SQLHelper</span><span class="token punctuation">(</span><span class="token string">""</span><span class="token punctuation">,</span> ConnectionString<span class="token punctuation">,</span> CommandType<span class="token punctuation">.</span>Text<span class="token punctuation">)</span><span class="token punctuation">;</span><br /> <span class="token class-name">Select</span> TempSelect<span class="token operator">=</span><span class="token keyword">new</span> <span class="token constructor-invocation class-name">Select</span><span class="token punctuation">(</span>Class<span class="token punctuation">,</span>Manager<span class="token punctuation">)</span><span class="token punctuation">;</span><br /> <span class="token keyword">return</span> TempSelect<span class="token punctuation">.</span><span class="token function">SelectByID</span><span class="token punctuation">(</span>IDValue<span class="token punctuation">,</span>Helper<span class="token punctuation">)</span><span class="token punctuation">;</span><br /> <span class="token punctuation">}</span><br /> <span class="token punctuation">}</span> <br /> <br /> <span class="token keyword">internal</span> <span class="token keyword">class</span> <span class="token class-name">Insert</span><span class="token punctuation">:</span><span class="token type-list"><span class="token class-name">IStatement</span></span><br /> <span class="token punctuation">{</span><br /> <span class="token keyword">public</span> <span class="token keyword">override</span> <span class="token return-type class-name"><span class="token keyword">string</span></span> <span class="token function">ToString</span><span class="token punctuation">(</span><span class="token punctuation">)</span><br /> <span class="token punctuation">{</span><br /> <span class="token class-name">StringBuilder</span> Builder <span class="token operator">=</span> <span class="token keyword">new</span> <span class="token constructor-invocation class-name">StringBuilder</span><span class="token punctuation">(</span><span class="token string">"EXEC dbo.sp\_executesql @statement = N'CREATE PROCEDURE dbo."</span> <span class="token operator">+</span> \_Class<span class="token punctuation">.</span>OriginalType<span class="token punctuation">.</span>Name <span class="token operator">+</span> <span class="token string">"\_Insert\\n"</span><span class="token punctuation">)</span><span class="token punctuation">;</span><br /> <span class="token class-name">StringBuilder</span> ListBuilder <span class="token operator">=</span> <span class="token keyword">new</span> <span class="token constructor-invocation class-name">StringBuilder</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">;</span><br /> <span class="token class-name"><span class="token keyword">string</span></span> Splitter <span class="token operator">=</span> <span class="token string">""</span><span class="token punctuation">;</span><br /> <span class="token class-name"><span class="token keyword">string</span></span> Splitter2<span class="token operator">=</span><span class="token string">""</span><span class="token punctuation">;</span><br /> <span class="token class-name">StringBuilder</span> Values<span class="token operator">=</span><span class="token keyword">new</span> <span class="token constructor-invocation class-name">StringBuilder</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">;</span><br /> <span class="token class-name">StringBuilder</span> Parameters<span class="token operator">=</span><span class="token keyword">new</span> <span class="token constructor-invocation class-name">StringBuilder</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">;</span><br /> <span class="token keyword">foreach</span> <span class="token punctuation">(</span><span class="token class-name">IDataType</span> Column <span class="token keyword">in</span> Columns<span class="token punctuation">)</span><br /> <span class="token punctuation">{</span><br /> <span class="token keyword">if</span> <span class="token punctuation">(</span>Column <span class="token operator">!=</span> <span class="token keyword">null</span> <span class="token operator">&&</span> <span class="token operator">!</span>Column<span class="token punctuation">.</span>Type<span class="token punctuation">.</span><span class="token function">Equals</span><span class="token punctuation">(</span><span class="token string">"List"</span><span class="token punctuation">,</span> StringComparison<span class="token punctuation">.</span>CurrentCultureIgnoreCase<span class="token punctuation">)</span><span class="token punctuation">)</span><br /> <span class="token punctuation">{</span><br /> <span class="token keyword">if</span> <span class="token punctuation">(</span><span class="token operator">!</span><span class="token keyword">string</span><span class="token punctuation">.</span><span class="token function">IsNullOrEmpty</span><span class="token punctuation">(</span>Column<span class="token punctuation">.</span><span class="token function">CreateStoredProcedureParameter</span><span class="token punctuation">(</span><span class="token boolean">false</span><span class="token punctuation">,</span> <span class="token boolean">true</span><span class="token punctuation">)</span><span class="token punctuation">)</span><span class="token punctuation">)</span><br /> <span class="token punctuation">{</span><br /> Builder<span class="token punctuation">.</span><span class="token function">Append</span><span class="token punctuation">(</span>Splitter <span class="token operator">+</span> Column<span class="token punctuation">.</span><span class="token function">CreateStoredProcedureParameter</span><span class="token punctuation">(</span><span class="token boolean">false</span><span class="token punctuation">,</span> <span class="token boolean">true</span><span class="token punctuation">)</span><span class="token punctuation">)</span><span class="token punctuation">;</span><br /> Values<span class="token punctuation">.</span><span class="token function">Append</span><span class="token punctuation">(</span>Splitter2 <span class="token operator">+</span> Column<span class="token punctuation">.</span>Name<span class="token punctuation">)</span><span class="token punctuation">;</span><br /> Parameters<span class="token punctuation">.</span><span class="token function">Append</span><span class="token punctuation">(</span>Splitter2 <span class="token operator">+</span> <span class="token string">"@"</span> <span class="token operator">+</span> Column<span class="token punctuation">.</span>Name<span class="token punctuation">)</span><span class="token punctuation">;</span><br /> Splitter <span class="token operator">=</span> <span class="token string">",\\n"</span><span class="token punctuation">;</span><br /> Splitter2 <span class="token operator">=</span> <span class="token string">","</span><span class="token punctuation">;</span><br /> <span class="token punctuation">}</span><br /> <span class="token punctuation">}</span><br /> <span class="token keyword">else</span> <span class="token keyword">if</span> <span class="token punctuation">(</span>Column <span class="token operator">!=</span> <span class="token keyword">null</span> <span class="token operator">&&</span> Column<span class="token punctuation">.</span>Type<span class="token punctuation">.</span><span class="token function">Equals</span><span class="token punctuation">(</span><span class="token string">"List"</span><span class="token punctuation">,</span> StringComparison<span class="token punctuation">.</span>CurrentCultureIgnoreCase<span class="token punctuation">)</span><span class="token punctuation">)</span><br /> <span class="token punctuation">{</span><br /> ListBuilder<span class="token punctuation">.</span><span class="token function">Append</span><span class="token punctuation">(</span><span class="token string">" "</span> <span class="token operator">+</span> Column<span class="token punctuation">.</span><span class="token function">CreateInsertCommand</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">)</span><span class="token punctuation">;</span><br /> <span class="token punctuation">}</span><br /> <span class="token punctuation">}</span> <br /> <br /> Builder<span class="token punctuation">.</span><span class="token function">Append</span><span class="token punctuation">(</span><span class="token string">"\\nAS\\nINSERT INTO "</span> <span class="token operator">+</span> \_Class<span class="token punctuation">.</span>OriginalType<span class="token punctuation">.</span>Name <span class="token operator">+</span> <span class="token string">"("</span> <span class="token operator">+</span> Values<span class="token punctuation">.</span><span class="token function">ToString</span><span class="token punctuation">(</span><span class="token punctuation">)</span> <span class="token operator">+</span> <span class="token string">") VALUES ("</span> <span class="token operator">+</span> Parameters<span class="token punctuation">.</span><span class="token function">ToString</span><span class="token punctuation">(</span><span class="token punctuation">)</span> <span class="token operator">+</span> <span class="token string">")\\nSELECT scope\_identity() as \[ID\]\\nRETURN'\\n"</span><span class="token punctuation">)</span><span class="token punctuation">;</span><br /> <span class="token keyword">return</span> Builder<span class="token punctuation">.</span><span class="token function">ToString</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token operator">+</span>ListBuilder<span class="token punctuation">.</span><span class="token function">ToString</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">;</span><br /> <span class="token punctuation">}</span><br /> <span class="token punctuation">}</span></code></pre>
<p>The SQL builder is called by our provider that we created last time. The builder then goes off and creates our stored procedures (note that at this time it doesn't check to see if they exist first, that will be added later). The SQLBuilder then creates an Insert (or Update, Select, etc. object), passing it the class definition as well as the ClassManager. This class then parses out the information that it needs for each property of the class and builds up a string containing the stored procedure.<br />
In the code above, it's the insert stored procedure that is created. You'll notice that it deals with lists in a different manner than the rest of the properties (note that we're still not dealing with classes). In order to represent a list effectively in a database, you really need to separate out that information in a separate table. As such, the list needs its own insert procedure (and its own delete and select stored procedures also). The code for this is within the List class:</p>
<pre class="language-csharp"><code class="language-csharp"> <span class="token keyword">public</span> <span class="token keyword">override</span> <span class="token return-type class-name"><span class="token keyword">string</span></span> <span class="token function">CreateInsertCommand</span><span class="token punctuation">(</span><span class="token punctuation">)</span><br /> <span class="token punctuation">{</span><br /> <span class="token class-name">StringBuilder</span> Builder <span class="token operator">=</span> <span class="token keyword">new</span> <span class="token constructor-invocation class-name">StringBuilder</span><span class="token punctuation">(</span><span class="token string">"EXEC dbo.sp\_executesql @statement = N'CREATE PROCEDURE dbo."</span> <span class="token operator">+</span> Name <span class="token operator">+</span> <span class="token string">"\_Insert\\n"</span><span class="token punctuation">)</span><span class="token punctuation">;</span><br /> <span class="token class-name"><span class="token keyword">string</span></span> Splitter <span class="token operator">=</span> <span class="token string">""</span><span class="token punctuation">;</span><br /> <span class="token keyword">foreach</span><span class="token punctuation">(</span><span class="token class-name">IDataType</span> Column <span class="token keyword">in</span> Columns<span class="token punctuation">)</span><br /> <span class="token punctuation">{</span><br /> Builder<span class="token punctuation">.</span><span class="token function">Append</span><span class="token punctuation">(</span>Splitter <span class="token operator">+</span> Column<span class="token punctuation">.</span><span class="token function">CreateStoredProcedureParameter</span><span class="token punctuation">(</span><span class="token boolean">false</span><span class="token punctuation">,</span> <span class="token boolean">true</span><span class="token punctuation">)</span><span class="token punctuation">)</span><span class="token punctuation">;</span><br /> Splitter <span class="token operator">=</span> <span class="token string">",\\n"</span><span class="token punctuation">;</span><br /> <span class="token punctuation">}</span><br /> Builder<span class="token punctuation">.</span><span class="token function">Append</span><span class="token punctuation">(</span><span class="token string">"\\nAS\\nINSERT INTO "</span><span class="token operator">+</span>Name<span class="token operator">+</span><span class="token string">"("</span><span class="token punctuation">)</span><span class="token punctuation">;</span><br /> <span class="token class-name">StringBuilder</span> Values<span class="token operator">=</span><span class="token keyword">new</span> <span class="token constructor-invocation class-name">StringBuilder</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">;</span><br /> Splitter <span class="token operator">=</span> <span class="token string">""</span><span class="token punctuation">;</span><br /> <span class="token keyword">foreach</span><span class="token punctuation">(</span><span class="token class-name">IDataType</span> Column <span class="token keyword">in</span> Columns<span class="token punctuation">)</span><br /> <span class="token punctuation">{</span><br /> Values<span class="token punctuation">.</span><span class="token function">Append</span><span class="token punctuation">(</span>Splitter<span class="token operator">+</span><span class="token string">"@"</span><span class="token operator">+</span>Column<span class="token punctuation">.</span>Name<span class="token punctuation">)</span><span class="token punctuation">;</span><br /> Builder<span class="token punctuation">.</span><span class="token function">Append</span><span class="token punctuation">(</span>Splitter<span class="token operator">+</span>Column<span class="token punctuation">.</span>Name<span class="token punctuation">)</span><span class="token punctuation">;</span><br /> Splitter<span class="token operator">=</span><span class="token string">","</span><span class="token punctuation">;</span><br /> <span class="token punctuation">}</span><br /> Builder<span class="token punctuation">.</span><span class="token function">Append</span><span class="token punctuation">(</span><span class="token string">") VALUES("</span> <span class="token operator">+</span> Values<span class="token punctuation">.</span><span class="token function">ToString</span><span class="token punctuation">(</span><span class="token punctuation">)</span> <span class="token operator">+</span> <span class="token string">")\\nRETURN'\\n"</span><span class="token punctuation">)</span><span class="token punctuation">;</span><br /> <span class="token keyword">return</span> Builder<span class="token punctuation">.</span><span class="token function">ToString</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">;</span><br /> <span class="token punctuation">}</span></code></pre>
<p>It's not pretty doing it this way and I'm sure that I'll figure another way to do this, but it is what it is for now. Anyway, we have similar code for update, delete, and select stored procedures (note that the select versions only deal with selecting an item by the ID field and selecting all of the items). These stored procedures and then thrown back to the SQLBuilder class and it runs it against the database.</p>
<p>So at this point we have our tables, our stored procedures, etc. Now how do we actually insert something into our database? Well in order to do this I've created a helper class called Session:</p>
<pre class="language-csharp"><code class="language-csharp"> <span class="token keyword">public</span> <span class="token keyword">class</span> <span class="token class-name">Session</span><br /> <span class="token punctuation">{</span><br /> <span class="token keyword">public</span> <span class="token function">Session</span><span class="token punctuation">(</span><span class="token punctuation">)</span><br /> <span class="token punctuation">{</span><br /> <span class="token punctuation">}</span> <br /> <br /> <span class="token keyword">internal</span> <span class="token function">Session</span><span class="token punctuation">(</span><span class="token class-name">IProvider</span> Provider<span class="token punctuation">)</span><br /> <span class="token punctuation">{</span><br /> \_Provider <span class="token operator">=</span> Provider<span class="token punctuation">;</span><br /> <span class="token punctuation">}</span> <br /> <br /> <span class="token keyword">public</span> <span class="token return-type class-name"><span class="token keyword">bool</span></span> <span class="token function">Save</span><span class="token punctuation">(</span><span class="token class-name"><span class="token keyword">object</span></span> Object<span class="token punctuation">)</span><br /> <span class="token punctuation">{</span><br /> <span class="token keyword">if</span> <span class="token punctuation">(</span>\_Provider <span class="token operator">!=</span> <span class="token keyword">null</span><span class="token punctuation">)</span><br /> <span class="token punctuation">{</span><br /> <span class="token keyword">return</span> \_Provider<span class="token punctuation">.</span><span class="token function">Save</span><span class="token punctuation">(</span>Object<span class="token punctuation">)</span><span class="token punctuation">;</span><br /> <span class="token punctuation">}</span><br /> <span class="token keyword">return</span> <span class="token boolean">false</span><span class="token punctuation">;</span><br /> <span class="token punctuation">}</span> <br /> <br /> <span class="token keyword">public</span> <span class="token return-type class-name"><span class="token keyword">void</span></span> <span class="token generic-method"><span class="token function">Select</span><span class="token generic class-name"><span class="token punctuation"><</span>T<span class="token punctuation">></span></span></span><span class="token punctuation">(</span><span class="token class-name"><span class="token keyword">object</span></span> ID<span class="token punctuation">,</span> <span class="token keyword">out</span> <span class="token class-name">T</span> Object<span class="token punctuation">)</span><br /> <span class="token punctuation">{</span><br /> <span class="token keyword">if</span> <span class="token punctuation">(</span>\_Provider <span class="token operator">!=</span> <span class="token keyword">null</span><span class="token punctuation">)</span><br /> <span class="token punctuation">{</span><br /> Object<span class="token operator">=</span> <span class="token punctuation">(</span>T<span class="token punctuation">)</span>\_Provider<span class="token punctuation">.</span><span class="token generic-method"><span class="token function">SelectByID</span><span class="token generic class-name"><span class="token punctuation"><</span>T<span class="token punctuation">></span></span></span><span class="token punctuation">(</span>ID<span class="token punctuation">)</span><span class="token punctuation">;</span><br /> <span class="token keyword">return</span><span class="token punctuation">;</span><br /> <span class="token punctuation">}</span><br /> Object <span class="token operator">=</span> <span class="token keyword">default</span><span class="token punctuation">(</span><span class="token type-expression class-name">T</span><span class="token punctuation">)</span><span class="token punctuation">;</span><br /> <span class="token punctuation">}</span> <br /> <br /> <span class="token keyword">public</span> <span class="token return-type class-name"><span class="token keyword">void</span></span> <span class="token function">Delete</span><span class="token punctuation">(</span><span class="token class-name"><span class="token keyword">object</span></span> Object<span class="token punctuation">)</span><br /> <span class="token punctuation">{</span><br /> <span class="token keyword">if</span> <span class="token punctuation">(</span>\_Provider <span class="token operator">!=</span> <span class="token keyword">null</span><span class="token punctuation">)</span><br /> <span class="token punctuation">{</span><br /> \_Provider<span class="token punctuation">.</span><span class="token function">Delete</span><span class="token punctuation">(</span>Object<span class="token punctuation">)</span><span class="token punctuation">;</span><br /> <span class="token punctuation">}</span><br /> <span class="token punctuation">}</span> <br /> <br /> <span class="token keyword">private</span> IProvider \_Provider<span class="token operator">=</span><span class="token keyword">null</span><span class="token punctuation">;</span><br /> <span class="token punctuation">}</span></code></pre>
<p>As you can see, all it really does is acts as a provider proxy between us and the provider. The two functions that you will want to take a look at are Save and Select. The Save function is pretty straightforward but the Select statement takes a bit more explaining. In the Save function's case, we can get the Type of the object at any time and discover what we should be selecting since we have our ClassManager already set up. In the case of the Select though, we don't know what we're suppose to be selecting. So in order to help, we use generics here. That way we can pull the Type class appropriately and pass that to our ClassManager to find out what to do.</p>
<p>Anyway, if we look back at the Provider class:</p>
<pre class="language-csharp"><code class="language-csharp"> <span class="token keyword">class</span> <span class="token class-name">Provider</span> <span class="token punctuation">:</span> <span class="token type-list"><span class="token class-name">IProvider</span></span><br /> <span class="token punctuation">{</span><br /> <span class="token keyword">internal</span> <span class="token keyword">override</span> <span class="token return-type class-name"><span class="token keyword">bool</span></span> <span class="token function">Save</span><span class="token punctuation">(</span><span class="token class-name"><span class="token keyword">object</span></span> Object<span class="token punctuation">)</span><br /> <span class="token punctuation">{</span><br /> <span class="token class-name">Class</span> TempClassDefinition <span class="token operator">=</span> <span class="token keyword">null</span><span class="token punctuation">;</span><br /> <span class="token keyword">try</span><br /> <span class="token punctuation">{</span><br /> TempClassDefinition <span class="token operator">=</span> ClassManager\<span class="token punctuation">[</span>Object<span class="token punctuation">.</span><span class="token function">GetType</span><span class="token punctuation">(</span><span class="token punctuation">)</span>\<span class="token punctuation">]</span><span class="token punctuation">;</span><br /> <span class="token punctuation">}</span><br /> <span class="token keyword">catch</span> <span class="token punctuation">{</span> TempClassDefinition <span class="token operator">=</span> <span class="token keyword">null</span><span class="token punctuation">;</span> <span class="token punctuation">}</span><br /> <span class="token keyword">return</span> SQLBuilder<span class="token punctuation">.</span><span class="token function">Save</span><span class="token punctuation">(</span>ConnectionString<span class="token punctuation">,</span> Object<span class="token punctuation">,</span> TempClassDefinition<span class="token punctuation">,</span> ClassManager<span class="token punctuation">)</span><span class="token punctuation">;</span><br /> <span class="token punctuation">}</span> <br /> <br /> <span class="token keyword">internal</span> <span class="token keyword">override</span> <span class="token return-type class-name"><span class="token keyword">object</span></span> <span class="token generic-method"><span class="token function">SelectByID</span><span class="token generic class-name"><span class="token punctuation"><</span>T<span class="token punctuation">></span></span></span><span class="token punctuation">(</span><span class="token class-name"><span class="token keyword">object</span></span> IDValue<span class="token punctuation">)</span><br /> <span class="token punctuation">{</span><br /> <span class="token class-name">Class</span> TempClassDefinition <span class="token operator">=</span> <span class="token keyword">null</span><span class="token punctuation">;</span><br /> <span class="token keyword">try</span><br /> <span class="token punctuation">{</span><br /> TempClassDefinition <span class="token operator">=</span> ClassManager\<span class="token punctuation">[</span><span class="token keyword">typeof</span><span class="token punctuation">(</span><span class="token type-expression class-name">T</span><span class="token punctuation">)</span>\<span class="token punctuation">]</span><span class="token punctuation">;</span><br /> <span class="token punctuation">}</span><br /> <span class="token keyword">catch</span> <span class="token punctuation">{</span> TempClassDefinition <span class="token operator">=</span> <span class="token keyword">null</span><span class="token punctuation">;</span> <span class="token punctuation">}</span><br /> <span class="token keyword">return</span> SQLBuilder<span class="token punctuation">.</span><span class="token function">SelectByID</span><span class="token punctuation">(</span>ConnectionString<span class="token punctuation">,</span> IDValue<span class="token punctuation">,</span> TempClassDefinition<span class="token punctuation">,</span> ClassManager<span class="token punctuation">)</span><span class="token punctuation">;</span><br /> <span class="token punctuation">}</span><br /> <span class="token punctuation">}</span></code></pre>
<p>You will notice that all it does is passes it on to the SQLBuilder class. The SQLBuilder class in turn simply creates an Insert/Select class depending on what is called and runs a function. Note that at this point Save only inserts items, but when Update is implemented it would check the ID and call the appropriate class here.<br />
The Insert class uses the following functions to actually go about and insert the information:</p>
<pre class="language-csharp"><code class="language-csharp"> <span class="token keyword">public</span> <span class="token keyword">override</span> <span class="token return-type class-name"><span class="token keyword">void</span></span> <span class="token function">Run</span><span class="token punctuation">(</span><span class="token class-name"><span class="token keyword">object</span></span> Object<span class="token punctuation">,</span> <span class="token class-name">SQLHelper</span> Helper<span class="token punctuation">)</span><br /> <span class="token punctuation">{</span><br /> <span class="token class-name">Type</span> ObjectType <span class="token operator">=</span> Object<span class="token punctuation">.</span><span class="token function">GetType</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">;</span><br /> <span class="token keyword">try</span><br /> <span class="token punctuation">{</span><br /> Helper<span class="token punctuation">.</span>Command <span class="token operator">=</span> \_Class<span class="token punctuation">.</span>OriginalType<span class="token punctuation">.</span>Name <span class="token operator">+</span> <span class="token string">"\_Insert"</span><span class="token punctuation">;</span><br /> Helper<span class="token punctuation">.</span>CommandType <span class="token operator">=</span> CommandType<span class="token punctuation">.</span>StoredProcedure<span class="token punctuation">;</span><br /> Helper<span class="token punctuation">.</span><span class="token function">Open</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">;</span><br /> <span class="token function">SetupProperties</span><span class="token punctuation">(</span>Object<span class="token punctuation">,</span> Helper<span class="token punctuation">,</span> ObjectType<span class="token punctuation">)</span><span class="token punctuation">;</span><br /> <span class="token class-name"><span class="token keyword">object</span></span> IDValue<span class="token operator">=</span>Helper<span class="token punctuation">.</span><span class="token function">ExecuteScalar</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">;</span><br /> <span class="token function">SetID</span><span class="token punctuation">(</span>Object<span class="token punctuation">,</span> ObjectType<span class="token punctuation">,</span> IDValue<span class="token punctuation">)</span><span class="token punctuation">;</span><br /> <span class="token punctuation">}</span><br /> <span class="token keyword">catch</span> <span class="token punctuation">{</span> <span class="token punctuation">}</span><br /> <span class="token keyword">finally</span> <span class="token punctuation">{</span> Helper<span class="token punctuation">.</span><span class="token function">Close</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token punctuation">}</span><br /> <span class="token function">SetupLists</span><span class="token punctuation">(</span>Object<span class="token punctuation">,</span> Helper<span class="token punctuation">,</span> ObjectType<span class="token punctuation">)</span><span class="token punctuation">;</span><br /> <span class="token punctuation">}</span> <br /> <br /> <span class="token keyword">private</span> <span class="token return-type class-name"><span class="token keyword">void</span></span> <span class="token function">SetupLists</span><span class="token punctuation">(</span><span class="token class-name"><span class="token keyword">object</span></span> Object<span class="token punctuation">,</span> <span class="token class-name">SQLHelper</span> Helper<span class="token punctuation">,</span> <span class="token class-name">Type</span> ObjectType<span class="token punctuation">)</span><br /> <span class="token punctuation">{</span><br /> <span class="token keyword">foreach</span> <span class="token punctuation">(</span><span class="token class-name">IDataType</span> Column <span class="token keyword">in</span> Columns<span class="token punctuation">)</span><br /> <span class="token punctuation">{</span><br /> <span class="token keyword">if</span> <span class="token punctuation">(</span>Column <span class="token operator">!=</span> <span class="token keyword">null</span> <span class="token operator">&&</span> Column<span class="token punctuation">.</span>Type<span class="token punctuation">.</span><span class="token function">Equals</span><span class="token punctuation">(</span><span class="token string">"List"</span><span class="token punctuation">,</span> StringComparison<span class="token punctuation">.</span>CurrentCultureIgnoreCase<span class="token punctuation">)</span><span class="token punctuation">)</span><br /> <span class="token punctuation">{</span><br /> <span class="token class-name"><span class="token keyword">string</span></span> IDName<span class="token operator">=</span><span class="token punctuation">(</span><span class="token punctuation">(</span>List<span class="token punctuation">)</span>Column<span class="token punctuation">)</span><span class="token punctuation">.</span>IDName<span class="token punctuation">;</span><br /> <span class="token class-name">SqlDbType</span> IDType<span class="token operator">=</span><span class="token punctuation">(</span><span class="token punctuation">(</span>List<span class="token punctuation">)</span>Column<span class="token punctuation">)</span><span class="token punctuation">.</span>IDType<span class="token punctuation">;</span><br /> <span class="token class-name"><span class="token keyword">string</span></span> DataName<span class="token operator">=</span><span class="token punctuation">(</span><span class="token punctuation">(</span>List<span class="token punctuation">)</span>Column<span class="token punctuation">)</span><span class="token punctuation">.</span>DataName<span class="token punctuation">;</span><br /> <span class="token class-name">SqlDbType</span> DataType<span class="token operator">=</span><span class="token punctuation">(</span><span class="token punctuation">(</span>List<span class="token punctuation">)</span>Column<span class="token punctuation">)</span><span class="token punctuation">.</span>DataType<span class="token punctuation">;</span><br /> <span class="token class-name"><span class="token keyword">int</span></span> DataSize<span class="token operator">=</span><span class="token punctuation">(</span><span class="token punctuation">(</span>List<span class="token punctuation">)</span>Column<span class="token punctuation">)</span><span class="token punctuation">.</span>Size<span class="token punctuation">;</span> <br /> <br /> <span class="token class-name">PropertyInfo</span> IDPropertyInfo <span class="token operator">=</span> ObjectType<span class="token punctuation">.</span><span class="token function">GetProperty</span><span class="token punctuation">(</span>IDName<span class="token punctuation">)</span><span class="token punctuation">;</span><br /> <span class="token class-name"><span class="token keyword">object</span></span> IDValue <span class="token operator">=</span> IDPropertyInfo<span class="token punctuation">.</span><span class="token function">GetValue</span><span class="token punctuation">(</span>Object<span class="token punctuation">,</span> <span class="token keyword">null</span><span class="token punctuation">)</span><span class="token punctuation">;</span> <br /> <br /> Helper<span class="token punctuation">.</span>Command <span class="token operator">=</span> Column<span class="token punctuation">.</span>Name <span class="token operator">+</span> <span class="token string">"\_Insert"</span><span class="token punctuation">;</span> <br /> <br /> <span class="token class-name">PropertyInfo</span> PropertyInfo <span class="token operator">=</span> ObjectType<span class="token punctuation">.</span><span class="token function">GetProperty</span><span class="token punctuation">(</span>Column<span class="token punctuation">.</span>Attribute<span class="token punctuation">.</span>Name<span class="token punctuation">)</span><span class="token punctuation">;</span><br /> <span class="token class-name"><span class="token keyword">object</span></span> ListValue <span class="token operator">=</span> PropertyInfo<span class="token punctuation">.</span><span class="token function">GetValue</span><span class="token punctuation">(</span>Object<span class="token punctuation">,</span> <span class="token keyword">null</span><span class="token punctuation">)</span><span class="token punctuation">;</span><br /> <span class="token class-name">Type</span> ListType <span class="token operator">=</span> ListValue<span class="token punctuation">.</span><span class="token function">GetType</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">;</span><br /> <span class="token class-name">PropertyInfo</span> IndexProperty <span class="token operator">=</span> ListType<span class="token punctuation">.</span><span class="token function">GetProperty</span><span class="token punctuation">(</span><span class="token string">"Item"</span><span class="token punctuation">)</span><span class="token punctuation">;</span><br /> <span class="token class-name">PropertyInfo</span> CountProperty <span class="token operator">=</span> ListType<span class="token punctuation">.</span><span class="token function">GetProperty</span><span class="token punctuation">(</span><span class="token string">"Count"</span><span class="token punctuation">)</span><span class="token punctuation">;</span><br /> <span class="token class-name"><span class="token keyword">int</span></span> Count <span class="token operator">=</span> <span class="token punctuation">(</span><span class="token keyword">int</span><span class="token punctuation">)</span>CountProperty<span class="token punctuation">.</span><span class="token function">GetValue</span><span class="token punctuation">(</span>ListValue<span class="token punctuation">,</span> <span class="token keyword">null</span><span class="token punctuation">)</span><span class="token punctuation">;</span><br /> <span class="token keyword">for</span> <span class="token punctuation">(</span><span class="token class-name"><span class="token keyword">int</span></span> x <span class="token operator">=</span> <span class="token number">0</span><span class="token punctuation">;</span> x <span class="token operator"><</span> Count<span class="token punctuation">;</span> <span class="token operator">++</span>x<span class="token punctuation">)</span><br /> <span class="token punctuation">{</span><br /> <span class="token keyword">try</span><br /> <span class="token punctuation">{</span><br /> Helper<span class="token punctuation">.</span><span class="token function">Open</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">;</span><br /> Helper<span class="token punctuation">.</span><span class="token function">AddParameter</span><span class="token punctuation">(</span><span class="token string">"@"</span> <span class="token operator">+</span> IDName<span class="token punctuation">,</span> IDValue<span class="token punctuation">,</span> IDType<span class="token punctuation">)</span><span class="token punctuation">;</span><br /> <span class="token keyword">if</span> <span class="token punctuation">(</span>DataType <span class="token operator">==</span> SqlDbType<span class="token punctuation">.</span>NVarChar<span class="token punctuation">)</span><br /> <span class="token punctuation">{</span><br /> Helper<span class="token punctuation">.</span><span class="token function">AddParameter</span><span class="token punctuation">(</span><span class="token string">"@"</span> <span class="token operator">+</span> DataName<span class="token punctuation">,</span> <span class="token punctuation">(</span><span class="token keyword">string</span><span class="token punctuation">)</span>IndexProperty<span class="token punctuation">.</span><span class="token function">GetValue</span><span class="token punctuation">(</span>ListValue<span class="token punctuation">,</span> <span class="token keyword">new</span> <span class="token keyword">object</span>\<span class="token punctuation">[</span>\<span class="token punctuation">]</span> <span class="token punctuation">{</span> x <span class="token punctuation">}</span><span class="token punctuation">)</span><span class="token punctuation">,</span> DataSize<span class="token punctuation">)</span><span class="token punctuation">;</span><br /> <span class="token punctuation">}</span><br /> <span class="token keyword">else</span><br /> <span class="token punctuation">{</span><br /> Helper<span class="token punctuation">.</span><span class="token function">AddParameter</span><span class="token punctuation">(</span><span class="token string">"@"</span> <span class="token operator">+</span> DataName<span class="token punctuation">,</span> IndexProperty<span class="token punctuation">.</span><span class="token function">GetValue</span><span class="token punctuation">(</span>ListValue<span class="token punctuation">,</span> <span class="token keyword">new</span> <span class="token keyword">object</span>\<span class="token punctuation">[</span>\<span class="token punctuation">]</span> <span class="token punctuation">{</span> x <span class="token punctuation">}</span><span class="token punctuation">)</span><span class="token punctuation">,</span> DataType<span class="token punctuation">)</span><span class="token punctuation">;</span><br /> <span class="token punctuation">}</span><br /> Helper<span class="token punctuation">.</span><span class="token function">ExecuteNonQuery</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">;</span><br /> <span class="token punctuation">}</span><br /> <span class="token keyword">catch</span> <span class="token punctuation">{</span> <span class="token punctuation">}</span><br /> <span class="token keyword">finally</span> <span class="token punctuation">{</span> Helper<span class="token punctuation">.</span><span class="token function">Close</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token punctuation">}</span><br /> <span class="token punctuation">}</span><br /> <span class="token punctuation">}</span><br /> <span class="token punctuation">}</span><br /> <span class="token punctuation">}</span> <br /> <br /> <span class="token keyword">private</span> <span class="token return-type class-name"><span class="token keyword">void</span></span> <span class="token function">SetupProperties</span><span class="token punctuation">(</span><span class="token class-name"><span class="token keyword">object</span></span> Object<span class="token punctuation">,</span> <span class="token class-name">SQLHelper</span> Helper<span class="token punctuation">,</span> <span class="token class-name">Type</span> ObjectType<span class="token punctuation">)</span><br /> <span class="token punctuation">{</span><br /> <span class="token keyword">foreach</span> <span class="token punctuation">(</span><span class="token class-name">IDataType</span> Column <span class="token keyword">in</span> Columns<span class="token punctuation">)</span><br /> <span class="token punctuation">{</span><br /> <span class="token keyword">if</span> <span class="token punctuation">(</span>Column <span class="token operator">!=</span> <span class="token keyword">null</span> <span class="token operator">&&</span> <span class="token operator">!</span>Column<span class="token punctuation">.</span>Type<span class="token punctuation">.</span><span class="token function">Equals</span><span class="token punctuation">(</span><span class="token string">"List"</span><span class="token punctuation">,</span> StringComparison<span class="token punctuation">.</span>CurrentCultureIgnoreCase<span class="token punctuation">)</span><span class="token punctuation">)</span><br /> <span class="token punctuation">{</span><br /> <span class="token class-name">PropertyInfo</span> PropertyInfo <span class="token operator">=</span> ObjectType<span class="token punctuation">.</span><span class="token function">GetProperty</span><span class="token punctuation">(</span>Column<span class="token punctuation">.</span>Name<span class="token punctuation">)</span><span class="token punctuation">;</span><br /> <span class="token class-name"><span class="token keyword">object</span></span> Value <span class="token operator">=</span> PropertyInfo<span class="token punctuation">.</span><span class="token function">GetValue</span><span class="token punctuation">(</span>Object<span class="token punctuation">,</span> <span class="token keyword">null</span><span class="token punctuation">)</span><span class="token punctuation">;</span><br /> <span class="token keyword">if</span> <span class="token punctuation">(</span>Column <span class="token keyword">is</span> <span class="token class-name">NVarChar</span> <span class="token operator">&&</span> <span class="token operator">!</span>Column<span class="token punctuation">.</span>IsPrimaryKey<span class="token punctuation">)</span><br /> <span class="token punctuation">{</span><br /> <span class="token keyword">foreach</span> <span class="token punctuation">(</span><span class="token class-name">IConstraint</span> Constraint <span class="token keyword">in</span> Column<span class="token punctuation">.</span>Constraints<span class="token punctuation">)</span><br /> <span class="token punctuation">{</span><br /> <span class="token keyword">if</span> <span class="token punctuation">(</span>Constraint <span class="token keyword">is</span> <span class="token class-name">Size</span><span class="token punctuation">)</span><br /> <span class="token punctuation">{</span><br /> Helper<span class="token punctuation">.</span><span class="token function">AddParameter</span><span class="token punctuation">(</span><span class="token string">"@"</span> <span class="token operator">+</span> Column<span class="token punctuation">.</span>Name<span class="token punctuation">,</span> <span class="token punctuation">(</span><span class="token keyword">string</span><span class="token punctuation">)</span>Value<span class="token punctuation">,</span> <span class="token punctuation">(</span><span class="token punctuation">(</span>Size<span class="token punctuation">)</span>Constraint<span class="token punctuation">)</span><span class="token punctuation">.</span>Length<span class="token punctuation">)</span><span class="token punctuation">;</span><br /> <span class="token keyword">break</span><span class="token punctuation">;</span><br /> <span class="token punctuation">}</span><br /> <span class="token punctuation">}</span><br /> <span class="token punctuation">}</span><br /> <span class="token keyword">else</span> <span class="token keyword">if</span> <span class="token punctuation">(</span><span class="token operator">!</span>Column<span class="token punctuation">.</span>IsPrimaryKey<span class="token punctuation">)</span><br /> <span class="token punctuation">{</span><br /> Helper<span class="token punctuation">.</span><span class="token function">AddParameter</span><span class="token punctuation">(</span><span class="token string">"@"</span> <span class="token operator">+</span> Column<span class="token punctuation">.</span>Name<span class="token punctuation">,</span> Value<span class="token punctuation">,</span> Column<span class="token punctuation">.</span>DataType<span class="token punctuation">)</span><span class="token punctuation">;</span><br /> <span class="token punctuation">}</span><br /> <span class="token punctuation">}</span><br /> <span class="token punctuation">}</span><br /> <span class="token punctuation">}</span> <br /> <br /> <span class="token keyword">private</span> <span class="token return-type class-name"><span class="token keyword">void</span></span> <span class="token function">SetID</span><span class="token punctuation">(</span><span class="token class-name"><span class="token keyword">object</span></span> Object<span class="token punctuation">,</span> <span class="token class-name">Type</span> ObjectType<span class="token punctuation">,</span> <span class="token class-name"><span class="token keyword">object</span></span> IDValue<span class="token punctuation">)</span><br /> <span class="token punctuation">{</span><br /> <span class="token keyword">foreach</span> <span class="token punctuation">(</span><span class="token class-name">IDataType</span> Column <span class="token keyword">in</span> Columns<span class="token punctuation">)</span><br /> <span class="token punctuation">{</span><br /> <span class="token keyword">if</span> <span class="token punctuation">(</span>Column <span class="token operator">!=</span> <span class="token keyword">null</span> <span class="token operator">&&</span><br /> <span class="token operator">!</span>Column<span class="token punctuation">.</span>Type<span class="token punctuation">.</span><span class="token function">Equals</span><span class="token punctuation">(</span><span class="token string">"List"</span><span class="token punctuation">,</span> StringComparison<span class="token punctuation">.</span>CurrentCultureIgnoreCase<span class="token punctuation">)</span> <span class="token operator">&&</span><br /> Column<span class="token punctuation">.</span>IsPrimaryKey<span class="token punctuation">)</span><br /> <span class="token punctuation">{</span><br /> <span class="token class-name">PropertyInfo</span> PropertyInfo <span class="token operator">=</span> ObjectType<span class="token punctuation">.</span><span class="token function">GetProperty</span><span class="token punctuation">(</span>Column<span class="token punctuation">.</span>Name<span class="token punctuation">)</span><span class="token punctuation">;</span><br /> <span class="token keyword">if</span> <span class="token punctuation">(</span>Column <span class="token keyword">is</span> <span class="token class-name">Int</span><span class="token punctuation">)</span><br /> <span class="token punctuation">{</span><br /> PropertyInfo<span class="token punctuation">.</span><span class="token function">SetValue</span><span class="token punctuation">(</span>Object<span class="token punctuation">,</span> <span class="token keyword">int</span><span class="token punctuation">.</span><span class="token function">Parse</span><span class="token punctuation">(</span>IDValue<span class="token punctuation">.</span><span class="token function">ToString</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">)</span><span class="token punctuation">,</span> <span class="token keyword">null</span><span class="token punctuation">)</span><span class="token punctuation">;</span><br /> <span class="token punctuation">}</span><br /> <span class="token keyword">else</span> <span class="token keyword">if</span> <span class="token punctuation">(</span>Column <span class="token keyword">is</span> <span class="token class-name">UniqueIdentifier</span><span class="token punctuation">)</span><br /> <span class="token punctuation">{</span><br /> PropertyInfo<span class="token punctuation">.</span><span class="token function">SetValue</span><span class="token punctuation">(</span>Object<span class="token punctuation">,</span> <span class="token keyword">new</span> <span class="token constructor-invocation class-name">Guid</span><span class="token punctuation">(</span>IDValue<span class="token punctuation">.</span><span class="token function">ToString</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">)</span><span class="token punctuation">,</span> <span class="token keyword">null</span><span class="token punctuation">)</span><span class="token punctuation">;</span><br /> <span class="token punctuation">}</span><br /> <span class="token keyword">break</span><span class="token punctuation">;</span><br /> <span class="token punctuation">}</span><br /> <span class="token punctuation">}</span><br /> <span class="token punctuation">}</span></code></pre>
<p>The setup properties function uses some basic reflection to get each property's value and inserts it as a parameter with the exception of lists (once again, these have to be handled separately. We then run the stored procedure and get back the new ID (since we're auto generating these from the database for now) and setting the ID field of the class. We then go through each list and insert it's information. This is a bit more in depth as we have to get the List property, pull out a couple properties of the List (specifically Count and Item), and then set each item in the list up and run it separately...</p>
<p>But when all is said and done, we can simply call Save and our item is saved to the database. Now what about selecting it back out?</p>
<pre class="language-csharp"><code class="language-csharp"> <span class="token keyword">public</span> <span class="token return-type class-name"><span class="token keyword">object</span></span> <span class="token function">SelectByID</span><span class="token punctuation">(</span><span class="token class-name"><span class="token keyword">object</span></span> IDValue<span class="token punctuation">,</span> <span class="token class-name">SQLHelper</span> Helper<span class="token punctuation">)</span><br /> <span class="token punctuation">{</span><br /> Helper<span class="token punctuation">.</span>Command <span class="token operator">=</span> \_Class<span class="token punctuation">.</span>OriginalType<span class="token punctuation">.</span>Name <span class="token operator">+</span> <span class="token string">"\_Select"</span><span class="token punctuation">;</span><br /> Helper<span class="token punctuation">.</span>CommandType <span class="token operator">=</span> CommandType<span class="token punctuation">.</span>StoredProcedure<span class="token punctuation">;</span><br /> <span class="token class-name"><span class="token keyword">object</span></span> ClassInstance <span class="token operator">=</span> <span class="token keyword">null</span><span class="token punctuation">;</span><br /> <span class="token class-name">IDataType</span> IDField <span class="token operator">=</span> <span class="token keyword">null</span><span class="token punctuation">;</span><br /> IDField <span class="token operator">=</span> <span class="token function">FindIDField</span><span class="token punctuation">(</span>IDField<span class="token punctuation">)</span><span class="token punctuation">;</span><br /> ClassInstance <span class="token operator">=</span> <span class="token function">LoadMainClass</span><span class="token punctuation">(</span>IDValue<span class="token punctuation">,</span> Helper<span class="token punctuation">,</span> ClassInstance<span class="token punctuation">,</span> IDField<span class="token punctuation">)</span><span class="token punctuation">;</span><br /> ClassInstance <span class="token operator">=</span> <span class="token function">LoadLists</span><span class="token punctuation">(</span>IDValue<span class="token punctuation">,</span> Helper<span class="token punctuation">,</span> ClassInstance<span class="token punctuation">,</span> IDField<span class="token punctuation">)</span><span class="token punctuation">;</span><br /> <span class="token keyword">return</span> ClassInstance<span class="token punctuation">;</span><br /> <span class="token punctuation">}</span> <br /> <br /> <span class="token keyword">private</span> <span class="token return-type class-name"><span class="token keyword">object</span></span> <span class="token function">LoadLists</span><span class="token punctuation">(</span><span class="token class-name"><span class="token keyword">object</span></span> IDValue<span class="token punctuation">,</span> <span class="token class-name">SQLHelper</span> Helper<span class="token punctuation">,</span> <span class="token class-name"><span class="token keyword">object</span></span> ClassInstance<span class="token punctuation">,</span> <span class="token class-name">IDataType</span> IDField<span class="token punctuation">)</span><br /> <span class="token punctuation">{</span><br /> <span class="token keyword">foreach</span> <span class="token punctuation">(</span><span class="token class-name">IDataType</span> Column <span class="token keyword">in</span> Columns<span class="token punctuation">)</span><br /> <span class="token punctuation">{</span><br /> <span class="token keyword">if</span> <span class="token punctuation">(</span>Column <span class="token operator">!=</span> <span class="token keyword">null</span> <span class="token operator">&&</span> Column<span class="token punctuation">.</span>Type<span class="token punctuation">.</span><span class="token function">Equals</span><span class="token punctuation">(</span><span class="token string">"List"</span><span class="token punctuation">,</span> StringComparison<span class="token punctuation">.</span>CurrentCultureIgnoreCase<span class="token punctuation">)</span><span class="token punctuation">)</span><br /> <span class="token punctuation">{</span><br /> <span class="token class-name">PropertyInfo</span> ColumnInfo <span class="token operator">=</span> \_Class<span class="token punctuation">.</span>DerivedType<span class="token punctuation">.</span><span class="token function">GetProperty</span><span class="token punctuation">(</span><span class="token punctuation">(</span><span class="token punctuation">(</span>List<span class="token punctuation">)</span>Column<span class="token punctuation">)</span><span class="token punctuation">.</span>DataName<span class="token punctuation">)</span><span class="token punctuation">;</span><br /> Helper<span class="token punctuation">.</span>Command <span class="token operator">=</span> Column<span class="token punctuation">.</span>Name <span class="token operator">+</span> <span class="token string">"\_Select"</span><span class="token punctuation">;</span><br /> Helper<span class="token punctuation">.</span><span class="token function">ClearParameters</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">;</span><br /> <span class="token keyword">try</span><br /> <span class="token punctuation">{</span><br /> Helper<span class="token punctuation">.</span><span class="token function">Open</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">;</span><br /> <span class="token keyword">if</span> <span class="token punctuation">(</span>IDField <span class="token keyword">is</span> <span class="token class-name">NVarChar</span><span class="token punctuation">)</span><br /> <span class="token punctuation">{</span><br /> <span class="token keyword">foreach</span> <span class="token punctuation">(</span><span class="token class-name">IConstraint</span> Constraint <span class="token keyword">in</span> IDField<span class="token punctuation">.</span>Constraints<span class="token punctuation">)</span><br /> <span class="token punctuation">{</span><br /> <span class="token keyword">if</span> <span class="token punctuation">(</span>Constraint <span class="token keyword">is</span> <span class="token class-name">Size</span><span class="token punctuation">)</span><br /> <span class="token punctuation">{</span><br /> Helper<span class="token punctuation">.</span><span class="token function">AddParameter</span><span class="token punctuation">(</span><span class="token string">"@"</span> <span class="token operator">+</span> IDField<span class="token punctuation">.</span>Name<span class="token punctuation">,</span> <span class="token punctuation">(</span><span class="token keyword">string</span><span class="token punctuation">)</span>IDValue<span class="token punctuation">,</span> <span class="token punctuation">(</span><span class="token punctuation">(</span>Size<span class="token punctuation">)</span>Constraint<span class="token punctuation">)</span><span class="token punctuation">.</span>Length<span class="token punctuation">)</span><span class="token punctuation">;</span><br /> <span class="token punctuation">}</span><br /> <span class="token punctuation">}</span><br /> <span class="token punctuation">}</span><br /> <span class="token keyword">else</span><br /> <span class="token punctuation">{</span><br /> Helper<span class="token punctuation">.</span><span class="token function">AddParameter</span><span class="token punctuation">(</span><span class="token string">"@"</span> <span class="token operator">+</span> IDField<span class="token punctuation">.</span>Name<span class="token punctuation">,</span> IDValue<span class="token punctuation">,</span> IDField<span class="token punctuation">.</span>DataType<span class="token punctuation">)</span><span class="token punctuation">;</span><br /> <span class="token punctuation">}</span><br /> Helper<span class="token punctuation">.</span><span class="token function">ExecuteReader</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">;</span> <br /> <br /> ColumnInfo<span class="token punctuation">.</span><span class="token function">SetValue</span><span class="token punctuation">(</span>ClassInstance<span class="token punctuation">,</span> Activator<span class="token punctuation">.</span><span class="token function">CreateInstance</span><span class="token punctuation">(</span>Column<span class="token punctuation">.</span>Attribute<span class="token punctuation">.</span>Type<span class="token punctuation">)</span><span class="token punctuation">,</span> <span class="token keyword">null</span><span class="token punctuation">)</span><span class="token punctuation">;</span><br /> <span class="token class-name"><span class="token keyword">object</span></span> CurrentList <span class="token operator">=</span> ColumnInfo<span class="token punctuation">.</span><span class="token function">GetValue</span><span class="token punctuation">(</span>ClassInstance<span class="token punctuation">,</span> <span class="token keyword">null</span><span class="token punctuation">)</span><span class="token punctuation">;</span><br /> <span class="token class-name">Type</span> ListType <span class="token operator">=</span> CurrentList<span class="token punctuation">.</span><span class="token function">GetType</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">;</span><br /> <span class="token keyword">while</span> <span class="token punctuation">(</span>Helper<span class="token punctuation">.</span><span class="token function">Read</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">)</span><br /> <span class="token punctuation">{</span><br /> <span class="token class-name"><span class="token keyword">object</span></span> ListItemValue<span class="token operator">=</span>Helper<span class="token punctuation">.</span><span class="token function">GetParameter</span><span class="token punctuation">(</span><span class="token punctuation">(</span><span class="token punctuation">(</span>List<span class="token punctuation">)</span>Column<span class="token punctuation">)</span><span class="token punctuation">.</span>DataName<span class="token punctuation">,</span><span class="token keyword">null</span><span class="token punctuation">)</span><span class="token punctuation">;</span><br /> <span class="token keyword">if</span> <span class="token punctuation">(</span>Column<span class="token punctuation">.</span>Attribute<span class="token punctuation">.</span>Type<span class="token punctuation">.</span><span class="token function">GetGenericArguments</span><span class="token punctuation">(</span><span class="token punctuation">)</span>\<span class="token punctuation">[</span><span class="token number">0</span>\<span class="token punctuation">]</span><span class="token punctuation">.</span>FullName<span class="token punctuation">.</span><span class="token function">Equals</span><span class="token punctuation">(</span><span class="token string">"System.Single"</span><span class="token punctuation">,</span> StringComparison<span class="token punctuation">.</span>CurrentCultureIgnoreCase<span class="token punctuation">)</span><span class="token punctuation">)</span><br /> <span class="token punctuation">{</span><br /> Column<span class="token punctuation">.</span>Attribute<span class="token punctuation">.</span>Type<span class="token punctuation">.</span><span class="token function">InvokeMember</span><span class="token punctuation">(</span><span class="token string">"Add"</span><span class="token punctuation">,</span> BindingFlags<span class="token punctuation">.</span>InvokeMethod<span class="token punctuation">,</span> <span class="token keyword">null</span><span class="token punctuation">,</span> CurrentList<span class="token punctuation">,</span> <span class="token keyword">new</span> <span class="token keyword">object</span>\<span class="token punctuation">[</span>\<span class="token punctuation">]</span> <span class="token punctuation">{</span> <span class="token keyword">float</span><span class="token punctuation">.</span><span class="token function">Parse</span><span class="token punctuation">(</span>ListItemValue<span class="token punctuation">.</span><span class="token function">ToString</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">)</span> <span class="token punctuation">}</span><span class="token punctuation">)</span><span class="token punctuation">;</span><br /> <span class="token punctuation">}</span><br /> <span class="token keyword">else</span><br /> <span class="token punctuation">{</span><br /> Column<span class="token punctuation">.</span>Attribute<span class="token punctuation">.</span>Type<span class="token punctuation">.</span><span class="token function">InvokeMember</span><span class="token punctuation">(</span><span class="token string">"Add"</span><span class="token punctuation">,</span> BindingFlags<span class="token punctuation">.</span>InvokeMethod<span class="token punctuation">,</span> <span class="token keyword">null</span><span class="token punctuation">,</span> CurrentList<span class="token punctuation">,</span> <span class="token keyword">new</span> <span class="token keyword">object</span>\<span class="token punctuation">[</span>\<span class="token punctuation">]</span> <span class="token punctuation">{</span> ListItemValue <span class="token punctuation">}</span><span class="token punctuation">)</span><span class="token punctuation">;</span><br /> <span class="token punctuation">}</span><br /> <span class="token punctuation">}</span><br /> <span class="token punctuation">}</span><br /> <span class="token keyword">catch</span> <span class="token punctuation">{</span> <span class="token punctuation">}</span><br /> <span class="token keyword">finally</span><br /> <span class="token punctuation">{</span><br /> Helper<span class="token punctuation">.</span><span class="token function">Close</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">;</span><br /> <span class="token punctuation">}</span><br /> <span class="token punctuation">}</span><br /> <span class="token punctuation">}</span><br /> <span class="token keyword">return</span> ClassInstance<span class="token punctuation">;</span><br /> <span class="token punctuation">}</span> <br /> <br /> <span class="token keyword">private</span> <span class="token return-type class-name">IDataType</span> <span class="token function">FindIDField</span><span class="token punctuation">(</span><span class="token class-name">IDataType</span> IDField<span class="token punctuation">)</span><br /> <span class="token punctuation">{</span><br /> <span class="token keyword">foreach</span> <span class="token punctuation">(</span><span class="token class-name">IDataType</span> Column <span class="token keyword">in</span> Columns<span class="token punctuation">)</span><br /> <span class="token punctuation">{</span><br /> <span class="token keyword">if</span> <span class="token punctuation">(</span>Column <span class="token operator">!=</span> <span class="token keyword">null</span> <span class="token operator">&&</span> <span class="token operator">!</span>Column<span class="token punctuation">.</span>Type<span class="token punctuation">.</span><span class="token function">Equals</span><span class="token punctuation">(</span><span class="token string">"List"</span><span class="token punctuation">,</span> StringComparison<span class="token punctuation">.</span>CurrentCultureIgnoreCase<span class="token punctuation">)</span><span class="token punctuation">)</span><br /> <span class="token punctuation">{</span><br /> <span class="token keyword">if</span> <span class="token punctuation">(</span>Column<span class="token punctuation">.</span>IsPrimaryKey<span class="token punctuation">)</span><br /> <span class="token punctuation">{</span><br /> IDField <span class="token operator">=</span> Column<span class="token punctuation">;</span><br /> <span class="token keyword">break</span><span class="token punctuation">;</span><br /> <span class="token punctuation">}</span><br /> <span class="token punctuation">}</span><br /> <span class="token punctuation">}</span><br /> <span class="token keyword">return</span> IDField<span class="token punctuation">;</span><br /> <span class="token punctuation">}</span> <br /> <br /> <span class="token keyword">private</span> <span class="token return-type class-name"><span class="token keyword">object</span></span> <span class="token function">LoadMainClass</span><span class="token punctuation">(</span><span class="token class-name"><span class="token keyword">object</span></span> IDValue<span class="token punctuation">,</span> <span class="token class-name">SQLHelper</span> Helper<span class="token punctuation">,</span> <span class="token class-name"><span class="token keyword">object</span></span> ClassInstance<span class="token punctuation">,</span> <span class="token class-name">IDataType</span> IDField<span class="token punctuation">)</span><br /> <span class="token punctuation">{</span><br /> <span class="token keyword">try</span><br /> <span class="token punctuation">{</span><br /> Helper<span class="token punctuation">.</span><span class="token function">Open</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">;</span><br /> <span class="token keyword">if</span> <span class="token punctuation">(</span>IDField <span class="token keyword">is</span> <span class="token class-name">NVarChar</span><span class="token punctuation">)</span><br /> <span class="token punctuation">{</span><br /> <span class="token keyword">foreach</span> <span class="token punctuation">(</span><span class="token class-name">IConstraint</span> Constraint <span class="token keyword">in</span> IDField<span class="token punctuation">.</span>Constraints<span class="token punctuation">)</span><br /> <span class="token punctuation">{</span><br /> <span class="token keyword">if</span> <span class="token punctuation">(</span>Constraint <span class="token keyword">is</span> <span class="token class-name">Size</span><span class="token punctuation">)</span><br /> <span class="token punctuation">{</span><br /> Helper<span class="token punctuation">.</span><span class="token function">AddParameter</span><span class="token punctuation">(</span><span class="token string">"@"</span> <span class="token operator">+</span> IDField<span class="token punctuation">.</span>Name<span class="token punctuation">,</span> <span class="token punctuation">(</span><span class="token keyword">string</span><span class="token punctuation">)</span>IDValue<span class="token punctuation">,</span> <span class="token punctuation">(</span><span class="token punctuation">(</span>Size<span class="token punctuation">)</span>Constraint<span class="token punctuation">)</span><span class="token punctuation">.</span>Length<span class="token punctuation">)</span><span class="token punctuation">;</span><br /> <span class="token punctuation">}</span><br /> <span class="token punctuation">}</span><br /> <span class="token punctuation">}</span><br /> <span class="token keyword">else</span><br /> <span class="token punctuation">{</span><br /> Helper<span class="token punctuation">.</span><span class="token function">AddParameter</span><span class="token punctuation">(</span><span class="token string">"@"</span> <span class="token operator">+</span> IDField<span class="token punctuation">.</span>Name<span class="token punctuation">,</span> IDValue<span class="token punctuation">,</span> IDField<span class="token punctuation">.</span>DataType<span class="token punctuation">)</span><span class="token punctuation">;</span><br /> <span class="token punctuation">}</span><br /> Helper<span class="token punctuation">.</span><span class="token function">ExecuteReader</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">;</span><br /> <span class="token keyword">if</span> <span class="token punctuation">(</span>Helper<span class="token punctuation">.</span><span class="token function">Read</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">)</span><br /> <span class="token punctuation">{</span><br /> ClassInstance <span class="token operator">=</span> Activator<span class="token punctuation">.</span><span class="token function">CreateInstance</span><span class="token punctuation">(</span>\_Class<span class="token punctuation">.</span>DerivedType<span class="token punctuation">)</span><span class="token punctuation">;</span><br /> <span class="token keyword">foreach</span> <span class="token punctuation">(</span><span class="token class-name">IDataType</span> Column <span class="token keyword">in</span> Columns<span class="token punctuation">)</span><br /> <span class="token punctuation">{</span><br /> <span class="token keyword">if</span> <span class="token punctuation">(</span>Column <span class="token operator">!=</span> <span class="token keyword">null</span> <span class="token operator">&&</span> <span class="token operator">!</span>Column<span class="token punctuation">.</span>Type<span class="token punctuation">.</span><span class="token function">Equals</span><span class="token punctuation">(</span><span class="token string">"List"</span><span class="token punctuation">,</span> StringComparison<span class="token punctuation">.</span>CurrentCultureIgnoreCase<span class="token punctuation">)</span><span class="token punctuation">)</span><br /> <span class="token punctuation">{</span><br /> <span class="token class-name">PropertyInfo</span> TempProperty <span class="token operator">=</span> \_Class<span class="token punctuation">.</span>DerivedType<span class="token punctuation">.</span><span class="token function">GetProperty</span><span class="token punctuation">(</span>Column<span class="token punctuation">.</span>Name<span class="token punctuation">)</span><span class="token punctuation">;</span><br /> <span class="token keyword">if</span> <span class="token punctuation">(</span>TempProperty<span class="token punctuation">.</span>PropertyType<span class="token punctuation">.</span>FullName<span class="token punctuation">.</span><span class="token function">Equals</span><span class="token punctuation">(</span><span class="token string">"System.Single"</span><span class="token punctuation">,</span> StringComparison<span class="token punctuation">.</span>CurrentCultureIgnoreCase<span class="token punctuation">)</span><span class="token punctuation">)</span><br /> <span class="token punctuation">{</span><br /> TempProperty<span class="token punctuation">.</span><span class="token function">SetValue</span><span class="token punctuation">(</span>ClassInstance<span class="token punctuation">,</span> <span class="token keyword">float</span><span class="token punctuation">.</span><span class="token function">Parse</span><span class="token punctuation">(</span>Helper<span class="token punctuation">.</span><span class="token function">GetParameter</span><span class="token punctuation">(</span>Column<span class="token punctuation">.</span>Name<span class="token punctuation">,</span> <span class="token keyword">null</span><span class="token punctuation">)</span><span class="token punctuation">.</span><span class="token function">ToString</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">)</span><span class="token punctuation">,</span> <span class="token keyword">null</span><span class="token punctuation">)</span><span class="token punctuation">;</span><br /> <span class="token punctuation">}</span><br /> <span class="token keyword">else</span><br /> <span class="token punctuation">{</span><br /> TempProperty<span class="token punctuation">.</span><span class="token function">SetValue</span><span class="token punctuation">(</span>ClassInstance<span class="token punctuation">,</span> Helper<span class="token punctuation">.</span><span class="token function">GetParameter</span><span class="token punctuation">(</span>Column<span class="token punctuation">.</span>Name<span class="token punctuation">,</span> <span class="token keyword">null</span><span class="token punctuation">)</span><span class="token punctuation">,</span> <span class="token keyword">null</span><span class="token punctuation">)</span><span class="token punctuation">;</span><br /> <span class="token punctuation">}</span><br /> <span class="token punctuation">}</span><br /> <span class="token punctuation">}</span><br /> <span class="token punctuation">}</span><br /> <span class="token punctuation">}</span><br /> <span class="token keyword">catch</span> <span class="token punctuation">{</span> <span class="token punctuation">}</span><br /> <span class="token keyword">finally</span> <span class="token punctuation">{</span> Helper<span class="token punctuation">.</span><span class="token function">Close</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token punctuation">}</span><br /> <span class="token keyword">return</span> ClassInstance<span class="token punctuation">;</span><br /> <span class="token punctuation">}</span></code></pre>
<p>This is fairly similar. We first create our class object (using the Activator class) and then proceed to load the main (non list) portions of the class. You'll notice that there is a special case for floats. The reason for this is that they're singles and we're saving all of our floats as doubles within the database. This could be improved a bit by treating the various types as a bit more different instead of grouping them together. Once that is loaded, we then go and load our lists. Once again we have to use a bit of reflection here to first create the list and then go and invoke the Add method on that list for each item. But that's the only portions that may cause some confusion. Anyway, that's it really. At this point we send back our newly created object to the user. I would show you the update and delete code but I'm still working on it. So download the code, take a look, leave feedback, and happy coding.</p>
Creating an ORM in C# - Part 3
2009-06-09T00:00:00Z
http://www.gutgames.com/post/Creating-an-ORM-in-C-Part-3/
<p>Today is another post concerning the HaterAide ORM that I've been working on lately. The last couple of posts have dealt with the reflection and class definition portions of the code. Today I'm going to start posting about the SQL portion of the ORM. Specifically I'm going to discuss how I've gone about creating a database and tables from the information that the class definitions give us.</p>
<p>The first item that I need to deal with is the fact that this implementation needs to be extensible. Different databases have slightly different implementations/key words. So I decided to go with a provider model. The code is rather straightforward and basic. As such I'm just going to have the code in the download at the bottom of the post, but the classes that are of interest are the ProviderCollection, ProviderConfigSection, and ProviderManager (and also the IProvider class). You'll also note that in the download, a lot of the classes from <a href="http://www.gutgames.com/post/Creating-an-ORM-in-C-Part-1">Part 1</a> and <a href="http://www.gutgames.com/post/Creating-an-ORM-in-C-Part-2">Part 2</a> of this series have been slightly modified.</p>
<p>There provider model allows me to plug in classes for each database that I want to deal with. At present though, all I care about is SQL Server. Since that's the case I've also added an SQL Server provider (and a number of helper classes that are in various states of completion). Anyway, the provider manager starts up, creates any and all providers, and uses the one that we set as the default in the Web.Config file (once again, I'm only developing this for web apps so slight modifications would be needed to make this a bit more general purpose). It then calls the create function on the provider which creates the database.</p>
<p>If you look at the Create function in the Provider class:</p>
<pre class="language-csharp"><code class="language-csharp"> <span class="token keyword">internal</span> <span class="token keyword">override</span> <span class="token return-type class-name"><span class="token keyword">void</span></span> <span class="token function">Create</span><span class="token punctuation">(</span><span class="token punctuation">)</span><br /> <span class="token punctuation">{</span><br /> <span class="token class-name"><span class="token keyword">string</span></span> Database <span class="token operator">=</span> Regex<span class="token punctuation">.</span><span class="token function">Match</span><span class="token punctuation">(</span>ConnectionString<span class="token punctuation">,</span> <span class="token string">"Initial Catalog=(.\*?;)"</span><span class="token punctuation">)</span><span class="token punctuation">.</span>Value<span class="token punctuation">.</span><span class="token function">Replace</span><span class="token punctuation">(</span><span class="token string">"Initial Catalog="</span><span class="token punctuation">,</span> <span class="token string">""</span><span class="token punctuation">)</span><span class="token punctuation">.</span><span class="token function">Replace</span><span class="token punctuation">(</span><span class="token string">";"</span><span class="token punctuation">,</span> <span class="token string">""</span><span class="token punctuation">)</span><span class="token punctuation">;</span><br /> <span class="token class-name"><span class="token keyword">string</span></span> TempConnectionString <span class="token operator">=</span> Regex<span class="token punctuation">.</span><span class="token function">Replace</span><span class="token punctuation">(</span>ConnectionString<span class="token punctuation">,</span> <span class="token string">"Initial Catalog=(.\*?;)"</span><span class="token punctuation">,</span> <span class="token string">""</span><span class="token punctuation">)</span><span class="token punctuation">;</span><br /> SQLBuilder<span class="token punctuation">.</span><span class="token function">CreateDatabase</span><span class="token punctuation">(</span>TempConnectionString<span class="token punctuation">,</span> Database<span class="token punctuation">,</span> <span class="token boolean">false</span><span class="token punctuation">)</span><span class="token punctuation">;</span><br /> <span class="token keyword">foreach</span> <span class="token punctuation">(</span><span class="token class-name">Type</span> Key <span class="token keyword">in</span> ClassManager<span class="token punctuation">.</span>Keys<span class="token punctuation">)</span><br /> <span class="token punctuation">{</span><br /> SQLBuilder<span class="token punctuation">.</span><span class="token function">CreateTable</span><span class="token punctuation">(</span>ConnectionString<span class="token punctuation">,</span> ClassManager\<span class="token punctuation">[</span>Key\<span class="token punctuation">]</span><span class="token punctuation">,</span> ClassManager<span class="token punctuation">,</span> <span class="token boolean">false</span><span class="token punctuation">)</span><span class="token punctuation">;</span><br /> <span class="token punctuation">}</span><br /> <span class="token punctuation">}</span></code></pre>
<p>You will see that the only things it does, is parses the connection string finding the name of the database that we're connecting to and calling two functions. One function that is called is the CreateDatabase function and the other being CreateTable.<br />
The CreateDatabase function can be seen below:</p>
<pre class="language-csharp"><code class="language-csharp"> <span class="token keyword">public</span> <span class="token keyword">static</span> <span class="token return-type class-name"><span class="token keyword">void</span></span> <span class="token function">CreateDatabase</span><span class="token punctuation">(</span><span class="token class-name"><span class="token keyword">string</span></span> ConnectionString<span class="token punctuation">,</span> <span class="token class-name"><span class="token keyword">string</span></span> DatabaseName<span class="token punctuation">,</span> <span class="token class-name"><span class="token keyword">bool</span></span> RecreateIfExists<span class="token punctuation">)</span><br /> <span class="token punctuation">{</span><br /> <span class="token class-name"><span class="token keyword">bool</span></span> Exists <span class="token operator">=</span> <span class="token boolean">false</span><span class="token punctuation">;</span><br /> <span class="token class-name">Utilities<span class="token punctuation">.</span>SQLHelper<span class="token punctuation">.</span>SQLHelper</span> Helper <span class="token operator">=</span> <span class="token keyword">new</span> <span class="token constructor-invocation class-name">Utilities<span class="token punctuation">.</span>SQLHelper<span class="token punctuation">.</span>SQLHelper</span><span class="token punctuation">(</span><span class="token string">"SELECT \* FROM Master.sys.Databases where name=@DatabaseID"</span><span class="token punctuation">,</span> ConnectionString<span class="token punctuation">,</span> CommandType<span class="token punctuation">.</span>Text<span class="token punctuation">)</span><span class="token punctuation">;</span><br /> <span class="token keyword">if</span> <span class="token punctuation">(</span><span class="token operator">!</span>RecreateIfExists<span class="token punctuation">)</span><br /> <span class="token punctuation">{</span><br /> <span class="token keyword">try</span><br /> <span class="token punctuation">{</span><br /> Helper<span class="token punctuation">.</span><span class="token function">Open</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">;</span><br /> Helper<span class="token punctuation">.</span><span class="token function">AddParameter</span><span class="token punctuation">(</span><span class="token string">"@DatabaseID"</span><span class="token punctuation">,</span> DatabaseName<span class="token punctuation">,</span> <span class="token number">100</span><span class="token punctuation">)</span><span class="token punctuation">;</span><br /> Helper<span class="token punctuation">.</span><span class="token function">ExecuteReader</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">;</span><br /> <span class="token keyword">if</span> <span class="token punctuation">(</span>Helper<span class="token punctuation">.</span><span class="token function">Read</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">)</span><br /> <span class="token punctuation">{</span><br /> Exists <span class="token operator">=</span> <span class="token boolean">true</span><span class="token punctuation">;</span><br /> <span class="token punctuation">}</span><br /> <span class="token punctuation">}</span><br /> <span class="token keyword">catch</span> <span class="token punctuation">{</span> <span class="token punctuation">}</span><br /> <span class="token keyword">finally</span> <span class="token punctuation">{</span> Helper<span class="token punctuation">.</span><span class="token function">Close</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token punctuation">}</span><br /> <span class="token punctuation">}</span><br /> <span class="token keyword">if</span> <span class="token punctuation">(</span><span class="token operator">!</span>Exists<span class="token punctuation">)</span><br /> <span class="token punctuation">{</span><br /> Helper<span class="token punctuation">.</span>Command <span class="token operator">=</span> <span class="token string">"CREATE DATABASE "</span> <span class="token operator">+</span> DatabaseName<span class="token punctuation">.</span><span class="token function">Replace</span><span class="token punctuation">(</span><span class="token string">"'"</span><span class="token punctuation">,</span> <span class="token string">""</span><span class="token punctuation">)</span><span class="token punctuation">;</span><br /> <span class="token keyword">try</span><br /> <span class="token punctuation">{</span><br /> Helper<span class="token punctuation">.</span><span class="token function">Open</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">;</span><br /> Helper<span class="token punctuation">.</span><span class="token function">ExecuteNonQuery</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">;</span><br /> <span class="token punctuation">}</span><br /> <span class="token keyword">catch</span> <span class="token punctuation">{</span> <span class="token punctuation">}</span><br /> <span class="token keyword">finally</span> <span class="token punctuation">{</span> Helper<span class="token punctuation">.</span><span class="token function">Close</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token punctuation">}</span><br /> <span class="token punctuation">}</span><br /> <span class="token punctuation">}</span></code></pre>
<p>You'll notice that it uses the SQLHelper class from my <a href="https://github.com/JaCraig/Craig-s-Utility-Library">utility library</a>, but it's just to simplify connecting to the database. Anyway, the function simply does a call to the Master database asking what databases exist (and specifically if the database we want exists). If it doesn't exist, it creates the database. If it does exist, it skips that step. The CreateTable function is where the interesting parts occur:</p>
<pre class="language-csharp"><code class="language-csharp"> <span class="token keyword">public</span> <span class="token keyword">static</span> <span class="token return-type class-name"><span class="token keyword">void</span></span> <span class="token function">CreateTable</span><span class="token punctuation">(</span><span class="token class-name"><span class="token keyword">string</span></span> ConnectionString<span class="token punctuation">,</span> <span class="token class-name">Class</span> Class<span class="token punctuation">,</span> <span class="token class-name">ClassManager</span> Manager<span class="token punctuation">,</span> <span class="token class-name"><span class="token keyword">bool</span></span> RecreateIfExists<span class="token punctuation">)</span><br /> <span class="token punctuation">{</span><br /> <span class="token class-name"><span class="token keyword">bool</span></span> Exists <span class="token operator">=</span> <span class="token boolean">false</span><span class="token punctuation">;</span><br /> <span class="token class-name"><span class="token keyword">string</span></span> ClassName <span class="token operator">=</span> Class<span class="token punctuation">.</span>OriginalType<span class="token punctuation">.</span>Name<span class="token punctuation">;</span><br /> <span class="token class-name">Utilities<span class="token punctuation">.</span>SQLHelper<span class="token punctuation">.</span>SQLHelper</span> Helper <span class="token operator">=</span> <span class="token keyword">new</span> <span class="token constructor-invocation class-name">Utilities<span class="token punctuation">.</span>SQLHelper<span class="token punctuation">.</span>SQLHelper</span><span class="token punctuation">(</span><span class="token string">"Select \* from sys.Tables where name=@TableID"</span><span class="token punctuation">,</span> ConnectionString<span class="token punctuation">,</span> CommandType<span class="token punctuation">.</span>Text<span class="token punctuation">)</span><span class="token punctuation">;</span><br /> <span class="token keyword">if</span> <span class="token punctuation">(</span><span class="token operator">!</span>RecreateIfExists<span class="token punctuation">)</span><br /> <span class="token punctuation">{</span><br /> <span class="token keyword">try</span><br /> <span class="token punctuation">{</span><br /> Helper<span class="token punctuation">.</span><span class="token function">Open</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">;</span><br /> Helper<span class="token punctuation">.</span><span class="token function">AddParameter</span><span class="token punctuation">(</span><span class="token string">"@TableID"</span><span class="token punctuation">,</span> ClassName<span class="token punctuation">,</span> <span class="token number">200</span><span class="token punctuation">)</span><span class="token punctuation">;</span><br /> Helper<span class="token punctuation">.</span><span class="token function">ExecuteReader</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">;</span><br /> <span class="token keyword">if</span> <span class="token punctuation">(</span>Helper<span class="token punctuation">.</span><span class="token function">Read</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">)</span><br /> <span class="token punctuation">{</span><br /> Exists <span class="token operator">=</span> <span class="token boolean">true</span><span class="token punctuation">;</span><br /> <span class="token punctuation">}</span><br /> <span class="token punctuation">}</span><br /> <span class="token keyword">catch</span> <span class="token punctuation">{</span> <span class="token punctuation">}</span><br /> <span class="token keyword">finally</span> <span class="token punctuation">{</span> Helper<span class="token punctuation">.</span><span class="token function">Close</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token punctuation">}</span><br /> <span class="token punctuation">}</span><br /> <span class="token keyword">if</span> <span class="token punctuation">(</span><span class="token operator">!</span>Exists<span class="token punctuation">)</span><br /> <span class="token punctuation">{</span><br /> <span class="token class-name">CreateTable</span> Table <span class="token operator">=</span> <span class="token keyword">new</span> <span class="token constructor-invocation class-name">CreateTable</span><span class="token punctuation">(</span>Class<span class="token punctuation">,</span> Manager<span class="token punctuation">)</span><span class="token punctuation">;</span><br /> Helper<span class="token punctuation">.</span>Command <span class="token operator">=</span> Table<span class="token punctuation">.</span><span class="token function">ToString</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">;</span><br /> <span class="token keyword">try</span><br /> <span class="token punctuation">{</span><br /> Helper<span class="token punctuation">.</span><span class="token function">Open</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">;</span><br /> Helper<span class="token punctuation">.</span><span class="token function">ExecuteNonQuery</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">;</span><br /> <span class="token punctuation">}</span><br /> <span class="token keyword">catch</span> <span class="token punctuation">{</span> <span class="token punctuation">}</span><br /> <span class="token keyword">finally</span> <span class="token punctuation">{</span> Helper<span class="token punctuation">.</span><span class="token function">Close</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token punctuation">}</span><br /> <span class="token punctuation">}</span><br /> <span class="token punctuation">}</span></code></pre>
<p>The beginning portion of the function is very similar to the CreateDatabase function, simply asking if the table exists. After that it simply creates the table. However it does this by creating a CreateTable object:</p>
<pre class="language-csharp"><code class="language-csharp"> <span class="token keyword">internal</span> <span class="token keyword">class</span> <span class="token class-name">CreateTable</span><span class="token punctuation">:</span><span class="token type-list"><span class="token class-name">IStatement</span></span><br /> <span class="token punctuation">{</span><br /> <span class="token keyword">public</span> <span class="token function">CreateTable</span><span class="token punctuation">(</span><span class="token class-name">Class</span> Class<span class="token punctuation">,</span><span class="token class-name">ClassManager</span> Manager<span class="token punctuation">)</span><br /> <span class="token punctuation">{</span><br /> \_Class <span class="token operator">=</span> Class<span class="token punctuation">;</span><br /> <span class="token keyword">foreach</span> <span class="token punctuation">(</span><span class="token class-name">Property</span> TempProperty <span class="token keyword">in</span> Class<span class="token punctuation">.</span>Properties<span class="token punctuation">)</span><br /> <span class="token punctuation">{</span><br /> <span class="token keyword">if</span> <span class="token punctuation">(</span>TempProperty<span class="token punctuation">.</span>Attribute<span class="token punctuation">.</span>AttributeType <span class="token operator">==</span> AttributeType<span class="token punctuation">.</span>ID <span class="token operator">||</span> TempProperty<span class="token punctuation">.</span>Attribute<span class="token punctuation">.</span>AttributeType <span class="token operator">==</span> AttributeType<span class="token punctuation">.</span>Reference<span class="token punctuation">)</span><br /> <span class="token punctuation">{</span><br /> Columns<span class="token punctuation">.</span><span class="token function">Add</span><span class="token punctuation">(</span>GlobalFunctions<span class="token punctuation">.</span><span class="token function">GetSQLType</span><span class="token punctuation">(</span>TempProperty<span class="token punctuation">.</span>Attribute<span class="token punctuation">,</span> Class<span class="token punctuation">,</span> Manager<span class="token punctuation">)</span><span class="token punctuation">)</span><span class="token punctuation">;</span><br /> <span class="token punctuation">}</span><br /> <span class="token punctuation">}</span><br /> <span class="token punctuation">}</span> <br /> <br /> <span class="token keyword">private</span> <span class="token class-name">List<span class="token punctuation"><</span>IDataType<span class="token punctuation">></span></span> Columns <span class="token operator">=</span> <span class="token keyword">new</span> <span class="token constructor-invocation class-name">List<span class="token punctuation"><</span>IDataType<span class="token punctuation">></span></span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">;</span><br /> <span class="token keyword">private</span> Class \_Class <span class="token operator">=</span> <span class="token keyword">null</span><span class="token punctuation">;</span> <br /> <br /> <span class="token keyword">public</span> <span class="token keyword">override</span> <span class="token return-type class-name"><span class="token keyword">string</span></span> <span class="token function">ToString</span><span class="token punctuation">(</span><span class="token punctuation">)</span><br /> <span class="token punctuation">{</span><br /> <span class="token class-name">StringBuilder</span> Builder <span class="token operator">=</span> <span class="token keyword">new</span> <span class="token constructor-invocation class-name">StringBuilder</span><span class="token punctuation">(</span><span class="token string">"CREATE TABLE "</span> <span class="token operator">+</span> \_Class<span class="token punctuation">.</span>OriginalType<span class="token punctuation">.</span>Name <span class="token operator">+</span> <span class="token string">"("</span><span class="token punctuation">)</span><span class="token punctuation">;</span><br /> <span class="token class-name">StringBuilder</span> ListBuilder <span class="token operator">=</span> <span class="token keyword">new</span> <span class="token constructor-invocation class-name">StringBuilder</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">;</span><br /> <span class="token class-name"><span class="token keyword">string</span></span> Splitter <span class="token operator">=</span> <span class="token string">""</span><span class="token punctuation">;</span><br /> <span class="token keyword">foreach</span> <span class="token punctuation">(</span><span class="token class-name">IDataType</span> Column <span class="token keyword">in</span> Columns<span class="token punctuation">)</span><br /> <span class="token punctuation">{</span><br /> <span class="token keyword">if</span> <span class="token punctuation">(</span>Column <span class="token operator">!=</span> <span class="token keyword">null</span><span class="token operator">&&</span><span class="token operator">!</span>Column<span class="token punctuation">.</span>Type<span class="token punctuation">.</span><span class="token function">Equals</span><span class="token punctuation">(</span><span class="token string">"List"</span><span class="token punctuation">,</span>StringComparison<span class="token punctuation">.</span>CurrentCultureIgnoreCase<span class="token punctuation">)</span><span class="token punctuation">)</span><br /> <span class="token punctuation">{</span><br /> Builder<span class="token punctuation">.</span><span class="token function">Append</span><span class="token punctuation">(</span>Splitter <span class="token operator">+</span> Column<span class="token punctuation">.</span><span class="token function">ToString</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">)</span><span class="token punctuation">;</span><br /> Splitter <span class="token operator">=</span> <span class="token string">","</span><span class="token punctuation">;</span><br /> <span class="token punctuation">}</span><br /> <span class="token keyword">else</span> <span class="token keyword">if</span> <span class="token punctuation">(</span>Column <span class="token operator">!=</span> <span class="token keyword">null</span> <span class="token operator">&&</span> Column<span class="token punctuation">.</span>Type<span class="token punctuation">.</span><span class="token function">Equals</span><span class="token punctuation">(</span><span class="token string">"List"</span><span class="token punctuation">,</span> StringComparison<span class="token punctuation">.</span>CurrentCultureIgnoreCase<span class="token punctuation">)</span><span class="token punctuation">)</span><br /> <span class="token punctuation">{</span><br /> ListBuilder<span class="token punctuation">.</span><span class="token function">Append</span><span class="token punctuation">(</span><span class="token string">" "</span> <span class="token operator">+</span> Column<span class="token punctuation">.</span><span class="token function">ToString</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">)</span><span class="token punctuation">;</span><br /> <span class="token punctuation">}</span><br /> <span class="token punctuation">}</span><br /> Builder<span class="token punctuation">.</span><span class="token function">Append</span><span class="token punctuation">(</span><span class="token string">")"</span><span class="token punctuation">)</span><span class="token punctuation">;</span> <br /> <br /> <span class="token keyword">return</span> Builder<span class="token punctuation">.</span><span class="token function">ToString</span><span class="token punctuation">(</span><span class="token punctuation">)</span> <span class="token operator">+</span> ListBuilder<span class="token punctuation">.</span><span class="token function">ToString</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">;</span><br /> <span class="token punctuation">}</span><br /> <span class="token punctuation">}</span></code></pre>
<p>The CreateTable object is one of the many helper classes (in this case a statement class) that the system uses to actually form the SQL functions that it queries against the database. In this case the CreateTable constructor goes through each property within the class and (assuming it's an ID or Reference type since we're not dealing with classes yet) creates an IDataType class that it puts into a list. The IDataType class can be seen below:</p>
<pre class="language-csharp"><code class="language-csharp"> <span class="token keyword">internal</span> <span class="token keyword">class</span> <span class="token class-name">IDataType</span><br /> <span class="token punctuation">{</span><br /> <span class="token keyword">public</span> <span class="token function">IDataType</span><span class="token punctuation">(</span><span class="token punctuation">)</span><br /> <span class="token punctuation">{</span><br /> <span class="token punctuation">}</span> <br /> <br /> <span class="token keyword">public</span> <span class="token function">IDataType</span><span class="token punctuation">(</span><span class="token class-name">Attribute</span> Attribute<span class="token punctuation">)</span><br /> <span class="token punctuation">{</span><br /> Name <span class="token operator">=</span> Attribute<span class="token punctuation">.</span>Name<span class="token punctuation">;</span><br /> <span class="token keyword">if</span> <span class="token punctuation">(</span>Attribute<span class="token punctuation">.</span>AttributeType <span class="token operator">==</span> AttributeType<span class="token punctuation">.</span>ID<span class="token punctuation">)</span><br /> Constraints<span class="token punctuation">.</span><span class="token function">Add</span><span class="token punctuation">(</span><span class="token keyword">new</span> <span class="token constructor-invocation class-name">PrimaryKey</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">)</span><span class="token punctuation">;</span><br /> <span class="token punctuation">}</span> <br /> <br /> <span class="token keyword">public</span> <span class="token return-type class-name"><span class="token keyword">string</span></span> Name <span class="token punctuation">{</span> <span class="token keyword">get</span><span class="token punctuation">;</span> <span class="token keyword">set</span><span class="token punctuation">;</span> <span class="token punctuation">}</span><br /> <span class="token keyword">public</span> <span class="token class-name">List<span class="token punctuation"><</span>IConstraint<span class="token punctuation">></span></span> Constraints <span class="token operator">=</span> <span class="token keyword">new</span> <span class="token constructor-invocation class-name">List<span class="token punctuation"><</span>IConstraint<span class="token punctuation">></span></span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">;</span> <br /> <br /> <span class="token keyword">public</span> <span class="token return-type class-name"><span class="token keyword">string</span></span> Type <span class="token punctuation">{</span> <span class="token keyword">get</span><span class="token punctuation">;</span> <span class="token keyword">set</span><span class="token punctuation">;</span> <span class="token punctuation">}</span> <br /> <br /> <span class="token keyword">public</span> <span class="token keyword">override</span> <span class="token return-type class-name"><span class="token keyword">string</span></span> <span class="token function">ToString</span><span class="token punctuation">(</span><span class="token punctuation">)</span><br /> <span class="token punctuation">{</span><br /> <span class="token class-name">StringBuilder</span> Builder <span class="token operator">=</span> <span class="token keyword">new</span> <span class="token constructor-invocation class-name">StringBuilder</span><span class="token punctuation">(</span>Name <span class="token operator">+</span> <span class="token string">" "</span> <span class="token operator">+</span> Type<span class="token punctuation">)</span><span class="token punctuation">;</span><br /> <span class="token keyword">foreach</span> <span class="token punctuation">(</span><span class="token class-name">IConstraint</span> Constraint <span class="token keyword">in</span> Constraints<span class="token punctuation">)</span><br /> <span class="token punctuation">{</span><br /> Builder<span class="token punctuation">.</span><span class="token function">Append</span><span class="token punctuation">(</span>Constraint<span class="token punctuation">.</span><span class="token function">ToString</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">)</span><span class="token punctuation">;</span><br /> <span class="token punctuation">}</span><br /> <span class="token keyword">return</span> Builder<span class="token punctuation">.</span><span class="token function">ToString</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">;</span><br /> <span class="token punctuation">}</span><br /> <span class="token punctuation">}</span></code></pre>
<p>The IDataType classes are created by a global function which uses the type of the property to determine which one to create. For instance a double would create a Float class, a List<int> would throw back a List class, and a bool would pass back a Bit class. These individual classes then look at the attributes of the property and determine what if any sort of constraints to place on the object. For instance, if this is our ID, it creates a PrimaryKey class and adds it to a constraints list and each different type may have its own individual constraints that it needs (for instance the NVarChar class uses the Size constraint). All of these are straightforward and rather uniform with one exception, the List class:</int></p>
<pre class="language-csharp"><code class="language-csharp"> <span class="token keyword">internal</span> <span class="token keyword">class</span> <span class="token class-name">Int</span> <span class="token punctuation">:</span> <span class="token type-list"><span class="token class-name">IDataType</span></span><br /> <span class="token punctuation">{</span><br /> <span class="token keyword">public</span> <span class="token function">Int</span><span class="token punctuation">(</span><span class="token class-name">Attribute</span> Attribute<span class="token punctuation">)</span><br /> <span class="token punctuation">:</span> <span class="token keyword">base</span><span class="token punctuation">(</span>Attribute<span class="token punctuation">)</span><br /> <span class="token punctuation">{</span><br /> Type <span class="token operator">=</span> <span class="token string">"Int"</span><span class="token punctuation">;</span><br /> <span class="token keyword">if</span> <span class="token punctuation">(</span>Attribute<span class="token punctuation">.</span>AutoIncrement<span class="token punctuation">)</span><br /> Constraints<span class="token punctuation">.</span><span class="token function">Add</span><span class="token punctuation">(</span><span class="token keyword">new</span> <span class="token constructor-invocation class-name">AutoIncrement</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">)</span><span class="token punctuation">;</span><br /> <span class="token punctuation">}</span><br /> <span class="token punctuation">}</span> <br /> <br /> <span class="token keyword">internal</span> <span class="token keyword">class</span> <span class="token class-name">List</span><span class="token punctuation">:</span><span class="token type-list"><span class="token class-name">IDataType</span></span><br /> <span class="token punctuation">{</span><br /> <span class="token keyword">public</span> <span class="token function">List</span><span class="token punctuation">(</span><span class="token class-name">Attribute</span> Attribute<span class="token punctuation">,</span> <span class="token class-name">Class</span> Class<span class="token punctuation">,</span> <span class="token class-name">ClassManager</span> Manager<span class="token punctuation">)</span><br /> <span class="token punctuation">:</span> <span class="token keyword">base</span><span class="token punctuation">(</span>Attribute<span class="token punctuation">)</span><br /> <span class="token punctuation">{</span><br /> \_Class <span class="token operator">=</span> Class<span class="token punctuation">;</span><br /> Type <span class="token operator">=</span> <span class="token string">"List"</span><span class="token punctuation">;</span><br /> Name <span class="token operator">=</span> Class<span class="token punctuation">.</span>OriginalType<span class="token punctuation">.</span>Name <span class="token operator">+</span> <span class="token string">"\_"</span> <span class="token operator">+</span> Attribute<span class="token punctuation">.</span>Name<span class="token punctuation">;</span><br /> <span class="token class-name">Type</span> ObjectType <span class="token operator">=</span> Attribute<span class="token punctuation">.</span>Type<span class="token punctuation">.</span><span class="token function">GetGenericArguments</span><span class="token punctuation">(</span><span class="token punctuation">)</span>\<span class="token punctuation">[</span><span class="token number">0</span>\<span class="token punctuation">]</span><span class="token punctuation">;</span><br /> <span class="token class-name">Attribute</span> TempAttribute<span class="token operator">=</span><span class="token keyword">new</span> <span class="token constructor-invocation class-name">Attribute</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">;</span><br /> TempAttribute<span class="token punctuation">.</span>AttributeType<span class="token operator">=</span>AttributeType<span class="token punctuation">.</span>Reference<span class="token punctuation">;</span><br /> TempAttribute<span class="token punctuation">.</span>Length<span class="token operator">=</span>Attribute<span class="token punctuation">.</span>Length<span class="token punctuation">;</span><br /> TempAttribute<span class="token punctuation">.</span>Name<span class="token operator">=</span>Attribute<span class="token punctuation">.</span>Name<span class="token punctuation">;</span><br /> TempAttribute<span class="token punctuation">.</span>Type<span class="token operator">=</span>ObjectType<span class="token punctuation">;</span><br /> <span class="token class-name">IDataType</span> DataType <span class="token operator">=</span> GlobalFunctions<span class="token punctuation">.</span><span class="token function">GetSQLType</span><span class="token punctuation">(</span>TempAttribute<span class="token punctuation">,</span> Class<span class="token punctuation">,</span> Manager<span class="token punctuation">)</span><span class="token punctuation">;</span><br /> <span class="token keyword">if</span> <span class="token punctuation">(</span>DataType <span class="token operator">!=</span> <span class="token keyword">null</span><span class="token punctuation">)</span><br /> <span class="token punctuation">{</span><br /> Columns<span class="token punctuation">.</span><span class="token function">Add</span><span class="token punctuation">(</span>DataType<span class="token punctuation">)</span><span class="token punctuation">;</span><br /> <span class="token punctuation">}</span><br /> <span class="token keyword">else</span><br /> <span class="token punctuation">{</span><br /> <span class="token comment">//Find matching class and ID</span><br /> <span class="token punctuation">}</span><br /> <span class="token keyword">foreach</span> <span class="token punctuation">(</span><span class="token class-name">Property</span> Property <span class="token keyword">in</span> Class<span class="token punctuation">.</span>Properties<span class="token punctuation">)</span><br /> <span class="token punctuation">{</span><br /> <span class="token keyword">if</span> <span class="token punctuation">(</span>Property<span class="token punctuation">.</span>Attribute<span class="token punctuation">.</span>AttributeType <span class="token operator">==</span> AttributeType<span class="token punctuation">.</span>ID<span class="token punctuation">)</span><br /> <span class="token punctuation">{</span><br /> <span class="token class-name">IDataType</span> IDType <span class="token operator">=</span> GlobalFunctions<span class="token punctuation">.</span><span class="token function">GetSQLType</span><span class="token punctuation">(</span>Property<span class="token punctuation">.</span>Attribute<span class="token punctuation">,</span> Class<span class="token punctuation">,</span> Manager<span class="token punctuation">)</span><span class="token punctuation">;</span><br /> IDName <span class="token operator">=</span> IDType<span class="token punctuation">.</span>Name<span class="token punctuation">;</span><br /> IDType<span class="token punctuation">.</span>Constraints<span class="token punctuation">.</span><span class="token function">Clear</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">;</span><br /> <span class="token keyword">if</span> <span class="token punctuation">(</span>IDType <span class="token keyword">is</span> <span class="token class-name">NVarChar</span><span class="token punctuation">)</span><br /> <span class="token punctuation">{</span><br /> IDType<span class="token punctuation">.</span>Constraints<span class="token punctuation">.</span><span class="token function">Add</span><span class="token punctuation">(</span><span class="token keyword">new</span> <span class="token constructor-invocation class-name">Size</span><span class="token punctuation">(</span>Property<span class="token punctuation">.</span>Attribute<span class="token punctuation">.</span>Length<span class="token punctuation">)</span><span class="token punctuation">)</span><span class="token punctuation">;</span><br /> <span class="token punctuation">}</span><br /> Columns<span class="token punctuation">.</span><span class="token function">Add</span><span class="token punctuation">(</span>IDType<span class="token punctuation">)</span><span class="token punctuation">;</span><br /> <span class="token punctuation">}</span><br /> <span class="token punctuation">}</span><br /> <span class="token punctuation">}</span> <br /> <br /> <span class="token keyword">private</span> <span class="token class-name"><span class="token keyword">string</span></span> IDName <span class="token operator">=</span> <span class="token string">""</span><span class="token punctuation">;</span><br /> <span class="token keyword">private</span> <span class="token class-name">List<span class="token punctuation"><</span>IDataType<span class="token punctuation">></span></span> Columns <span class="token operator">=</span> <span class="token keyword">new</span> <span class="token constructor-invocation class-name">List<span class="token punctuation"><</span>IDataType<span class="token punctuation">></span></span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">;</span><br /> <span class="token keyword">private</span> Class \_Class<span class="token punctuation">;</span> <br /> <br /> <span class="token keyword">public</span> <span class="token keyword">override</span> <span class="token return-type class-name"><span class="token keyword">string</span></span> <span class="token function">ToString</span><span class="token punctuation">(</span><span class="token punctuation">)</span><br /> <span class="token punctuation">{</span><br /> <span class="token class-name">StringBuilder</span> Builder <span class="token operator">=</span> <span class="token keyword">new</span> <span class="token constructor-invocation class-name">StringBuilder</span><span class="token punctuation">(</span><span class="token string">"CREATE TABLE "</span> <span class="token operator">+</span> Name <span class="token operator">+</span> <span class="token string">"("</span><span class="token punctuation">)</span><span class="token punctuation">;</span> <br /> <br /> <span class="token class-name"><span class="token keyword">string</span></span> Splitter <span class="token operator">=</span> <span class="token string">""</span><span class="token punctuation">;</span><br /> <span class="token class-name"><span class="token keyword">string</span></span> PrimaryKey<span class="token operator">=</span><span class="token string">""</span><span class="token punctuation">;</span><br /> <span class="token keyword">foreach</span> <span class="token punctuation">(</span><span class="token class-name">IDataType</span> Column <span class="token keyword">in</span> Columns<span class="token punctuation">)</span><br /> <span class="token punctuation">{</span><br /> <span class="token keyword">if</span> <span class="token punctuation">(</span>Column <span class="token operator">!=</span> <span class="token keyword">null</span><span class="token punctuation">)</span><br /> <span class="token punctuation">{</span><br /> PrimaryKey<span class="token operator">+=</span>Splitter<span class="token operator">+</span>Column<span class="token punctuation">.</span>Name<span class="token punctuation">;</span><br /> Builder<span class="token punctuation">.</span><span class="token function">Append</span><span class="token punctuation">(</span>Splitter <span class="token operator">+</span> Column<span class="token punctuation">.</span><span class="token function">ToString</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">)</span><span class="token punctuation">;</span><br /> Splitter <span class="token operator">=</span> <span class="token string">","</span><span class="token punctuation">;</span><br /> <span class="token punctuation">}</span><br /> <span class="token punctuation">}</span><br /> Builder<span class="token punctuation">.</span><span class="token function">Append</span><span class="token punctuation">(</span><span class="token string">", PRIMARY KEY("</span> <span class="token operator">+</span> PrimaryKey <span class="token operator">+</span> <span class="token string">")"</span><span class="token punctuation">)</span><span class="token punctuation">;</span><br /> Builder<span class="token punctuation">.</span><span class="token function">Append</span><span class="token punctuation">(</span><span class="token string">", FOREIGN KEY("</span> <span class="token operator">+</span> IDName <span class="token operator">+</span> <span class="token string">") REFERENCES "</span> <span class="token operator">+</span> \_Class<span class="token punctuation">.</span>OriginalType<span class="token punctuation">.</span>Name <span class="token operator">+</span> <span class="token string">"("</span> <span class="token operator">+</span> IDName <span class="token operator">+</span> <span class="token string">")"</span><span class="token punctuation">)</span><span class="token punctuation">;</span><br /> Builder<span class="token punctuation">.</span><span class="token function">Append</span><span class="token punctuation">(</span><span class="token string">")"</span><span class="token punctuation">)</span><span class="token punctuation">;</span> <br /> <br /> <span class="token keyword">return</span> Builder<span class="token punctuation">.</span><span class="token function">ToString</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">;</span><br /> <span class="token punctuation">}</span><br /> <span class="token punctuation">}</span></code></pre>
<p>The top class is the Int class and as you can see, it's rather small. Most of the data type classes are this way but as you can see, the List class doesn't fall under that category. Whenever you have a list in a database, you can't exactly have it in the same table as the rest of the data without replicating all of the information for a row multiple times which isn't exactly desirable (or you can concat the data together, but it's usually more of a pain than it's worth). As such you create a new table with the ID (or whatever information you need to join the two tables) and the list item. As such the List class has to do this (create the secondary table). In order to do this, it needs to figure out what the type within the list is, create the base type for that. It then has to go back and find the ID for the class. This information is then used to create the table, set the primary/foreign keys, etc. You'll also notice that back in the CreateTable class that we also have to separate out the List items as they are separate commands from the main table. But that's it really. Everything else gets thrown into the main table. This in turn gets thrown back to the SQLBuilder class, which actually sends the commands to the database.</p>
<p>That's the basics at this point. We can create the tables and database for basic types. In the future I'll add in insertion, selection, and deletion. Once that's added, next come the more difficult types to deal with, namely other classes (ManyToMany, ManyToOne, and Map attribute types). But for now, take a look, leave feedback, and happy coding.</p>
Motion Detection in C#
2009-05-29T00:00:00Z
http://www.gutgames.com/post/Motion-Detection-in-C/
<p>Sadly I've come to the point where I will not be able to add more functionality to the Image class within my <a href="https://github.com/JaCraig/Craig-s-Utility-Library">utility library</a>. To be honest, I've run out of simple processing techniques (that I can think of anyway, although I'm sure that I've missed some). So I'm going to show how you can use those functions to do actual work (well that and how to use procedural content to do some cool image effects in the future). In this case I'm going to show you how to do basic motion detection.</p>
<p>Motion is really (as far as we're concerned) just a change in the environment assuming of course you consider the moving object a part of the environment. Therefore detecting motion is simply detecting a change within the environment. We really don't need to worry about object recognition, etc. Instead we simply need to determine that a group of pixels within our image has changed. This is done by taking two frames/images. The first image being the current frame and the second being whatever our baseline is. We take these two images and simply compare them pixel by pixel, seeing if there is a noticeable difference. If it is we mark that pixel as changed. And if we have enough of these pixels, we have motion. So how about some code:</p>
<pre class="language-csharp"><code class="language-csharp"> <span class="token operator">/</span>\<span class="token operator">*</span><br /> Copyright <span class="token punctuation">(</span>c<span class="token punctuation">)</span> <span class="token number">2010</span> <span class="token operator"><</span><span class="token class-name">a</span> href<span class="token operator">=</span><span class="token string">"http://www.gutgames.com"</span><span class="token operator">></span>James Craig<span class="token operator"><</span><span class="token operator">/</span>a<span class="token operator">></span><br /> <br /> Permission <span class="token keyword">is</span> <span class="token class-name">hereby</span> granted<span class="token punctuation">,</span> free <span class="token class-name">of</span> charge<span class="token punctuation">,</span> to any person obtaining a copy<br /> of <span class="token keyword">this</span> software <span class="token keyword">and</span> associated <span class="token return-type class-name">documentation</span> files <span class="token punctuation">(</span>the <span class="token string">"Software"</span><span class="token punctuation">)</span><span class="token punctuation">,</span> <span class="token class-name">to</span> deal<br /> <span class="token keyword">in</span> the Software <span class="token class-name">without</span> restriction<span class="token punctuation">,</span> including without limitation the rights<br /> <span class="token class-name">to</span> use<span class="token punctuation">,</span> copy<span class="token punctuation">,</span> modify<span class="token punctuation">,</span> merge<span class="token punctuation">,</span> publish<span class="token punctuation">,</span> distribute<span class="token punctuation">,</span> sublicense<span class="token punctuation">,</span> <span class="token keyword">and</span><span class="token operator">/</span><span class="token keyword">or</span> sell<br /> copies of <span class="token class-name">the</span> Software<span class="token punctuation">,</span> <span class="token keyword">and</span> to permit persons to whom the Software <span class="token keyword">is</span><br /> <span class="token class-name">furnished</span> to <span class="token keyword">do</span> so<span class="token punctuation">,</span> subject to the <span class="token class-name">following</span> conditions<span class="token punctuation">:</span><br /> <br /> The above copyright notice <span class="token keyword">and</span> <span class="token keyword">this</span> permission notice shall <span class="token class-name">be</span> included <span class="token keyword">in</span><br /> all copies <span class="token keyword">or</span> substantial portions of the Software<span class="token punctuation">.</span><br /> <br /> THE SOFTWARE IS PROVIDED <span class="token string">"AS IS"</span><span class="token punctuation">,</span> WITHOUT WARRANTY OF <span class="token class-name">ANY</span> KIND<span class="token punctuation">,</span> EXPRESS <span class="token class-name">OR</span><br /> IMPLIED<span class="token punctuation">,</span> INCLUDING BUT NOT LIMITED TO THE WARRANTIES <span class="token class-name">OF</span> MERCHANTABILITY<span class="token punctuation">,</span><br /> FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT<span class="token punctuation">.</span> IN NO EVENT SHALL THE<br /> AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR <span class="token class-name">ANY</span> CLAIM<span class="token punctuation">,</span> DAMAGES OR <span class="token class-name">OTHER</span><br /> LIABILITY<span class="token punctuation">,</span> WHETHER IN AN ACTION <span class="token class-name">OF</span> CONTRACT<span class="token punctuation">,</span> TORT <span class="token class-name">OR</span> OTHERWISE<span class="token punctuation">,</span> <span class="token class-name">ARISING</span> FROM<span class="token punctuation">,</span><br /> OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN<br /> THE SOFTWARE<span class="token punctuation">.</span>\<span class="token operator">*</span><span class="token operator">/</span><br /> <br /> <span class="token preprocessor property">#<span class="token directive keyword">region</span> Usings</span><br /> <span class="token keyword">using</span> <span class="token namespace">System<span class="token punctuation">.</span>Drawing</span><span class="token punctuation">;</span><br /> <span class="token keyword">using</span> <span class="token namespace">System<span class="token punctuation">.</span>Drawing<span class="token punctuation">.</span>Imaging</span><span class="token punctuation">;</span><br /> <span class="token preprocessor property">#<span class="token directive keyword">endregion</span></span><br /> <br /> <span class="token keyword">namespace</span> <span class="token namespace">Utilities<span class="token punctuation">.</span>Media<span class="token punctuation">.</span>Image</span><br /> <span class="token punctuation">{</span><br /> <span class="token comment">/// <summary></span><br /> <span class="token comment">/// Used for motion detection</span><br /> <span class="token comment">/// </summary></span><br /> <span class="token keyword">public</span> <span class="token keyword">static</span> <span class="token keyword">class</span> <span class="token class-name">MotionDetection</span><br /> <span class="token punctuation">{</span><br /> <span class="token preprocessor property">#<span class="token directive keyword">region</span> Public Static Functions</span><br /> <br /> <span class="token comment">/// <summary></span><br /> <span class="token comment">/// Runs the motion detection algorithm</span><br /> <span class="token comment">/// </summary></span><br /> <span class="token comment">/// <param name="NewImage">The "new" frame</param></span><br /> <span class="token comment">/// <param name="OldImage">The "old" frame</param></span><br /> <span class="token comment">/// <param name="Threshold">The threshold used to detect changes in the image</param></span><br /> <span class="token comment">/// <param name="DetectionColor">Color to display changes in the images as</param></span><br /> <span class="token comment">/// <returns>A bitmap indicating where changes between frames have occurred overlayed on top of the new image.</returns></span><br /> <span class="token keyword">public</span> <span class="token keyword">static</span> <span class="token return-type class-name">Bitmap</span> <span class="token function">Process</span><span class="token punctuation">(</span><span class="token class-name">Bitmap</span> NewImage<span class="token punctuation">,</span> <span class="token class-name">Bitmap</span> OldImage<span class="token punctuation">,</span> <span class="token class-name"><span class="token keyword">int</span></span> Threshold<span class="token punctuation">,</span> <span class="token class-name">Color</span> DetectionColor<span class="token punctuation">)</span><br /> <span class="token punctuation">{</span><br /> <span class="token keyword">using</span> <span class="token punctuation">(</span><span class="token class-name">Bitmap</span> NewImage1 <span class="token operator">=</span> Utilities<span class="token punctuation">.</span>Media<span class="token punctuation">.</span>Image<span class="token punctuation">.</span>Image<span class="token punctuation">.</span><span class="token function">ConvertBlackAndWhite</span><span class="token punctuation">(</span>NewImage<span class="token punctuation">)</span><span class="token punctuation">)</span><br /> <span class="token punctuation">{</span><br /> <span class="token keyword">using</span> <span class="token punctuation">(</span><span class="token class-name">Bitmap</span> OldImage1 <span class="token operator">=</span> Utilities<span class="token punctuation">.</span>Media<span class="token punctuation">.</span>Image<span class="token punctuation">.</span>Image<span class="token punctuation">.</span><span class="token function">ConvertBlackAndWhite</span><span class="token punctuation">(</span>OldImage<span class="token punctuation">)</span><span class="token punctuation">)</span><br /> <span class="token punctuation">{</span><br /> <span class="token keyword">using</span> <span class="token punctuation">(</span><span class="token class-name">Bitmap</span> NewImage2 <span class="token operator">=</span> Utilities<span class="token punctuation">.</span>Media<span class="token punctuation">.</span>Image<span class="token punctuation">.</span>Image<span class="token punctuation">.</span><span class="token function">SNNBlur</span><span class="token punctuation">(</span>NewImage1<span class="token punctuation">,</span> <span class="token number">5</span><span class="token punctuation">)</span><span class="token punctuation">)</span><br /> <span class="token punctuation">{</span><br /> <span class="token keyword">using</span> <span class="token punctuation">(</span><span class="token class-name">Bitmap</span> OldImage2 <span class="token operator">=</span> Utilities<span class="token punctuation">.</span>Media<span class="token punctuation">.</span>Image<span class="token punctuation">.</span>Image<span class="token punctuation">.</span><span class="token function">SNNBlur</span><span class="token punctuation">(</span>OldImage1<span class="token punctuation">,</span> <span class="token number">5</span><span class="token punctuation">)</span><span class="token punctuation">)</span><br /> <span class="token punctuation">{</span><br /> <span class="token keyword">using</span> <span class="token punctuation">(</span><span class="token class-name">Bitmap</span> OutputImage <span class="token operator">=</span> <span class="token keyword">new</span> <span class="token constructor-invocation class-name">Bitmap</span><span class="token punctuation">(</span>NewImage2<span class="token punctuation">,</span> NewImage2<span class="token punctuation">.</span>Width<span class="token punctuation">,</span> NewImage2<span class="token punctuation">.</span>Height<span class="token punctuation">)</span><span class="token punctuation">)</span><br /> <span class="token punctuation">{</span><br /> <span class="token keyword">using</span> <span class="token punctuation">(</span><span class="token class-name">Bitmap</span> Overlay <span class="token operator">=</span> <span class="token keyword">new</span> <span class="token constructor-invocation class-name">Bitmap</span><span class="token punctuation">(</span>NewImage<span class="token punctuation">,</span> NewImage<span class="token punctuation">.</span>Width<span class="token punctuation">,</span> NewImage<span class="token punctuation">.</span>Height<span class="token punctuation">)</span><span class="token punctuation">)</span><br /> <span class="token punctuation">{</span><br /> <span class="token class-name">BitmapData</span> NewImage2Data <span class="token operator">=</span> Image<span class="token punctuation">.</span><span class="token function">LockImage</span><span class="token punctuation">(</span>NewImage2<span class="token punctuation">)</span><span class="token punctuation">;</span><br /> <span class="token class-name"><span class="token keyword">int</span></span> NewImage2PixelSize <span class="token operator">=</span> Image<span class="token punctuation">.</span><span class="token function">GetPixelSize</span><span class="token punctuation">(</span>NewImage2Data<span class="token punctuation">)</span><span class="token punctuation">;</span><br /> <span class="token class-name">BitmapData</span> OldImage2Data <span class="token operator">=</span> Image<span class="token punctuation">.</span><span class="token function">LockImage</span><span class="token punctuation">(</span>OldImage2<span class="token punctuation">)</span><span class="token punctuation">;</span><br /> <span class="token class-name"><span class="token keyword">int</span></span> OldImage2PixelSize <span class="token operator">=</span> Image<span class="token punctuation">.</span><span class="token function">GetPixelSize</span><span class="token punctuation">(</span>OldImage2Data<span class="token punctuation">)</span><span class="token punctuation">;</span><br /> <span class="token class-name">BitmapData</span> OverlayData <span class="token operator">=</span> Image<span class="token punctuation">.</span><span class="token function">LockImage</span><span class="token punctuation">(</span>Overlay<span class="token punctuation">)</span><span class="token punctuation">;</span><br /> <span class="token class-name"><span class="token keyword">int</span></span> OverlayPixelSize <span class="token operator">=</span> Image<span class="token punctuation">.</span><span class="token function">GetPixelSize</span><span class="token punctuation">(</span>OverlayData<span class="token punctuation">)</span><span class="token punctuation">;</span><br /> <span class="token keyword">for</span> <span class="token punctuation">(</span><span class="token class-name"><span class="token keyword">int</span></span> x <span class="token operator">=</span> <span class="token number">0</span><span class="token punctuation">;</span> x <span class="token operator"><</span> OutputImage<span class="token punctuation">.</span>Width<span class="token punctuation">;</span> <span class="token operator">++</span>x<span class="token punctuation">)</span><br /> <span class="token punctuation">{</span><br /> <span class="token keyword">for</span> <span class="token punctuation">(</span><span class="token class-name"><span class="token keyword">int</span></span> y <span class="token operator">=</span> <span class="token number">0</span><span class="token punctuation">;</span> y <span class="token operator"><</span> OutputImage<span class="token punctuation">.</span>Height<span class="token punctuation">;</span> <span class="token operator">++</span>y<span class="token punctuation">)</span><br /> <span class="token punctuation">{</span><br /> <span class="token class-name">Color</span> NewPixel <span class="token operator">=</span> Image<span class="token punctuation">.</span><span class="token function">GetPixel</span><span class="token punctuation">(</span>NewImage2Data<span class="token punctuation">,</span> x<span class="token punctuation">,</span> y<span class="token punctuation">,</span> NewImage2PixelSize<span class="token punctuation">)</span><span class="token punctuation">;</span><br /> <span class="token class-name">Color</span> OldPixel <span class="token operator">=</span> Image<span class="token punctuation">.</span><span class="token function">GetPixel</span><span class="token punctuation">(</span>OldImage2Data<span class="token punctuation">,</span> x<span class="token punctuation">,</span> y<span class="token punctuation">,</span> OldImage2PixelSize<span class="token punctuation">)</span><span class="token punctuation">;</span><br /> <span class="token keyword">if</span> <span class="token punctuation">(</span>System<span class="token punctuation">.</span>Math<span class="token punctuation">.</span><span class="token function">Pow</span><span class="token punctuation">(</span><span class="token punctuation">(</span><span class="token keyword">double</span><span class="token punctuation">)</span><span class="token punctuation">(</span>NewPixel<span class="token punctuation">.</span>R <span class="token operator">-</span> OldPixel<span class="token punctuation">.</span>R<span class="token punctuation">)</span><span class="token punctuation">,</span> <span class="token number">2.0</span><span class="token punctuation">)</span> <span class="token operator">></span> Threshold<span class="token punctuation">)</span><br /> <span class="token punctuation">{</span><br /> Image<span class="token punctuation">.</span><span class="token function">SetPixel</span><span class="token punctuation">(</span>OverlayData<span class="token punctuation">,</span> x<span class="token punctuation">,</span> y<span class="token punctuation">,</span> Color<span class="token punctuation">.</span><span class="token function">FromArgb</span><span class="token punctuation">(</span><span class="token number">100</span><span class="token punctuation">,</span> <span class="token number">0</span><span class="token punctuation">,</span> <span class="token number">100</span><span class="token punctuation">)</span><span class="token punctuation">,</span> OverlayPixelSize<span class="token punctuation">)</span><span class="token punctuation">;</span><br /> <span class="token punctuation">}</span><br /> <span class="token keyword">else</span><br /> <span class="token punctuation">{</span><br /> Image<span class="token punctuation">.</span><span class="token function">SetPixel</span><span class="token punctuation">(</span>OverlayData<span class="token punctuation">,</span> x<span class="token punctuation">,</span> y<span class="token punctuation">,</span> Color<span class="token punctuation">.</span><span class="token function">FromArgb</span><span class="token punctuation">(</span><span class="token number">200</span><span class="token punctuation">,</span> <span class="token number">0</span><span class="token punctuation">,</span> <span class="token number">200</span><span class="token punctuation">)</span><span class="token punctuation">,</span> OverlayPixelSize<span class="token punctuation">)</span><span class="token punctuation">;</span><br /> <span class="token punctuation">}</span><br /> <span class="token punctuation">}</span><br /> <span class="token punctuation">}</span><br /> Image<span class="token punctuation">.</span><span class="token function">UnlockImage</span><span class="token punctuation">(</span>Overlay<span class="token punctuation">,</span> OverlayData<span class="token punctuation">)</span><span class="token punctuation">;</span><br /> Image<span class="token punctuation">.</span><span class="token function">UnlockImage</span><span class="token punctuation">(</span>NewImage2<span class="token punctuation">,</span> NewImage2Data<span class="token punctuation">)</span><span class="token punctuation">;</span><br /> Image<span class="token punctuation">.</span><span class="token function">UnlockImage</span><span class="token punctuation">(</span>OldImage2<span class="token punctuation">,</span> OldImage2Data<span class="token punctuation">)</span><span class="token punctuation">;</span><br /> <span class="token keyword">using</span> <span class="token punctuation">(</span><span class="token class-name">Bitmap</span> Overlay2 <span class="token operator">=</span> Utilities<span class="token punctuation">.</span>Media<span class="token punctuation">.</span>Image<span class="token punctuation">.</span>Image<span class="token punctuation">.</span><span class="token function">EdgeDetection</span><span class="token punctuation">(</span>Overlay<span class="token punctuation">,</span> <span class="token number">25</span><span class="token punctuation">,</span> DetectionColor<span class="token punctuation">)</span><span class="token punctuation">)</span><br /> <span class="token punctuation">{</span><br /> <span class="token class-name">BitmapData</span> Overlay2Data <span class="token operator">=</span> Image<span class="token punctuation">.</span><span class="token function">LockImage</span><span class="token punctuation">(</span>Overlay2<span class="token punctuation">)</span><span class="token punctuation">;</span><br /> <span class="token class-name"><span class="token keyword">int</span></span> Overlay2PixelSize <span class="token operator">=</span> Image<span class="token punctuation">.</span><span class="token function">GetPixelSize</span><span class="token punctuation">(</span>Overlay2Data<span class="token punctuation">)</span><span class="token punctuation">;</span><br /> <span class="token keyword">for</span> <span class="token punctuation">(</span><span class="token class-name"><span class="token keyword">int</span></span> x <span class="token operator">=</span> <span class="token number">0</span><span class="token punctuation">;</span> x <span class="token operator"><</span> OutputImage<span class="token punctuation">.</span>Width<span class="token punctuation">;</span> <span class="token operator">++</span>x<span class="token punctuation">)</span><br /> <span class="token punctuation">{</span><br /> <span class="token keyword">for</span> <span class="token punctuation">(</span><span class="token class-name"><span class="token keyword">int</span></span> y <span class="token operator">=</span> <span class="token number">0</span><span class="token punctuation">;</span> y <span class="token operator"><</span> OutputImage<span class="token punctuation">.</span>Height<span class="token punctuation">;</span> <span class="token operator">++</span>y<span class="token punctuation">)</span><br /> <span class="token punctuation">{</span><br /> <span class="token class-name">Color</span> Pixel1 <span class="token operator">=</span> Image<span class="token punctuation">.</span><span class="token function">GetPixel</span><span class="token punctuation">(</span>Overlay2Data<span class="token punctuation">,</span> x<span class="token punctuation">,</span> y<span class="token punctuation">,</span> Overlay2PixelSize<span class="token punctuation">)</span><span class="token punctuation">;</span><br /> <span class="token keyword">if</span> <span class="token punctuation">(</span>Pixel1<span class="token punctuation">.</span>R <span class="token operator">!=</span> DetectionColor<span class="token punctuation">.</span>R <span class="token operator">||</span> Pixel1<span class="token punctuation">.</span>G <span class="token operator">!=</span> DetectionColor<span class="token punctuation">.</span>G <span class="token operator">||</span> Pixel1<span class="token punctuation">.</span>B <span class="token operator">!=</span> DetectionColor<span class="token punctuation">.</span>B<span class="token punctuation">)</span><br /> <span class="token punctuation">{</span><br /> Image<span class="token punctuation">.</span><span class="token function">SetPixel</span><span class="token punctuation">(</span>Overlay2Data<span class="token punctuation">,</span> x<span class="token punctuation">,</span> y<span class="token punctuation">,</span> Color<span class="token punctuation">.</span><span class="token function">FromArgb</span><span class="token punctuation">(</span><span class="token number">200</span><span class="token punctuation">,</span> <span class="token number">0</span><span class="token punctuation">,</span> <span class="token number">200</span><span class="token punctuation">)</span><span class="token punctuation">,</span> Overlay2PixelSize<span class="token punctuation">)</span><span class="token punctuation">;</span><br /> <span class="token punctuation">}</span><br /> <span class="token punctuation">}</span><br /> <span class="token punctuation">}</span><br /> Image<span class="token punctuation">.</span><span class="token function">UnlockImage</span><span class="token punctuation">(</span>Overlay2<span class="token punctuation">,</span> Overlay2Data<span class="token punctuation">)</span><span class="token punctuation">;</span><br /> <span class="token keyword">return</span> Utilities<span class="token punctuation">.</span>Media<span class="token punctuation">.</span>Image<span class="token punctuation">.</span>Image<span class="token punctuation">.</span><span class="token function">Watermark</span><span class="token punctuation">(</span>OutputImage<span class="token punctuation">,</span> Overlay2<span class="token punctuation">,</span> <span class="token number">1.0f</span><span class="token punctuation">,</span> <span class="token number">0</span><span class="token punctuation">,</span> <span class="token number">0</span><span class="token punctuation">,</span> Color<span class="token punctuation">.</span><span class="token function">FromArgb</span><span class="token punctuation">(</span><span class="token number">200</span><span class="token punctuation">,</span> <span class="token number">0</span><span class="token punctuation">,</span> <span class="token number">200</span><span class="token punctuation">)</span><span class="token punctuation">)</span><span class="token punctuation">;</span><br /> <span class="token punctuation">}</span><br /> <span class="token punctuation">}</span><br /> <span class="token punctuation">}</span><br /> <span class="token punctuation">}</span><br /> <span class="token punctuation">}</span><br /> <span class="token punctuation">}</span><br /> <span class="token punctuation">}</span><br /> <span class="token punctuation">}</span><br /> <br /> <span class="token preprocessor property">#<span class="token directive keyword">endregion</span></span><br /> <span class="token punctuation">}</span><br /> <span class="token punctuation">}</span></code></pre>
<p>It uses a number of functions, classes, etc. from my <a href="http://cul.codeplex.com/">utility library</a> and It's a bit slow and can definitely be optimized but it gets the job done. Anyway originally it goes in and converts the images to black and white, next an <a href="http://www.gutgames.com/post/Symmetric-Nearest-Neighbor-in-C">SNN blur</a> is applied to them, and finally we compare the pixels. We could stop here but I've gone a step further and added some edge detection afterwords to outline what has changed which is then overlayed onto the original image... It's actually fairly simple and works fairly well. There are plenty of ways to improve the algorithm but this is definitely a good start. So give it a try, leave feedback, and happy coding.</p>