MVC4,public virtual ICollection,如何设置排序顺序

时间:2014-03-11 17:00:42

标签: c# asp.net-mvc asp.net-mvc-4 ef-code-first

我使用Code First EF 5进行MVC4项目。

我有使用公共虚拟ICollection的模型,我想设置这些集合中项目的排序顺序。

例如:

说我有一个订单型号:

public class Order
{
 public virtual ICollection<OrderItem> Items { get; set; }
}

和OrderItems模型:

public Class OrderItem
{
 public int ID;
 public string name;
 public decimal price;
}

我想为每个订单设置OrderItem集合的Order,以降序价格出现。我该怎么办呢?或者,事实上,它有可能吗?

我尝试过添加:

 this.Items.OrderByDescending(OrderItem,"price");

订单模型构造函数(胖模型,瘦控制器?)

我也尝试将它添加到Controller Action和View中,但没有一个有效。

我猜测在DbContext中可能有某种方法可以做到这一点,但我必须承认我有点迷失。

更新:到目前为止,我已根据建议尝试了以下解决方案,但无济于事。

    private ICollection<OrderItem> _Items;
    public virtual ICollection<OrderItem> Items
    {
        get { return _Items.OrderByDescending(item => item.Price).ToList(); }
        set { _Items = value; }
    }

这产生了这个错误:值不能为空。参数名称:source

我是否需要向构造函数添加内容?

我还尝试在Model和以下内容中添加一个Constructor:

public OrderItem()
{
this.Items = this.Items.OrderByDescending(i => i.Price).ToList();
}

这没有任何效果。

我也尝试过:

this.Items = this.Items.OrderByDescending(OrderItem, "price").ToList();

产生错误&#34; OrderItem是一种类型,但用作变量&#34;。

任何想法的人?

行。我刚刚将它添加到我的控制器中的详细信息方法中:

public ActionResult Details(int id = 0)
{
  order.Items = order.Items.OrderByDescending(item => item.price).ToList();         
}

哪个有效。我仍然想知道为什么可能获得;组;虽然解决方案不适合将来参考。 Lazy,Eager和Explicit Loading之间的区别是否与此相关?

非常感谢。

好的所以我尝试了Ken4z的建议,并补充道:

public Order()
{
_Items = new List<OrderItem>();
}

这可以防止任何错误,但在控制器中调用操作时实际上不会加载任何项目。可能是一个愚蠢的问题,但无论如何我都要问它:

set { _Items = value; }  

是不是构造函数现在将作为OrderItem列表传递而没有任何内容?试图完全掌握这一点。再次感谢您的帮助。

3 个答案:

答案 0 :(得分:2)

var orderedItems = Items.OrderByDescending(item => item.price);

编辑1:

根据David的评论,我正在解释&#34; Set&#34;意思是,您希望Items集合的访问者默认按价格按降序返回。在这种情况下,您需要实现getter。

public class Order
{
    private ICollection<OrderItems> _items;
    public virtual ICollection<OrderItems> Items 
    {
        get{ return _items.OrderByDescending(item => item.price); }
        set{ _items = value; }
    }
}

编辑2: 感谢大卫指出错误。

public class Order
{
    public Order()
    {
        _items = new List<OrderItems>();
    }

    private ICollection<OrderItems> _items;
    public virtual ICollection<OrderItems> Items 
    {
        get{ return _items.OrderByDescending(item => item.price).ToList(); }
        set{ _items = value; }
    }
}

答案 1 :(得分:1)

this.Items.OrderByDescending(OrderItem,"price");

LINQ方法返回一个新实例,因此您必须设置此结果:

this.Items = this.Items.OrderByDescending(OrderItem, "price").ToList();

注意ToList(),因为结果为IEnumerable<T>ICollection<T> : IEnumerable<T>,但IEnumerable<T>不属于ICollection<T>List<T> : ICollection<T>

您还可以使用“清洁”,类型安全的LINQ方法版本:

this.Items = this.Items.OrderByDescending(i => i.price).ToList();

答案 2 :(得分:0)

如果您最终经常需要排序ICollection导航属性,您可以随时添加如下内容: [NotMapped] public IList<OrderItem> ItemsSorted {get {return Items?.OrderBy(p=>p.price).ToList(); }}

到您的域实体,这样当您在控制器或其他代码中使用它时,您不必经常对事物进行排序。