<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0"
	xmlns:content="http://purl.org/rss/1.0/modules/content/"
	xmlns:wfw="http://wellformedweb.org/CommentAPI/"
	xmlns:dc="http://purl.org/dc/elements/1.1/"
	xmlns:atom="http://www.w3.org/2005/Atom"
	xmlns:sy="http://purl.org/rss/1.0/modules/syndication/"
	xmlns:slash="http://purl.org/rss/1.0/modules/slash/"
	>

<channel>
	<title>Sam Beauvois &#187; ADO.NET</title>
	<atom:link href="http://www.sambeauvois.be/blog/category/ado_net/feed/" rel="self" type="application/rss+xml" />
	<link>http://www.sambeauvois.be/blog</link>
	<description>general dev, .net and other stuff</description>
	<lastBuildDate>Tue, 31 Jan 2012 13:38:32 +0000</lastBuildDate>
	<language>en</language>
	<sy:updatePeriod>hourly</sy:updatePeriod>
	<sy:updateFrequency>1</sy:updateFrequency>
	<generator>http://wordpress.org/?v=3.1</generator>
		<item>
		<title>Bring a bit of the Subsonic power to Entity Framework by adding automatic audit and logical delete fields</title>
		<link>http://www.sambeauvois.be/blog/2011/11/bring-a-bit-of-the-subsonic-power-to-entity-framework-by-adding-automatic-audit-and-logical-delete-fields/</link>
		<comments>http://www.sambeauvois.be/blog/2011/11/bring-a-bit-of-the-subsonic-power-to-entity-framework-by-adding-automatic-audit-and-logical-delete-fields/#comments</comments>
		<pubDate>Fri, 04 Nov 2011 16:04:07 +0000</pubDate>
		<dc:creator>admin</dc:creator>
				<category><![CDATA[.NET]]></category>
		<category><![CDATA[ADO.NET]]></category>
		<category><![CDATA[Productivity]]></category>
		<category><![CDATA[SubSonic]]></category>
		<category><![CDATA[Uncategorized]]></category>

		<guid isPermaLink="false">http://www.sambeauvois.be/blog/?p=915</guid>
		<description><![CDATA[Here is the code to do the same thing than in my previous article &#8220;Bring a bit of the Subsonic power to Linq to sql by adding automatic audit and logical delete fields&#8221; namespace YouNamespace.DAL { using System; using System.Collections; using System.Collections.Generic; using System.Collections.ObjectModel; using System.Data; using System.Data.Common; using System.Data.Objects; using System.Linq; public partial class [...]]]></description>
			<content:encoded><![CDATA[<p>Here is the code to do the same thing than in my previous article <a href="http://www.sambeauvois.be/blog/2010/09/bring-a-bit-of-the-subsonic-power-to-linq-to-sql-by-adding-automatic-audit-and-logical-delete-fields/" target="_blank">&#8220;Bring a bit of the Subsonic power to Linq to sql by adding automatic audit and logical delete fields&#8221;</a></p>
<pre class="brush: csharp; title: ;">

namespace YouNamespace.DAL
{
 using System;
 using System.Collections;
 using System.Collections.Generic;
 using System.Collections.ObjectModel;
 using System.Data;
 using System.Data.Common;
 using System.Data.Objects;
 using System.Linq;

 public partial class YOURCONTEXTEntities
 {
 /// &lt;summary&gt;
 /// System fields for automatic audit and logical delete
 /// &lt;/summary&gt;
 private struct SystemFields
 {
 public const string CreatedOn = &quot;CREATEDON&quot;;
 public const string ModifiedOn = &quot;MODIFIEDON&quot;;
 public const string CreatedBy = &quot;CREATEDBY&quot;;
 public const string ModifiedBy = &quot;MODIFIEDBY&quot;;
 public const string IsDeleted = &quot;ISDELETED&quot;;
 }

 /// &lt;summary&gt;
 /// Overriding the SaveChanges method to automaticaly set system fields if any.
 /// &lt;/summary&gt;
 /// &lt;param name=&quot;options&quot;&gt;&lt;/param&gt;
 /// &lt;returns&gt;&lt;/returns&gt;
 public override int SaveChanges(System.Data.Objects.SaveOptions options)
 {
 IEnumerable&lt;ObjectStateEntry&gt; newEntries = this.ObjectStateManager.GetObjectStateEntries(EntityState.Added);

 foreach (ObjectStateEntry entry in newEntries)
 {
 ReadOnlyCollection&lt;FieldMetadata&gt; fieldsMetaData = entry.CurrentValues
 .DataRecordInfo.FieldMetadata;

 FieldMetadata createdOnField = fieldsMetaData
 .Where(f =&gt; string.Equals(f.FieldType.Name, SystemFields.CreatedOn, StringComparison.OrdinalIgnoreCase)).FirstOrDefault();

 if (createdOnField.FieldType != null)
 {
 entry.CurrentValues.SetValue(createdOnField.Ordinal, DateTime.Now);
 }

 FieldMetadata createdByField = fieldsMetaData
 .Where(f =&gt; string.Equals(f.FieldType.Name, SystemFields.CreatedBy, StringComparison.OrdinalIgnoreCase)).FirstOrDefault();

 if (createdByField.FieldType != null)
 {
 entry.CurrentValues.SetValue(createdByField.Ordinal, &quot;Sam&quot;);
 }

 FieldMetadata deletedField = fieldsMetaData
 .Where(f =&gt; string.Equals(f.FieldType.Name, SystemFields.IsDeleted, StringComparison.OrdinalIgnoreCase)).FirstOrDefault();

 if (deletedField.FieldType != null)
 {
 entry.CurrentValues.SetValue(deletedField.Ordinal, false);
 }
 }

 IEnumerable&lt;ObjectStateEntry&gt; modifiedEntries = this.ObjectStateManager.GetObjectStateEntries(EntityState.Modified);
 foreach (ObjectStateEntry entry in modifiedEntries)
 {
 ReadOnlyCollection&lt;FieldMetadata&gt; fieldsMetaData = entry.CurrentValues
 .DataRecordInfo.FieldMetadata;

 FieldMetadata createdOnField = fieldsMetaData
 .Where(f =&gt; string.Equals(f.FieldType.Name, SystemFields.ModifiedOn, StringComparison.OrdinalIgnoreCase)).FirstOrDefault();

 if (createdOnField.FieldType != null)
 {
 entry.CurrentValues.SetValue(createdOnField.Ordinal, DateTime.Now);
 }

 FieldMetadata createdByField = fieldsMetaData
 .Where(f =&gt; string.Equals(f.FieldType.Name, SystemFields.ModifiedBy, StringComparison.OrdinalIgnoreCase)).FirstOrDefault();

 if (createdByField.FieldType != null)
 {
 entry.CurrentValues.SetValue(createdByField.Ordinal, &quot;Sam&quot;);
 }
 }

 IEnumerable&lt;ObjectStateEntry&gt; deletedEntries = this.ObjectStateManager.GetObjectStateEntries(EntityState.Deleted);
 foreach (ObjectStateEntry entry in deletedEntries)
 {
 // change from deleted to modified (!important)
 this.ObjectStateManager.ChangeObjectState(entry.Entity, EntityState.Modified);

 ReadOnlyCollection&lt;FieldMetadata&gt; fieldsMetaData = entry.CurrentValues
 .DataRecordInfo.FieldMetadata;

 FieldMetadata deletedField = fieldsMetaData
 .Where(f =&gt; string.Equals(f.FieldType.Name, SystemFields.IsDeleted, StringComparison.OrdinalIgnoreCase)).FirstOrDefault();

 if (deletedField.FieldType != null)
 {
 entry.CurrentValues.SetValue(deletedField.Ordinal, true);
 }
else
 {
 // change back from modified to deleted (!important)
 this.ObjectStateManager.ChangeObjectState(entry.Entity, EntityState.Deleted);
 }
 }

 return base.SaveChanges(options);
 }
 }
}
</pre>
]]></content:encoded>
			<wfw:commentRss>http://www.sambeauvois.be/blog/2011/11/bring-a-bit-of-the-subsonic-power-to-entity-framework-by-adding-automatic-audit-and-logical-delete-fields/feed/</wfw:commentRss>
		<slash:comments>1</slash:comments>
		</item>
		<item>
		<title>Debugging ADO.NET Datatables</title>
		<link>http://www.sambeauvois.be/blog/2010/05/debugging-ado-net-datatables/</link>
		<comments>http://www.sambeauvois.be/blog/2010/05/debugging-ado-net-datatables/#comments</comments>
		<pubDate>Fri, 14 May 2010 13:32:54 +0000</pubDate>
		<dc:creator>Sam Beauvois</dc:creator>
				<category><![CDATA[.NET]]></category>
		<category><![CDATA[ADO.NET]]></category>
		<category><![CDATA[Debug]]></category>
		<category><![CDATA[Development]]></category>

		<guid isPermaLink="false">http://www.sambeauvois.be/blog/?p=246</guid>
		<description><![CDATA[Do you ever had the famous error message : &#8220;Failed to enable constraints. One or more rows  contain values violating non-null, unique, or foreign-key  constraints.&#8221; when using ADO.NET Datasets ? Tthis is an incredibly useful message isn&#8217;t it ? So what can you do to spare you some headaches ? Retrieve a more useful message [...]]]></description>
			<content:encoded><![CDATA[<p>Do you ever had the famous error message :</p>
<blockquote><p>&#8220;Failed to enable constraints. One or more rows  contain values violating non-null, unique, or foreign-key  constraints.&#8221;</p></blockquote>
<p>when using ADO.NET Datasets ?</p>
<p>Tthis is an incredibly useful message isn&#8217;t it ?</p>
<p>So what can you do to spare you some headaches ? Retrieve a more useful message sure !</p>
<p>You have to know that a Datatable object have a &#8220;HasError&#8221; property, this property allows you to know if the datatable has one ore more rows in error.</p>
<p>When HasError is true, you can retrieve the rows havin an error with the DataTable&#8217;s &#8220;GetErrors()&#8221; method wich return an array with all datarow having an error.</p>
<p>The &#8220;in errror&#8221; rows can inform you about errors with the &#8220;RowError&#8221; property.</p>
<p>Here is a simple helper class which can be used to debug a single DataTable or an entire DataSet:</p>
<pre class="brush: csharp; title: ;">
using System;
using System.Data;

public class DataSetErrorRevealer
{

   /// &lt;summary&gt;
   /// Get errors on rows of a DataTable
   /// &lt;/summary&gt;
   /// &lt;param name=&quot;errorDataTable&quot;&gt;The DataTable to be checked&lt;/param&gt;
   public static void RevealTableErrors(DataTable errorDataTable)
   {
      if (errorDataTable == null)
      {
         Console.WriteLine(&quot;The provided DataTable object is null&quot;);
         return;
      }

      if (errorDataTable.HasErrors)
      {
         DataRow[] rowsInError = errorDataTable.GetErrors();
         if (rowsInError.Length &lt;= 0)
         {
            Console.WriteLine(&quot;There is no problem with table {0}&quot;, errorDataTable.TableName);
         }
         else
         {
            foreach (DataRow errorRow in rowsInError)
            {
               Console.WriteLine(errorRow.RowError);
            }
         }
      }
   }

   /// &lt;summary&gt;
   /// Get errors on row for all tables of a DataSet
   /// &lt;/summary&gt;
   /// &lt;param name=&quot;errorDataSet&quot;&gt;The Dataset to be checked&lt;/param&gt;
   public static void RevealDataSetErrors(DataSet errorDataSet)
   {
         if (errorDataSet == null)
         {
            Console.WriteLine(&quot;The provided DataSet is null&quot;);
            return;
         }

         foreach (DataTable errorTable in errorDataSet.Tables)
         {
            RevealTableErrors(errorTable);
         }
      }
   }
</pre>
<p>Use it this way :</p>
<pre class="brush: csharp; title: ;">

   TestDataSet dataset = new TestDataSet();
   try
   {
      using (SqlConnection sqlCon = new SqlConnection(&quot;MyConnectionString&quot;))
      {
         SqlCommand sqlComm = sqlCon.CreateCommand();
         sqlComm.CommandType = CommandType.StoredProcedure;
         sqlComm.CommandText = &quot;Select Stored procedure&quot;;
         SqlDataAdapter sqlDa = new SqlDataAdapter(sqlComm);
         sqlDa.Fill(dataset);
      }
   }
   catch (Exception ex)
   {
   // Will provide the error message :
   // &quot;Failed to enable constraints. One or more rows
   // contain values violating non-null, unique,
   // or foreign-key  constraints.&quot;
   Console.WriteLine(&quot;Error : {0}&quot;, ex);

   // will provide a more helpful message
   DataSetErrorRevealer.RevealDataSetErrors(dataset);
   }
</pre>
<p>If you prefer, you can use an extension method :</p>
<pre class="brush: csharp; title: ;">

using System.Data;
using System;

public static class DataSetExtensions
{
   public static void RevealErrors(this DataSet errorDataSet)
   {
      if (errorDataSet == null)
      {
         Console.WriteLine(&quot;The provided DataSet is null&quot;);
         return;
      }

      foreach (DataTable errorTable in errorDataSet.Tables)
      {
         errorTable.RevealErrors();
      }
   }

   public static void RevealErrors(this DataTable errorDataTable)
   {
      if (errorDataTable == null)
      {
         Console.WriteLine(&quot;The provided DataTable object is null&quot;);
         return;
      }

      if (errorDataTable.HasErrors)
      {
         DataRow[] rowsInError = errorDataTable.GetErrors();
         if (rowsInError.Length &lt;= 0)
         {
            Console.WriteLine(&quot;There is no problem with table {0}&quot;, errorDataTable.TableName);
         }
         else
         {
            foreach (DataRow errorRow in rowsInError)
            {
               Console.WriteLine(errorRow.RowError);
            }
         }
      }
   }
}
</pre>
<p>use :</p>
<pre class="brush: csharp; title: ;">

catch (Exception ex)
{
   // will provide an helpful message
   dataset.RevealErrors();
}
</pre>
<p>Hope this helps !</p>
<div id="_mcePaste" style="position: absolute; left: -10000px; top: 211px; width: 1px; height: 1px; overflow: hidden;">using System;<br />
using System.Data;public class DataSetErrorRevealer<br />
{</p>
<p>/// &lt;summary&gt;<br />
/// Get errors on rows of a DataTable<br />
/// &lt;/summary&gt;<br />
/// &lt;param name=&#8221;errorDataTable&#8221;&gt;The DataTable to be checked&lt;/param&gt;<br />
public static void RevealTableErrors(DataTable errorDataTable)<br />
{<br />
if (errorDataTable == null)<br />
{<br />
Console.WriteLine(&#8220;The provided DataTable object is null&#8221;);<br />
return;<br />
}</p>
<p>if (errorDataTable.HasErrors)<br />
{<br />
DataRow[] rowsInError = errorDataTable.GetErrors();<br />
if (rowsInError.Length &lt;= 0)<br />
{<br />
Console.WriteLine(&#8220;There is no problem with table {0}&#8221;, errorDataTable.TableName);<br />
}<br />
else<br />
{<br />
foreach (DataRow errorRow in rowsInError)<br />
{<br />
Console.WriteLine(errorRow.RowError);<br />
}<br />
}<br />
}<br />
}</p>
<p>/// &lt;summary&gt;<br />
/// Get errors on row for all tables of a DataSet<br />
/// &lt;/summary&gt;<br />
/// &lt;param name=&#8221;errorDataSet&#8221;&gt;The Dataset to be checked&lt;/param&gt;<br />
public static void RevealDataSetErrors(DataSet errorDataSet)<br />
{<br />
if (errorDataSet == null)<br />
{<br />
Console.WriteLine(&#8220;The provided DataSet is null&#8221;);<br />
return;<br />
}</p>
<p>foreach (DataTable errorTable in errorDataSet.Tables)<br />
{<br />
RevealTableErrors(errorTable);<br />
}<br />
}<br />
}</p>
</div>
]]></content:encoded>
			<wfw:commentRss>http://www.sambeauvois.be/blog/2010/05/debugging-ado-net-datatables/feed/</wfw:commentRss>
		<slash:comments>1</slash:comments>
		</item>
	</channel>
</rss>

