如何从内部类获取属性进行排序 [英] How to get property from inner class for sorting
问题描述
嗨..
我比较新鲜,想知道如何从内部类中获取属性以进行排序
说明如下
我有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屋!