C# 使用数组作为比较器覆盖LINQ查询中的默认排序

C# 使用数组作为比较器覆盖LINQ查询中的默认排序,c#,linq,C#,Linq,我有一个从会话变量中提取的ID号列表,并将其转换为一个数组,用于LINQ查询,然后用于填充下拉列表。这基本上是程序访问的最近客户端的列表。我希望它能按上次访问的顺序显示它们 示例数组值66、78、55、24、80 在LINQ查询之后,默认情况下,它按ID对它们进行排序:24、55、66、78、80 因此,当它显示在dropdownlist中时,它是按这种方式排序的,而我真正需要的是让它保持在数组值的顺序上,只是颠倒过来:80、24、55、78、66 代码: 使用接受的解决方案编辑更正的代码: /

我有一个从会话变量中提取的ID号列表,并将其转换为一个数组,用于LINQ查询,然后用于填充下拉列表。这基本上是程序访问的最近客户端的列表。我希望它能按上次访问的顺序显示它们

示例数组值66、78、55、24、80

在LINQ查询之后,默认情况下,它按ID对它们进行排序:24、55、66、78、80

因此,当它显示在dropdownlist中时,它是按这种方式排序的,而我真正需要的是让它保持在数组值的顺序上,只是颠倒过来:80、24、55、78、66

代码:

使用接受的解决方案编辑更正的代码:

// Grab pre-built session variable with comma delimited int values
string RecentClients = Session["RecentClients"].ToString();

// Convert to Array
int[] RecentClientsArray = Array.ConvertAll(RecentClients.Split(','), n => Convert.ToInt32(n));

// Setup LINQ
DataClasses1DataContext db = new DataClasses1DataContext();

// Populate RecenClientList using RecentClientsArray to compare to ConsumerID
var RecentClientList = (from c in db.ClientNames
                        where RecentClientsArray.Contains(c.ConsumerID)
                        select new { FullName = c.LastName + ", " + c.FirstName + " #" + c.ConsumerID, recentConsumerID = c.ConsumerID });

var clients = (from item in RecentClientsArray
                join client in RecentClientList.ToList()
                on item equals client.recentConsumerID
                select client).Reverse().Distinct();

// Set and bind values for dropdown list.
ddLastClients.DataSource = clients;
ddLastClients.DataTextField = "FullName";
ddLastClients.DataValueField = "recentConsumerID";
ddLastClients.DataBind();

我认为您需要使用OrderByFunc、IComparer并指定您自己的比较器,它将直接实现您的复制,对不起。。。还没有优雅的解决方案来实现它,尽管尝试下面的方法,我使用List是因为我需要访问IndexOf,我在LINQ查询的added orderby子句中使用IndexOf:

       List<int> RecentClientsArray = Array.ConvertAll(RecentClients.Split(','), n => Convert.ToInt32(n)).ToList();
       // other code
       var RecentClientList = (from c in db.ClientNames
                               where RecentClientsArray.Contains(c.ConsumerID)
                               orderby RecentClientsArray.IndexOf(c.ConsumerID) descending
                               select new { FullName = c.LastName + ", " + c.FirstName + " #" + c.ConsumerID, recentConsumerID = c.HorizonID });

我会按照您当时写的那样保留您的查询,然后在内存中处理排序

给定

您可以使用Enumerable.Join将这些集合在一起。Join具有在Join操作中保持外部序列顺序的特性。使用join来获得基于数组的初始订单,然后使用Reverse来满足需求的最后部分。所以你可能只是

var clients = 
    (from item in RecentClientsArray 
     join client in RecentClientList.ToList() // materialize result from db
     on item equals client.recentConsumerID
     select client).Reverse();

您应该以数组的相反顺序查看客户端,然后将其用作控件上的数据源。

我的解决方案:使用字典和反向数组项。 这是我的密码:

            // Grab pre-built session variable with comma delimited int values
            string RecentClients = Session["RecentClients"].ToString();

            // Convert to Array
            int[] RecentClientsArray = Array.ConvertAll(RecentClients.Split(','), n => Convert.ToInt32(n));


            //NEW- I use dictionary to get the right place in reverse
            int ind = 0;
            Dictionary<int, int> dic = new Dictionary<int, int>();
            foreach (var item in RecentClientsArray.Reverse())
            {
                dic.Add(item, ind);
                ind++;
            }


            // Display in gridview to see current order of array (For debug purposes)
            gridArray.DataSource = RecentClientsArray;
            gridArray.DataBind();

            // Setup LINQ
            DataClasses1DataContext db = new DataClasses1DataContext();

            // Populate RecenClientList using RecentClientsArray to compare to ConsumerID
            //NEW- use orderby with dictionary
            var RecentClientList = (from c in db.ClientNames
            where RecentClientsArray.Contains(c.ConsumerID)
            orderby dic[c.ConsumerID]
            select new { FullName = c.LastName + ", " + c.FirstName + " #" + c.ConsumerID, recentConsumerID = c.HorizonID, ID = c.ConsumerID });

            // Display in gridview to see new order after populating var RecentClientList (for debug purposes)
            gridList.DataSource = RecentClientList;
            gridList.DataBind();

            // Set and bind values for dropdown list.
            ddLastClients.DataSource = RecentClientList;
            ddLastClients.DataTextField = "FullName";
            ddLastClients.DataValueField = "recentConsumerID";
            ddLastClients.DataBind();           

祝你好运,

谢谢你的列表提示。虽然我在编译时没有遇到错误,但我确实遇到了一个错误:DataSource和DataSourceID都是在“gridList”上定义的。删除一个定义。我的gridview是在没有数据源的.aspx页面上定义的,所以不确定为什么会发生这种情况。如果我删除orderby,它会工作,但仍然以错误的顺序进行调试,而不能够看到gridview开始标记和后面的整个代码。你确定你没有在某个地方设置它吗,Ctrl+F?这是aspx页面上标记中的全部内容:所有发布的内容都在页面加载中,并且是唯一的代码。你是否更改了RecentClientList的大小写?要检查的项目很好,但是使用intellisense,它会保留案例。只是仔细检查了一下。注意,我还尝试过按照其他用户的建议,在代码隐藏中将DataSourceID和DataSource for gridList设置为null。太棒了!这就成功了。现在,我只需要确保它有一个独特的,这样,如果我点击客户端66,然后点击其他一些,然后返回到66,它不会列出他们两次。编辑:哦。。非常感谢你!添加。在。反转之后是不同的。我们在做生意。再次感谢。将以原件形式发布完成的代码。
var clients = 
    (from item in RecentClientsArray 
     join client in RecentClientList.ToList() // materialize result from db
     on item equals client.recentConsumerID
     select client).Reverse();
            // Grab pre-built session variable with comma delimited int values
            string RecentClients = Session["RecentClients"].ToString();

            // Convert to Array
            int[] RecentClientsArray = Array.ConvertAll(RecentClients.Split(','), n => Convert.ToInt32(n));


            //NEW- I use dictionary to get the right place in reverse
            int ind = 0;
            Dictionary<int, int> dic = new Dictionary<int, int>();
            foreach (var item in RecentClientsArray.Reverse())
            {
                dic.Add(item, ind);
                ind++;
            }


            // Display in gridview to see current order of array (For debug purposes)
            gridArray.DataSource = RecentClientsArray;
            gridArray.DataBind();

            // Setup LINQ
            DataClasses1DataContext db = new DataClasses1DataContext();

            // Populate RecenClientList using RecentClientsArray to compare to ConsumerID
            //NEW- use orderby with dictionary
            var RecentClientList = (from c in db.ClientNames
            where RecentClientsArray.Contains(c.ConsumerID)
            orderby dic[c.ConsumerID]
            select new { FullName = c.LastName + ", " + c.FirstName + " #" + c.ConsumerID, recentConsumerID = c.HorizonID, ID = c.ConsumerID });

            // Display in gridview to see new order after populating var RecentClientList (for debug purposes)
            gridList.DataSource = RecentClientList;
            gridList.DataBind();

            // Set and bind values for dropdown list.
            ddLastClients.DataSource = RecentClientList;
            ddLastClients.DataTextField = "FullName";
            ddLastClients.DataValueField = "recentConsumerID";
            ddLastClients.DataBind();