Prajwal Tuladhar’s Blog
 
programming, life and some random thoughts

Archive for the 'C#' Category

Nov 23 2008

Many-to-many mapping in NHibernate

Published by Prajwal Tuladhar under .NET, C#

In systems analysis, a many-to-many relationship refers to a relationship between two entities (see also Entity-Relationship Model) A and B in which A may contain a parent row for which there are many children in B and vice versa. Because most DBMSs only support one-to-many relationships, it is necessary to implement such relationships physically via a third junction table, say, AB with two one-to-many relationships A -> AB and B -> AB. In this case the logical primary key for AB is formed from the two foreign keys (i.e. copies of the primary keys of A and B).

In web application frameworks such as CakePHP and Ruby on Rails, a many-to-many relationship between database tables in a model is usually referred to as a hasAndBelongsToMany (HABTM) relationship. - Wikipedia

Before going through many-to-many mapping in NHibernate, we need to have basic concept of some collection types used in NHibernate.

  • Bag: It is a collection type in which elements can be repeated {1, 2, 1, 3, 2, 3, 4} and it is implemented as IList or IList<T>.
  • Set: It is a collection type in which elements must be unique {1, 2, 3, 4} and it is implemented as ISet or Iset<T> as a part pf Iesi.Collections.dll.
  • List: It is a collection of objects with integer indices {1, “Max”}, {2, “Prajwal”} , {3, “Max”} and it is also implemented as IList or IList<T>.
  • Map: It is a collection of key-value pairs {{”Prajwal”, 1}, {”Max”, 2}} and it is implemented as HashTable or IDictionary<TKey, TValue>.

I am using Northwind database to illustrate many-to-many mapping.

The above table relationship between Customers, CustomerDemographics and CustomerCustomerDemo represent many-to-many relationship because CustomerCustomerDemo table has many forms of Customers as well as CustomerDemographics. I need only Customers entity and CustomerDemographics entity to match the third table CustomerCustomerDemo in NHibernate to map the relation among these tables. The two strong entities are responsible for mapping a weak entity. Mapping is straight forward.

XML Mapping file for Customers Customer.hbm.xml


<?xml version="1.0" encoding="utf-8" ?>
<hibernate-mapping xmlns="urn:nhibernate-mapping-2.2" assembly="DataTransfer" namespace="DataTransfer">
<class name="DataTransfer.Customer,DataTransfer" table="`Customers`">
<id name="CustomerID" column="CustomerID" type="string" length="5">
<generator class="assigned" />
</id>

<property name="CompanyName" column="CompanyName" type="string" length="40" not-null="true" />
<property name="ContactName" column="ContactName" type="string" length="30" not-null="true" />
<property name="ContactTitle" column="ContactTitle" type="string" length="30" not-null="true" />
<property name="Address" column="Address" type="string" length="60" not-null="true" />
<property name="City" column="City" type="string" length="15" not-null="true" />
<property name="Region" column="Region" type="string" length="15" not-null="true" />
<property name="PostalCode" column="PostalCode" type="string" length="10" not-null="true" />
<property name="Country" column="Country" type="string" length="15" not-null="true" />
<property name="Phone" column="Phone" type="string" length="24" not-null="true" />
<property name="Fax" column="Fax" type="string" length="24" not-null="true" />

<bag name="CustomerDemographics" generic="true" table="CustomerCustomerDemo" lazy="true">
<key column="CustomerID" />
<many-to-many column="CustomerTypeID" class="DataTransfer.CustomerDemographic,DataTransfer" />
</bag>

</class>
</hibernate-mapping>

<strong>XML Mapping file for CustomerDemographics CustomerDemographic.hbm.xml</strong>


<?xml version="1.0" encoding="utf-8" ?>
<hibernate-mapping xmlns="urn:nhibernate-mapping-2.2" assembly="DataTransfer" namespace="DataTransfer">
<class name="DataTransfer.CustomerDemographic,DataTransfer" table="CustomerDemographics">
<id name="CustomerTypeID" column="CustomerTypeID" type="string" length="10">
<generator class="assigned" />
</id>
<property name="CustomerDesc" type="string" not-null="false" />

<bag name="Customers" table="CustomerCustomerDemo" lazy="true">
<key column="CustomerTypeID" />
<many-to-many column="CustomerID" class="DataTransfer.Customer,DataTransfer" />
</bag>
</class>
</hibernate-mapping>

Data Access Layer Code for getting CustomerDemographics value having CustomerID


public IList GetCustomerDemographicsWithCustomerID(string customerID)
{
return _session
.CreateCriteria(typeof(CustomerDemographic))
.CreateCriteria("Customers")
.Add(Expression.Eq("CustomerID", customerID))
.List();
}

Unit Testing the code


[Test]
public void CanGetCustomerDemographicsWithCustomerID()
{
IList demographics = _provider.GetCustomerDemographicsWithCustomerID("CACTU");
Assert.GreaterThan(demographics.Count, 0);
}

Debug time vale of the object IList<CustomerDemographic>

Download this solution

Technorati Tags: ,
kick it on DotNetKicks.com


Comments

Nov 20 2008

Mapping a View in NHibernate

Published by Prajwal Tuladhar under .NET, C#

There is not so much difference in mapping between a table and a View in NHibernate. Since view is generally considered a virtual table with read only mode. Some properties needs to be changed in the hbml.xml file and a persistence class.

For clarifying the concept here is my table definition consisting two tables Milestones and MilestoneCompletions.

From the above two table I have created a View “ViewCompletedMilestone” which is responsible for selecting only completed milestones.

SQL for View

SELECT dbo.MilestoneCompletions.CompletionDate, dbo.Milestones.MilestoneID, dbo.Milestones.ProjectID, dbo.Milestones.MemberID, dbo.Milestones.Name, dbo.Milestones.Description, dbo.Milestones.DueDate, dbo.Milestones.CreatedDate, dbo.Milestones.UpdatedDate FROM dbo.MilestoneCompletions INNER JOIN dbo.Milestones ON dbo.MilestoneCompletions.MilestoneID = dbo.Milestones.MilestoneID

Persistence Class - ViewCompletedMilestone.cs


namespace DataTransfer
{
	public class ViewCompletedMilestone
	{
		private Guid _milestoneId;
		public virtual Guid MilestoneId
		{
			get { return _milestoneId; }
			private set { _milestoneId = value; }
		}

		private DateTime _CompletedDate;
		public virtual DateTime CompletionDate
		{
			get { return _CompletedDate; }
			private set { _CompletedDate = value; }
		}

		private Guid _ProjectID;
		public virtual Guid ProjectID
		{
			get { return _ProjectID; }
			private set { _ProjectID = value; }
		}

		private int _MemberID;
		public virtual int MemberID
		{
			get { return _MemberID; }
			private set { _MemberID = value; }
		}

		private string _Name;
		public virtual string Name
		{
			get { return _Name; }
			private set { _Name = value; }
		}

		private string _Description;
		public virtual string Description
		{
			get { return _Description; }
			private set { _Description = value; }
		}

		private DateTime _DueDate;
		public virtual DateTime DueDate
		{
			get { return _DueDate; }
			private set { _DueDate = value; }
		}

		private DateTime _CreatedDate;
		public virtual DateTime CreatedDate
		{
			get { return _CreatedDate; }
			private set { _CreatedDate = value; }
		}

		private DateTime _UpdatedDate;
		public virtual DateTime UpdatedDate
		{
			get { return _UpdatedDate; }
			private set { _UpdatedDate = value; }
		}
	}
}

Since we are not going to change the data from our persistence class, setters are declared as private.

Hibernate Mapping File - ViewCompletedMilestone.hbm.xml

<?xml version="1.0" encoding="utf-8" ?>
<hibernate-mapping xmlns="urn:nhibernate-mapping-2.2" assembly="DataTransfer" namespace="DataTransfer">
<class name="DataTransfer.ViewCompletedMilestone" table="ViewCompletedMilestone" mutable="false">
<id name="MilestoneId" column="MilestoneId" type="Guid">
<generator class="guid" />
</id>
<property name="CompletionDate" column="CompletionDate" type="DateTime" not-null="true" />
<property name="ProjectID" column="ProjectID" type="Guid" not-null="true" />
<property name="MemberID" column="MemberID" type="Int32" not-null="true" />
<property name="Name" column="MemberID" type="string" length="255" not-null="true" />
<property name="Description" column="Description" type="string" not-null="true" />
<property name="DueDate" column="DueDate" type="DateTime" not-null="true" />
<property name="CreatedDate" column="CreatedDate" type="DateTime" not-null="true" />
<property name="UpdatedDate" column="UpdatedDate" type="DateTime" not-null="true" />
</class>
</hibernate-mapping>

It should be noted that the mutable property of the class node is set as false because we don’t want our mapped class to make some changes.

Data Access Layer for mapped class - NHibernateDataProvider.cs


using NHibernate;
using NHibernate.Cfg;
using DataTransfer;

namespace DataAccessLayer
{
	public class NHibernateDataProvider
	{
		private ISession _session;
		public ISession Session
		{
			set { _session = value; }
		}

		public NHibernateDataProvider(ISession session)
		{
			_session = session;
		}

		public IList<ViewCompletedMilestone> GetCompletedMilestones()
		{
			return _session
			.CreateCriteria(typeof(ViewCompletedMilestone))
			.List<ViewCompletedMilestone>();
		}
	}
}

In order to check the result of our class we should do unit testing. I have used MBUnit for unit testing.

Unit Testing Class - DataAccessLayerTest.cs


using MbUnit.Framework;
using DataTransfer;
using DataAccessLayer;
using NHibernate;

namespace DataAccessLayerTest
{
	[TestFixture]
	public class DataAccessLayerTest
	{
		private NHibernateDataProvider _provider;
		private NHibernateSessionManager _manager;
		private ISession _session;

		[TestFixtureSetUp]
		public void TestFixtureSetUp()
		{
			_manager = new NHibernateSessionManager();
		}

		[SetUp]
		public void SetUp()
		{
			_session = _manager.GetSession();
			_provider = new NHibernateDataProvider(_session);
		}

		[Test]
		public void CanGetCompletedMilestones()
		{
			IList<ViewCompletedMilestone> milestones = _provider.GetCompletedMilestones();
			foreach (ViewCompletedMilestone m in milestones)
			{
				Assert.GreaterThan(m.CompletionDate, m.CreatedDate);
			}
		}
	}
}

Result of the unit test:

SQL generated by NHibernate in the console:

SELECT this_.MilestoneId as Mileston1_0_0_, this_.CompletionDate as Completi2_0_0_, this_.ProjectID as ProjectID0_0_, this_.MemberID as MemberID0_0_, this_.Description as Descript5_0_0_, this_.DueDate as DueDate0_0_, this_.CreatedDate as CreatedD7_0_0_, this_.UpdatedDate as UpdatedD8_0_0_ FROM ViewCompletedMilestone this_

Download this file here.


Comments

Nov 11 2008

Parsing query string in ASP.NET safely

Published by Prajwal Tuladhar under ASP.NET, C#

Both of the code behind languages for ASP.NET (C# or Visual Basic.NET) are statically typed languages. So, the type checking operation is performed during the compiled time unlike during the run-time for dynamically typed languages like PHP, Perl, Python, Ruby and so on. This make a-bit difficult to validate and parse the query string for ASP.NET pages. All the ASP.NET query string are treated as a String by default. Parsing needs to be performed in order to get appropriate data types.

For instance lets take a URL: http://somedomain.com/Default.aspx?QueryStringInt=2

It has a single query string named QueryStingInt which is expected to have data type Int32. In a default scenario it would be enough to change the query string to an integer type by

Int32.Parse(Request.QueryString["QueryStringInt"]);

But what if someone just manipulated the URL like: http://somedomain.com/Default.aspx?QueryStringInt=a

There would be error.

This condition can be avoided by using a simple technique. Consider the code below:


    private int _queryStringInt;
    public int? QueryStringInt
    {
        get
        {
            return (int.TryParse(Request.QueryString["QueryStringInt"], out _queryStringInt))
                ? int.Parse(Request.QueryString["QueryStringInt"]) : 0;
        }
    }

    private string _queryStringDefault;
    public string QueryStringDefault
    {
        get
        {
            return (Request.QueryString["QueryStringDefault"] == null || Request.QueryString["QueryStringDefault"] == "")
                ? "" : Request.QueryString["QueryStringDefault"];
        }
    }

    private Guid _queryStringGuid;
    public Guid QueryStringGuid
    {
        get
        {
            try
            {
                _queryStringGuid = new Guid(Request.QueryString["QueryStringGuid"]);
            }
            catch (FormatException)
            {
                _queryStringGuid = new Guid("00000000000000000000000000000000");
            }
            catch (ArgumentNullException)
            {
                _queryStringGuid = new Guid("00000000000000000000000000000000");
            }
            catch (OverflowException)
            {
                _queryStringGuid = new Guid("00000000000000000000000000000000");
            }
            return _queryStringGuid;
        }
    }

    protected void Page_Load(object sender, EventArgs e)
    {
        //_queryStringInt = (int.TryParse())
        Response.Write(QueryStringInt + "<br/>");
        Response.Write(QueryStringDefault + "<br/>");
        Response.Write(QueryStringGuid + "<br/>");
    }

If the query string is not of the expected data type then there would not be error rather a default value can be assigned in those situation.

Invalid Type Query Strings

Query String Values:

Valid Type Query Strings

Query String Values:

Technorati Tags: ,,,

Comments

Oct 10 2008

Abstract Class versus Interface

Published by Prajwal Tuladhar under .NET, C#, Patterns, Programming

In software engineering, an abstract type is a type in a nominative type system which is declared by the programmer, and which has the property that it contains no members which are also not members of some declared subtype.
Interface generally refers to an abstraction that an entity provides of itself to the outside. This separates the methods of external communication from internal operation, and allows it to be internally modified without affecting the way outside entities interact with it, as well as provide multiple abstractions of itself. It may also provide a means of translation between entities which do not speak the same language, such as between a human and a computer. Because interfaces are a form of indirection, some additional overhead is incurred versus direct communication. -Wikipedia

In Java, .NET and PHP 5 there are three ways to create and object i.e. inheritance, composition and interface.

  • Inheritance defines “is-a” relationship. Example: Student and Programmer is a Person
  • Composition defines “has-a” relationship. Example: Class Student contains class Book
  • Interface only models the behavior of an object. Example: Student and Programmer are both Nameable and both may have actions.

In Java, .NET and PHP 5, multiple inheritance (child class with more than one parent class) is not allowed so, interface can be used as a powerful tool to separate implementation. Interface is not a strict “is a” relationship. Abstract class represents some sort of implementation and it is a strict “is a” relationship. For example: A dog is a mammal and a reptile is not a mammal showing strict relationship whereas both dog and reptile may be nameable and both may have some actions.

abstract interface example

As we know that interface and abstract class both provide abstract methods so, making the best use of them is crucial in the object oriented paradigm. Abstract class provides both concrete and abstract methods whereas interface provides only abstract methods. Lets go through an example:

Assume that we have an abstract class Person and its concrete implementation class Student and Programmer. We have an interface called IWork that may or may not be implemented by the concrete classes Student and Programmer. We also have a composite class Address, though it is not required while distinguishing between interface and abstract class, using composite class will help us to clarify the scenario.

Class Diagram

Abstract Interface Class Diagram

Abstract Interface Class Diagram

C# Code

Abstract Class - Person

Abstract Class - Person

Interface - IWork

Interface - IWork

Class Address

Class - Address

Class - Programmer

Class - Programmer

Class - Program

Class - Program

Conclusion

  • Classes in a strict inheritance relationship must be related.
  • Interfaces can be used for classes that are not related. In the above example, only Programmer class is implemented but it is not necessary that Student also implements the IWork interface.
  • An interface never provides any implementation, only behavior.

References

You can download the example from here.


Comments

RSS Feed
Subscribe by email
Follow me @ Twitter