Click here to Skip to main content
15,886,199 members
Please Sign up or sign in to vote.
2.00/5 (1 vote)
Hi..
I am a fresher and want to know how to get property from inner class for sorting
Description as follows
I have ClassOne which have properties and object of ClassTwo class which also have properties.
So I want to get property of ClassTwo so that I can apply sorting depending on that property of ClassTwo which is in ClassOne using LINQ query.
Posted
Updated 3-Feb-12 10:26am
v2

Hi,

I don't know exactly what you want to achieve, but I tried to make example for your question.
First of all, this example is written in LINQPad[^]. You must have this tool if yuo want to play with linq. :)
Download LINQPad and paste this code example in new query. For language select "C# Program" and run it.

C#
void Main()
{
	// Collection of Parent objects
	var parents = new List<parent>(new Parent[]
		{
			new Parent { ParentID = 1, Name = "John", Child = new Child { ChildID = 1, Name = "Child1", Date = new DateTime(2012, 02, 01) }},
			new Parent { ParentID = 2, Name = "Mark", Child = new Child { ChildID = 2, Name = "Child2", Date = new DateTime(2012, 02, 10) }},
			new Parent { ParentID = 3, Name = "Jack", Child = new Child { ChildID = 3, Name = "Child3", Date = new DateTime(2012, 01, 31) }}
		}
	);
	parents.Dump("Before Sort");
	
	var parentsSortedByChildDate = from p in parents
									orderby p.Child.Date ascending
									select p;
									
	parentsSortedByChildDate.Dump("After Sort");
}

// Define other methods and classes here
public class Parent
{
  public int ParentID { get; set; }
  public string Name { get; set; } 
  public Child Child { get; set; }
}

public class Child
{
  public int ChildID { get; set; }
  public string Name { get; set; }
  public DateTime Date { get; set; }
}


I guess you are using some ORM tool/framewrok (NHibernate,EntityFramewrok, LinqToSQL) and you have objects that are related like these in my example?!
Never mind! I just want to say that you can use LINQ to query any enumerable collections such as
C#
List<t>, Array, or Dictionary<tkey,>

In general, you can query "anything" that implements
C#
IEnumerable or IEnumerable<t>
interfaces.
You can visti msdn sites[^] for more info about LINQ for start.

Ok, I talk too much... ;)
Bye...
 
Share this answer
 
v2
Comments
Sergey Alexandrovich Kryukov 2-Feb-12 20:03pm    
And where is the inner class?
--SA
Martin Arapovic 3-Feb-12 1:08am    
Well "innerclass" in my example is child class. Two classes from example are created to fit the problem.
Sergey Alexandrovich Kryukov 2-Feb-12 20:05pm    
Bad OOP design; ParentID, ChildID, Name should go in common base class. The problem is not addressed. Sorry, as the answer of an expert this only deserves the vote of 1.
--SA
Martin Arapovic 3-Feb-12 1:17am    
Yes they should go, but i wanted to write simple example thta fits user question.
And one more thing about your vote! I don't care about votes and points! I just tried to help. So, you sholud do the same thing.
Pete O'Hanlon 3-Feb-12 4:15am    
Good for you. This is typical SA behaviour, and I hope it doesn't get to you. My vote of 5 because while the answer wasn't perfect (what answer is), it's a good stab at it.
Hi,

Here is one more flexible solution that will fit your needs..

C#
void Main()
{
	// Collection of Parent objects
	var parents = new List<Parent>(new Parent[]
		{
			new Parent { ParentID = 1, Name = "John", Child = new Child { ChildID = 1, Name = "Child1", Date = new DateTime(2012, 02, 01) }},
			new Parent { ParentID = 2, Name = "Mark", Child = new Child { ChildID = 2, Name = "Child2", Date = new DateTime(2012, 02, 10) }},
			new Parent { ParentID = 3, Name = "Jack", Child = new Child { ChildID = 3, Name = "Child3", Date = new DateTime(2012, 01, 31) }}
		}
	);
	parents.Dump("Before Sort");
	var parentOrdered = parents.AsQueryable().OrderBy("Child.Date").ToList();;
	parentOrdered.Dump("After Sort");
}

// Found on http://landman-code.blogspot.com/2008/11/linq-to-entities-string-based-dynamic.html
public static class StringFieldNameSortingSupport
{
	#region Private expression tree helpers

	private static LambdaExpression GenerateSelector<TEntity>(String propertyName, out Type resultType) where TEntity : class
	{
		// Create a parameter to pass into the Lambda expression (Entity => Entity.OrderByField).
		var parameter = Expression.Parameter(typeof(TEntity), "Entity");
		//  create the selector part, but support child properties
		PropertyInfo property;
		Expression propertyAccess;
		if (propertyName.Contains('.'))
		{
			// support to be sorted on child fields.
			String[] childProperties = propertyName.Split('.');
			property = typeof(TEntity).GetProperty(childProperties[0], BindingFlags.Instance | BindingFlags.NonPublic | BindingFlags.Public);
			propertyAccess = Expression.MakeMemberAccess(parameter, property);
			for (int i = 1; i < childProperties.Length; i++)
			{
				property = property.PropertyType.GetProperty(childProperties[i], BindingFlags.Instance | BindingFlags.NonPublic | BindingFlags.Public);
				propertyAccess = Expression.MakeMemberAccess(propertyAccess, property);
			}
		}
		else
		{
			property = typeof(TEntity).GetProperty(propertyName, BindingFlags.Instance | BindingFlags.NonPublic | BindingFlags.Public);
			propertyAccess = Expression.MakeMemberAccess(parameter, property);
		}
		resultType = property.PropertyType;
		// Create the order by expression.
		return Expression.Lambda(propertyAccess, parameter);
	}
	private static MethodCallExpression GenerateMethodCall<TEntity>(IQueryable<TEntity> source, string methodName, String fieldName) where TEntity : class
	{
		Type type = typeof(TEntity);
		Type selectorResultType;
		LambdaExpression selector = GenerateSelector<TEntity>(fieldName, out selectorResultType);
		MethodCallExpression resultExp = Expression.Call(typeof(Queryable), methodName,
						new Type[] { type, selectorResultType },
						source.Expression, Expression.Quote(selector));
		return resultExp;
	}
	#endregion
	public static IOrderedQueryable<TEntity> OrderBy<TEntity>(this IQueryable<TEntity> source, string fieldName) where TEntity : class
	{
		MethodCallExpression resultExp = GenerateMethodCall<TEntity>(source, "OrderBy", fieldName);
		return source.Provider.CreateQuery<TEntity>(resultExp) as IOrderedQueryable<TEntity>;
	}

	public static IOrderedQueryable<TEntity> OrderByDescending<TEntity>(this IQueryable<TEntity> source, string fieldName) where TEntity : class
	{
		MethodCallExpression resultExp = GenerateMethodCall<TEntity>(source, "OrderByDescending", fieldName);
		return source.Provider.CreateQuery<TEntity>(resultExp) as IOrderedQueryable<TEntity>;
	}
	public static IOrderedQueryable<TEntity> ThenBy<TEntity>(this IOrderedQueryable<TEntity> source, string fieldName) where TEntity : class
	{
		MethodCallExpression resultExp = GenerateMethodCall<TEntity>(source, "ThenBy", fieldName);
		return source.Provider.CreateQuery<TEntity>(resultExp) as IOrderedQueryable<TEntity>;
	}
	public static IOrderedQueryable<TEntity> ThenByDescending<TEntity>(this IOrderedQueryable<TEntity> source, string fieldName) where TEntity : class
	{
		MethodCallExpression resultExp = GenerateMethodCall<TEntity>(source, "ThenByDescending", fieldName);
		return source.Provider.CreateQuery<TEntity>(resultExp) as IOrderedQueryable<TEntity>;
	}
	public static IOrderedQueryable<TEntity> OrderUsingSortExpression<TEntity>(this IQueryable<TEntity> source, string sortExpression) where TEntity : class
	{
		String[] orderFields = sortExpression.Split(',');
		IOrderedQueryable<TEntity> result = null;
		for (int currentFieldIndex = 0; currentFieldIndex < orderFields.Length; currentFieldIndex++)
		{
			String[] expressionPart = orderFields[currentFieldIndex].Trim().Split(' ');
			String sortField = expressionPart[0];
			Boolean sortDescending = (expressionPart.Length == 2) && (expressionPart[1].Equals("DESC", StringComparison.OrdinalIgnoreCase));
			if (sortDescending)
			{
				result = currentFieldIndex == 0 ? source.OrderByDescending(sortField) : result.ThenByDescending(sortField);
			}
			else
			{
				result = currentFieldIndex == 0 ? source.OrderBy(sortField) : result.ThenBy(sortField);
			}
		}
		return result;
	}
}
// Define other methods and classes here
public class Parent
{
  public int ParentID { get; set; }
  public string Name { get; set; } 
  public Child Child { get; set; }
}
 
public class Child
{
  public int ChildID { get; set; }
  public string Name { get; set; }
  public DateTime Date { get; set; }
}


Use LinqPad to test it...
I hope that i helped a little...
 
Share this answer
 
v2

This content, along with any associated source code and files, is licensed under The Code Project Open License (CPOL)



CodeProject, 20 Bay Street, 11th Floor Toronto, Ontario, Canada M5J 2N8 +1 (416) 849-8900