Click here to Skip to main content
Rate this: bad
good
Please Sign up or sign in to vote.
See more: ASP.NET entity Link
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:56am
bipin9892
Edited 3-Feb-12 10:26am
Keith Barrow144.9K
v2
Rate this: bad
good
Please Sign up or sign in to vote.

Solution 1

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  
v2
Comments
SAKryukov at 2-Feb-12 20:03pm
   
And where is the inner class?
--SA
martin_arapovic at 3-Feb-12 1:08am
   
Well "innerclass" in my example is child class. Two classes from example are created to fit the problem.
SAKryukov at 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 at 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 at 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.
Martin Arapovic at 3-Feb-12 11:35am
   
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 at 3-Feb-12 4:14am
   
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 at 3-Feb-12 0:37am
   
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 at 3-Feb-12 13:03pm
   
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 at 3-Feb-12 4:42am
   
My 5. For answering the original question.
Keith Barrow at 3-Feb-12 16:28pm
   
My 5 too, don't let the comments of others put you off.
thatraja at 4-Feb-12 2:45am
   
My 5 too
Rate this: bad
good
Please Sign up or sign in to vote.

Solution 2

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  
v2

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

  Print Answers RSS
0 OriginalGriff 230
1 Sergey Alexandrovich Kryukov 104
2 Richard MacCutchan 100
3 kbrandwijk 75
4 Vinay Mistry 70
0 Sergey Alexandrovich Kryukov 9,040
1 OriginalGriff 8,121
2 CPallini 2,613
3 Richard MacCutchan 2,221
4 Abhinav S 1,928


Advertise | Privacy | Mobile
Web03 | 2.8.140827.1 | Last Updated 3 Feb 2012
Copyright © CodeProject, 1999-2014
All Rights Reserved. Terms of Service
Layout: fixed | fluid

CodeProject, 503-250 Ferrand Drive Toronto Ontario, M3C 3G8 Canada +1 416-849-8900 x 100