实体框架通用

时间:2012-03-30 21:49:17

标签: c# entity-framework

我的代码如下:

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个字段(比如'代码'和'名称'),我不想复制和粘贴只有一个区别的相似代码 - 字段名称。

是否存在以某种方式概括查询的方法?

3 个答案:

答案 0 :(得分:7)

您可以使用反射(假设codename属性;如果它们是公共变量,则必须相应地修改):

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

答案 1 :(得分:3)

这可以帮助您入门,但如果属性和列完全匹配,您还可以使用反射通过列获取属性名称。

// 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);

但是通过反思,你可以在没有开关的情况下做到这一点,但我在反思上有点弱,所以如果他们想要的话,我会把它留给别人。

答案 2 :(得分:1)

正如'No Such 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/