Click here to Skip to main content
Sign Up to vote bad
good
See more: ASP.NETentityLink
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 2 Feb '12 - 3:56
bipin9840
Edited 3 Feb '12 - 10:26


2 solutions

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. Smile | :)
Download LINQPad and paste this code example in new query. For language select "C# Program" and run it.
 
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
List<t>, Array, or Dictionary<tkey,>
In general, you can query "anything" that implements
IEnumerable or IEnumerable<t>
interfaces.
You can visti msdn sites[^] for more info about LINQ for start.
 
Ok, I talk too much... Wink | ;)
Bye...
  Permalink  
Comments
SAKryukov - 2 Feb '12 - 20:03
And where is the inner class? --SA
martin_arapovic - 3 Feb '12 - 1:08
Well "innerclass" in my example is child class. Two classes from example are created to fit the problem.
SAKryukov - 2 Feb '12 - 20:05
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:17
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:15
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.
Martin Arapovic - 3 Feb '12 - 11:35
Thx... I don't like people that are destructive! He could give right answer to the question and then review my answer. That would be the right way and then we all can learn something from "expert". :)
Pete O'Hanlon - 3 Feb '12 - 4:14
Where do you get off with being so arrogant to someone who's trying to help? "as the answer of an expert" - Lord preserve us from people with an inflated sense of self worth; always remember that there is someone who knows more than you do, perhaps a bit of humility wouldn't hurt. Your arrogance is driving people away from helping out on this site. There's a reason I don't help out much in Q and A anymore and you are that reason. Your noise on the answers sometimes only serves to confuse the original poster. Dial the attitude back and appreciate that others are trying to help. Encourage them by all means, but don't be such an arrogant dick.
bipin9 - 3 Feb '12 - 0:37
Thanks a lot... Yes this is something i want to have but how i can pass sort expression that is i am getting value for sorting from grid(grid column name) i.e in this example how can i get date as sort expression and then want to apply sorting.
Martin Arapovic - 3 Feb '12 - 13:03
Hi! There is a solution to that to, but you need to use DynimcLINQ (ExpressionTrees and lambdas). I think you will find solution for your problem on this page. http://landman-code.blogspot.com/2008/11/linq-to-entities-string-based-dynamic.html This solution is written for LinqToEntities, but I'll update my answer to include methods from given link...
Wayne Gaylard - 3 Feb '12 - 4:42
My 5. For answering the original question.
Keith Barrow - 3 Feb '12 - 16:28
My 5 too, don't let the comments of others put you off.
thatraja - 4 Feb '12 - 2:45
My 5 too
Hi,
 
Here is one more flexible solution that will fit your needs..
 
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...
  Permalink  

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

  Print Answers RSS
Your Filters
Interested
Ignored
     
0 Mahesh Bailwal 413
1 Sergey Alexandrovich Kryukov 384
2 Maciej Los 200
3 Aarti Meswania 193
4 Rohan Leuva 165
0 Sergey Alexandrovich Kryukov 9,417
1 OriginalGriff 7,204
2 CPallini 3,933
3 Rohan Leuva 3,211
4 Maciej Los 2,743


Advertise | Privacy | Mobile
Web04 | 2.6.130516.1 | Last Updated 3 Feb 2012
Copyright © CodeProject, 1999-2013
All Rights Reserved. Terms of Use
Layout: fixed | fluid