使用.Toarray方法后对通用列表进行排序

3
我正在使用以下代码将分页数据源绑定到重复控件:
  protected void Paging()
    {
        Array q = (Array)Session["q"];
        PagedDataSource objPds = new PagedDataSource();
        objPds.DataSource = q;
        objPds.AllowPaging = true;
        objPds.PageSize = Convert.ToInt32(ddlPageNo.SelectedValue);

        objPds.CurrentPageIndex = CurrentPage;

        lblCurrentPage.Text = "Page: " + (CurrentPage + 1).ToString() + " of "
           + objPds.PageCount.ToString();

        // Disable Prev or Next buttons if necessary
        cmdPrev.Enabled = !objPds.IsFirstPage;
        cmdNext.Enabled = !objPds.IsLastPage;

        rptHotels.DataSource = objPds;
        rptHotels.DataBind();

    }

其中q表示

 getAvailableHotelResponse getres = new getAvailableHotelResponse();    
  getres = objsoap.getAvailableHotel(apiKey, destinationId, checkIn, checkOut, strCurrencyCode, "UK", false, rooms, f);   
            List<hotel> hr = new List<hotel>();
            hr = getres.availableHotels.ToList();

            List<BALHotelList> bh = new List<BALHotelList>();
            bh = h.GetHotelListByDestinationId(destinationId);
     var q = from a in bh
                    join b in hr on a.HotelCode equals b.hotelCode
                    orderby a.HotelName
                    select new
            {
                a.HotelCode,
                a.ImageURL_Text,
                a.HotelName,
                a.StarRating,
                a.HotelAddress,
                a.Destination,
                a.Country,
                a.HotelInfo,
                a.Latitude,
                a.Longitude,
                b.totalPrice,
                b.totalPriceSpecified,
                b.totalSalePrice,
                b.totalSalePriceSpecified,
                b.rooms

            };


            //rptHotels.DataSource = getres.availableHotels;

            Session["q"] = q.ToArray();

现在我想要使用

想要按照 hotelname 或者 starRating 对数组 q 进行排序。

我找不到像

q.sort(); 

或者
q.orderBy(q->hotelName)

1
添加 using System.Linq; - Tim Schmelter
@TimSchmelter 我已经包含了这个命名空间。 - rahularyansharma
3个回答

2

对现有数组按成员进行原地排序:

Array.Sort(theArray, (x,y) => string.Compare(x.HotelName, y.HotelName));

2

使用以下命令在终端中打开文件:

q.OrderBy(x => x.HotelName);

更新

从会话中回溯,可以像这样执行:

//if you have concrete type instead of object, use that type

var t = (IEnumerable<object>)Session["q"];

更新2

您的投影应该是一个具体类型(即创建一个新的Hotel类来表示您的投影),否则您将无法按照投影的某个属性进行排序。


2
我认为应该这样写:q.OrderBy(result -> result.HotelName); ...不需要 ToList() - IAbstract
@Anand,q上没有出现OrderBy方法。 - rahularyansharma
@Anand,system.array没有OrderBy的定义。 - rahularyansharma
请查看此链接:http://msdn.microsoft.com/zh-cn/library/bb534966.aspx。 这是一个 Enumerable 类的扩展方法,应该在那里。数组也是 Enumerable。 - Anand
你需要引用 System.Core 程序集和 System.Linq 命名空间。 - Anand
在那个时候,您仍然无法对参数进行排序,因为它现在只是一个对象的可枚举集合。 - Servy

1

q 对于您来说是 Array 类的一个实例,而不是某种类型的数组(即 int[]string[]object[])。Array 只实现了 IEnumerable,而没有实现 IEnumerable<T>,因此 Linq 方法不适用。这里的根本问题在于它是一个匿名类型的数组,因此除非使用非常混乱的解决方法,否则无法有效地获取强类型化的数组。

目前最好的解决方案是创建一个新类来保存您的数据(即 Hotel),而不是将其放入匿名类型中。当您填充会话时,请创建该类型(Hotel)的新实例,然后当您将其从会话中取出时,请将其转换为该类型的数组(Hotel[]),而不是通用的 Array。此时,您将能够在对象上使用 Linq 方法。


我已经使用了两个类,一个是BALHotel和Hotel,q是两个类对象的内部连接结果。我认为创建一个仅包含两个类对象内部连接结果的新类不是一个好的做法。这是正确的方法吗? - rahularyansharma
如果您已经有一个 Hotel 类,则需要使用不同的名称,但您几乎肯定希望为此创建一个新的具体类。匿名类型被设计用于单个方法体范围内使用,并且在方法之间不会保留。在这里创建一个新的具体类将是最容易的方法。 - Servy
是的,实际问题就在于var只能在方法内部使用,我们不能将var声明为全局变量。 - rahularyansharma
当我应用这种类型的连接时,我是否应该为每个结果创建单独的类? - rahularyansharma
如果你只在一个方法的范围内使用结果,那么不需要。但是,如果你想要返回结果或将其存储在字段中以便在其他地方访问,那么你需要创建一个具体类。@rahularyansharma - Servy

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接