【问题标题】:Random order with Entity Framework and MySQL使用实体框架和 MySQL 的随机顺序
【发布时间】:2013-12-21 02:56:27
【问题描述】:

总结:我想找到一种使用 Entity Framework 和 MySQL 进行随机排序的方法(这很重要)。该解决方案不应在从数据库加载所有值之后使用原始 sql 查询或排序。

我的尝试:

我想到了使用 NewGuid() 来自 that answer 的随机顺序。

代码:

var query = from e in context.Table
orderby Guid.NewGuid()
select e;
var test = query.FirstOrDefault();

总是抛出异常:

An error occurred while executing the command definition. See the inner exception for details.
Inner exception:
FUNCTION MyDatabase.NewGuid does not exist System.Exception {MySql.Data.MySqlClient.MySqlException}

似乎问题在于 MySQL 没有函数 NewGuid()。

如何通过 MySQL 函数 RAND() 而不是 NewGuid() 进行排序。也就是说,如何在Entity Framework中使用自定义函数RAND

【问题讨论】:

  • 您有一个 PK 为 Guid 的实体,并试图通过创建新的 Guids 来订购?如果是这种情况,你应该order by e.NameOfYourId
  • @Tico,不,我没有 Guid 字段。我的 PK 是具有自动增量的整数。 NewGuid() 是用于(在这种情况下)随机顺序的函数。所以每个查询结果都是不同的。我从这里 stackoverflow.com/a/4120132/596207 了解了 NewGuid()
  • 静态方法Guid.NewGuid() 创建一个新的有效Guid,因此您基本上是在不“有效”的条件下订购您的查询。我认为最好列出所有元素,然后将它们随机化。
  • 问题中的编辑(当前代码):,它似乎正在工作。
  • @Tico,它有效 :) 几乎是我目前用作解决方法的那个变体(区别在于我使用 AsEnumerable() 而不是 ToList())。我不经常使用这种变体的原因是从数据库加载到客户端的所有行而不是有限的行(例如 500 行而不是 10 行)。无论如何,感谢您帮助调查此案。

标签: c# mysql entity-framework


【解决方案1】:

似乎问题在于 MySQL 没有函数 NewGuid()。

叫我偷懒,不过问题好像是MySql没有一个叫NewGuid的函数。那么最简单的解决方案不是在 MySql 中创建一个名为 NewGuid 的函数吗?

DELIMITER $$
CREATE DEFINER=`root`@`localhost` FUNCTION `NewGuid`() RETURNS char(36)
BEGIN
RETURN UUID();
END$$
DELIMITER ;

在创建 MySQL NewGuid 函数后,问题为我解决了。

编辑:问题指出“解决方案不应使用原始 sql 查询”,这不需要原始 SELECT/INSERT 语句。但它确实需要创建数据库函数。

额外说明:我会说这在技术上是 MySQL 实现中的一个错误。 Canonical Functions 被微软称为“所有数据提供商都支持”。 NewGuid 列于Other Canonical Functions

【讨论】:

  • 谢谢。有趣的解决方案。
  • 我用了这个,它工作了,但是用这个获取相关实体有问题。所以我首先获取随机记录,然后创建另一个查询来获取随机记录的相关实体。
【解决方案2】:

使用以下查询:

var query = from e in context.Table
            orderby SqlFunctions.Rand(1) 
            select e).Take(10);

希望你的 MySql Data Providor 不能被 VS 识别。

我知道 Vs 不直接支持 MySQL to LINQ。所以也许你可以使用类似的东西。

而且可能你需要下载这种数据提供者并尝试一下

下载它们并尝试一下:

  1. ALinq
  2. ORDesigner_VS2008ORDesigner_VS2010
  3. MySQL ADO.NET Data Provider(如果已安装,无需重新安装)。


如果你仍然失败,这可能是对的假设 Students 是 Student 表中的模型

using (ConsoleApplications.DataClasses1DataContext dd = new ConsoleApplications.DataClasses1DataContext())
{
   var result = (from stu in dd.Students.AsEnumerable()
      select new
      {
       stu.StudentName,
       RandomId = new Random(DateTime.Now.Millisecond).Next(dd.Students.Count())
      }).OrderBy(s => s.RandomId);

      foreach (var item in result)
      {
        Console.WriteLine(item.StudentName);
      }
}

【讨论】:

    【解决方案3】:

    我遵循了@Monkey Code 给出的答案,但有所不同的是,生成的 guid 尽管是随机的,但它是有序的,我的快速解决方案是使用以下内容:

    ...
    RETURN MD5(UUID());
    ...
    

    【讨论】:

    • 它基于以前的解决方案工作,但是在获取相关实体时存在问题。所以我首先获取随机记录,然后创建另一个查询来获取随机记录的相关实体。
    【解决方案4】:

    这可能对你有帮助

    var yourRecords = context.Table().OrderBy(c=>c.Name);
    
    yourRecords = yourRecords.OrderBy(a => Guid.NewGuid());
    

    【讨论】:

    • 请阅读问题。此变体适用于 MSSQL,但不适用于 MySQL。
    • 将结果转换为列表,这样您就不再与数据库绑定。然后按 guid 的顺序将使用 linq2objects。 context.Table().ToList().OrderBy(x => Guid.NewGuid()); 只需确保限制记录集,以免将太多数据加载到内存中。
    猜你喜欢
    • 1970-01-01
    • 2021-10-12
    • 1970-01-01
    • 2020-08-12
    • 2017-02-11
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多