C# 随机查询每次返回相同的记录

C# 随机查询每次返回相同的记录,c#,ms-access,oledb,C#,Ms Access,Oledb,我使用以下查询从表中选择5条随机记录 SELECT Top 5 * FROM (SELECT *, Rnd(ID) AS RandomValue FROM Words) ORDER BY RandomValue 此查询在MS Access中运行良好 但是,当我在c应用程序中使用它时,问题就出现了。它每次返回相同的5条记录 using System; using System.Collections.Generic; using System.D

我使用以下查询从表中选择5条随机记录

SELECT Top 5 *
FROM   (SELECT *,
           Rnd(ID) AS RandomValue
        FROM   Words)
ORDER  BY RandomValue 
此查询在MS Access中运行良好

但是,当我在c应用程序中使用它时,问题就出现了。它每次返回相同的5条记录

using System;
using System.Collections.Generic;
using System.Data;
using System.Data.Common;
using System.Text;

namespace MicrosiftAccessDbProviderFactory______Test
{
    public class MyClass 
    {
        public int ID { get; set; }
        public string Name { get; set; }
    }

    public class Program
    {
        static void Main(string[] args)
        {
            string connString = @"Provider=Microsoft.ACE.OLEDB.12.0;Data Source=D:\db1.mdb;Persist Security Info=False";
            string providerName = @"System.Data.OleDb";
            DbProviderFactory factory = DbProviderFactories.GetFactory(providerName);

            IDbConnection Connection = factory.CreateConnection();
            Connection.ConnectionString = connString;
            Connection.Open();

            IDbTransaction Transaction = Connection.BeginTransaction();

            IDbCommand Command = factory.CreateCommand();
            Command.Connection = Connection;
            Command.Transaction = Transaction;

            int count = 5;

            Command.CommandText = @"SELECT Top " + count + @" ID, Name
                                    FROM   (SELECT *,
                                               Rnd(ID) AS RandomValue
                                            FROM   Words)
                                    ORDER  BY RandomValue";
            IDataReader dataReader = Command.ExecuteReader();
            IList<MyClass> list = null;
            MyClass item = null;
            while (dataReader.Read())
            {
                if (list == null)
                {
                    list = new List<MyClass>();
                }

                item = new MyClass();
                item.ID = dataReader.GetInt32(0);
                item.Name = dataReader.GetString(1);

                list.Add(item);
            }

            dataReader.Close();

            Transaction.Commit();

            string str = string.Empty;
        }
    }
}

我如何解决这个问题?

这一直让我很感兴趣。真正让我着迷的是它为什么在Access中工作。我能理解为什么它不能与c一起工作:rnd总是用相同的值初始化。我的解决方案很难看,但很有效。我希望有人能看看解决方案,看看如何改进。至少它包含了一个想法的种子,如何在Access和c之间工作

第一步

在Access中创建一个与目标表相同的表WordsGUID,但有一个额外的字段RandomGUID,设置为数据类型AutoNumber,字段大小复制Id。为了更好地衡量,我使它没有重复的索引,但我怀疑这是必要的

第二步

在C中插入以下内容

Command.CommandText ="DELETE FROM WordsGUID";
Command.ExecuteNonQuery();

Command.CommandText ="INSERT INTO WordsGUID SELECT * FROM Words";
Command.ExecuteNonQuery();

Command.CommandText ="SELECT TOP 5 * FROM WordsGUID ORDER BY RandomGUID";
IDataReader dataReader = Command.ExecuteReader();
等等

就像我说的,很难看,如果你有一张大桌子,速度可能会非常慢,但我想不出比这更好的了

您需要为Rnd函数添加盐,如:

SELECT * FROM SomeTable ORDER BY Rnd(-Timer()*[ID])
因此,在您的查询中:

Command.CommandText = @"SELECT Top " + count + @" ID, [Name]
                        FROM Words
                        ORDER BY Rnd(-Timer()*[ID])";

看起来您使用的是两个不同的表MyTable和Words。@jdweng,这是一个输入错误。您可以在oneL中执行这3个步骤,从Words order by newid中选择前5个*,至少在MS SQL中可以使用;我已经多年没有使用Access了。@JohnLBevan不幸的是Access中没有新ID