Generic function to Find Duplicates in Generic List

I’ve created a new function to Find Duplicates in Generic List similar to Generic function to removeDuplicates from Generic List as well as bool AreValuesUnique.

<!–

.csharpcode{font-size: 10pt;color: black;font-family: Courier New , Courier, Monospace;background-color:Transparent;}.csharpcode pre { margin: 0px; }.rem { color: #008000; }.kwrd { color: #0000ff; }.str { color: #006080; }.op { color: #0000c0; }.preproc { color: #cc6633; }.asp { background-color: #ffff00; }.html { color: #800000; }.attr { color: #ff0000; }.alt{background-color: #f4f4f4;width: 100%;margin: 0px;}.lnum { color: #606060; }>

 public static List<GenericType> FindDuplicates<GenericType>(List<GenericType> inputList)
        {
            Dictionary<GenericType, int> uniqueStore = new Dictionary<GenericType, int>();
            List<GenericType> finalList = new List<GenericType>();
 
            foreach (GenericType currValue in inputList)
            {
                if (uniqueStore.ContainsKey(currValue))
                {
                    finalList.Add(currValue);
                }
                else
                {
                    uniqueStore.Add(currValue, 0);
                }
            }
            return finalList;
        }
     public static bool AreValuesUnique<GenericType>(List<GenericType> inputList)
        {
            foreach (GenericType currValue in inputList)
            {
                if (inputList.IndexOf(currValue) != inputList.LastIndexOf(currValue))
                    return false;
            }

EntitySpaces API: How to get esQueryItem column name.

In constructor columnName is passed as parameter.

public esQueryItem (
	esDynamicQuery query,
	string columnName
)
However I wasn't able to fint the property ColumnName or something similar.
After some time I understood, that they use implicit operator string
public static implicit operator string  (
	esQueryItem item
)
which does the magic.
However  the explicit read-Only property ColumnName will be useful.

By the way the help shows 2 different operators as the same
static memberImplicit(esQueryItem)
ToString() (to use in GroupBy/OrderBy and such ....)

static memberImplicit(esQueryItem)
ToString() (to use in GroupBy/OrderBy and such ....)

DataSetHelper Class that I am using

Previously I’ve posted a few Helper Classes . This post describes  DataSetHelper class, that mostly based on series of MSDN articles. However I did some modifications(e.g see posts DataSetHelper.SelectDistinct method for multiple columns and  “Handling missing source columns in DataSetHelper.InsertInto method” )

using System;
using System.Data;
using System.Data.SqlClient;
using System.Diagnostics;
using System.Collections;
using Microsoft.ApplicationBlocks.Data;
using System.Collections.Generic;
 
namespace FSHelperLib
{
      ///<summary>
      /// Created based on HOW TO: Implement a DataSet SELECT INTO Helper Class in Visual C# .NET
      ///</summary>
      public class DataSetHelper
      {
            public DataSet m_ds;
 
            public DataSetHelper(ref DataSet DataSet)
            {
                  m_ds = DataSet;
            }
            public DataSetHelper()
            {
                  m_ds = null;
            }
        private List<FieldInfo> m_FieldInfo;//System.Collections.ArrayList
        private string m_FieldList;
 
            public class FieldInfo
            {
                  public string RelationName;
                  public string FieldName;      //source table field name
                  public string FieldAlias;     //destination table field name
                  //public string Aggregate;
            }
            #region “private Helper methods”
            private void ParseFieldList(string FieldList, bool AllowRelation)
            {
                  /*
                   * This code parses FieldList into FieldInfo objects and then
                   * adds them to the m_FieldInfo private member.
                   *
                   * FieldList syntax: [relationname.]fieldname[ alias], …
                  */
                  if (m_FieldList == FieldList) return;
            m_FieldInfo = new List<FieldInfo>();// System.Collections.ArrayList();
                  m_FieldList = FieldList;
            m_FieldInfo=ParseToFieldInfoList(FieldList, AllowRelation);
            }
///<summary>
        ///              * FieldList syntax: [relationname.]fieldname[ [AS] alias], …
///</summary>
///<param name=”FieldList”></param>
///<param name=”AllowRelation”></param>
///<returns></returns>
        public static List<FieldInfo> ParseToFieldInfoList(string FieldList, bool AllowRelation)
        {
            // Doesn’t support parsing comticate function like the following “, Left(ma_compdate,10) as Closed,”
            List<FieldInfo> lstFieldInfo = new List<FieldInfo>();
            FieldInfo Field; string[] FieldParts;
            string[] Fields = FieldList.Split(‘,’);
            int i;
            for (i = 0; i <= Fields.Length – 1; i++)
            {
                Field = new FieldInfo();
                //Parse FieldAlias.
                FieldParts = Fields[i].Trim().Split(new char[] { ‘ ‘ }, StringSplitOptions.RemoveEmptyEntries);
                switch (FieldParts.Length)
                {
                    case 1:
                        //to be set at the end of the loop
                        break;
                    case 2:
                        Field.FieldAlias = FieldParts[1];
                        break;
                    default: //if more than 2 , it shoud ended with ” AS Alias “
                        if (FieldParts[FieldParts.Length-2].ToUpper().Trim() == “AS”)
                            Field.FieldAlias = FieldParts[FieldParts.Length – 1];
                        else
                            throw new Exception(“Too many parts in field definition: ‘” + Fields[i] + “‘.”);
                        break;
                }
                if (FieldParts.Length <= 3)
                {                    //Parse FieldName and RelationName.
                    FieldParts = FieldParts[0].Split(‘.’);
                    switch (FieldParts.Length)
                    {
                        case 1:
                            Field.FieldName = FieldParts[0];
                            break;
                        case 2:
                            if (AllowRelation == false)
                                throw new Exception(“Relation specifiers not permitted in field list: ‘” + Fields[i] + “‘.”);
                            Field.RelationName = FieldParts[0].Trim();
                            Field.FieldName = FieldParts[1].Trim();
                            break;
                        default:
                            throw new Exception(“Invalid field definition: “ + Fields[i] + “‘.”);
                    }
                }
                else //In case of calculated field (e.g. cl_Addr1 + cl_Addr2 + cl_Addr3 as Address)
                {
                  Field.FieldName= StringHelper.LeftBeforeLast(Fields[i].Trim().ToUpper() , ” AS “);//not always reliable
                }
                if (Field.FieldAlias == null)
                    Field.FieldAlias = Field.FieldName;
                lstFieldInfo.Add(Field);
            }
            return lstFieldInfo;
        }
            #endregion //”private Helper methods”
           
            #region “CreateTable,INSERTInto and SelectINTO”
            ///<summary>
            /// This code creates a DataTable and creates the fields (not specified types) in the
            ///   order that is specified in the FieldList.
            /// See Also CreateTable overload with SourceTable parameter />
            ///</summary>
            ///<example>
            /// Sample of call
            ///<code>dt = dsHelper.CreateTable(“TestTable”, “FirstName FName,LastName LName,BirthDate”);
            ///</code></example>
            public DataTable CreateTable(string TableName, string FieldList)
            {
                  /*
                  */
                  DataTable dt;
                  {
                        dt = new DataTable(TableName);
                        ParseFieldList(FieldList,false);
                        DataColumn dc;
                        foreach (FieldInfo Field in m_FieldInfo)
                        {
                              dc = new DataColumn(Field.FieldName);//not specified types
                              dt.Columns.Add(Field.FieldAlias, dc.DataType);
                        }
                  }
                  if (m_ds!=null)
                        m_ds.Tables.Add(dt);
                  return dt;
            }
            ///<summary>
            /// This code creates a DataTable by using the SourceTable as a template and creates the fields in the
            ///   order that is specified in the FieldList. If the FieldList is blank, the code uses DataTable.Clone().
            /// See Also CreateTable overload without SourceTable parameter />
            ///</summary>
            ///<example>
            /// Sample of call
            ///<code>dt = dsHelper.CreateTable(“TestTable”, ds.Tables[“Employees”], “FirstName FName,LastName LName,BirthDate”);
            ///</code></example>
            public DataTable CreateTable(string TableName, DataTable SourceTable, string FieldList)
            {
                  DataTable dt;
            if (FieldList.Trim() == “”)
            {
                dt = SourceTable.Clone();
                dt.TableName = TableName;
            }
            else
            {
                dt = new DataTable(TableName);
                ParseFieldList(FieldList, false);//not static
                DataColumn dc;
                foreach (FieldInfo Field in m_FieldInfo)
                {
                    dc = SourceTable.Columns[Field.FieldName];
                    dt.Columns.Add(Field.FieldAlias, dc.DataType);
                }
            }
            if (m_ds != null)
                        m_ds.Tables.Add(dt);
                  return dt;
            }
            ///<summary>
            /// Sample of call
            /// dsHelper.InsertInto(ds.Tables[“TestTable”], ds.Tables[“Employees”], “FirstName FName,LastName LName,BirthDate”, “EmployeeID&lt;5”, “BirthDate”) ;
            ///</summary>
            public void InsertInto(DataTable DestTable, DataTable SourceTable,
                  string FieldList, string RowFilter, string Sort)
            {
                  //
                  // This code copies the selected rows and columns from SourceTable and inserts them into DestTable.
                  //
                  ParseFieldList(FieldList, false);
                  DataRow[] Rows = SourceTable.Select(RowFilter, Sort);
                  DataRow DestRow;
                  foreach(DataRow SourceRow in Rows)
                  {
                        DestRow = DestTable.NewRow();
                        if (DataHelper.IsNullOrEmpty(FieldList))
                        {
                    foreach (DataColumn dc in DestRow.Table.Columns)
                    {
                        if (dc.Expression == “”)
                        {
                            if (SourceTable.Columns.Contains(dc.ColumnName))//source can miss some target columns
                                DestRow[dc] = SourceRow[dc.ColumnName];
                            else
                                DebugHelper.LineWithTrace(“The column is missing in the source:” + dc.ColumnName);
                        }
                    }
                        }
                        else
                        {
                              foreach(FieldInfo Field in m_FieldInfo)
                              {
                                    DestRow[Field.FieldAlias] = SourceRow[Field.FieldName];
                              }
                        }
                        DestTable.Rows.Add(DestRow);
                  }
            }
            //MNF 10/9/2004
            ///<summary>
            /// Sample of call
            /// dsHelper.ImportInto(sTestTable, rSourceRow) ;
            ///</summary>
            ///<returns>true if inserted, false if primary key is already in the table</returns>
            public bool ImportInto(string sDestTableName, DataRow rSourceRow)
            {
                  //
                  // This code copies the specified row and inserts it into DestTable.
                  //
                 
                  Debug.Assert(m_ds!=null);
                  DataTable tbl=m_ds.Tables[sDestTableName];
                  if (tbl==null)
                  { tbl=CreateTable(sDestTableName,rSourceRow.Table,“”);
                  }
            bool bRet=RowInTableExists( tbl, rSourceRow );
                  //DataColumn[] colKeys=tbl.PrimaryKey;
            //object[] keyValues=PrimaryKeyValues(rSourceRow);
 
//                if (tbl.Rows.Find(keyValues)==null)
                  if (bRet==false)
                  {
                        tbl.ImportRow(rSourceRow); //TODO can be change to use foreach as in InsertInto
//                      bRet=true;
                  }
            //else //already exists
            //    bRet=false;
                  return bRet;
            }
           
            ///<summary>
            /// Sample of call
            /// dt = dsHelper.SelectInto(“TestTable”, ds.Tables[“Employees”], “FirstName FName,LastName LName,BirthDate”, “EmployeeID&lt;5”, “BirthDate”) ;
            ///</summary>
            public DataTable SelectInto(string TableName, DataTable SourceTable,
                  string FieldList, string RowFilter, string Sort)
            {
                  /*
                   * This code selects values that are sorted and filtered from one DataTable into another.
                   * The FieldList specifies which fields are to be copied.
                  */
                  DataTable dt = CreateTable(TableName, SourceTable, FieldList);
                  InsertInto(dt, SourceTable, FieldList, RowFilter, Sort);
                  return dt;   
            }
            #region “SelectDistinct”
            //It is used to compare field values (including NULL).
            private static bool ColumnEqual(object A, object B)
            {
 
                  // Compares two values to see if they are equal. Also compares DBNULL.Value.
                  // Note: If your DataTable contains object fields, then you must extend this
                  // function to handle them in a meaningful way if you intend to group on them.
 
                  if ( A == DBNull.Value && B == DBNull.Value ) // both are DBNull.Value
                        return true;
                  if ( A == DBNull.Value || B == DBNull.Value ) // only one is DBNull.Value
                        return false;
                  return ( A.Equals(B) ); // value type standard comparison
            }
                             
 
      //    2. Add the following Public method to the class definition. This method copies unique values of the field that you select into a new DataTable. If the field contains NULL values, a record in the destination table will also contain NULL values.
            public DataTable SelectDistinct(string TableName, DataTable SourceTable, string FieldName)
            {
            DataTable dt = SelectDistinct(SourceTable, FieldName);
            dt.TableName = TableName;
                  if (m_ds != null)
                        m_ds.Tables.Add(dt);
                  return dt;
            }
 
        public static DataTable SelectDistinct(DataTable SourceTable, string FieldName)
        {
            DataTable dt = new DataTable();
            dt.Columns.Add(FieldName, SourceTable.Columns[FieldName].DataType);
 
            object LastValue = null;
            foreach (DataRow dr in SourceTable.Select(“”, FieldName))
            {
                if (LastValue == null || !(ColumnEqual(LastValue, dr[FieldName])))
                {
                    LastValue = dr[FieldName];
                    dt.Rows.Add(new object[] { LastValue });
                }
            }
            return dt;
        }
            public static DataTable SelectDistinct( DataTable SourceTable, string[] FieldNames)
            {// select distinct on multiple fields.
//From: Nageswara Reddy http://www.dotnet247.com/247reference/msgs/43/218182.aspx
            FieldNames = StringArrayHelper.ToLower(FieldNames);
            DataTable DistinctTable = SourceTable.Clone();
                  DataColumn [] constraintColumns = new DataColumn[FieldNames.Length];
            int nFound=0;
                  for (int i =0 ; i< DistinctTable.Columns.Count ; i++)
            {
                if (Array.IndexOf(FieldNames, DistinctTable.Columns[i].ColumnName.ToLower()) >= 0)
                {
                    if (nFound >= FieldNames.Length)
                    {
                        throw new ApplicationException(“Too many fields are similar to passed FieldNames “ + FieldNames.ToString());
                    }
                    constraintColumns[nFound++] = DistinctTable.Columns[i];
                }
                  }
            //Report if passed field names are not found in the table
            if (nFound < FieldNames.Length)
            {
                throw new ApplicationException(“Some of fields “ + FieldNames.ToString() + ” not found in the database”);
            }
                  UniqueConstraint _UniqueConstraint = new UniqueConstraint(constraintColumns);
                  DistinctTable.Constraints.Add(_UniqueConstraint);
 
                  for (int i =0 ; i< SourceTable.Rows.Count ; i++)
                  {
                        try
                        {
                              DistinctTable.ImportRow(SourceTable.Rows[i]);
                        }
                        catch(Exception ex)
                        { // Keep quite
                              Debug.WriteLine(ex.ToString());
                        }
                  }
                  return DistinctTable;
            }
      #endregion “SelectDistinct”
 
 
            //MNF 10/12/2004
            ///<summary>
            /// Merge consider merged items as new
        /// dsHelper.MergeAsNew(tblSource,      MissingSchemaAction.AddWithKey) ;
            ///</summary>
            ///<remarks> function clones source table to modify status of records as add </remarks>       
            ///<returns>true if inserted, false if primary key is already in the table</returns>
            public DataSet MergeAsNew( DataTable tblSource, MissingSchemaAction missingSchemaAction)
            {
                  Debug.Assert(m_ds!=null);
                  DataTable tblClone=tblSource.Clone();
                  InsertInto(tblClone, tblSource, “”,“”,“”);
                  bool preserveChanges=true;//hardcoded
                  m_ds.Merge(tblClone, preserveChanges,missingSchemaAction);
                  return m_ds;
            }
        ///<summary>
        /// The function expects that original table exist in the dataset.
        /// New records from tblToAdd will have DataRowState.Added and existing records will have DataRowState.Modified
        /// dsHelper.MergeAsNewOrModified(tblToAdd,   MissingSchemaAction) ;
        ///</summary>
        ///<remarks> function clones source table to modify status of records as add </remarks>       
        ///<returns>modified dataset
        /// Newly added rows are marked as insertions, and changes to existing rows are marked as modifications.
        ///</returns>
        public DataSet MergeAsNewOrModified(DataTable tblToAdd,MissingSchemaAction missingSchemaAction)
        {
                  Debug.Assert(m_ds!=null);
            string sTableName = tblToAdd.TableName;
            if (m_ds.Tables[sTableName] == null)
            {
                MergeAsNew(tblToAdd, missingSchemaAction);
            }
            else
            {
                DataTable tblOrig = m_ds.Tables[sTableName];
                foreach (DataRow rowToAdd in tblToAdd.Rows)
                      {
                   //Finds and updates a specific row. If no matching row is found, a new row is created using the given values.
                  DataRow row= DataHelper.LoadDataRow(tblOrig, rowToAdd, true);
                      }
            }
            return m_ds;
        }
        #endregion //”CreateTable,INSERTInto and SelectINTO”
            //MNF 10/9/2004
            ///<summary>
            /// Sample of call
            /// dsHelper.RemoveFromTable(sTestTable, rSourceRow) ;
            ///</summary>
            ///<returns>true if delete, false if primary key is not in the table</returns>
            public bool RemoveFromTable(string sTableName, DataRow rSourceRow)
            {
                  Debug.Assert(m_ds!=null);
                  DataTable tbl=m_ds.Tables[sTableName];
                  if (tbl==null)
                  {
                              return false;
                  }
            //bool bRet=RowInTableExists( tbl, rSourceRow );
            //object[] keyValues=PrimaryKeyValues(rSourceRow);
            return RemoveFromTable( tbl,rSourceRow);
            }
        ///<summary>
        ///
        ///</summary>
        ///<param name=”tbl”></param>
        ///<param name=”rSourceRow”></param>
        ///<returns>true if delete, false if primary key is not in the table</returns>
        public static bool RemoveFromTable(DataTable tbl,DataRow rSourceRow )
        {
            DataRow row = FindRow(tbl, rSourceRow);
            if (null != row)
            {
                tbl.Rows.Remove(row);
                //bRet=true;
            }
            //else //not exist
            //    bRet=false;
            return (null != row);
        }
        ///<summary>
        /// Remove Rows with the specified state, e.g during refresh it may be required to delete Unchanged rows
        ///</summary>
        ///<param name=”sTableName”></param>
        ///<param name=”RowState”></param>
        ///<returns></returns>
        public static bool RemoveRowsFromTable( DataTable tbl, DataRowState RowState)
        {
            if (tbl == null) { throw new ArgumentNullException(“DataTable tbl”); }
            foreach (DataRow row in tbl.Rows)
            {
              if(row.RowState==RowState)
              {
                  row.Delete();  
              }
            }
            return true;
        }
 
        ///<summary>
        /// return table(not attached to dataset) with row copies with specified keys 
///</summary>
///<param name=”tbl”></param>
        ///<param name=”keys”>if Keys is null,return copy of full table not attached to dataset</param>
///<returns></returns>
        public static DataTable FilterTableByKeys(DataTable tbl, string[] keys)
        {
            if (tbl == null) { throw new ArgumentNullException(“DataTable tbl”); }
            if (keys == null) { throw new ArgumentNullException(“string[] keys”); }
            DataTable newTbl = null;
            if (keys != null)
            {
                newTbl = tbl.Clone();
                foreach (string key in keys)
                {
                    DataRow row = tbl.Rows.Find(key);
                    if (null != row)
                        newTbl.ImportRow(row);
                    else
                    {
                        DebugHelper.TracedLine(“key not found” + key);
                        Debug.Assert(false, “key not found” + key);
                    }
                }
            }
            return newTbl;
        }
        ///<summary>
        /// return table(not attached to dataset) with row copies with specified keys 
        ///</summary>
        ///<param name=”tbl”>Not Null</param>
        ///<param name=”lstKeys”>Not Null</param>
        ///<returns></returns>
        public static DataTable FilterTableByKeys(DataTable tbl, List<string> lstKeys)
        {
            string[] keys = null;
            if (null!=lstKeys)
            {
                keys = lstKeys.ToArray();
            }
            return FilterTableByKeys(tbl, keys);
        }
        ///<summary>
        /// Remove all rows that have keys different to listed in lstKeys
        ///</summary>
        ///<param name=”tbl”></param>
        ///<param name=”lstKeys”>if lstKeys is null, the unchanged table is returned</param>
        ///<returns></returns>
        public static DataTable ReplaceTableWithFilteredByKeys(DataTable tbl, List<string> lstKeys)
        {
            if (null != lstKeys)
            {
                DataTable tblNew = FilterTableByKeys(tbl, lstKeys);
                tbl.Clear();
               tbl.Merge(tblNew);
            }
            return tbl;
        }
 
        //MNF 21/10/2004
            ///<summary>
            /// Sample of call
            /// dsHelper.FindInTable(sTestTable, rSourceRow) ;
            ///</summary>
            ///<returns>true if found, false if primary key is not in the table</returns>
            public bool FindInTable(string sTableName, DataRow rSourceRow)
            {
                  //bool bRet;
                  Debug.Assert(m_ds!=null);
                  DataTable tbl=m_ds.Tables[sTableName];
                  if (tbl==null)
                  {
                        return false;
                  }
            return RowInTableExists( tbl, rSourceRow);
            }
        public static bool RowInTableExists(DataTable tbl,DataRow rSourceRow )
        {
            //    bool bRet;
            if(tbl==null){    throw new ArgumentNullException(“tbl”);}
            DataRow row = FindRow(tbl, rSourceRow);
            return (null!=row) ;
        }
        public static DataRow FindRow(DataTable tbl, DataRow rSourceRow)
        {
           // bool bRet;
            object[] keyValues = PrimaryKeyValues(rSourceRow);
            return tbl.Rows.Find(keyValues);
 
        }
 
            ///<summary>
            /// Sample of call
            /// dsHelper.InsertInto(sTestTable, ds.Tables[“Employees”], “FirstName FName,LastName LName,BirthDate”, “EmployeeID<5″, “BirthDate”) ;
            /// </summary>
            /// <returns>true if inserted, false if primary key is already in the table</returns>
            public static object[] PrimaryKeyValues(DataRow rSourceRow)
            {
                  DataColumn[] colKeys=rSourceRow.Table.PrimaryKey;
                  ArrayList values = new ArrayList();
                  foreach(DataColumn dc in colKeys)
                  {
                              values.Add( rSourceRow[dc.ColumnName]);
                  }
                  return values.ToArray();;
            }
 
            ///<summary>
            /// Sample of call
            /// dsHelper.InsertInto(sTestTable, ds.Tables[“Employees”], “FirstName FName,LastName LName,BirthDate”, “EmployeeID<5″, “BirthDate”) ;
            /// </summary>
            /// <returns>true if inserted, false if primary key is already in the table</returns>
            public static bool IsIndexValid(DataTable tbl,int RowIndex)
            {
                  return ((RowIndex>=0) && (RowIndex< tbl.Rows.Count) ) ;
            }
            public static bool HasChanges(DataTable tbl)
            { //from http://www.groupsrv.com/dotnet/viewtopic.php?t=30224&view=previous
                  //thisDataSet.Tables[tableName]
                  foreach (DataRow dr in tbl.Rows) 
                  {
                        if (dr.RowState != DataRowState.Unchanged)
                              return true;
                  }
                  return false;
            }
 
 
            //use SqlCommandBuilder
        public static DataTable UpdateDataSet(string connString, DataSet ds, string sSelectSQL, string TableName)
            { return UpdateDataSet( connString, ds, sSelectSQL, TableName,false);
            }
            public static DataTable UpdateDataSet(string connString, DataSet ds,string sSelectSQL,string TableName,bool ContinueUpdateOnError )
            {
                  //SqlCommandBuilder commandBuilder;
            DataTable dt = null;
            if (null == TableName)
            {
                dt = ds.Tables[0];//assume that only the first table(with defalt name “Table”) is updated
            }
            else
            {
                dt = ds.Tables[TableName];
            }
            DataTable dtChanges = dt.GetChanges();
                  if (!(dtChanges == null))
                  {
                dtChanges=UpdateDataTable(connString, dt, sSelectSQL, ContinueUpdateOnError);
                //SqlDataAdapter da = new SqlDataAdapter(sSelectSQL, connString);
                //commandBuilder = new SqlCommandBuilder(da);
                //commandBuilder.QuotePrefix =”[“;//TODO for all SqlCommandBuilder
                //commandBuilder.QuoteSuffix =”]”;
                //da.ContinueUpdateOnError = ContinueUpdateOnError;
                //DebugHelper.PrintSqlCommandBuilder(commandBuilder,”UpdateDataSet:”);
                //if (null==TableName)
                //{
                //    da.Update(dsChanges);//assume that only the first table(with defalt name “Table”) is updated
                //    ds.AcceptChanges();
                //}
                //else
                //{
                //    da.Update( dsChanges, TableName);
                //    ds.Tables[TableName].AcceptChanges();
                //    //                                    LogErrors(dsChanges, “UpdateKeywordTables ” + tbl + ” SQL=” + sSQL);
                //}
                  }
            return dtChanges; //important GetErrors
        }
        ///<summary>
        ///
        ///</summary>
        ///<param name=”connString”></param>
        ///<param name=”dt”></param>
        ///<param name=”sSelectSQL”></param>
        ///<param name=”ContinueUpdateOnError”></param>
        ///<returns>can return null, if no cahnges</returns>
        public static DataTable UpdateDataTable(string connString, DataTable dt, string sSelectSQL, bool ContinueUpdateOnError)
        {
            DataTable dtChanges = dt.GetChanges();
            if (!(dtChanges == null))
            {
                SqlDataAdapter da = CreateSqlDataAdapterWithBuilder(sSelectSQL, connString, ContinueUpdateOnError);
                da.Update(dtChanges);//assume that only the first table(with defalt name “Table”) is updated
                dtChanges.AcceptChanges();//not sure, it is required
                dt.AcceptChanges(); //alternatively dt.Merge(dtChanges) 5/4/2006
                //                                    LogErrors(dsChanges, “UpdateKeywordTables ” + tbl + ” SQL=” + sSQL);
            }
            return dtChanges;
        }
        public static SqlDataAdapter CreateSqlDataAdapterWithBuilder(string sSelectSQL, string connString, bool ContinueUpdateOnError)
        {
            SqlCommandBuilder commandBuilder;
            SqlDataAdapter da = new SqlDataAdapter(sSelectSQL, connString);
            commandBuilder = new SqlCommandBuilder(da);
            commandBuilder.QuotePrefix = “[“;//TODO for all SqlCommandBuilder
            commandBuilder.QuoteSuffix = “]”;
            da.ContinueUpdateOnError = ContinueUpdateOnError;
            DebugHelper.PrintSqlCommandBuilder(commandBuilder, “UpdateDataSet:”);
            return da;
        }
 
        #region “DataView operations”  
 
            public static DataTable CreateTable(DataView vwSource)
            {
                  // short circuiting out here
                  int nRowCount = vwSource.Count;
                  if (0 == nRowCount) return null;
                  DataTable tableNew = vwSource.Table.Clone();// clone the schema
                  // copy the values to the new table
                  foreach(DataRowView rv in vwSource)
                  {
                     tableNew.ImportRow(rv.Row);
                  }
                  return tableNew;
            }
        public static string SqlTableForNewRows(string TableName)
        {
            // short circuiting out here
            string sSQL = “Select * From “ + TableName + ” where 0=1″;
            return sSQL;
        }
        public static DataTable OpenTableForNewRows(string TableName,string connString)
        {
            // short circuiting out here
            string sSQL = SqlTableForNewRows(TableName );
            return ExecuteTable(connString, CommandType.Text, sSQL);
            //DataSet ds = SqlHelper.ExecuteDataset(connString, CommandType.Text, sSQL);
            //DataTable tableNew = ds.Tables[0];
            //return tableNew;
        }
        public static DataTable ExecuteTable(string connectionString, CommandType commandType, string commandText)
        {
            DataSet ds = SqlHelper.ExecuteDataset(connectionString, commandType, commandText);
            DataTable tableFirst = ds.Tables[0];
            return tableFirst;
        }
        public static void Delete(DataView view, int startRecord, int maxRecords)
            {
                  view.RowStateFilter = DataViewRowState.CurrentRows | DataViewRowState.Deleted;
                  int nLastRecord = startRecord+ maxRecords – 1;
                  for (int num1 = startRecord; num1 <= nLastRecord; num1++)
            {
                if (num1<view.Count)//5/4/2006
                {
                              view[num1].Delete();
                }
            }
                  view.Table.AcceptChanges();
            }
        public static DataView CloneDataView(DataView vwSource,string newSort)
        {
            return new DataView(vwSource.Table ,vwSource.RowFilter,newSort,vwSource.RowStateFilter) ;
        }
        #endregion “DataView operations”
 
    }//public class DataSetHelper
 
}//namespace
 


DataGrid to GridView Conversion changes

I created a table describing, which fields/elements I had to change when converted existing DataGrid to GridView .
Mapping for some other elements can be found in the article here.
 
 
asp:DataGrid
asp:GridView
Comment
asp:TemplateColumn
 
asp:TemplateField
 
asp:BoundColumn
 
asp:BoundField
 
AlternatingItemStyle
 
ItemStyle
 
DataGridItemEventArgs
 
ItemDataBound event
DataGridItemEventHandler
 
 
ItemCreated event
 
e.Item
e.Row
e is EventArgs parameter
e.Item.ItemType
e.Row.RowType
 
ItemType.Item
DataControlRowState.Normal
ItemType.AlternatingItem
DataControlRowState.Alternate
 
 
ItemTemplate for alternating item not available, in code used check for ItemType.AlternatingItem or
AlternatingItemStyle

AlternatingItemTemplate
 
 

Custom DropDownList with DataBind and extra option “Please Select”

There is a common requirement to have DropDownList populated from Collection(e.g.DataTable) with extra (usually default) option “Please Select”.
I wanted to find a custom control that will allow to specify this extra option and use standard DataSource/DataBind.
I wasn’t able to find it in Google, so probably I will write it myself.

Relevant links to consider:An ASP.NET 2.0 AutoComplete DropDownList  

‘Dropdown1’ has a SelectedValue which is invalid

MetaBuilders.ComboBox[^]

My EntitySpaces notes

I have a few blog posts about EntitySpaces(started from this one) , as well as my posts on their forums. I want to put them together in this article as well as the links, that I consider useful.

If you need to change name of database in config, it is recommended , when generating Business Entities, in Advanced tab to set tick to Metadata Class Should  Ignore Catalog.  

To implement join for multiple tables it is suggested to create a view that brings  joined tables. They will support  joins in a future version.
There are useful EntitySpaces Query API and Query API Samples.

Filling an EsCollection out of an ordinary DataTable not supported,but you can try

    public bool CustomPopulate(DataTable dt )
{

this.Table = dt;
this.PopulateCollection();//protected method
}
}
To Clone EntitySpaces entities - the thread suggests binary serialisation(seems not always working?) and column by column copy.
Paging and Sorting on Sql 2000 using esDataSource
The ASP.NET demo source can be downloaded using Trial version and solution GridLoader.sln located under GridLoadersASP.NETC#GridLoader folder
See also EntitySpaces DotNetNuke ASCX Admin Grid Template Suite Released
  EntitySpaces and LINQ and LINQ to SQL-Aug 2007 thread .

ASP.NET MVC Northwind Demo using Entity Spaces 


Stop background find in “visual studio” not always stops search

In VS 2005 (I have SP1) it is a toolbar icon called “Stops a background Find”, that suppose to cancel the find .

However I noticed on my machine and on my colleage’s machine, that sometimes VS hangs on searching(shows the search as processing, but doesn’t change the filename on status bar).The button nether shortcut (Alt-F3,S)  doesn’t stop search and you need to close VS to re-enable searching.
I don’t have enough details to reproduce the problem, so it is pointless to report to MS Feedback site