实体框架通用
本文关键字:框架 实体 | 更新日期: 2023-09-27 18:29:38
我有如下代码:
switch(sort.Column)
{
case "code":
model = (sort.Direction == SortDirection.Ascending)
? model.OrderBy(x => x.code)
: model.OrderByDescending(x => x.code);
break;
case "name":
model = (sort.Direction == SortDirection.Ascending)
? model.OrderBy(x => x.name)
: model.OrderByDescending(x => x.name);
break;
..............
}
我有大约10-15个字段(如"代码"answers"名称"),我不想复制和粘贴只有一个不同的类似代码-字段名称。
是否有某种方法可以概括查询?
您可以使用反射(这假设code
和name
是属性;如果它们是公共变量,则必须进行相应的修改):
model = (sort.Direction == SortDirection.Ascending)
? model.OrderBy( x => x.GetType()
.GetProperty( sort.Column ).GetValue( x, null ) ) :
: model.OrderByDescending( x => x.GetType()
.GetProperty( sort.Column ).GetValue( x, null ) );
正如Dunc在下面的评论中指出的那样,这种方法在枚举的每一步都强制进行反射,并且随着操作的进行,反射是昂贵的。如果集合是同构的,则可以通过将反射移出枚举来获得更好的性能。如果您的model
只包含类型为Foo
的元素,则可以执行以下操作:
var prop = typeof( Foo ).GetProperty( sort.Column );
model = (sort.Direction == SortDirection.Ascending)
? model.OrderBy( x => prop.GetValue( x, null ) ) :
: model.OrderByDescending( x => prop.GetValue( x, null ) );
如果您的集合不是同质的,请不要这样做会抛出TargetException
。
这会让您开始,但如果属性和列完全匹配,您也可以使用反射通过Column获取属性名称。
// inline function
Func<Func<Model, TResult>, Model> Order = criteria =>
{
return (sort.Direction == SortDirection.Ascending)
? model.OrderBy(criteria)
: model.OrderByDescending(criteria);
}
... code down to switch ...
这会将您的姓名大小写缩短为:
model = Order(x => x.name);
但有了反思,你可以不用开关就可以做到,但我的反思能力有点弱,所以如果其他人愿意,我会把它留给他们。
正如"没有这样的IP"所说,这有一些模式-命令调度器/工厂方法等。这些都是有效的选择。但有时这些只是掩盖了复杂性。我的建议是考虑使用动态linq。这里有一个链接可以让你开始:http://weblogs.asp.net/scottgu/archive/2008/01/07/dynamic-linq-part-1-using-the-linq-dynamic-query-library.aspx
如果你愿意,你也可以自己滚动,因为它并不太复杂。创建您自己的扩展方法,允许您传递有关您的顺序的参数(即排序方向、排序列),在该扩展方法中,使用system.linq.expressions命名空间通过语句建立您自己的顺序。以下也是一个例子:http://ronniediaz.com/2011/05/24/orderby-string-in-linq-c-net-dynamic-sorting-of-anonymous-types/