Next step of programming

Just another WordPress.com weblog

Archive for the ‘C#’ Category

Convert ILIST, LIST to DataSet with child tables and relations

with 5 comments

There was requirement to convert ILIST or LIST to DataSet so that it can be assigned to some of the controls like Grid or DevExpress Grid. For that i have written following class to convert from LIST or ILIST to DataSet

  • Converts only ILIST and LIST
  • Convert sub lists to another table which will be related to the parent list
  • Creates Relation between tables
  • Works only on the properties not on fields. You can easily modify it for that

using System;
using System.Collections;
using System.Collections.Generic;
using System.Data;
using System.Linq;
using System.Reflection;

namespace TowardsNext
{
public static class ListConvertor    
{
public static DataSet ConvertToDataSet<T>(IList list)
{
DataSet dataSet = new DataSet();

CreateDataSet(dataSet, typeof(T), false);
FillDataSet(typeof(T), list.ToList(), dataSet, -1);
CreateRelations(dataSet, typeof(T), null);

return dataSet;
}

/// 
/// Create the structure for all the tables in the data set        
/// 
/// Data set in which tables will be created
/// Type of which dataset has to be created
/// Whether current type is a child table        
private static void CreateDataSet(DataSet dataSet, Type type, bool isChildTable)
{
DataTable dataTable = new DataTable(type.Name);

//Create the ID columns for having relation in the tables 
            dataTable.Columns.Add(new DataColumn("ID", typeof(int)));
if (isChildTable)
{
dataTable.Columns.Add(new DataColumn("ParentID", typeof(int)));
}

// Create the structure for the data tables to be
// added in the the data set            
foreach (PropertyInfo pInfo in type.GetProperties())
{
if (pInfo.PropertyType.IsGenericType &&
(pInfo.PropertyType.GetGenericTypeDefinition() == typeof(List<>)
|| pInfo.PropertyType.GetGenericTypeDefinition() == typeof(IList<>)))
{
// If associate lists are there make then another table
                    CreateDataSet(dataSet,
pInfo.PropertyType.GetGenericArguments()[0],
true);
}
else                
{
dataTable.Columns.Add(new DataColumn(pInfo.Name, pInfo.PropertyType));
}
}

//Add the table to the dataset
            dataSet.Tables.Add(dataTable);
}

/// 
/// Fill all the tables of data set with data in the respective list        
/// 
/// Type of which datatable is to be filled
/// List of data
/// Data Set in which data tables will be filled with data
/// ID of parent record. If -1 one then no parent        
private static void FillDataSet(Type type, IList list, DataSet dataSet, int parentID)
{
PropertyInfo[] propertyInfos = type.GetProperties();
DataTable dataTable = dataSet.Tables[type.Name];
int id = dataTable.Rows.Count + 1;

foreach (object item in list)
{
DataRow row = dataTable.NewRow();

// Set new id and related parent id
                row["ID"] = id;
if (parentID != -1)
row["ParentID"] = parentID;

// Load all the data from the properties of the type
// and save them into the datatable                
foreach (PropertyInfo info in propertyInfos)
{
if (info.PropertyType.IsGenericType &&
(info.PropertyType.GetGenericTypeDefinition() == typeof(List<>)
|| info.PropertyType.GetGenericTypeDefinition() == typeof(IList<>)))
{
IList subList = (IList)info.GetValue(item, null);
if (subList != null && subList.Count > 0)
{
FillDataSet(subList[0].GetType(),
subList,
dataSet, id);
}
}
else                    
{
row[info.Name] = info.GetValue(item, null);
}
}

dataTable.Rows.Add(row);
id++;
}
}

/// 
/// Creates the relation between the tables according to the         
/// type and parent table on field ID and ParentID        
/// 
/// Data set containing parent and child table
/// Type of the list
/// Parent table to which relations has to be done        
private static void CreateRelations(DataSet dataSet, Type type, DataTable parentTable)
{
DataTable dataTable = dataSet.Tables[type.Name];

// If parent table exsits then create relation
// with child table on field Parent ID            
if (parentTable != null)
{
dataSet.Relations.Add(
new DataRelation(parentTable.TableName + "_ID_"
                        + "PARENTID_" + dataTable.TableName,
parentTable.Columns["ID"],
dataTable.Columns["ParentID"]));
}

// Check for other lists under current object
// go for another relation if exists            
foreach (PropertyInfo pInfo in type.GetProperties())
{
if (pInfo.PropertyType.IsGenericType &&
(pInfo.PropertyType.GetGenericTypeDefinition() == typeof(List<>)
|| pInfo.PropertyType.GetGenericTypeDefinition() == typeof(IList<>)))
{
// If associate lists are there make then another table
                    CreateRelations(dataSet,
pInfo.PropertyType.GetGenericArguments()[0],
dataTable);
}
}
}
}
}


Tested with following code


;public class Student    
{
public string Name { get; set; }
public string Class { get; set; }
}

public class Teacher    
{
public string Name { get; set; }
public string Address { get; set; }
public List<Student> Students { get; set; }
}

class Program    
{
static void Main(string[] args)
{
List<Student> students = new List<Student>();
students.Add(new Student { Name = "Ram Prasad", Class = "LKG" });
students.Add(new Student { Name = "Dina Nath", Class = "Prep" });

List<Teacher> teachers = new List<Teacher>();
teachers.Add(
new Teacher{
Name="Om Prakash",
Address="Mangalore",
Students = students
});
teachers.Add(new Teacher                
{
Name = "Om Prakash 2",
Address = "Gurgaon",
Students = students
});

DataSet dataSet = ListConvertor.ConvertToDataSet<Teacher>(teachers);
}
}


It is not tested in all the cases and condition only checked with few cases and requirement. If any problem do reply, i will fix it up and re-post it. After converting we assigned it to devexpress grid and get the following successful output

Grid assigned to parent data table list with all child tables

Grid assigned to parent data table list with all child tables


Written by A.Sethi

April 16, 2009 at 11:20 am

Posted in General

Tagged with , , , ,

Named & Optional Parameter, C# 4.0 Part 2

with one comment

In visual basic we were having optional parameter option which can help you to send only some parameter to methods and reset will take the default values. Same feature is part of C# 4.0 where you can have default values for the parameters.

Optional Parameters & Their default values

Optional Parameters & Their default values


But one more noticeable feature is “named parameter”. You might have seen in VB also that if you want to set any of the parameter no values then you have to leave all other parameters also which are defined after that variable. To sort this out you can use named parameter which specify the name of the parameter and value for it “seats:4” where seats is the parameter and 4 is the value.

Named Parameters

Named Parameters


Both of the features are shown below in sample

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;

namespace ParameterFeatures
{
class Program    
{
static void Main(string[] args)
{
Vehicle car = new Vehicle("V6");
Vehicle van = new Vehicle(seats:4);

Console.WriteLine("Engine : " + car.Engine);
Console.WriteLine("Seats : " + van.Seats.ToString());

Console.ReadLine();
}
}

class Vehicle    
{
public string Engine { get; set; }
public int Seats { get; set; }

public Vehicle(string engine = "V8", int seats = 5)
{
Engine = engine;
Seats = seats;
}
}
}

Written by A.Sethi

March 16, 2009 at 12:39 pm

Dynamic Lookup & dynamic Type, C# 4.0 Part 1

with one comment

C# 4.0 is out once again with new set of features. Now we will see one of the new feature of it, which is know as Dynamic Lookup. It is new approach for invoking thing more dynamically than before. It gives big freedom and working with various different kind of objects like COM etc will be too easy.

Big question how. I have written one sample below where i am grabbing the object of excel instance which is already running and filling data in it. In the previous version of C# we used to do it with the help of InvokeMember funtions of the object. But in C# 4.0 story is differentM

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;

namespace DynamicObjects
{
class Program    
{
static void Main(string[] args)
{
dynamic excel = System.Runtime.
InteropServices.Marshal.GetActiveObject("Excel.Application");

//Display the name of the work book            
Console.WriteLine(excel.ActiveWorkbook.Name);

//Select the range and place some data here
excel.Range("B2").Select();
excel.ActiveCell.FormulaR1C1 = "Sample Data";

//Wait for the input            
Console.ReadLine();
}
}
}


It was so simple to use the dynamic object, That i have to just type out the properties and method in the front of dynamic object. At the time of getting that object it will be handled automatically and will map the functions and methods. Its really a great feature, which can save time and give more freedom to the developer.

Difference between VAR & DYNAMIC

VAR It is also know as local type inference feature of C#. This feature will allow you to remove the data type from the left hand side and create the type on the fly. But still you have to specify the type in the right hand side and var will be replaced by the new type which will be built at compile time.

DYNAMIC it is step ahead of the VAR. It will get the information of the object not at the compile time rather at the time of creation of that object. It is done at runtime only.

Written by A.Sethi

March 16, 2009 at 11:27 am

Posted in General

Tagged with , , ,

Listing All the references of Assembly

without comments

We can list all the references of the assembly in a recursive manner. Here i have avoided System Assemblies since those are not required & they are in circular references. Download the code from this link


private void btnList_Click(object sender, EventArgs e)
{
txtReferences.Text = "";

OpenFileDialog openFileDlg = new OpenFileDialog();
if (openFileDlg.ShowDialog() == DialogResult.OK)
{
txtAssemblyPath.Text = openFileDlg.FileName;
Assembly assembly = Assembly.LoadFrom(txtAssemblyPath.Text);
ListReferences("",assembly);
}

MessageBox.Show("Listing Completed");
}

public void ListReferences(string location, Assembly assembly)
{
//List all references            
string name = assembly.GetName().Name;
string CurrentLocation = location;
txtReferences.Text += CurrentLocation + ">" + name + "\r\n";
location += "--";

if (!name.StartsWith("System.") && !Name.Equals("System"))
{
foreach (AssemblyName assemblyName in assembly.GetReferencedAssemblies())
{
assembly = Assembly.Load(assemblyName);
ListReferences(location, assembly);
Application.DoEvents();
}
}
}

Written by A.Sethi

February 13, 2009 at 7:15 am

Posted in Reflection

Tagged with , , ,

XML Serialization

without comments

Some time we need to save the data in the files which is nothing but the details of the object. For example i am having a application doing vector drawing and i want to save the details of the line object not the image file. How to save the line object and how to get it back. We can use serialization with which we can save our object in file directly and can load it too. Also we can use XML Serialization which is so popular these days.

We have to just mark out objects and class with certain Attributes like XMLRoot, XMLElement, XMLAttribute and so on.


using System;
using System.Collections.Generic;
using System.IO;
using System.Xml.Serialization;

namespace XMLSerialization
{
static class Program    
{
static void Main()
{
DoSerialization();
}

private static void DoSerialization()
{
Student student1 = new Student { Name = "A", Marks = 23 };
Student student2 = new Student { Name = "B", Marks = 25 };
Students students = new Students();

students.StudentList.Add(student1);
students.StudentList.Add(student2);

XmlSerializer xmlSerialize = new XmlSerializer(students.GetType());
StreamWriter writer = new StreamWriter("a.xml");
xmlSerialize.Serialize(writer, students);
writer.Close();

StreamReader reader = new StreamReader("a.xml");
Students studentsfromFile = (Students)xmlSerialize.Deserialize(reader);

foreach (Student st in studentsfromFile.StudentList)
{
Console.WriteLine("Name : {0} Marks : {1}", st.Name, st.Marks);
}

Console.ReadLine();
}
}

[XmlRoot("Students")]
public class Students    
{
[XmlElement("Student")]
public List<Student> StudentList = new List<Student>();
}

public class Student    
{
[XmlElement("Name")]
public string Name;
[XmlElement("Marks")]
public int Marks;
}
}

Written by A.Sethi

February 10, 2009 at 10:24 am

Netstat in C#

without comments

Check out how to perform Netstat command functions of DOS in C#. It will list you all the current network connections of your System


using System;
using System.Net;
using System.Net.NetworkInformation;

namespace MyNetstat
{
class Program    
{
static void Main(string[] args)
{
IPGlobalProperties ipProperties = IPGlobalProperties.GetIPGlobalProperties();

IPEndPoint[] endPoints = ipProperties.GetActiveTcpListeners();
TcpConnectionInformation[] tcpConnections = ipProperties.GetActiveTcpConnections();

foreach (TcpConnectionInformation info in tcpConnections)
{
Console.WriteLine("Local : " + info.LocalEndPoint.Address.ToString()
+ ":" + info.LocalEndPoint.Port.ToString()
+ "\nRemote : " + info.RemoteEndPoint.Address.ToString()
+ ":" + info.RemoteEndPoint.Port.ToString()
+ "\nState : " + info.State.ToString() + "\n\n");
}
Console.ReadLine();
}
}
}

Written by A.Sethi

February 9, 2009 at 12:09 pm

Listing Domains, Groups, Schemas, User, Computer from DirectoryEntry

with one comment

To list the Domains and their respective Groups, Schemas, User and Computer use DirectoryEntry and enumerate through the Children of the respective Entry. Check out the following code for more understanding

Include Reference to System.DirectoryServices in the project

using System;
using System.Collections.Generic;
using System.Text;
using System.DirectoryServices;

namespace ConsoleApplication2
{
class Program    
{
static void Main(string[] args)
{
DirectoryEntry dirEntry = new DirectoryEntry("WinNT:");

foreach (DirectoryEntry de in dirEntry.Children)
{
if (de.SchemaClassName == "Domain")
{
Console.WriteLine("Domain : " + de.Name);
Console.WriteLine("=================\n");
foreach (DirectoryEntry de2 in de.Children)
{
Console.WriteLine("  Name : " + de2.Name + " \t\t Type : " + de2.SchemaClassName);
}
}
de.Dispose();
}

dirEntry.Dispose();
Console.ReadLine();
}
}
}

Written by A.Sethi

February 9, 2009 at 10:12 am

Generics with simple example

without comments

Generics are the feature supported from the version 2.0 of .Net framework. Why it is required and where it is used. Consider a case in which you are creating a collection of objects now those objects can be int or string or anything. Now how we will design the class since we are not aware of the type used by the developer. In this case we can make of use of Generics where the type of the object will be specified only at the initialization or declaration of the collection class. Here we have to use generic type parameter T.


public class GCollection
{
private List _list = new List();

public void Add(T item)
{
_list.Add(item);
}

public T GetItem(int index)
{
return _list[index];
}
}

See the following image to get an idea how it works

Generics Sample

Generics Sample

Written by A.Sethi

February 3, 2009 at 7:55 am

Posted in General

Tagged with ,

Save Settings/Data in IsolatedStorage C#

without comments

IsolatedStorage is a storage isolated from users and assemblies. Application has to just tell the name of the file and location of the file will be handled by .net. This storage is safe has compared to keeping file in the application path and saving settings in it. Developer can save the settings of the application in the isolatedstorage in a file. Which he can recover easily. Isolated Storage is a kind of a virtual folder only. These file can have scope for user, domain, application, machine and more.

Check out the following sample


class Program    
{
static void Main(string[] args)
{
IsolatedStorageFile storage = IsolatedStorageFile.GetStore(
IsolatedStorageScope.User | IsolatedStorageScope.Assembly, null, null);

CreateFile("settings", storage);
Console.WriteLine("File Contents : \n" + ReadFile("settings", storage));

GetStoreInformation(storage);
storage.Close();
storage.Dispose();

Console.ReadLine();
}

public static void CreateFile(string fileName, IsolatedStorageFile storage)
{
IsolatedStorageFileStream stream =
new IsolatedStorageFileStream(fileName,
System.IO.FileMode.Create, storage);

StreamWriter writer = new StreamWriter(stream);
writer.WriteLine("Sample text");
writer.WriteLine("Isolated Storage");
writer.Close();
stream.Close();
}

public static string ReadFile(string fileName, IsolatedStorageFile storage)
{
IsolatedStorageFileStream stream =
new IsolatedStorageFileStream(fileName,
System.IO.FileMode.Open, storage);

StreamReader reader = new StreamReader(stream);
string data = reader.ReadToEnd();

reader.Close();
stream.Close();

return data;
}
public static void GetStoreInformation(IsolatedStorageFile storage)
{

string[] dirs =  storage.GetDirectoryNames("*");
string[] files = storage.GetFileNames("*");

Console.WriteLine("Files");
foreach (string filename in files)
{
Console.WriteLine("  |- " + filename);
}

Console.WriteLine("\nDirectories" );
foreach (string dir in dirs)
{
Console.WriteLine("  |- " + dir);
}
}

}

Written by A.Sethi

February 2, 2009 at 11:56 am

Posted in General

Tagged with , ,

Replace data in file C#

with 3 comments

There was one of the requirement to find and replace the data from the file. First we have written code to load all the data in the variable and then replace it. But it will be a problem with a huge files. So we wrote two methods to replace it line by line or chunk by chunk. Both of these methods are written below. These methods although seems correct to us but not tested. If any problem do reply back so that it can be modified

Download sample from FileFindReplace Sample

public class FileFindRelpace    
{
/// 
/// Replace the data in the Huge files searching and replacing chunk        
/// by chunk. It will create new file as filepath + ".tmp" file with        
/// replaced data        
/// 
/// Path of the file
/// Text to be replaced
/// Text with which it is replaced        
public void ReplaceLineByLine(string filePath, string replaceText, string withText)
{
StreamReader streamReader = new StreamReader(filePath);
StreamWriter streamWriter = new StreamWriter(filePath + ".tmp");

while (!streamReader.EndOfStream)
{
string data = streamReader.ReadLine();
data = data.Replace(replaceText, withText);
streamWriter.WriteLine(data);
}

streamReader.Close();
streamWriter.Close();
}

/// 
/// Replace the data in the Huge files searching and replacing chunk        
/// by chunk. It will create new file as filepath + ".tmp" file with        
/// replaced data        
/// 
/// Path of the file
/// Text to be replaced
/// Text with which it is replaced
/// Length of the data to be loaded at one go        
public void ReplaceByChunk(string filePath, string replaceText, string withText, int chunkLength)
{
int loadLength = chunkLength + replaceText.Length;
char[] buffer = new char[loadLength];
int index = 0;
int replaceLength = replaceText.Length;

StreamReader streamReader = new StreamReader(filePath);
StreamWriter streamWriter = new StreamWriter(filePath + ".tmp");

//Load the data according to the chunk length specified
//also load the extra data according to the length of
//the replace text so that chunk end and start text break
//can be handled            
while(true)
{
//Seek to the position from where we want to start and
//load the data in to the memory
                streamReader.DiscardBufferedData();
streamReader.BaseStream.Seek(index, SeekOrigin.Begin);
int count = streamReader.ReadBlock(buffer,0,loadLength);
if (count == 0) break;

//Get the data and check whether the extra loaded data
//is replaceable if yes then set end replaced flag                
string data = ConvertToString(buffer, count);
bool isEndReplaced = false;
if(count >= chunkLength)
isEndReplaced = (data.LastIndexOf(withText, chunkLength) > 0);

//Replace the data with the specified data and save the
//new data in the new file
                data = data.Replace(replaceText, withText);
if(isEndReplaced)
{
streamWriter.Write(data);
index += count;
}
else                
{
if (count >= chunkLength)
{
streamWriter.Write(data.Substring(0, data.Length - replaceLength));
index += chunkLength;
}
else                    
{
streamWriter.Write(data);
index += chunkLength;
}
}
}

streamReader.Close();
streamWriter.Close();
}

private string ConvertToString(char[] buffer, int count)
{
StringBuilder data = new StringBuilder(buffer.Length);

for (int i = 0; i < count; i++)
{
data.Append(buffer[i]);
}

return data.ToString();
}
}

Written by A.Sethi

February 2, 2009 at 9:53 am

Posted in General

Tagged with , , , ,