如何从内部类获取属性进行排序 [英] How to get property from inner class for sorting

查看:81
本文介绍了如何从内部类获取属性进行排序的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

嗨..
我比较新鲜,想知道如何从内部类中获取属性以进行排序
说明如下
我有ClassOne具有属性,而ClassTwo类的对象也具有属性.
因此,我想获取ClassTwo的属性,以便可以使用LINQ查询根据ClassOne中的ClassTwo的属性进行排序.

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.

推荐答案



我不完全知道您要实现什么目标,但是我尝试为您的问题举一个例子.
首先,此示例使用 LINQPad [ ^ ].如果您想与linq一起玩,则必须具有此工具. :)
下载LINQPad并将此代码示例粘贴到新查询中.对于语言,选择"C#程序"并运行它.

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.

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; }
}



我猜您正在使用某些ORM工具/framewrok(NHibernate,EntityFramewrok,LinqToSQL),并且在我的示例中有类似的对象吗? 没关系!我只想说您可以使用LINQ查询任何可枚举的集合,例如



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>

接口.
您可以访问 msdn网站 [

interfaces.
You can visti msdn sites[^] for more info about LINQ for start.

Ok, I talk too much... ;)
Bye...




这是一种更灵活的解决方案,可以满足您的需求..

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; }
}



使用LinqPad对其进行测试...
我希望我能有所帮助...



Use LinqPad to test it...
I hope that i helped a little...


这篇关于如何从内部类获取属性进行排序的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆