<?xml version='1.0' encoding='UTF-8'?><?xml-stylesheet href="http://www.blogger.com/styles/atom.css" type="text/css"?><feed xmlns='http://www.w3.org/2005/Atom' xmlns:openSearch='http://a9.com/-/spec/opensearchrss/1.0/' xmlns:georss='http://www.georss.org/georss' xmlns:gd='http://schemas.google.com/g/2005' xmlns:thr='http://purl.org/syndication/thread/1.0'><id>tag:blogger.com,1999:blog-6525302577308628916</id><updated>2012-01-27T05:46:19.370-08:00</updated><category term='alias'/><category term='LINQ'/><category term='table'/><category term='design patterns'/><category term='FOR XML'/><category term='documentation'/><category term='bug'/><category term='Image'/><category term='JPEG'/><category term='Visual Studio 2005'/><category term='SharePoint'/><category term='ConsoleTraceListener'/><category term='Bitmap'/><category term='F#'/><category term='B2Bits'/><category term='normalization'/><category term='MS SQL'/><category term='join'/><category term='Oracle'/><category term='Trace'/><category term='WSS'/><category term='ASP.NET'/><category term='C#'/><category term='Data entity'/><category term='Array'/><category term='Microsoft licenses'/><category term='Stringly-typed dataset'/><category term='Mutidimensional'/><category term='Gamma correction'/><category term='optimization'/><category term='CMS'/><category term='Convert'/><category term='ExecuteXmlReader'/><category term='Windows Internal Database'/><category term='Initialization'/><category term='Transaction'/><category term='Blog'/><category term='.NET'/><category term='FIXML'/><category term='Kentico'/><title type='text'>Bogdan Chernyachuk's Blog on .NET</title><subtitle type='html'></subtitle><link rel='http://schemas.google.com/g/2005#feed' type='application/atom+xml' href='http://bogdandotnet.blogspot.com/feeds/posts/default'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/6525302577308628916/posts/default?max-results=100'/><link rel='alternate' type='text/html' href='http://bogdandotnet.blogspot.com/'/><link rel='hub' href='http://pubsubhubbub.appspot.com/'/><author><name>Bogdan Chernyachuk</name><uri>http://www.blogger.com/profile/09091829339994105257</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='28' height='32' src='http://bp1.blogger.com/_gJkSPqzmaQA/R9eTVo7ynCI/AAAAAAAAAyo/UliQCi_C1Hs/S220/c-moscow_small.JPG'/></author><generator version='7.00' uri='http://www.blogger.com'>Blogger</generator><openSearch:totalResults>12</openSearch:totalResults><openSearch:startIndex>1</openSearch:startIndex><openSearch:itemsPerPage>100</openSearch:itemsPerPage><entry><id>tag:blogger.com,1999:blog-6525302577308628916.post-6684210546768273876</id><published>2009-09-03T15:01:00.000-07:00</published><updated>2009-09-03T15:14:35.345-07:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='.NET'/><category scheme='http://www.blogger.com/atom/ns#' term='B2Bits'/><category scheme='http://www.blogger.com/atom/ns#' term='documentation'/><category scheme='http://www.blogger.com/atom/ns#' term='FIXML'/><title type='text'>Using Sandcastle as a documentation tool</title><content type='html'>Recently, we evaluated several documentation tools, like ndoc, doxygen etc. We found that SandCastle (together with SandCastle Help File Builder GUI app - &lt;a href="http://shfb.codeplex.com/"&gt;http://shfb.codeplex.com&lt;/a&gt;/) is the most appropriate tool for generation of rich documentation to .NET libraries.&lt;br /&gt;&lt;br /&gt;It can create HTML DOC 1.1, 2.0 and pure HTML output, and here is an example of our work.&lt;br /&gt;&lt;br /&gt;&lt;a href="http://corp-web.b2bits.com/fixanet/doc/html/"&gt;http://corp-web.b2bits.com/fixanet/doc/html/&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;What bugs we has found&lt;br /&gt;1) When we add a picture to the headers of help content files, some fonts will be smaller then it was supposed. Perhaps the tool adds additional div and corrupts styles somehow&lt;br /&gt;2) Sync topics button doesnt work in FireFox (but it is OK in other browsers)&lt;br /&gt;&lt;br /&gt;In generally, it is the best free tool for .NET, I believe, while there are also several commercial tools one may consider - a list of them can be found there &lt;a href="http://stackoverflow.com/questions/546053/anyone-using-ndoc-or-a-similar-tool-to-help-with-system-documentation/1200561#1200561"&gt;http://stackoverflow.com/questions/546053/anyone-using-ndoc-or-a-similar-tool-to-help-with-system-documentation/1200561#1200561&lt;/a&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/6525302577308628916-6684210546768273876?l=bogdandotnet.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://bogdandotnet.blogspot.com/feeds/6684210546768273876/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=6525302577308628916&amp;postID=6684210546768273876' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/6525302577308628916/posts/default/6684210546768273876'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/6525302577308628916/posts/default/6684210546768273876'/><link rel='alternate' type='text/html' href='http://bogdandotnet.blogspot.com/2009/09/using-sandcastle-as-documentation-tool.html' title='Using Sandcastle as a documentation tool'/><author><name>Bogdan Chernyachuk</name><uri>http://www.blogger.com/profile/09091829339994105257</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='28' height='32' src='http://bp1.blogger.com/_gJkSPqzmaQA/R9eTVo7ynCI/AAAAAAAAAyo/UliQCi_C1Hs/S220/c-moscow_small.JPG'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-6525302577308628916.post-7704110031123612149</id><published>2009-06-04T09:59:00.000-07:00</published><updated>2009-06-04T10:23:44.013-07:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='Trace'/><category scheme='http://www.blogger.com/atom/ns#' term='.NET'/><category scheme='http://www.blogger.com/atom/ns#' term='C#'/><category scheme='http://www.blogger.com/atom/ns#' term='ConsoleTraceListener'/><title type='text'>Avoid verbose log formatting in .NET TraceListeners</title><content type='html'>The problem is:&lt;br /&gt;&lt;br /&gt;when you use any of default TraceListeners (for example, I need ConsoleTraceListener), and when you call Trace.LogInfo , Trace.LogError or Trace.LogWarning, you wil have something like&lt;br /&gt;&lt;br /&gt;&lt;span style="font-size:85%;"&gt;&lt;span style="font-family:courier new;"&gt;Your application name: Information :  : And here is a text of your message&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family:courier new;"&gt;Your application name: Warning :  : And here is a text of your warning&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family:courier new;"&gt;....&lt;/span&gt;&lt;br /&gt;&lt;/span&gt;&lt;br /&gt;Well, I don't need application name and I want to exactly control how the log is formatted. Setting traceOutputOptions in app.config will not change the situation, because with traceOutputOptions you can add date, timestamp or even full stack to the log, but there is no way to remove something out from there. Damn, now I understand why we have been used Log4Net for logging instead of System.Diagnostics.Trace! But in the current project I can't use Log4Net&lt;br /&gt;&lt;br /&gt;Ok, to solve the problem I try to understand how the MS code works, when going from the point where you call LogInfo (message) to the point where it outputs to the stream.&lt;br /&gt;I noticed that&lt;br /&gt;&lt;br /&gt;When I call Trace.LogInfo(message), the following happens&lt;br /&gt;&lt;br /&gt;1)  TraceListener.Write is called with parameter like  "application_name: message_type: 0 "&lt;br /&gt;2)  TraceListener.WriteLine is called with my message&lt;br /&gt;&lt;br /&gt;So actually they write a log message in 2 turns, OK, sound great for me, as far as we can handle it now in the following way:&lt;br /&gt;&lt;br /&gt;1) I created a simple class LaconicTraceListener, and the code you will find below. You need to override just one function there&lt;br /&gt;2) And I added new cutom listener to the app.config file to the &lt;system.diagnostics&gt; &lt;trace&gt; &lt;listeners&gt; section.&lt;br /&gt;&lt;br /&gt;  &lt;add name="MyTraceListener" type="MyApplication.LaconicConsoleTraceListener, MyApplication" traceoutputoptions="None"&gt;&lt;br /&gt;       &lt;br /&gt;And it works!&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;span style="font-size:85%;"&gt;&lt;span style="font-family:courier new;"&gt;    /// &lt;summary&gt;&lt;/summary&gt;&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family:courier new;"&gt;    /// Class overrides one function of standard ConsoleTraceListener&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family:courier new;"&gt;    /// to make output less verbose&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family:courier new;"&gt;    /// &lt;/span&gt;&lt;/span&gt;&lt;/add&gt;&lt;span style="font-size:85%;"&gt;&lt;br /&gt;&lt;/span&gt;&lt;span style=";font-family:courier new;font-size:85%;"  &gt;    public class LaconicConsoleTraceListener: System.Diagnostics.ConsoleTraceListener&lt;/span&gt;&lt;span style="font-size:85%;"&gt;&lt;br /&gt;&lt;/span&gt;&lt;span style=";font-family:courier new;font-size:85%;"  &gt;    {&lt;/span&gt;&lt;span style="font-size:85%;"&gt;&lt;br /&gt;&lt;/span&gt;&lt;span style=";font-family:courier new;font-size:85%;"  &gt;      &lt;br /&gt;  public LaconicConsoleTraceListener(): base()&lt;/span&gt;&lt;span style="font-size:85%;"&gt;&lt;br /&gt;&lt;/span&gt;&lt;span style=";font-family:courier new;font-size:85%;"  &gt;   {&lt;/span&gt;&lt;span style="font-size:85%;"&gt;&lt;br /&gt;&lt;/span&gt;&lt;span style=";font-family:courier new;font-size:85%;"  &gt;          }&lt;/span&gt;&lt;span style="font-size:85%;"&gt;&lt;br /&gt;&lt;br /&gt;&lt;/span&gt;&lt;span style=";font-family:courier new;font-size:85%;"  &gt;          public LaconicConsoleTraceListener(bool useErrorStream)&lt;/span&gt;&lt;span style="font-size:85%;"&gt;&lt;br /&gt;&lt;/span&gt;&lt;span style=";font-family:courier new;font-size:85%;"  &gt;                : base(useErrorStream)&lt;/span&gt;&lt;span style="font-size:85%;"&gt;&lt;br /&gt;&lt;/span&gt;&lt;span style=";font-family:courier new;font-size:85%;"  &gt;          { &lt;/span&gt;&lt;span style="font-size:85%;"&gt;&lt;br /&gt;&lt;/span&gt;&lt;span style=";font-family:courier new;font-size:85%;"  &gt;          }&lt;/span&gt;&lt;span style="font-size:85%;"&gt;&lt;br /&gt;&lt;br /&gt;&lt;/span&gt;&lt;span style=";font-family:courier new;font-size:85%;"  &gt;          public override void Write(string message)&lt;/span&gt;&lt;span style="font-size:85%;"&gt;&lt;br /&gt;&lt;/span&gt;&lt;span style=";font-family:courier new;font-size:85%;"  &gt;          {&lt;/span&gt;&lt;span style="font-size:85%;"&gt;&lt;br /&gt;&lt;/span&gt;&lt;span style=";font-family:courier new;font-size:85%;"  &gt;            /*&lt;/span&gt;&lt;span style="font-size:85%;"&gt;&lt;br /&gt;&lt;/span&gt;&lt;span style=";font-family:courier new;font-size:85%;"  &gt;            A trick to avoid verbose logging.&lt;/span&gt;&lt;span style="font-size:85%;"&gt;&lt;br /&gt;&lt;/span&gt;&lt;span style=";font-family:courier new;font-size:85%;"  &gt;            LogInformation function works in following way -&lt;/span&gt;&lt;span style="font-size:85%;"&gt;&lt;br /&gt;&lt;/span&gt;&lt;span style=";font-family:courier new;font-size:85%;"  &gt;            For each call of LogInformation(Message) it actually calls:&lt;/span&gt;&lt;span style="font-size:85%;"&gt;&lt;br /&gt;&lt;/span&gt;&lt;span style=";font-family:courier new;font-size:85%;"  &gt;            1) Write("AssemblyName: MessageType: MessageIndent");&lt;/span&gt;&lt;span style="font-size:85%;"&gt;&lt;br /&gt;&lt;/span&gt;&lt;span style=";font-family:courier new;font-size:85%;"  &gt;            2) WriteLine(message)&lt;/span&gt;&lt;span style="font-size:85%;"&gt;&lt;br /&gt;&lt;/span&gt;&lt;span style=";font-family:courier new;font-size:85%;"  &gt;            &lt;/span&gt;&lt;span style="font-size:85%;"&gt;&lt;br /&gt;&lt;/span&gt;&lt;span style=";font-family:courier new;font-size:85%;"  &gt;            We don't want to have an assembly name in each trace line, so we will exclude it &lt;/span&gt;&lt;span style="font-size:85%;"&gt;&lt;br /&gt;&lt;/span&gt;&lt;span style=";font-family:courier new;font-size:85%;"  &gt;            */&lt;/span&gt;&lt;span style="font-size:85%;"&gt;&lt;br /&gt;&lt;/span&gt;&lt;span style=";font-family:courier new;font-size:85%;"  &gt;                if (!message.StartsWith(this.GetType().Assembly.GetName().Name,&lt;br /&gt;       StringComparison.InvariantCultureIgnoreCase))&lt;/span&gt;&lt;span style="font-size:85%;"&gt;&lt;br /&gt;&lt;/span&gt;&lt;span style=";font-family:courier new;font-size:85%;"  &gt;                {&lt;/span&gt;&lt;span style="font-size:85%;"&gt;&lt;br /&gt;&lt;/span&gt;&lt;span style=";font-family:courier new;font-size:85%;"  &gt;                       base.Write(message);&lt;/span&gt;&lt;span style="font-size:85%;"&gt;&lt;br /&gt;&lt;/span&gt;&lt;span style=";font-family:courier new;font-size:85%;"  &gt;                }&lt;/span&gt;&lt;span style="font-size:85%;"&gt;&lt;br /&gt;&lt;/span&gt;&lt;span style=";font-family:courier new;font-size:85%;"  &gt;  }&lt;br /&gt;}&lt;br /&gt;&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&lt;/listeners&gt;&lt;/trace&gt;&lt;/system.diagnostics&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/6525302577308628916-7704110031123612149?l=bogdandotnet.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://bogdandotnet.blogspot.com/feeds/7704110031123612149/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=6525302577308628916&amp;postID=7704110031123612149' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/6525302577308628916/posts/default/7704110031123612149'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/6525302577308628916/posts/default/7704110031123612149'/><link rel='alternate' type='text/html' href='http://bogdandotnet.blogspot.com/2009/06/how-to-avoid-verbose-log-formatting.html' title='Avoid verbose log formatting in .NET TraceListeners'/><author><name>Bogdan Chernyachuk</name><uri>http://www.blogger.com/profile/09091829339994105257</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='28' height='32' src='http://bp1.blogger.com/_gJkSPqzmaQA/R9eTVo7ynCI/AAAAAAAAAyo/UliQCi_C1Hs/S220/c-moscow_small.JPG'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-6525302577308628916.post-8969341411416402937</id><published>2009-05-14T05:32:00.001-07:00</published><updated>2009-05-14T05:38:39.463-07:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='MS SQL'/><category scheme='http://www.blogger.com/atom/ns#' term='normalization'/><title type='text'>Using SET ROWCOUNT to limit number of deleted records</title><content type='html'>I was given MS SQL database with no normalization, no primary keys in tables and lot of duplicates.&lt;br /&gt;How can you delete a duplicate rows from the table, if you have 2 rows where no unique key exists, all fields are equal, so there is no way to distinguish one row from another?&lt;br /&gt;&lt;br /&gt;In Oracle you always have row_id so 2 between 2 rows you can delete a row with max(row_id)&lt;br /&gt;&lt;br /&gt;In MS SQL you can use SET ROWCOUNT &lt;n&gt; to limit the number of deleted records.&lt;br /&gt;&lt;br /&gt;Run the following example, and you wil get and idea.&lt;br /&gt;&lt;blockquote&gt;&lt;br /&gt;create table t&lt;br /&gt;(&lt;br /&gt;id int,&lt;br /&gt;name varchar(100)&lt;br /&gt;)&lt;br /&gt;GO&lt;br /&gt;&lt;br /&gt;insert t values(1, 'Number One')&lt;br /&gt;insert t values(2, 'Number Two')&lt;br /&gt;insert t values(3, 'Number Three')&lt;br /&gt;insert t values(1, 'Number One')&lt;br /&gt;&lt;br /&gt;GO&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;SELECT count(*) FROM t  /* will return 4  */&lt;br /&gt;&lt;br /&gt;GO&lt;br /&gt;&lt;br /&gt;SET ROWCOUNT 1&lt;br /&gt;DELETE from t where ID = 1  /* will delete only one record from 2 records with ID = 1  */&lt;br /&gt;&lt;br /&gt;GO&lt;br /&gt;&lt;br /&gt;SELECT count(*) FROM t  /* will return 3  */&lt;br /&gt;&lt;br /&gt;GO&lt;/blockquote&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/6525302577308628916-8969341411416402937?l=bogdandotnet.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://bogdandotnet.blogspot.com/feeds/8969341411416402937/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=6525302577308628916&amp;postID=8969341411416402937' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/6525302577308628916/posts/default/8969341411416402937'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/6525302577308628916/posts/default/8969341411416402937'/><link rel='alternate' type='text/html' href='http://bogdandotnet.blogspot.com/2009/05/using-set-rowcount-to-limit-number-of.html' title='Using SET ROWCOUNT to limit number of deleted records'/><author><name>Bogdan Chernyachuk</name><uri>http://www.blogger.com/profile/09091829339994105257</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='28' height='32' src='http://bp1.blogger.com/_gJkSPqzmaQA/R9eTVo7ynCI/AAAAAAAAAyo/UliQCi_C1Hs/S220/c-moscow_small.JPG'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-6525302577308628916.post-6566749898196752203</id><published>2009-05-08T04:03:00.000-07:00</published><updated>2009-05-08T04:38:54.477-07:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='MS SQL'/><category scheme='http://www.blogger.com/atom/ns#' term='SharePoint'/><category scheme='http://www.blogger.com/atom/ns#' term='WSS'/><category scheme='http://www.blogger.com/atom/ns#' term='Microsoft licenses'/><category scheme='http://www.blogger.com/atom/ns#' term='Windows Internal Database'/><title type='text'>The cheapest option to deploy Windows SharePoint Service solution for external users</title><content type='html'>Recently, we were estimating a solution for our customers. They want a Sharepoint (WSS 3.0) solution to be installed on a dedicated server and then used by their 100+ employees (they do not want to install a box in their own domain because don't want to bear additional administrative expenses, and don't want to pay too much for hardware, while renting a dedicated server will let them safely starts with small monthly payments for the hardware.&lt;br /&gt;&lt;br /&gt;We were to find the cheapest solution with as less licensing costs as possible&lt;br /&gt;&lt;br /&gt;The licensing politics of the Microsoft is very tricky. :) First of all, they recommend Windows Server Web Edition for front end servers. It has no limits in number of users. It costs only approx. 500$. However it is not suited for WSS deployment well, because you cannot install any database except MS SQL Express there. And SQL Express is limited with 4G, but our customer expects to have more then 100 Gb of documents in WSS document libraries.&lt;br /&gt;&lt;br /&gt;Well so we though we will have to use SQL Workgroup Edition (to store more then 4Gb) and that means that we need to use Windows Server Standard Edition. We have 100 users, so per-user licensing model of SQL Server is not good for us, but per processor license is also not very cheap. And what if we have 2 processors...&lt;br /&gt;&lt;br /&gt;Hopefully, I find the solution &lt;a href="http://social.technet.microsoft.com/Forums/en-US/sharepointadmin/thread/59a2b088-3147-421e-adb4-c2bf2d725d71"&gt;that post &lt;/a&gt;. It tells that Windows Internal Database, that is automatically installed when you install WSS in basic mode, is actually a special version of MS SQL Express with &lt;span style="font-weight: bold;"&gt;no memory limitation&lt;/span&gt; !&lt;br /&gt;&lt;br /&gt;So, we proceed with installing Windows Server Standard Edition (costs approx. 1000$) and that should be enough to deploy WSS solution on one box, using Basic setup option.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/6525302577308628916-6566749898196752203?l=bogdandotnet.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://bogdandotnet.blogspot.com/feeds/6566749898196752203/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=6525302577308628916&amp;postID=6566749898196752203' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/6525302577308628916/posts/default/6566749898196752203'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/6525302577308628916/posts/default/6566749898196752203'/><link rel='alternate' type='text/html' href='http://bogdandotnet.blogspot.com/2009/05/cheapest-option-to-deploy-windows.html' title='The cheapest option to deploy Windows SharePoint Service solution for external users'/><author><name>Bogdan Chernyachuk</name><uri>http://www.blogger.com/profile/09091829339994105257</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='28' height='32' src='http://bp1.blogger.com/_gJkSPqzmaQA/R9eTVo7ynCI/AAAAAAAAAyo/UliQCi_C1Hs/S220/c-moscow_small.JPG'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-6525302577308628916.post-3899738729958857486</id><published>2009-04-07T09:45:00.000-07:00</published><updated>2009-04-07T10:13:11.378-07:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='Array'/><category scheme='http://www.blogger.com/atom/ns#' term='.NET'/><category scheme='http://www.blogger.com/atom/ns#' term='Initialization'/><category scheme='http://www.blogger.com/atom/ns#' term='F#'/><category scheme='http://www.blogger.com/atom/ns#' term='Mutidimensional'/><title type='text'>Multi-dimensional arrays vs arrays of arrays in F#</title><content type='html'>Recently, I had to write a module with some array-manipulation functionality, and I decided to write it on F#&lt;br /&gt;&lt;br /&gt;I had an array initialization function, something like this&lt;br /&gt;&lt;br /&gt;&lt;span style="font-family: courier new;"&gt;let size = 100&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family: courier new;"&gt;let create_empty_array() = Array.create size (Array.create size 0)&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;Actually I meant to create an array of arrays initialized with zero.  :)&lt;br /&gt;But then I found that I have a lot of bugs with the functions that use that array.  What an idiot I was when I was writing this!&lt;br /&gt;Of course it will not work, because this code doesn't create 100 arrays of arrays, it actually initializes 1 array int[100] and then creates &lt;span style="font-weight: bold;"&gt;100 references to the same array&lt;/span&gt;.&lt;br /&gt;&lt;br /&gt;So I have to change it for the following&lt;br /&gt;&lt;br /&gt;&lt;span style="font-family: courier new;"&gt;let create_empty_array() = Array.init size (fun i -&gt; Array.create size 0)&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;The difference is that init function is evaluated value (using lambda expression) for each row, so it will really initialize 100 arrays of 100 integers&lt;br /&gt;&lt;br /&gt;If you will use multidimensional arrays (instead of arrays of arrays) you will find that it will more convenient to use Array2 class (for 2-dimensional arrays) or Array3 (for 3-dimentional)...&lt;br /&gt;&lt;br /&gt;&lt;span style="font-family: courier new;"&gt;let create_empty_array() = Array2.create size size 0&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;So what will you prefer - multidimensional arrays or arrays of arrays?&lt;br /&gt;&lt;br /&gt;In my case I use arrays of arrays only to simplify multithreading processing if the need of it will arise in the future. I have a function that takes one row of array for some long-running processing, and I can run several threads to process rows in parallel (currently my function is not working &lt;span style="font-style: italic;"&gt;that &lt;/span&gt;long, so it is only an imaginary scenario :) )&lt;br /&gt;&lt;br /&gt;For those who is interested in some intorduction to arrays in F#, I will recommend the following post &lt;a href="http://mariusbancila.ro/blog/?p=109"&gt;http://mariusbancila.ro/blog/?p=109&lt;/a&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/6525302577308628916-3899738729958857486?l=bogdandotnet.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://bogdandotnet.blogspot.com/feeds/3899738729958857486/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=6525302577308628916&amp;postID=3899738729958857486' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/6525302577308628916/posts/default/3899738729958857486'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/6525302577308628916/posts/default/3899738729958857486'/><link rel='alternate' type='text/html' href='http://bogdandotnet.blogspot.com/2009/04/multi-dimensional-arrays-vs-arrays-of.html' title='Multi-dimensional arrays vs arrays of arrays in F#'/><author><name>Bogdan Chernyachuk</name><uri>http://www.blogger.com/profile/09091829339994105257</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='28' height='32' src='http://bp1.blogger.com/_gJkSPqzmaQA/R9eTVo7ynCI/AAAAAAAAAyo/UliQCi_C1Hs/S220/c-moscow_small.JPG'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-6525302577308628916.post-6324720576500797858</id><published>2009-03-26T06:14:00.000-07:00</published><updated>2009-03-30T08:19:07.029-07:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='ASP.NET'/><category scheme='http://www.blogger.com/atom/ns#' term='Kentico'/><category scheme='http://www.blogger.com/atom/ns#' term='CMS'/><category scheme='http://www.blogger.com/atom/ns#' term='Blog'/><title type='text'>Is there a really free full-functional blog in Kentico CMS (free edition)?</title><content type='html'>Really, if one will look at the &lt;a href="http://www.kentico.com/cms-asp-net-features/Feature-Matrix.aspx"&gt;http://www.kentico.com/cms-asp-net-features/Feature-Matrix.aspx&lt;/a&gt; to evaluate if Kentico CMS free edition is something that you can use for building a personal web site for your small non-profit organization, it will be clear that free edition contains only one blog. ok 1 blog will be enough for me, who cares, if our organization has only 10 people so let them use 1 common blog, that's all.&lt;br /&gt;&lt;br /&gt;But, the truth is that Blog for the free edition comes &lt;span style="font-weight: bold;"&gt;without front-end editors&lt;/span&gt; for Blog. To post a blog message, you have to log in to CMSDesk (it is a content administration console) and add a new blog there.&lt;br /&gt;&lt;br /&gt;I played with the blog page design trying to add a Edit Blog web part, but I got an error message saying that your license doesn't allow this.&lt;br /&gt;&lt;br /&gt;Actual reason for this license limitation is that blog editing is implemented with the User contributions module (see Kentico developer's guide, Blog Module, On-site management via User contributions).&lt;br /&gt;&lt;br /&gt;And, guess what, User contribution is not included neither in a Free edition nor in a profeccional one. So if you want to be your Blog a real blog, you will have to prepare 2K $ for an enterprise edition of Kentico.  Or find another free blog engine for you .NET site (for example, subtext)  :)&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/6525302577308628916-6324720576500797858?l=bogdandotnet.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://bogdandotnet.blogspot.com/feeds/6324720576500797858/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=6525302577308628916&amp;postID=6324720576500797858' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/6525302577308628916/posts/default/6324720576500797858'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/6525302577308628916/posts/default/6324720576500797858'/><link rel='alternate' type='text/html' href='http://bogdandotnet.blogspot.com/2009/03/is-there-really-free-full-functional.html' title='Is there a really free full-functional blog in Kentico CMS (free edition)?'/><author><name>Bogdan Chernyachuk</name><uri>http://www.blogger.com/profile/09091829339994105257</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='28' height='32' src='http://bp1.blogger.com/_gJkSPqzmaQA/R9eTVo7ynCI/AAAAAAAAAyo/UliQCi_C1Hs/S220/c-moscow_small.JPG'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-6525302577308628916.post-6556776074085254344</id><published>2008-08-19T06:12:00.000-07:00</published><updated>2008-08-19T06:35:46.610-07:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='ExecuteXmlReader'/><category scheme='http://www.blogger.com/atom/ns#' term='optimization'/><category scheme='http://www.blogger.com/atom/ns#' term='FOR XML'/><category scheme='http://www.blogger.com/atom/ns#' term='LINQ'/><title type='text'>Using Linq for SQL with FOR XML procedures</title><content type='html'>The problem is&lt;br /&gt;&lt;br /&gt;I have a stored procedure in MS SQL that ends with SELECT ... FOR XML, and formerly I used XmlReader to access the data from it (by calling SqlCommand.&lt;span class="identifier"&gt;ExecuteXmlReader&lt;/span&gt;())&lt;br /&gt;&lt;br /&gt;Now I'm trying to figure out how to access to this using LINQ&lt;br /&gt;With VS constructor I drag and drop this procedure into Linq To SQL data class designer.&lt;br /&gt;&lt;br /&gt;It creates something like that&lt;br /&gt;&lt;br /&gt; [Function(Name="dbo.my_Procedure")]&lt;br /&gt; public ISingleResult&lt;my_procedureresult&gt; my_Procedure([Parameter(Name="param1", DbType="VarChar(50)")] string param1, ... all other params)&lt;br /&gt; {&lt;br /&gt;      IExecuteResult result = this.ExecuteMethodCall(this, ((MethodInfo)   (MethodInfo.GetCurrentMethod())), param1, ... all other params);&lt;br /&gt;      return ((ISingleResult&lt;my_procedureresult&gt;)(result.ReturnValue));&lt;br /&gt; }&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;Strange thing that actually procedure returns not a sinlgle line but a collection of arbitrary broken XML source (I'm just wondering what parameter controls the size of each piece)&lt;br /&gt;&lt;br /&gt;So to put all XML together you need to create a stream (memory stream) or file and an XmlTextWriter object, opened over the stream and a code like that to select all parts of the XML&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;System.Collections.Generic.IEnumerable&lt;string&gt; rawXMLLines =&lt;br /&gt;                   (new &lt;/string&gt;&lt;/my_procedureresult&gt;my_Procedure&lt;my_procedureresult&gt;&lt;my_procedureresult&gt;DataContext()).my_Procedure(param1, ....)&lt;br /&gt;                   .Select(&lt;/my_procedureresult&gt;&lt;/my_procedureresult&gt;my_Procedure&lt;my_procedureresult&gt;&lt;my_procedureresult&gt; =&gt; &lt;/my_procedureresult&gt;&lt;/my_procedureresult&gt;my_Procedure&lt;my_procedureresult&gt;&lt;my_procedureresult&gt;.XML_F52E2B61_18A1_11d1_B105_00805F49916B);&lt;br /&gt;&lt;br /&gt;               foreach (string rawXML in rawXMLLines)&lt;br /&gt;               {&lt;br /&gt;                   writer.WriteRaw( rawXML );&lt;br /&gt;               }&lt;br /&gt;&lt;br /&gt;Well, not so much development work but...&lt;br /&gt;&lt;br /&gt;Seems, that we lost here the main advantage of the &lt;/my_procedureresult&gt;&lt;/my_procedureresult&gt;SELECT ... FOR XML clause - an ability to write Xml to the output stream directly from XmlReader (that we get from &lt;/my_procedureresult&gt;&lt;span class="identifier"&gt;ExecuteXmlReader&lt;/span&gt;()&lt;my_procedureresult&gt;) , which is the most effective way if you are working with large XML files.&lt;br /&gt;&lt;br /&gt;In the example, shown above, the results of the procedure is extracted by LINQ engine to the collection of strings before we start writing these strings one by one into output stream with XmlWriter.&lt;br /&gt;&lt;br /&gt;&lt;my_procedureresult&gt;&lt;my_procedureresult&gt;&lt;br /&gt;&lt;/my_procedureresult&gt;&lt;/my_procedureresult&gt;&lt;/my_procedureresult&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/6525302577308628916-6556776074085254344?l=bogdandotnet.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://bogdandotnet.blogspot.com/feeds/6556776074085254344/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=6525302577308628916&amp;postID=6556776074085254344' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/6525302577308628916/posts/default/6556776074085254344'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/6525302577308628916/posts/default/6556776074085254344'/><link rel='alternate' type='text/html' href='http://bogdandotnet.blogspot.com/2008/08/using-linq-for-sql-with-for-xml.html' title='Using Linq for SQL with FOR XML procedures'/><author><name>Bogdan Chernyachuk</name><uri>http://www.blogger.com/profile/09091829339994105257</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='28' height='32' src='http://bp1.blogger.com/_gJkSPqzmaQA/R9eTVo7ynCI/AAAAAAAAAyo/UliQCi_C1Hs/S220/c-moscow_small.JPG'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-6525302577308628916.post-5536308938806168241</id><published>2008-08-14T00:47:00.000-07:00</published><updated>2008-08-14T01:02:03.778-07:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='bug'/><category scheme='http://www.blogger.com/atom/ns#' term='alias'/><category scheme='http://www.blogger.com/atom/ns#' term='join'/><category scheme='http://www.blogger.com/atom/ns#' term='Oracle'/><category scheme='http://www.blogger.com/atom/ns#' term='table'/><title type='text'>Strange Oracle behaviour</title><content type='html'>In our project we have one very complicated query that involves 10 or more tables joined with left joins or inner joins&lt;br /&gt;&lt;br /&gt;IN EACH TABLE there was a field DELETED.&lt;br /&gt;&lt;br /&gt;Developer who writes a SQL query made a mistake forgetting to add an alias to the DELETED field in the following WHERE clause&lt;br /&gt;&lt;br /&gt;select ... &lt;br /&gt;from table1 t1 join table2 t2 on t1.table1_id = t2.table1_id etc...&lt;br /&gt;WHERE DELETED = 0&lt;br /&gt;&lt;br /&gt;and what was strange - there were no compilation errors, oracle executes that query but guess from what table it takes DELETED field? I don't know! But not from the first table :) This behaviour leads to the bug that was very hard to find, debug and correct. &lt;br /&gt;&lt;br /&gt;Finally when developer corrected where condition, it starts work as expected&lt;br /&gt;&lt;br /&gt;WHERE t1.DELETED = 0&lt;br /&gt;&lt;br /&gt;It is not the first case that makes me furrious about Oracle!&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/6525302577308628916-5536308938806168241?l=bogdandotnet.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://bogdandotnet.blogspot.com/feeds/5536308938806168241/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=6525302577308628916&amp;postID=5536308938806168241' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/6525302577308628916/posts/default/5536308938806168241'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/6525302577308628916/posts/default/5536308938806168241'/><link rel='alternate' type='text/html' href='http://bogdandotnet.blogspot.com/2008/08/strange-oracle-bahaviour.html' title='Strange Oracle behaviour'/><author><name>Bogdan Chernyachuk</name><uri>http://www.blogger.com/profile/09091829339994105257</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='28' height='32' src='http://bp1.blogger.com/_gJkSPqzmaQA/R9eTVo7ynCI/AAAAAAAAAyo/UliQCi_C1Hs/S220/c-moscow_small.JPG'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-6525302577308628916.post-2553191925412732929</id><published>2008-05-28T00:39:00.000-07:00</published><updated>2008-08-14T01:03:17.847-07:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='MS SQL'/><category scheme='http://www.blogger.com/atom/ns#' term='design patterns'/><category scheme='http://www.blogger.com/atom/ns#' term='LINQ'/><title type='text'>Architecture of .NET projects with LINQ</title><content type='html'>LINQ promises a lot of advantages and simplify most things that usually should be implemented in Data acess layer&lt;br /&gt;&lt;br /&gt;However, currently I can't find any suitable design patterns that can show how one can build a huge project (say 100+) tables avoiding copy-paste code.&lt;br /&gt;&lt;br /&gt;Recently, I found a post &lt;a href="http://www.codeproject.com/KB/aspnet/NTierApp_UsingLINQ.aspx"&gt;Building Multi-Tier Web Application in .NET 3.5 Framework Using LINQ to SQL&lt;/a&gt; but there is no answer to how to avoid a lot of copy-paste code.&lt;br /&gt;&lt;br /&gt;So, I think I should play more with that code, generic classes and new C# 3.0 language features...&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/6525302577308628916-2553191925412732929?l=bogdandotnet.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://bogdandotnet.blogspot.com/feeds/2553191925412732929/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=6525302577308628916&amp;postID=2553191925412732929' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/6525302577308628916/posts/default/2553191925412732929'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/6525302577308628916/posts/default/2553191925412732929'/><link rel='alternate' type='text/html' href='http://bogdandotnet.blogspot.com/2008/05/architecture-of-net-projects-with-linq.html' title='Architecture of .NET projects with LINQ'/><author><name>Bogdan Chernyachuk</name><uri>http://www.blogger.com/profile/09091829339994105257</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='28' height='32' src='http://bp1.blogger.com/_gJkSPqzmaQA/R9eTVo7ynCI/AAAAAAAAAyo/UliQCi_C1Hs/S220/c-moscow_small.JPG'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-6525302577308628916.post-4192655705417704704</id><published>2008-03-19T07:21:00.000-07:00</published><updated>2008-03-19T08:47:09.845-07:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='Visual Studio 2005'/><category scheme='http://www.blogger.com/atom/ns#' term='Data entity'/><category scheme='http://www.blogger.com/atom/ns#' term='Stringly-typed dataset'/><category scheme='http://www.blogger.com/atom/ns#' term='Transaction'/><title type='text'>Using Transactions with Strongly Typed datasets</title><content type='html'>Strongly typed datasets , generated by Visual Studio 2005 have a lot of disadvantages and developer of a real-world application usually have to write a lot of additional code in order to use them.&lt;br /&gt;&lt;br /&gt;One of the issues - you cannot use SqlTransaction object with auto-generated datasets unless you write some additional code in partial classes of data adapters. Surprisingly, most .NET developers even don't care about that. But if you develop dataset composed of several tables that together mean one business entity, one may expect that if any exception during update of this entity happens, all changes should be rolled back, otherwise you may get inconsistent data.&lt;br /&gt;&lt;br /&gt;In my example I created a Windows Console Application in VS 2005 C#. Then using database explorer connected to AdventureWorks database (that comes with MS SQL Server 2005 examples) created a dataset with the tables Customer (mapped to Sales.Customer), Address (mapped to Person.Customer) and CustomerAddress (mapped to Sales.CustomerAddress)&lt;br /&gt;&lt;br /&gt;Supposing that I will have a form on UI where I want to edit customer's data and customer's addresses as well. It is not so unusual scenario, and I naturally will want to save all this in one transaction.&lt;br /&gt;&lt;br /&gt;In order to do this I have to created a partial classes for all table adapters to make transaction property available to set from an external class, i.e.:&lt;br /&gt;&lt;br /&gt;namespace TestDatasetTransaction.CustomerDataSetTableAdapters&lt;br /&gt;{&lt;br /&gt;    partial class CustomerTableAdapter&lt;br /&gt;    {&lt;br /&gt;        public void SetTransaction(SqlTransaction tran)&lt;br /&gt;        {&lt;br /&gt;            this._adapter.UpdateCommand.Transaction = tran;&lt;br /&gt;            this._adapter.InsertCommand.Transaction = tran;&lt;br /&gt;            this._adapter.DeleteCommand.Transaction = tran;&lt;br /&gt;        }&lt;br /&gt;    }&lt;br /&gt;&lt;br /&gt;    partial class AddressTableAdapter&lt;br /&gt;    {&lt;br /&gt;        public void SetTransaction(SqlTransaction tran)&lt;br /&gt;        {&lt;br /&gt;            this._adapter.UpdateCommand.Transaction = tran;&lt;br /&gt;            this._adapter.InsertCommand.Transaction = tran;&lt;br /&gt;            this._adapter.DeleteCommand.Transaction = tran;&lt;br /&gt;        }&lt;br /&gt;    }&lt;br /&gt;&lt;br /&gt;    partial class CustomerAddressTableAdapter&lt;br /&gt;    {&lt;br /&gt;        public void SetTransaction(SqlTransaction tran)&lt;br /&gt;        {&lt;br /&gt;            this._adapter.UpdateCommand.Transaction = tran;&lt;br /&gt;            this._adapter.InsertCommand.Transaction = tran;&lt;br /&gt;            this._adapter.DeleteCommand.Transaction = tran;&lt;br /&gt;        }&lt;br /&gt;    }&lt;br /&gt;}&lt;br /&gt;&lt;br /&gt;in Visual Studio designer I created a &lt;br /&gt;&lt;br /&gt;then I wrote the following code in the console's main class to prove that transactions really works.&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;using System;&lt;br /&gt;using System.Collections.Generic;&lt;br /&gt;using System.Text;&lt;br /&gt;using System.Data.SqlClient;&lt;br /&gt;&lt;br /&gt;namespace TestDatasetTransaction&lt;br /&gt;{&lt;br /&gt;    class Program&lt;br /&gt;    {&lt;br /&gt;        static void Main(string[] args)&lt;br /&gt;        {&lt;br /&gt;            int customerID = 1;&lt;br /&gt;&lt;br /&gt;            CustomerDataSet customer = new CustomerDataSet();&lt;br /&gt;&lt;br /&gt;            //fill all records in CustomerDataSet with data for one customer&lt;br /&gt;            CustomerDataSetTableAdapters.CustomerTableAdapter customerTableAdapter = new CustomerDataSetTableAdapters.CustomerTableAdapter();&lt;br /&gt;            customerTableAdapter.FillByCustomerID(customer.Customer, customerID);&lt;br /&gt;&lt;br /&gt;            CustomerDataSetTableAdapters.AddressTableAdapter addressTableAdapter = new CustomerDataSetTableAdapters.AddressTableAdapter();&lt;br /&gt;            addressTableAdapter.FillByCustomerID(customer.Address, customerID);&lt;br /&gt;&lt;br /&gt;            CustomerDataSetTableAdapters.CustomerAddressTableAdapter customerAddressTableAdapter = new CustomerDataSetTableAdapters.CustomerAddressTableAdapter();&lt;br /&gt;            customerAddressTableAdapter.FillByCustomerID(customer.CustomerAddress, customerID);&lt;br /&gt;&lt;br /&gt;            Console.WriteLine("Current Customer's ModifiedDate is : {0:g}", customer.Customer[0].ModifiedDate);&lt;br /&gt;&lt;br /&gt;            //make some changes&lt;br /&gt;            //this change is valid&lt;br /&gt;            customer.Customer[0].ModifiedDate = DateTime.Now;&lt;br /&gt;            Console.WriteLine("Will change Customer's  ModifiedDate to : {0:g}", customer.Customer[0].ModifiedDate);&lt;br /&gt;&lt;br /&gt;            //this change is not valid, sql server will not accept such date&lt;br /&gt;            customer.Address[0].ModifiedDate = DateTime.MinValue;&lt;br /&gt;            Console.WriteLine("Will change Address ModifiedDate to : {0:g}", customer.Address[0].ModifiedDate);&lt;br /&gt;&lt;br /&gt;            &lt;br /&gt;&lt;br /&gt;            using (SqlConnection conn = new SqlConnection(&lt;br /&gt;                TestDatasetTransaction.Properties.Settings.Default.AdventureWorksConnectionString))&lt;br /&gt;            {&lt;br /&gt;                conn.Open();&lt;br /&gt;                SqlTransaction tran = null;&lt;br /&gt;                try&lt;br /&gt;                {&lt;br /&gt;                    tran = conn.BeginTransaction();&lt;br /&gt;&lt;br /&gt;                    customerTableAdapter.Connection = conn;&lt;br /&gt;                    addressTableAdapter.Connection = conn;&lt;br /&gt;                    customerAddressTableAdapter.Connection = conn;&lt;br /&gt;&lt;br /&gt;                    customerTableAdapter.SetTransaction(tran);&lt;br /&gt;                    addressTableAdapter.SetTransaction(tran);&lt;br /&gt;                    customerAddressTableAdapter.SetTransaction(tran);&lt;br /&gt;&lt;br /&gt;                    customerTableAdapter.Update(customer);&lt;br /&gt;                    addressTableAdapter.Update(customer);&lt;br /&gt;                    customerAddressTableAdapter.Update(customer);&lt;br /&gt;&lt;br /&gt;                    tran.Commit();&lt;br /&gt;&lt;br /&gt;                }&lt;br /&gt;                catch (Exception ex)&lt;br /&gt;                {&lt;br /&gt;                    if (tran != null) tran.Rollback();&lt;br /&gt;                    Console.WriteLine(ex.Message);&lt;br /&gt;                }&lt;br /&gt;                tran.Dispose();&lt;br /&gt;&lt;br /&gt;                customerTableAdapter.FillByCustomerID(customer.Customer, customerID);&lt;br /&gt;            &lt;br /&gt;&lt;br /&gt;                conn.Close();&lt;br /&gt;            }&lt;br /&gt;&lt;br /&gt;            Console.WriteLine("Finally Customer's ModifiedDate is : {0:g}", customer.Customer[0].ModifiedDate);&lt;br /&gt;            Console.WriteLine();&lt;br /&gt;            Console.WriteLine("Press a key");&lt;br /&gt;            Console.ReadKey();&lt;br /&gt;&lt;br /&gt;        }&lt;br /&gt;    }&lt;br /&gt;}&lt;br /&gt;&lt;br /&gt;-------------&lt;br /&gt;&lt;br /&gt;The console output was respectivly&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;Current Customer's ModifiedDate is : 19.03.2008 17:16&lt;br /&gt;Will change Customer's  ModifiedDate to : 19.03.2008 17:33&lt;br /&gt;Will change Address ModifiedDate to : 01.01.0001 0:00&lt;br /&gt;Over SqlDateTime. Should be from 1/1/1753 12:00:00 AM to&lt;br /&gt; 12/31/9999 11:59:59 PM.&lt;br /&gt;Finally Customer's ModifiedDate is : 19.03.2008 17:16&lt;br /&gt;Press a key&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;------------&lt;br /&gt;&lt;br /&gt;So, the transaction really works, and because of an exception happened during update of the 2nd table, all changes made to the first table was rolled back.&lt;br /&gt;&lt;br /&gt;Of course the more simple solution is to use the TransactionScope() object from System.Transaction.dll, however this will not work on all platforms and databases. Also it seems, that an internal mechanism that exist in System.Transaction that is responsible for transparent (from developer's point of view) transaction enlisting from different resource managers should have affect on performance. If I will have some time, I will try to make a small performance test comparing TransactionScope() and SqlTransaction later...&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/6525302577308628916-4192655705417704704?l=bogdandotnet.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://bogdandotnet.blogspot.com/feeds/4192655705417704704/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=6525302577308628916&amp;postID=4192655705417704704' title='3 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/6525302577308628916/posts/default/4192655705417704704'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/6525302577308628916/posts/default/4192655705417704704'/><link rel='alternate' type='text/html' href='http://bogdandotnet.blogspot.com/2008/03/using-transactions-with-strongly-typed.html' title='Using Transactions with Strongly Typed datasets'/><author><name>Bogdan Chernyachuk</name><uri>http://www.blogger.com/profile/09091829339994105257</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='28' height='32' src='http://bp1.blogger.com/_gJkSPqzmaQA/R9eTVo7ynCI/AAAAAAAAAyo/UliQCi_C1Hs/S220/c-moscow_small.JPG'/></author><thr:total>3</thr:total></entry><entry><id>tag:blogger.com,1999:blog-6525302577308628916.post-7843418674684779847</id><published>2008-03-13T01:04:00.000-07:00</published><updated>2008-03-13T05:00:33.078-07:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='Gamma correction'/><category scheme='http://www.blogger.com/atom/ns#' term='C#'/><category scheme='http://www.blogger.com/atom/ns#' term='Image'/><category scheme='http://www.blogger.com/atom/ns#' term='JPEG'/><title type='text'>Applying Gamma correction  to an Image</title><content type='html'>Recently, one of my tasks was to apply non-linear gamma correction to JPEG image. Using  .NET Framework 2.0 System.Drawing.Imaging library one can reach this target quickly, however there is one big notice about working with JPEGs: Never do any transformations with JPEG images, first confert them to 32 bit Argb! If you pbey this, you may catch System.OutOfMemoryException. Also I was found in one post (can't find that link... :( ) that this format is also most efficient in terms of performance...&lt;br /&gt;&lt;br /&gt;&lt;blockquote&gt;&lt;br /&gt;      public static Bitmap CorrectGamma(Image source, decimal gamma)&lt;br /&gt;      {&lt;br /&gt;   Bitmap intermediate = new Bitmap(source.Width, source.Height,       PixelFormat.Format32bppPArgb);&lt;br /&gt;&lt;br /&gt;   // Create an ImageAttributes object and set the gamma&lt;br /&gt;   ImageAttributes imageAttr = new ImageAttributes();&lt;br /&gt;   imageAttr.SetGamma(Convert.ToSingle(gamma));&lt;br /&gt;    &lt;br /&gt;   Rectangle rect = new Rectangle(0, 0, source.Width, source.Height);&lt;br /&gt;   using (Graphics g = Graphics.FromImage(intermediate))&lt;br /&gt;   {&lt;br /&gt;       g.DrawImage(source, rect, 0, 0, source.Width, source.Height, GraphicsUnit.Pixel);&lt;br /&gt;   }&lt;br /&gt;&lt;br /&gt;   Bitmap corrected = new Bitmap(source.Width, source.Height,             PixelFormat.Format32bppPArgb);&lt;br /&gt;   using (Graphics g = Graphics.FromImage(corrected))&lt;br /&gt;   {&lt;br /&gt;       g.DrawImage(intermediate, rect, 0, 0, intermediate.Width, intermediate.Height,         GraphicsUnit.Pixel, imageAttr);&lt;br /&gt;   }&lt;br /&gt;&lt;br /&gt;   intermediate.Dispose();&lt;br /&gt;   return corrected;&lt;br /&gt;&lt;br /&gt;      }&lt;br /&gt;&lt;br /&gt;&lt;/blockquote&gt;&lt;br /&gt;&lt;br /&gt;It is essential that image is transformed once from JPEG to Format32bppPArgb (I described this in &lt;a href="http://bogdandotnet.blogspot.com/2008/03/converting-jpeg-to-bmp-and-other-issues.html"&gt;another post&lt;/a&gt;) and only after that it is transfomed second time, applying ImageAttributes. Doing both at one time will cause OutOfMemoryException, but of course you can try this out for yourself :)&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/6525302577308628916-7843418674684779847?l=bogdandotnet.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://bogdandotnet.blogspot.com/feeds/7843418674684779847/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=6525302577308628916&amp;postID=7843418674684779847' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/6525302577308628916/posts/default/7843418674684779847'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/6525302577308628916/posts/default/7843418674684779847'/><link rel='alternate' type='text/html' href='http://bogdandotnet.blogspot.com/2008/03/applying-gamma-correction-to-image.html' title='Applying Gamma correction  to an Image'/><author><name>Bogdan Chernyachuk</name><uri>http://www.blogger.com/profile/09091829339994105257</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='28' height='32' src='http://bp1.blogger.com/_gJkSPqzmaQA/R9eTVo7ynCI/AAAAAAAAAyo/UliQCi_C1Hs/S220/c-moscow_small.JPG'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-6525302577308628916.post-7172002325220578847</id><published>2008-03-12T01:04:00.000-07:00</published><updated>2008-03-12T01:44:23.086-07:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='Convert'/><category scheme='http://www.blogger.com/atom/ns#' term='.NET'/><category scheme='http://www.blogger.com/atom/ns#' term='Image'/><category scheme='http://www.blogger.com/atom/ns#' term='Bitmap'/><category scheme='http://www.blogger.com/atom/ns#' term='JPEG'/><title type='text'>Converting JPEG to BMP and other issues with Graphics</title><content type='html'>I was wondering why it is so difficult to find an easy solution using .NET Fremework 2.0 to convert  JPEG  image  into  BMP format (why there is a tone of examples to do BMP to JPEG convertion)&lt;br /&gt;&lt;br /&gt;So here is my C# code, may be someone will find it helpfull&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;       public static Image ConvertToBMP(Image source)&lt;br /&gt;       {&lt;br /&gt;           Bitmap result = new Bitmap(source.Width, source.Height, PixelFormat.Format32bppPArgb);&lt;br /&gt;&lt;br /&gt;           Rectangle rect = new Rectangle(0, 0, source.Width, source.Height);&lt;br /&gt;           using (Graphics g = Graphics.FromImage(result))&lt;br /&gt;           {&lt;br /&gt;               g.DrawImage(source, rect, 0, 0, source.Width, source.Height, GraphicsUnit.Pixel);&lt;br /&gt;           }&lt;br /&gt;&lt;br /&gt;           return result;&lt;br /&gt;&lt;br /&gt;       }&lt;br /&gt;&lt;br /&gt;I didn't tested yet this for all image types, however for JPEG it works :)&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/6525302577308628916-7172002325220578847?l=bogdandotnet.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://bogdandotnet.blogspot.com/feeds/7172002325220578847/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=6525302577308628916&amp;postID=7172002325220578847' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/6525302577308628916/posts/default/7172002325220578847'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/6525302577308628916/posts/default/7172002325220578847'/><link rel='alternate' type='text/html' href='http://bogdandotnet.blogspot.com/2008/03/converting-jpeg-to-bmp-and-other-issues.html' title='Converting JPEG to BMP and other issues with Graphics'/><author><name>Bogdan Chernyachuk</name><uri>http://www.blogger.com/profile/09091829339994105257</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='28' height='32' src='http://bp1.blogger.com/_gJkSPqzmaQA/R9eTVo7ynCI/AAAAAAAAAyo/UliQCi_C1Hs/S220/c-moscow_small.JPG'/></author><thr:total>0</thr:total></entry></feed>
