C# – List all fields of a table in Entity Data Model

The ADO.NET Data Model alleviates our time when working with database by mapping all database objects into .NET classes object. Instead of writing complex SQL queries with consideration about SQL Injection and tons of security requirments the developer must only concentrate on how they write programming code to accomplish their tasks.
However sometimes it makes us confused when working with “new technique”. For examples how we can list all fields of a table? In traditional way we can just fill a DataTable with a simple query “SELECT * FROM TABLE_NAME” from DataAdapter then run through the columns to list all fields with their data types. But how does it work with Entity Data Model? In the code snippet below I would like to demonstrate how I do it

1. With Entity Data Model

NorthwindEntities nwEntity = new NorthwindEntities();
MetadataWorkspace mdw = ((EntityConnection)nwEntity.Connection).GetMetadataWorkspace();
EntityType tblCustomers = mdw.GetItem<EntityType>("NorthwindModel.Store.Customers", DataSpace.SSpace);
if (tblCustomers != null)
{				
	foreach (var prop in tblCustomers.Members)
	{
		Console.WriteLine(String.Format("MemberName:{0}; Type:{1}", prop.Name, prop.TypeUsage.EdmType.Name));
	}
}

The identity for function GetItem can be got through editing file Nortwind.edmx with a text editor.

Open with ...

XML-Editor

Read EntityType from .edmx

2. With Reflection
As every class in .NET, the mapping classes of Entity Data Model have their own properties and can be accessed through Reflection. Therefore in the 2. code snippet I would like to use Reflection to list all availables properties of a mapping class. However the foreign keys properties and so on are also properties which I do not want to read out.So I use a “bad condition” to filter what are really fields. If you know another way to filter, please tell me.

Type tTemp = (typeof(Customers));
PropertyInfo[] piFields = tTemp.GetProperties(BindingFlags.Public | BindingFlags.Instance );
foreach (PropertyInfo pi in piFields)
{
	if (!pi.PropertyType.Namespace.Contains("System.Data")) Console.WriteLine(String.Format("MemberName:{0}; Type:{1}", pi.Name, pi.PropertyType));
}

The image below show results of two methods. It can be easily realized that the data type of 2 methods are different. One is SQL data type and the other is .NET data type

Results of two methods

The complete source code of this blog you can download here “Field List Entity Data Model

C#, WPF – Copy files with progress bar by CopyFileEx API

When we copy a lot of files to a folder we would like our program showing the copying progress with useful information, for example how does the copying run or how many file left to be copied. The managed function File.Copy does not allow us to monitor its process by providing any callback function. There are already in internet many articles show us how to copy files with progress bar in Windows Form. Therefor in this example below, I would like to make a demo with WPF. The core function of our example is the CopyFileEx API.
CopyFileEx Function copies an existing file to a new file, notifying the application of its progress through a callback function.
From the beginning, I thought it’s pretty simple but then I was stuck in a mess which takes me many hours to solve. The signature of CopyFileEx API in C# looks like following.

[DllImport("kernel32.dll", SetLastError = true, CharSet = CharSet.Auto)]
[return: MarshalAs(UnmanagedType.Bool)]
static extern bool CopyFileEx(string lpExistingFileName, string lpNewFileName,
   CopyProgressRoutine lpProgressRoutine, IntPtr lpData, ref bool pbCancel,
   CopyFileFlags dwCopyFlags);

I took the signature from pinvoke.net but changed the “ref int pbCancel” to “ref bool pbCancel” so that the argument get more meaningful. Code to call to this API

bool bSuccess = CopyFileEx(lstSource[nIndex], m_strDestFile, new CopyProgressRoutine(CopyProgressHandler), IntPtr.Zero, ref m_bCancel, CopyFileFlags.COPY_FILE_RESTARTABLE);
if (!bSuccess)
{
	int error = Marshal.GetLastWin32Error();
	throw new Win32Exception(error);
}

Whereas the variable lstSource contains paths to all of source files, m_strDestFile is the folder where we want to copy to, m_bCancel is variable to cancel the copy progress when it is set to be true. In the callback function we have possibility to get how much data was already copied and other info.

private CopyProgressResult CopyProgressHandler(long total, long transferred, long streamSize, long StreamByteTrans, uint dwStreamNumber, CopyProgressCallbackReason reason, IntPtr hSourceFile, IntPtr hDestinationFile, IntPtr lpData)
{
	switch (reason)
	{
		case CopyProgressCallbackReason.CALLBACK_CHUNK_FINISHED:
			m_dtElapsedTime = DateTime.Now - m_dtStartTime;
			EventCopyHandler(this, new CopyEventArgs(((double)transferred / total) * 100, (transferred / 1024) / m_dtElapsedTime.TotalSeconds));
			return m_bCancel ? CopyProgressResult.PROGRESS_CANCEL : CopyProgressResult.PROGRESS_CONTINUE;                    
		default:                    
			return CopyProgressResult.PROGRESS_CONTINUE;
	}
}

You can see that the data was sent in chunk. As I remembered (if not wrong ^^) in my computer, the chunk size is about 0x10000 bytes. In this callback function we will update our progress bar and cancel if receiving cancel-event from user. That’s all about main ideas. I think it’s not difficult to understand. I would like now to talk more about 2 big problems which I met during programming.
1. WPF Control, exactly progress bar, does not update itself when copying
When I test to copy a big file, the complete GUI just completely freezes. The progress bar doesn’t run smoothly. It just jumps from 0 to 100. Thanks to the post of this blog http://geekswithblogs.net/NewThingsILearned/archive/2008/08/25/refresh–update-wpf-controls.aspx , I solved the problem as following

private void UpdateProgress(int nPercent)
{
	pbBar.Value = nPercent;
	pbBar.Refresh();
	btnCopy.RefreshInput();
}

void cfewEngine_EventCopyHandler(CopyFileExWrapper sender, CopyEventArgs e)
{
	this.Dispatcher.Invoke(new UpdateProgressDelegate(UpdateProgress), new object[] { Convert.ToInt32(e.Percent) });            
}

public static class ExtensionMethods
{
	private static Action EmptyDelegate = delegate() { };
	public static void Refresh(this UIElement uiElement)
	{
		uiElement.Dispatcher.Invoke(DispatcherPriority.Render, EmptyDelegate);
	}

	public static void RefreshInput(this UIElement uiElement)
	{
		uiElement.Dispatcher.Invoke(DispatcherPriority.Input, EmptyDelegate);
	}
}

2. m_bCancel lost its value
When the user click to cancel copying, I set the m_bCancel to “true”. But in the callback function it has value “false” again. Until now I still do not understand why it losts its value. I solve the problem by adding “static” keyword to m_bCancel variable and it works. But I can not explain myself, why it turns to be false although I set it to true.

The complete source code you can download here “CopyFileEx Wrapper”

UPDATE 12.04.2012
– Fix code so that m_bCancel doesn’t have to be static.

C# – List all referenced assemblies with Mono.Cecil

Mono.Cecil is a powerful open-source library for reading and writing .NET assembly. I used for it for many tools for editing assembly. This library is written and maintained by Jb Evain and is being rewritten with new model therefore some old codes do not work anymore. For example the AssemblyFactory is not supported anymore. If you want to find more about this library, you can browse its code at following link http://github.com/jbevain/cecil.

I often use Mono.Cecil to edit IL code so that I can rewrite and deobfuscate the code. Today I read a thread on mycsharp.de asking how to list all referenced assemblies so I make a small code snippet to solve this question.

AssemblyDefinition asmDef = AssemblyDefinition.ReadAssembly(@"D:\Synchronize\My Dropbox\Applications\Sudoku\Auto Fill In.exe");
foreach (AssemblyNameReference anrRef in asmDef.MainModule.AssemblyReferences)
{
	Console.WriteLine(anrRef.FullName + Environment.NewLine);
}
Console.ReadLine();

The code snippet is very simple. I just load the assembly into AssemblyDefinition and read the AssemblyReferences from the MainModule then write them out.

All referenced assemblies

However using this method I can not decide which type of referenced assembly (.exe or .dll) and where the referenced assemblies locate.