Tip of the day: Replace your switch case statement with generic Dictionary in c#

As i said in my previous post that i got the chance to work in one legacy application where i also optimized some of the code. Today’s post is inspired from one of the situation that i found in that application.

Now let me explain you the requirement. We have used “Dev Express” as reporting tool for our application and we have developed more than 20 reports. Each report binds to one view model / custom class i.e. you can say its a data source to that report. To fill our view model / custom class, we have used one third party dll which will return one class object but in their own format. So we developed individual method to bind our view model / custom class from their object. Before you think let me tell you one thing, We cannot develop common method here to bind model as each report contain different property and have their own logic. In this scenario any one can think of switch case or if else condition. So as expected i found that type of code in this application. Alright now no more detail and let’s jump into the situation and showing you some code.

First let’s create the required view model / custom class to bind report. Here assume that we wants to develop two reports, so we require two view model class as shown below.


class FranchiseeSalesEmployeeViewModel
{
	public int EmployeeID { get; set; }

	public string EmployeeName { get; set; }

	public int ExpectedTargetAmount { get; set; }

	public int AchievedAmount { get; set; }
}

class HREmployeeViewModel
{
	public int EmployeeID { get; set; }

	public string EmployeeName { get; set; }

	public int NoOfInterviweTaken { get; set; }

	public int NoOfRejectedCandidate { get; set; }
}

Now let’s create the source object which we’ll get from other third party dll.


class SourceThirdPartyObject
{
	public int EmployeeID { get; set; }

	public string EmployeeName { get; set; }

	public string DepartmentName { get; set; }

	// -- Other dependent sub class for HR activity

	// -- Other dependent sub class for Sales activity

	// -- and many more...
}

First let’s see the code in which we’ll use switch case statement.


static void Main(string[] args)
{
	// First bind the third party object
	// In real scenario we'll get the data from the third party dll
	SourceThirdPartyObject sourceObj = new SourceThirdPartyObject() {
		EmployeeID = 1,
		EmployeeName = "Bill Gates",
		DepartmentName = "Admin"
	};

	var modelObj = BindReportModel("Report_Name1", sourceObj);

	// same way for other report like this
	// var modelObj = BindReportModel("Report_Name2", sourceObj);
	// Now bind this model class to your report
}

private static object BindReportModel(string reportName, SourceThirdPartyObject sourceObj)
{
	object modelObj = null;

	switch (reportName)
	{
		case "Report_Name1":
			return BindModelForReportName1(sourceObj);

		case "Report_Name2":
			return BindModelForReportName2(sourceObj);

		// Same way for report3, report4 etc...

		//case "Report_Name3":
		//    return BindModelForReportName1(sourceObj);

		// Case so on...
	};

	return modelObj;
}

private static HREmployeeViewModel BindModelForReportName1(SourceThirdPartyObject sourceObj)
{
	// This method contain some complex logic to bind this model
	HREmployeeViewModel hrEmpModel = new HREmployeeViewModel()
	{
		EmployeeID = sourceObj.EmployeeID,
		EmployeeName = sourceObj.EmployeeName,
		NoOfInterviweTaken = 10,
		NoOfRejectedCandidate = 4
	};

	return hrEmpModel;
}

private static FranchiseeHREmployeeViewModel BindModelForReportName2(SourceThirdPartyObject sourceObj)
{
	FranchiseeHREmployeeViewModel franchiseeModel = new FranchiseeHREmployeeViewModel()
	{
		EmployeeID = sourceObj.EmployeeID,
		EmployeeName = sourceObj.EmployeeName,
		ExpectedTargetAmount = 50000,
		AchievedAmount = 45000
	};

	return franchiseeModel;
}

Now let’s see the same code, but this time we’ll replace the switch case statement with pre-initialize generic dictionary.


private static Dictionary<string, Func<SourceThirdPartyObject, object>> 
	methodDictionary = new Dictionary<string, Func<SourceThirdPartyObject, object>>
{
	{"Report_Name1", (sourceObj) => BindModelForReportName1(sourceObj) },
	{"Report_Name2", (sourceObj) => BindModelForReportName2(sourceObj) }
	// Same way for report3, report4 etc...
};

static void Main(string[] args)
{
	// First bind the third party object
	// In real scenario we'll get the data from the third party dll
	SourceThirdPartyObject sourceObj = new SourceThirdPartyObject() {
		EmployeeID = 1,
		EmployeeName = "Bill Gates",
		DepartmentName = "Admin"
	};

	var modelObj = methodDictionary["Report_Name1"](sourceObj);
    //var modelObj = BindReportModel("Report_Name1", sourceObj);
}

As you can see in the above code that we have completely replace our BindReportModel() method with Dictionary. So here we have already initialize our dictionary object with report name as key and its related bind method as value using Func delegate.

Reference

That’s it guys. Hope you enjoyed this post. Thanks for reading this post.

Advertisements

Alter table definition not reflected in SQL Server View

Few days ago, i got the chance to work with one of our legacy application. There was some changes in business requirement and i need to drop few columns from the table and so on and that table was used in one sql server view. After done my changes in table when i test my view, surprisingly it gives me an error! whooa!

Msg 4502, Level 16, State 1, Line 7
View or function ‘view_name’ has more column names specified than columns defined.

How is it possible as i have used “Select *” in my view. It should automatically reflect the changes in my view. Well, SQL server will not work in that way. After referring MSDN, i knew that metadata for my view is not automatically updated when i alter any dependent tables. So in today’s post we’ll see how we can resolve this type of error in SQL Server. Alright, let’s create this scenario.


CREATE TABLE [dbo].[EmployeeMaster](
	[Id] [int] IDENTITY(1,1) NOT NULL,
	[FirstName] [varchar](40) NOT NULL,
	[LastName] [varchar](40) NOT NULL,
	[JoiningDate] [date] NULL,
	[BloodGroup] [varchar](5) NULL,
	[PANNo] [varchar](20) NULL
 )
GO

INSERT INTO EmployeeMaster(FirstName,LastName,JoiningDate,BloodGroup)
	VALUES ('Azim', 'Premji', '2015-04-27', 'B+'),
			('Narayana', 'Moorthy', '2015-04-27', 'A+')
GO

Now let’s create the view.


CREATE VIEW view_Employee
AS
    SELECT * FROM  dbo.EmployeeMaster 

If you querying the view, everything works fine as expected. Now let us drop the “PANNo” column from the EmployeeMaster table.


ALTER TABLE EmployeeMaster
	DROP COLUMN PANNo

And let’s querying our view and see what happen.

ErrorInView

We get the error! Now to fix this error one of the way is alter our view or use the sp_refreshview stored procedure. So let’s see how we can fix the error using sp_refreshview SP.


EXEC SP_REFRESHVIEW view_Employee

Now again querying our view and as expected the error is gone now. Same way let say if you have added 2 new columns in your table then this time you won’t get any error when you querying your view but those 2 new columns not reflected in your view. So again to fix this issue you need to use “sp_refreshview” as shown above.

That’s it guys. Hope you like and enjoyed this post.

Execute a predefined tSql query stored in a column of table

Today’s post is inspired from the question asked here in the stackoverflow site. So the question is how to execute a predefined tsql query which is stored in a column of table and then display the result in one report. You can find the answer here i gave him. You might find it yourself in this type of situation in your application where you need to display the consolidated report over your other report in which you need to display the name of the report and its associated count or some other data.

Allright, let’s create this situation. For explanation i copied the data from that question. so here is the required table with some required records in it.


CREATE TABLE #tmpConsReport
(
	ReportName [varchar](100), 
	ReportQuery [varchar](2000)
);

INSERT INTO #tmpConsReport (ReportName, ReportQuery) 
	VALUES ('Sales Daily Report Count', 'Select COUNT(*) FROM Sales WHERE SaleDate = CAST(GETDATE() AS DATE)'),
			    ('Sales Weekly Report Count', 'Select COUNT(*) FROM Sales WHERE SaleDate >= CAST(GETDATE() -6 AS DATE) '),
				('HR Dept. Count', 'Select COUNT(*) FROM Users DepartmentID = 1'),
				('Todays New Joiny', 'Select TOP 1 firstname FROM Users ORDER BY EmpID DESC');

Now to execute the query which is stored in column of table we need to build dynamic query which looks something like this –


DECLARE @query VARCHAR(MAX) = ''

SELECT @query += 'SELECT ' + QUOTENAME(ReportName, '''') 
							+ ' AS ReportName, CAST((' + ReportQuery + ') AS VARCHAR) AS Result UNION ALL ' 
From #tmpConsReport

SET @query = LEFT(@query, LEN(@query) - 10)

PRINT(@query)
EXEC(@query)

If you don’t get any idea after seeing this query, no problem. Let’s print that dynamic query and it looks like this –


SELECT 'Sales Daily Report Count' AS ReportName, 
			CAST((Select COUNT(*) FROM Sales WHERE SaleDate = CAST(GETDATE() AS DATE)) AS VARCHAR) AS Result 

UNION ALL 

SELECT 'Sales Weekly Report Count' AS ReportName, 
			CAST((Select COUNT(*) FROM Sales WHERE SaleDate >= CAST(GETDATE() -6 AS DATE) ) AS VARCHAR) AS Result 

UNION ALL 

SELECT 'HR Dept. Count' AS ReportName, 
			CAST((Select COUNT(*) FROM Users DepartmentID = 1) AS VARCHAR) AS Result 
			
UNION ALL 

SELECT 'Todays New Joiny' AS ReportName, 
         CAST((Select TOP 1 firstname FROM Users ORDER BY EmpID DESC) AS VARCHAR) AS Result

Hmmm Now looks better. But its easy right!!! Yes, using UNION ALL i have built the dynamic query and then execute it.

That’s it guys. Hope you like this post and learned something new today. Have a nice day.

Implement multiple interfaces with same function name and parameters in a class

Few days ago, I got the consultancy work for one of my friend’s firm. In their project i have had faced one interesting issue where there were two interfaces which contain same function name with same parameters and i needed to implement it in one class.

Rather than go into much theory let’s create this situation and see how we can get rid of this situation.

But first we see that what happen if we implement those interfaces in one class. So let’s create the required interfaces and class. So here we have our first interface named – “IStudent

public interface IStudent
{
	///<summary>
	/// Get list of student who have birthday today
	/// </summary>
	/// <returns></returns>
	DataTable GetTodaysBirthdayList(string date = "");
}

And here we have second interface.

public interface IStaff
{
	///<summary>
	/// Get list of staff member who have birthday today
	/// </summary>
	/// <returns></returns>
	DataTable GetTodaysBirthdayList(string date = "");
}

Now let’s try to implement these two interfaces in class.

public class School : IStudent, IStaff
{
	#region IStudent Members

	public DataTable GetTodaysBirthdayList(string date = "")
	{
		var dtList = new DataTable();
		// Business logic to get list of student who have birthday today
		return dtList;
	}

	#endregion

	#region IStaff Members

	public DataTable GetTodaysBirthdayList(string date = "")
	{
		var dtList = new DataTable();
		// Business logic to get list of staff who have birthday today
		return dtList;
	}

	#endregion
}

Alright let’s rebuild the application and see what happen. Whoaa… we get the error!

InterfaceError

Error: Type “School” already defines a member “GetTodaysBirthdayList”

I think no need to explain the error message. Now let’s remove any of the method from the class and rebuild the application. Error is gone now, But the problem is how can you know that which interface method you wanna call!

So to overcome to this situation we need to explicitly implement those interfaces. How ? Let’s see this practically.

public class School : IStudent, IStaff
{

	#region IStudent Members

	DataTable IStudent.GetTodaysBirthdayList(string date)
	{
		var dtList = new DataTable();
		// Business logic to get list of studnet who have birthday today
		Console.WriteLine("=> From IStudent interface.");
		return dtList;
	}

	#endregion

	#region IStaff Members

	DataTable IStaff.GetTodaysBirthdayList(string date)
	{
		var dtList = new DataTable();
		// Business logic to get list of staff who have birthday today
		Console.WriteLine("=> From IStaff interface.");
		return dtList;
	}

	#endregion

	// You cannot directly access explicitly implemented interface method
	// So we need two public method to call above interface method

	public DataTable GetTodaysBirthdayListOfStudent(string date = "")
	{
		IStudent objStudent = (IStudent)this;
		return objStudent.GetTodaysBirthdayList();
	}

	public DataTable GetTodaysBirthdayListOfStaff(string date = "")
	{
		IStaff objStaff = (IStaff)this;
		return objStaff.GetTodaysBirthdayList();
	}
}

By creating an instance of the above class you cannot directly access explicitly implemented interface method. For that we need two public method to call implemented interface method as shown in above class.

And now its time to call the above class method, like this –

static void Main(string[] args)
{
    var school = new School();
            
    var staffList = school.GetTodaysBirthdayListOfStaff();
    var studnetList = school.GetTodaysBirthdayListOfStudent();
}

And we are done. Well after seeing above code you might think that instead of following the above stuff i can make one common interface with common method and inherit that interface in IStaff and IStudent interface. Well Ofcouse you can do that, But consider a situation where you are using any third party DLL or in your existing application you cannot alter or made any changes due to any architectural restriction.

Alright, Hope you enjoyed this post. Thanks for reading this post.

How to achieve UNION ALL and UNION in LINQ

In one of my application, I came to a situation where I had to use UNION ALL like functionality for two enumerable list by using LINQ. So in today’s post we’ll learn about how we can achieve UNION and UNION ALL like functionality using LINQ. You can do a UNION operation using the Union method in LINQ and UNION ALL operation using the Concat method.

Let’s see this practically –

First we will learn about Union method.

static void Main(string[] args)
{
	var productsFromMicrosoft = new List<string>
	{
		"Visual Studio",
		"MS Office",
		"Xbox",
		"Mail Service"  // <-- This product is in both list
	};

	var productsFromGoogle = new List<string>
	{
		"Google Chrome",
		"Mail Service",  // <-- This product is in both list
		"Blogger"
	};

	var unionList = productsFromMicrosoft.Union(productsFromGoogle).ToList();

	Console.WriteLine(unionList);
}

UnionList

So as expected, UNION method excludes duplicates from the return set.

Now we will see Concat operator.

static void Main(string[] args)
{
	var productsFromMicrosoft = new List<string>
	{
		"Visual Studio",
		"MS Office",
		"Xbox",
		"Mail Service"  // <-- This product is in both list
	};

	var productsFromGoogle = new new List<string>
	{
		"Google Chrome",
		"Mail Service",  // <-- This product is in both list
		"Blogger"
	};

	var unionAllList = productsFromMicrosoft.Concat(productsFromGoogle).ToList();

	foreach (var product in unionAllList)
	{
		Console.WriteLine(product);
	}
}

UnionAllList

The Concat method differs from the Union method because the Concat() method returns all the original elements in the input sequences. The Union method returns only unique elements.

Reference Link:

That’s it folks. Hope you like this post.

NOWAIT hint in SQL Server

Today, I was reading about Table Hint in MSDN for other reason and came across this “NOWAIT” hint. In today’s post we will learn about NOWAIT hint. Well, SQL server uses locks to ensure that the data in your table can be accessed, without risk of corruption or dirty reads. Let say when you are inserting or updating records within transaction then your table are locked and other transaction have to wait to read or change the records.

Sometime we are in situation that when our application request for data and if our request is locked by SQL server then rather than wait for some interval, its better to move out. So in that type of situations “NOWAIT” hint comes into the picture. It means when you apply this hint and requesting for select records from the table, the command fails immediately if current request is blocked and then reporting an error.

Let’s see this practically –

Open two query window in your SQL Server Management Studio. Assume that you have a table named Products and you tried to insert some records within one transaction as shown below in query window 1.

BEGIN TRAN

INSERT INTO Products
     VALUES (1, 'iPhone 5s', 55200)

--ROLLBACK
--COMMIT TRAN

To create the blocking situation, i have not committed transaction in above query

Query_Window_1

Now in second query window if you fire select statement command without any hint then you have to wait for infinite interval of time as our above transaction is not completed. But what happen if you fire select command with “NOWAIT” hint like below –

SELECT * FROM Products WITH (NOWAIT);

Above query results in an error as shown below.

Query_With_NoWaitHint

And you have to now manage the exception in your application and modify the code accordingly. Hope this post may help you in future.

That’s it for now folks. Hope you like this post.

Resolve same namespace collision between two assembly

One of my friend worked in his freelancing project. In his project there were more than 4 class library projects used within his application. But by mistake he had created the same namespace with same class name within the two class library project. After adding the references of that class library in his main project, when he tried to create an instance of that class, he got the following error.


Error 1
The type ‘Lib1.PatientDataContext’ exists in both ‘d:\TFS\Lib1\bin\Debug\Lib1.dll’ and ‘d:\TFS\Lib2\bin\Debug\Lib2.dll’

It means the C# compiler gets confused that which assembly it has to use for creating an instance of the class. That’s why it throws an above error.

So he asked me to resolve his issue. well, i have never faced this type of error before. So i did some googling and came to the solution that by using extern alias provided in C#, above issue can be resolve.  How ? Let’s see this practically by creating that scenario.

In Visual studio, let’s create one console application and named it as – NameSpaceCollisionApp. Now within the same solution of the application add the two new class library project. In each class library assembly add one new class named – PatientDataContext.cs. But keep in mind that both of these class are within same namespace. The code of both the class looks like this –

ClassLibrary1 / PatientDataContext.cs

namespace DataServiceFactory.DataContext
{
    public class PatientDataContext
    {
        public PatientDataContext()
        {
        }

        public override string ToString()
        {
            return "From Class Library 1";
        }
    }
}

ClassLibrary2 / PatientDataContext.cs

namespace DataServiceFactory.DataContext
{
    public class PatientDataContext
    {
        public PatientDataContext()
        {
        }

        public override string ToString()
        {
            return "From Class Library 2";
        }
    }
}

When you build the application, you’ll get the error highlighted above. So let’s resolve it by following the below steps.

Step-1: In the solution explorer, expand the “References” folder and  select the required assembly name then right click on it and open its property window.

Service1Property

Step-2: In the property window, change the aliases name from “global” to “Service1 (Whatever you want)”.

ChangeAliase

Step-3: Same way follow the Step-2 for ClassLibrary2 reference also.

Step-4: Now to use it in your main application, you need to add – extern alias “alias name”; line of code to the top of your source file, something like this –

extern alias Service1;
extern alias Service2;

using System;

namespace NameSpaceCollision
{
    class Program
    {
        static void Main(string[] args)
        {
            var object1 = new Service1.DataServiceFactory.DataContext.PatientDataContext();

            var object2 = new Service2.DataServiceFactory.DataContext.PatientDataContext();

            Console.WriteLine(object1);
            Console.WriteLine(object2);
            Console.ReadLine();
        }
    }
}

And we are done. Hope you like this post and hope it may help to my future readers. You can find the demo application from here.

 

Tip: Finding a value in any of the columns in a SQL Server table

Few days ago one of my colleague working in another team in my office asked me one question that he have had one table named “PatientDetail” with 58 columns and he wanted to find value from all varchar columns. As a developer the first solution came in my mind was – check value in each column like this FirstName = ‘hello’ OR LastName = ‘hello’ OR…so on. One thing to note here is there are more than 50 varchar columns out of 58 columns. So your query looks something like this –

SELECT * FROM PatientDetail
    WHERE FirstName = 'hello'
	  OR LastName = 'hello'
	  OR Column3 = 'hello'
	  OR Column4 = 'hello'
	  Or Column5 = 'hello'
	  OR ... Column52 = 'hello'

Don’t you think that above query becomes too much lengthy if i write each column name here. So What is the preferred solution ?

Hmm Do you know that you can use column name in “IN Clause” in sql server!! Really ??

Yes, the above query you can rewrite like this –

SELECT * FROM PatientDetail
     WHERE 'hello' IN (FirstName, LastName, Column3, Column4, Column5,...)

Well, we just reverse the IN Clause! and this is perfectly valid statement for sql server. Try it yourself. Now the only problem here is we still have to write more than 50 columns in “IN” clause. So to overcome this problem, let’s convert the above query into dynamic sql.

-- *** Prepare comma seperated column list ***
DECLARE @ColumnNames VARCHAR(3000)

SELECT @ColumnNames = ISNULL(@ColumnNames + ', ' + QUOTENAME(COLUMN_NAME), QUOTENAME(COLUMN_NAME)) 
FROM INFORMATION_SCHEMA.COLUMNS
WHERE TABLE_NAME = 'PatientDetail'
	AND DATA_TYPE IN ('char', 'nvarchar', 'text', 'varchar')

--PRINT @ColumnNames

DECLARE @query VARCHAR(MAX)=
	'SELECT * FROM PatientDetail
	WHERE ''hello'' IN (' + @ColumnNames + ')'
	
EXEC SP_EXECUTESQL @query

That’s it. Hope you like this tip. If you know any other solution then post it in the comments. Thank you for reading this post.

Zen Coding in Visual Studio 2015 using Web Essesntial Extension

Few months ago, I have added web essentials 2015 extension to my visual studio and studied its features. This is truly for web developers which makes their life easier. In this post we’ll see one of its great productivity booster feature and that is Zen Coding.

Zen Coding is a plug-in to generate HTML or CSS code in much faster way using jquery/css like selectors. Before we go into the detail let’s first install it in our visual studio.

Follow the below steps.

  • Open the visual studio.
  • Go to the Tools menu and click on Extensions and Updates menu item which will open one window.
    Web_Essesntials_Install
  • In the Extensions and Updates window, click on “Online” in the left pane. Once you click on it you got the list of extensions on the right side.

Web_Essesntials_Extension

  • Select the “Web Essesntials 2015” and click on “Download” button.

 

After installing this plug-in, it’s time to play with it.

Let’s say I want to generate simple table tr HTML. So here is how you can generate it with Zen coding.

table>tr>td

Now hit “Tab” key and it generate the following html code.

<table>
    <tr>
        <td></td>
    </tr>
</table>

Now I want to generate table with 3 “tr” and 2 “td” with some content in each “td”.

table>tr*3>td{hello world}*2

Now hit “Tab” key and it generate the following html code.

<table>
    <tr>
        <td>hello world</td>
        <td>hello world</td>
    </tr>
    <tr>
        <td>hello world</td>
        <td>hello world</td>
    </tr>
    <tr>
        <td>hello world</td>
        <td>hello world</td>
    </tr>
</table>

As a web developer you know all the html tags but what is the use of “*”(star) and “{ }”(curly braces) in the above zen code ?

Well, there are some more characters available which will have its own usage in zen code. Let’s first understand each one with example.

1). “#” – Creates an Id attribute for specified tag.

Example

div#testId>span

Hit “Tab” key which will generate the following html code.

<div id="testId">
    <span></span>
</div>

 

2). “.” – Creates a class attribute for specified tag.

Example

div.inlineBlock>ul>li

Hit “Tab” key which will generate the following html code.

<div class="inlineBlock">
    <ul>
        <li></li>
    </ul>
</div>

 

3). “[]” – Creates a custom attribute for specified tag.

Example

div[title]>button[value=”Save”]

generates the following html.

<div title="">
    <button value="Save"></button>
</div>

 

4). “>” – Creates a child element after specified tag.

Example

div>p>img

generates the following html.

<div>
    <p>
        <img src="" alt="" />
    </p>
</div>

 

5). “+” – Creates a Sibling element.

Example

div>p>img+a

generates the following html.

<div>
    <p>
        <img src="" alt="" />
        <a href=""></a>
    </p>
</div>

 

6). “*n” – Creates the specified elements for n number of times.

Example

div>ul>li*2>a

generates the following html.

<div>
    <ul>
        <li><a href=""></a></li>
        <li><a href=""></a></li>
    </ul>
</div>

 

7). “$$” – Generates the incremental numbers.

Example

table>tr#id$$*3>td

generates the following html.

<table>
    <tr id="id01">
        <td></td>
    </tr>
    <tr id="id02">
        <td></td>
    </tr>
    <tr id="id03">
        <td></td>
    </tr>
</table>

 

8). “{}” – Add the text inside the elements.

Example

div>p*4>span{This is my own text $$}

generates the following html.

<div>
    <p>
        <span>This is my own text 01</span>
    </p>
    <p>
        <span>This is my own text 02</span>
    </p>
    <p>
        <span>This is my own text 03</span>
    </p>
    <p>
        <span>This is my own text 04</span>
    </p>
</div>

 

9). “()” – Grouping the expression and generate HTML accordingly.

Example

table>(tr>th{column $$}*3)+(tr>td*3)

generates the following html.

<table>
    <tr>
        <th>column 01</th>
        <th>column 02</th>
        <th>column 03</th>
    </tr>
    <tr>
        <td></td>
        <td></td>
        <td></td>
    </tr>
</table>

 

Apart from all of the above, you can now also add Lorem Ipsum text in your HTML Code. Simply type lorem and hit TAB and a 30 words of Lorem Ipsum text is inserted. If you want to add only 4 words of Lorem Ipsum then just type below code and hit “Tab” key.

div>p*4>lorem4

<div>
    <p>Amet, consectetur adipiscing elit.</p>
    <p>Fusce vel sapien elit.</p>
    <p>In malesuada semper mi.</p>
    <p>Id sollicitudin urna fermentum.</p>
</div>

You can find many more other features from its official web site.

That’s it for now. Hope you enjoy this post.

Get list of property value from another list based on supplied property name using indexer in c#

Recently in one of our MVC application, I have had a requirement to read property value from one generic list by using property name, i.e. For exa. Consider one function named – GetPropertyValueList() which has one parameter named – propertyName. By using that parameter this function return the List<object> (List of property value).

OK, Let me explain further my requirement in detail. One of our end user wanted to migrate some of his customers manually. So I had to develop one page which displays specific customer list retrieve from the database. Now this page contains different sections to display list of property value. For exa. “LastName” property section displays only list of customer’s last name in radio-button list. Same way in other section let say “Age” property section displays only list of customer’s age in radio-button list. Same way for other properties too of customer class.

Now let’s see this practically. To achieve this functionality I need to develop several modal classes in my application’s modal layer. For demo purpose I have shown you these things in action in one console application in this post.

My first modal class is a normal “Customer” class.

public class Customer
{

    public string FirstName { get; set; }

    public string LastName { get; set; }

    public int Age { get; set; }

    public string MobileNo { get; set; }

    // Same way there are more than 20 properties in my mvc application
    //public string Address { get; set; }
}

My second modal class is “SourceCustomerInfo” class.

public class SourceCustomerInfo
{
	///<summary>
	/// To get the name of property at run time of Customer class
	/// </summary>

	public Customer customerField { get; set; }

	///<summary>
	/// Contain list of customers from database to migrate
	/// </summary>

	public List<Customer> customerList { get; set; }

}

 

In SourceCustomerInfo class first property customerField is used to get list of property value from customerList property. You can see the detail usage of this class in our console application.

My third modal class is “CustomerFieldValueList” class.

public class CustomerFieldValueList
{
	///<summary>
	/// Contain name of the property to render in the lable
	/// </summary>

	public string FieldName { get; set; }

	///<summary>
	/// Contain list of property value to render in the radio-button list
	/// </summary>

	public List<object> FieldValueList { get; set; }

}

Why I need to develop this modal ? Well, my MVC View renders all labels and its related radio-button list dynamically (By using above modal class). In the above class first property FieldName is used as label in MVC View and second property FieldValueList is used to fill radio-button list. Hmmm sorry for my bad English, But Here is the screen-shot of this class of what you’ll get at run time in each property for better understanding.

FieldValueList

All right, now the key point is here. To achieve my key requirement I need to use “Indexers” – a very special type of class member in C#. An indexer allows an object to be indexed like an array. The main use of “indexers” is to support the creation of specialized arrays or list. For more information on “Indexers” refer this MSDN link.

Here is the indexer that I have added in “Customer” class.

public class Customer
{

	///<summary>
	/// Get the value by supplied property name
	/// </summary>
	/// <param name="propertyName"></param>
	/// <returns></returns>
	public object this[string propertyName]
	{
		get
		{
			return this.GetType().GetProperty(propertyName).GetValue(this, null);
		}
	}

	public string FirstName { get; set; }

	public string LastName { get; set; }

	public int Age { get; set; }

	public string MobileNo { get; set; }

	// Same way there are more than 20 properties in my mvc application
	//public string Address { get; set; }

}

As you can see that I have read property value by using propertyName as parameter thru reflection in indexer.
Let’s combine all of these modal classes in one console application and see it in action. Here i have show you only the Main() method code. You can download the full source code from here.

static void Main(string[] args)
{
	var sourceCustomerInfo = new SourceCustomerInfo() {customerField = new Customer() };

	// Get the name of all property of customer class using reflection in array.
	var arrayPropNames = sourceCustomerInfo.customerField
							.GetType()
							.GetProperties()
							.Select(p => p.Name)
							.ToArray();
	// Fill the Customer list
	sourceCustomerInfo.customerList = new List<Customer>
	{
		new Customer() { FirstName="Kapil", LastName="Dev", Age=55, MobileNo="123" },
		new Customer() { FirstName="Sachin", LastName="Tendulkar", Age=45, MobileNo="123" },
		new Customer() { FirstName="Rahul", LastName="Dravid", Age=50, MobileNo="123" }
	};

	var fieldValueList = new List<CustomerFieldValueList>();
	//Now we iterate thru each property name that we already get in array
	foreach (var propertyName in arrayPropNames)
	{
		// Check propertyName is not blank or not our indexers
		if (!string.IsNullOrEmpty(propertyName) && propertyName != "Item")
		{
			// Initialize new instance of CustomerFieldValueList class
			var customerFieldValueList = new CustomerFieldValueList();

			// Set customerField with current property name
			customerFieldValueList.FieldName = propertyName;

			// Get the list of property value by supplied propertyName parameter using indexers
			// from the customerList property of SourceCustomerInfo class.
			customerFieldValueList.FieldValueList = sourceCustomerInfo.customerList.Select(p => p[propertyName]).ToList();

			// Now add this class instance into fieldValueList List.
			fieldValueList.Add(customerFieldValueList);
		}
	}

	// Now we are ready to render it in our MVC View.
	// Here we'll render it in console.
	fieldValueList.ForEach(obj =>
		{
			// Display FieldName value after 15 spaces
                        Console.WriteLine("FieldName  => {0, 15}", obj.FieldName);

			obj.FieldValueList.ForEach(lst =>
				{
					// Display property value after 15 spaces
					Console.WriteLine("     List  => {0, 15}", lst);
				});
			Console.WriteLine("=========================================");
		});

	Console.ReadLine();
}

And here is the output in console.

FinalResult

That’s it folks. Hope you like this post. Leave your comments.